That’s the sort of system that you can easily automatize in less than 5 minutes, and see if it’s profitable or not. For learning this, start here: 301 Moved Permanently
Back to money management, also called risk management. It’s an algorithmic method of distributing your money among a portfolio of assets and trade algorithms in a way that your profit is maximized and your risk is minimized. As you can imagine, there are many money management methods and philosophies. Zorro follows a method developed by Ralph Vince; he uses a computer algorithm that evaluates the equity curve for calculating the optimal percentage of the gained capital to be reinvested. This percentage is called the OptimalF factor (OptF in the above performance sheet). Multiply OptimalF with the capital earned so far, and you’ll get the maximum margin to be allocated to a certain trade.
Normally people try to stay well below this maximum margin; OptimalF was calculated from historic performance, after all, and there’s no guarantee that this performance will continue in the future. Thus normally only half or a third of OptimalF is reinvested.
Alice has modified her script for calculating the trade margin according to OptimalF. She has also split the trade algorithms for getting separately optimized parameters for long and for short trades. This is the new script (Workshop6_2):
function tradeTrend()
{
TimeFrame = 1;
var *Price = series(price());
var *Trend = series(LowPass(Price,optimize(250,100,1000)));
Stop = optimize(2,1,10) * ATR(100);
if(strstr(Algo,":L") and valley(Trend))
enterLong();
else if(strstr(Algo,":S") and peak(Trend))
enterShort();
}
function tradeCounterTrend()
{
var *Price = series(price());
var Threshold = optimize(1.0,0.5,2,0.1);
var *DomPeriod = series(DominantPeriod(Price,30));
var LowPeriod = LowPass(DomPeriod,500);
var *HP = series(HighPass(Price,LowPeriod*optimize(1,0.5,2)));
var *Signal = series(Fisher(HP,500));
Stop = optimize(2,1,10) * ATR(100);
if(strstr(Algo,":L") and crossUnder(Signal,-Threshold))
enterLong();
else if(strstr(Algo,":S") and crossOver(Signal,Threshold))
enterShort();
}
function run()
{
set(PARAMETERS+FACTORS); // use optimized parameters and reinvestment factors
BarPeriod = 240; // 4 hour bars
LookBack = 500; // needed for Fisher()
NumWFOCycles = 8; // activate WFO
NumBarCycles = 4; // 4 times oversampling
if(ReTrain) {
UpdateDays = 30; // reload new price data from the server every 30 days
SelectWFO = -1; // select the last cycle for re-optimization
}
// portfolio loop
while(asset(loop("EUR/USD","USD/CHF")))
while(algo(loop("TRND:L","TRND:S","CNTR:L","CNTR:S")))
{
// set up the optimal margin
if(Train)
Lots = 1;
else if(strstr(Algo,":L") and OptimalFLong > 0)
Lots = 1;
else if(strstr(Algo,":S") and OptimalFShort > 0)
Lots = 1;
else
Lots = 0;
if(strstr(Algo,"TRND"))
tradeTrend();
else if(strstr(Algo,"CNTR"))
tradeCounterTrend();
}
}
We now have four instead of two algorithm identifiers:
while(algo(loop(“TRND:L”,“TRND:S”,“CNTR:L”,“CNTR:S”)))
They are the same algorithms as before, only now separately for long and short trades by adding a “:L” or a “:S” to the algorithm identifier. Accordingly, some code within the trade functions must ensure that only the right sort of trades are opened:
if(strstr(Algo,":L") and crossUnder(Signal,-Threshold))
enterLong();
else if(strstr(Algo,":S") and crossOver(Signal,Threshold))
enterShort();
The strstr function checks if a substring (":L" in the first line above) occurs within a string (Algo), and returns nonzero (true) in that case. With this function we can see if two strings match partially. The and operator (also known, for C++ programmers, as the && operator) combines the two conditions in the if comparison. As a result, long trades are now only entered when the Algo string contains “:L”, and short trades are only entered when the Algo string contains “:S”.
The other modification lets Zorro now also calculate OptimalF factors in [Train] mode:
set(PARAMETERS+FACTORS);
The factors are then used in the inner loop for determining whether to allow trades or not:
if(Train)
Lots = 1;
else if(strstr(Algo,":L") and OptimalFLong > 0)
Lots = 1;
else if(strstr(Algo,":S") and OptimalFShort > 0)
Lots = 1;
else
Lots = 0;
The Lots variable is used for enabling or disabling trades in the subsequent algorithm. When Lots is 0, no new trade is opened, but the enterLong/enterShort functions can still exit trades that were open in the opposite direction. As the OptimalF factors are calculated separately for long and short trades, we need to check if the Algo string contains “:L” or “:S” for determining which factor to use. If the OptimalF factor is above zero, we have a profitable component and thus can enable trades. In training mode (Train flag is true) trades must always be enabled, otherwise the OptimalF factors could not be calculated at all in the first place.
This is the reward of Alice’s script improvements:
Due to the disabling of unprofitable components and the separate parameter generation for long and short trades, the equity curve now looks much smoother:
Be aware that the OptimalF factors are not calculated in every WFO step, but use the whole test period. This is better for life trading because money management factors need to be calculated from all data available; but strictly speaking this violates the out-of-sample test method. Therefore the real trading performance might be worse than the 493% predicted by the WFO test. This should be kept in mind.
A theoretical 493% annual return is certainly fine, but can we squeeze more than $13K out of this strategy over 2 years, from the same initial capital? By re-investing our profits, the overall result can be far better. This is the real purpose of the OptimalF factors. For this, Alice modifies the script a last time:
if(Train)
Lots = 1;
else if(strstr(Algo,":L") and OptimalFLong > 0) {
Lots = 1;
Margin = clamp((WinLong-LossLong) * OptimalFLong/2, 50, 10000);
} else if(strstr(Algo,":S") and OptimalFShort > 0) {
Lots = 1;
Margin = clamp((WinShort-LossShort) * OptimalFShort/2, 50, 10000);
} else
Lots = 0;
WinLong is the sum of all wins, LossLong the sum of all losses of long trades of the current component (i.e. asset/algo combination); therefore WinLong-LossLong is the component profit earned so far. The result is multiplied with half the OptimalF factor - we divide it by 2 for staying well below the maximum capital allocation. This gives the Margin that is now invested per trade. Finally, the clamp(…, 50, 10000) function limits the margin to between $50 and $10000. This ensures that the script starts trading even when no profit was achieved yet, and also sets an upper limit for not letting Bob’s wealth increase beyond all borders.
We can see that reinvesting profits has two effects. The absolute profit after 2 years has now more than doubled; if we had simulated a longer period, the difference had been even more remarkable. The bad thing is that also the drawdown in Summer 2011 now got much deeper, thus reducing the average annual return that is calculated as the ratio of profit to balance drawdown. Reinvesting profits generates more money, but requires stronger nerves. No risk, no fun.
What have we learned in this lesson?
-
The loop function can be used to go through a list of assets or algorithms.
-
The asset and algo functions select a certain asset and set up an algorithm identifier.
-
The strstr function can be used for comparing strings partially.
-
The OptimalF factors give the maximum capital allocation to a certain strategy component.
-
Increasing the return by reinvesting profits comes at a cost.
This was the last lesson of part 2 of the automated trading course. It’s now up to you to experiment with your own trade ideas and systems…
If anything was unclear or bad explained, please post here and I’ll try to help.
yes your right, ok i will start from page one thank you
Hey jcl, I’ve got some questions about where to find some kind of list or manual on all predefined trading functions (like enterLong(), crossUnder() etc.) and also what indicators are used or can be used in ZorroTrader is there a list somewhere. And the last question is, are there any books on lite-C, or is it the same as C. Thanks
Yes, there is a manual with all functions listed:
There is a book on lite-C, but it has the focus on game programming. But any C book will do also, as lite-C mostly uses the C syntax. For going deeper in lite-C I recommend “Sam’s Teach Yourself C in 24 Hours”. It’s more than 24 hours but you should find it online somewhere.
Nice threads. Will there be a part 3 or have you decided not to go ahead with it? That’s where I am more interested in. These two threads are a little basic.
They are probably not basic for most people here, but I see your point. Part 3 will be done. I just have to find some strategies that really rely on a perceptron or decision tree.
Great, looking forward to it. I dabbled in back-propagation with some success, and more failure, but it’s all very interesting to me. I think even some basic data mining would get a good following no doubt. Anyways, I don’t want to steer your threads away from you, it seems you know what you are doing. All the best.
I know these are rhetorical fees, but are EA programmers capable of earning this much in RL?
Anyway, your threads Part 1 and 2 are pure gold. I’ve been slowly progressing my way into becoming a mechanical trader and hope to move onto programming EAs and automating my system design by early next year. At the momet I do everything manually (i.e. record historical trades in an excel spreadsheet, one by one). Manually optimising more than one or two parameters is out of the question, although I suppose it acts as a safeguard against over-optimisation.
EA coders that only translate an existing trading system into an EA won’t earn much. All this is pretty easy stuff and quickly done, and many people can do EAs, so it’s not well paid.
It’s different when you have to implement a complex algorithm, such as a neural network, or develop and optimize a trade system from scratch, as Alice did. Then you can charge similar fees as Alice, but you have usually more work. The algorithm will look more complex and you’ll have a lot more problems to solve for your fee ;).
I think the keyword here though, is [B]look[/B].
Hi
Back in post#6 you have a line in the LowPass filter function:
var* LP = series(*Data,3);
I am trying to emulate the code in MQL. In this line, you call series function with [B]two[/B] arguments. What does the 2nd argument do/mean?
Thank you!
EDIT:
Scratch that, I worked it out from the context.
In the case that someone else runs into the same question: it is the length of the series.
For reproducing it in MT4, make sure that the series is shifted once per bar, not once per tick like the MT4 start function, and that the lowpass function is not called when the last candle is still incomplete. It is somewhat tricky to write correct code in MQL4. You can find some tips for lite-C <-> MQL4 conversion and and example on this website: Converting strategies.
Thanks for the link
Interesting post, well it is… But I had a look at the Zorro manual and noted this:
Zorro is intended to distribute money from the rich to the poor, not the other way around. For enforcing this, the free Zorro license has the following trading restrictions to prevent people from getting too rich by using the software:
Excellent!
But when using, also consider this:
- You can use Zorro for an annual trading profit of US$ 30,000. If you have reached that limit, you’re required to stop trading with Zorro for the rest of the year.
- You can have a capital of up to US$ 7,000 under direct or indirect control by Zorro. If the balance in your broker account exceeds that limit, you must withdraw your profits until it’s below that limit again. This also includes capital in other broker accounts when Zorro is used to generate trade signals or otherwise determine trade decisions with that capital.
*You can trade only with one Zorro. It is not allowed to trade with several Zorro instances simultaneously (this restriction only applies to Zorro version 1.05 and above).
- When you violate the above trading restrictions, you’re legally required to pay a US$ 1000 fee plus all the excess profit to oP group. We’ll gratefully take your donation and use it to add new features to Zorro.
Well for most retail traders this doesn’t apply, but for more serious users it is good to know that there are trade restrictions related to using Zorro. I don’t know how they will enforce the fee, plus extra profits, but it is still a claim that in theory can be enforced.
The last two lessons of the cource are finally finished - I’ll post them over the next days in this new thread:
They offer a “Zorro S” version for sale, with the restrictions removed. Obviously, if the free/demo version makes you $30,000 you’d be happy to buy the unrestricted version.
Hi, sorry for reviving this thread… there’s something I don’t understand about the low-pass function.
LP is a series containing the last 3 values of Data. Yet, the function uses e.g., LP[1] and Data[1]… shouldn’t these two things be equal? Is there a practical difference between LP and Data in this case?
Thanks
LP is only initialized with Data. Afterwards it’s very different. Data is the series to be filtered and LP is the filtered result.
The indicator code can only be directly used in platforms that natively support series, such as TradeStation. In MT4 you’d need some modifications with the usual EA spaghetti code around that function for handling and shifting series.
Oh, I see, makes sense. Thanks for still checking this thread after such a long time!