Walk Forward and chasing the market in real live trading

Chasing the market

Recently many forex robot failed in spite of a great statistical analysis. One particular robot which at that time I considered one of the best because it survived on 15 years of unseen data (DEMUSD) also failed. Now, volatility breakout robots are hitting the ground even if they had 2 years of glory. What happens? Is the market changing that fast? Past performance is not a guarantee for future performance. But still, on a certain degree the present and future are correlated to the past. That’s why good traders are making money because history tends to repeat itself. It repeats, but with a great deal of noise addition which renders out forex robots useless. I wish the holy grail was more than a dream, but unfortunately it is just that: a beautiful dream. The market will always outclass us. Ok, enough with the introduction let’s discuss a bit about applied walk forward and chasing the market. And, if  possible, let’s try to draw some conclusions out of it.

Here is my little experiment: I have a nice performing private EA which has only 2 available parameters: Take Profit and Stop Loss. What I’m gonna do is to optimize it for a period and test the resulted parameters against a future period. I’m going to optimize it from 2010 to 2012 and test the results against the first 5 months of 2013.

Sample walk forward optimization

Sample walk forward optimization

Profit: 4,000 pips
Drawdown: 1,000 pips
Average profit / maximum historical DD: 2

I’m using these parameters against the first 5 months of 2013, here is the result:

Walk Forward unseen data

Walk Forward unseen data

Profit: 1,104 pips
Drawdown: 698 pips
Average profit / maximum historical DD: 1.58

Sounds good, but average profit / maximum historical DD is lower then the previous and that can be easily explained: curve fitting outputs the best results, the maximum of a system which may not be (and most of the time it isn’t)  the maximum of another future system. Still looks good, but is this sustainable over time?

Optimization period: 2000.01.01 – 2002.12.30Profit: 4,494 pips
Drawdown: 1,106 pips
Forward testing period: 2003.01.01 – 2003.05.30
Profit: 510 pips
Drawdown: 820 pips

Optimization period: 2001.05.30 – 2003.05.30
Profit: 2,402 pips
Drawdown: 667 pips
Forward testing period: 2003.05.30 – 2003.10.30
Profit: 223 pips
Drawdown: 1,048 pips

Optimization period: 2001.10.30 – 2003.10.30
Profit: 2,524 pips
Drawdown: 830 pips
Forward testing period: 2003.10.30 – 2004.03.30
Profit: 1,493 pips
Drawdown: 941 pips

Optimization period: 2002.03.30 – 2004.03.30
Profit: 3,367 pips
Drawdown: 658 pips
Forward testing period: 2004.03.30 – 2004.07.30
Profit: 143 pips
Drawdown: 455 pips

Optimization period: 2002.07.30 – 2004.07.30
Profit: 3,293 pips
Drawdown: 906 pips
Forward testing period: 2004.07.30 – 2004.12.30
Profit: 946 pips
Drawdown: 561 pips

Optimization period: 2002.07.30 – 2004.12.30
Profit: 3,506 pips
Drawdown: 906 pips
Forward testing period: 2004.12.30 – 2005.05.30
Profit: -1363 pips
Drawdown: 1649 pips

Oops, it seems like the market is always one or more steps ahead of us. What conclusions can we draw from this little experiment?

1. If the optimization sample is too small it doesn’t cover many market aspects therefore it is guaranteed to fail when testing the results against a future period. Market changes constantly and even if the history tends to repeat itself, it repeats a bit different every time.

2. Short term curve fitting is not an option because it doesn’t cover many market aspects. The best solution for a previous system is not the best solution for a future system that’s why neural network based EAs tend to fail most of the time. But designing a neural netw0rk is more of an art than a science so who knows? Maybe someone hits the jackpot eventually 🙂

3. I’m not saying that short term curve fitting doesn’t work at all, it might work for some strategies, certainly not for mine because my EA is not a frequent trader therefore an average of 100 trades per year can’t be relevant for the future. How many market aspects can we cover within 100 trades? Alm0st none. In order to work, my strategy should be optimized against a larger data sample and tested another larger unseen data sample. And even so the results may not be that great as I hoped they would:

Optimization period: 2000.01.01 – 2009.12.30
Profit: 10,372 pips
Drawdown: 890 pips
Forward testing period: 2010.01.01- 2013.12.30
Profit: -2,318 pips
Drawdown: 2,875 pips

Sadly, the market may change even after 10 years, another market aspect never seen in the past may pop up out of nowhere and hit the EA.

4. So even if a forex robot performs great on backtests the future can always invalidate its results. Same happens to manual traders, the market always changes and invalidates any past results. If you compare signal providers with forex robots results you see that none of them are doing better on the long run. But there are few of both categories that makes money.

5. So what’s the proper way of optimization? The best I can think of is to optimize a forex robot every month against ALL available data (13 years). This way there are more chances to catch up similar market faces and also incorporate new market aspects.

My solution to this is a properly built portfolio which consists out of many uncorrelated strategies, every one of them being optimized every month against all available data. I will explain everything in a future article.

Btw, I wrote a simple optimizer which works inside MT4 optimizer and optimizes my 2 parameters: take profit and stop loss. Please note that trade() function that provides entry signals must be adapted to work with the optimizer and the EA must trade at the beginning of a new candle only otherwise it takes ages. Took me 30 minutes to code it, I haven’t even tested it properly, so feel free to use it, abuse it and modify it any way you like. 🙂

void optimize(int N)
{
double ThePoint;
if (Digits == 5 || Digits == 3) ThePoint = 10.0 * Point;
else ThePoint = Point;

double profit=0;
double maximum=0;

double tp_start=20;
double tp_stop=100;
double sl_start=50;
double sl_stop=200;

GlobalVariableSet(“optimize_intrade”,0);
GlobalVariableSet(“optimize_price”,0);

for(int i=tp_start;i<=tp_stop;i++)
{
for(int j=sl_start;j<=sl_stop;j++)
{
for(int bars=N;bars>-1;bars–)
{
if(GlobalVariableGet(“optimize_intrade”)==0)
{
int d=trade(bars);
if(d==1){GlobalVariableSet(“optimize_price”,Open[bars]);GlobalVariableSet(“optimize_intrade”,1);}
if(d==2){GlobalVariableSet(“optimize_price”,Open[bars]);GlobalVariableSet(“optimize_intrade”,2);}
}
else
{
int intrade=GlobalVariableGet(“optimize_intrade”);
double price=GlobalVariableGet(“optimize_price”);
if(intrade==1 && Close[bars+1]-price>=i*ThePoint)
{
GlobalVariableSet(“optimize_intrade”,0);
GlobalVariableSet(“optimize_price”,0);
profit=profit+i;
}

if(intrade==2 && price-Close[bars+1]>=i*ThePoint)
{
GlobalVariableSet(“optimize_intrade”,0);
GlobalVariableSet(“optimize_price”,0);
profit=profit+i;
}

if(intrade==1 && price-Close[bars+1]>=j*ThePoint)
{
GlobalVariableSet(“optimize_intrade”,0);
GlobalVariableSet(“optimize_price”,0);
profit=profit-j;
}

if(intrade==2 && Close[bars+1]-price>=j*ThePoint)
{
GlobalVariableSet(“optimize_intrade”,0);
GlobalVariableSet(“optimize_price”,0);
profit=profit-j;
}
}

}
if(profit>maximum)
{
maximum=profit;
GlobalVariableSet(“TPFINAL”,i);
GlobalVariableSet(“SLFINAL”,j);
}
profit=0;
}

}

GlobalVariableSet(“optimize_intrade”,0);
GlobalVariableSet(“optimize_price”,0);
return;
}