Step 1f: Goal: identify modifiers that work well
Yes WFO; Yes oversample; Yes maxtrades; Yes all param optimizing; No emode

I believe the modifiers dusktrader have a potential of leading me to curve fit. I will therefore try to find economic or financial outlook reasons of why I think they should be applied before I include any of them. I will therefore pick them one after another and see if it should be included.

fridayClose()
Since this is a trend following strategy we hope to follow the trend as long as possible. So I will overlook this modifier,

hourOpen()
I dont think I will be needing this too.

todayOpenCombo()
I am a big believer in the markets being influenced by the big players to an extent. I therefore believe if trends are going to develop over the long term then the big boys are going to have to plan on how best to jump on it. A conspiracy nut over here, I know. I therefore see this tool as essential in reducing noise. I will therefore be including it.

todayCloseCombo()

marketOpenCombo()
As a conspiracy nut, I believe when the big boys are on a trade, they are ready to let it ride and more often than not this will be when they are in the market and when volume is there to ride. I will therefore be using this modifier.

Following dusktraders procedure:


1. DISABLE WFO temporarily (comment out the NumWFOCycles and DataSplit lines)

2. Hardcode all currently optimizable parameters. I do it this way, for example:
Code:
var TimeCycle = 64; //optimize(64,55,75,1,0);


3. Set an optimize on the first modifier to check, such as this:
Code:
int marketopencombo = optimize(1,1,15,1);


After viewing the optimality graph. I pick 3 as the default.
Code:
int dayopencombo = optimize(1,1,63,1);


After viewing the optimality graph, I pick 37 as the default.


I don't have any idea what the "estimated best start value" is yet, so I've used just 1. IMPORTANT: no other parameters should be set to optimize except the modifier at this stage.

4. Now tell Zorro to Train. It will recurse through each value of the modifier, as compared with the known-reasonable values that we hardcoded in all the other parameters. This produces a figure in the Zorro window after Train that can then become your "estimated best start value". I will now store this value in my script like this:
Code:
int marketopencombo = 15; //optimize(3,1,15,1);


Code:
int dayopencombo = 63; //optimize(37,1,63,1);



Shown here: 3 was the best value in that Train, so I'm recording that as part of my optimize statement. It is commented-out because my next step was to check the dayopecombo modifier. The value 63 in this case is the default "days" value for this particular modifier.

5. Go back and repeat for each optimizable modifier, starting from step #3. This will allow you to realize the "estimated best start value" for each optimizable modifier.

6. Don't forget to re-ENABLE the WFO that we disabled in step #1. Also re-ENABLE all core parameter and Stop/Trail optimization statements before proceeding.

So putting all this together... the strategy now looks like the one below, after identifying all the "estimated best start values" for each modifier. Rather than go by dusktraders route of having picking modifiers based on AR effect, I decided to use my understanding of the markets so I stick with these two modifiers.
Code:
function fridayClose(int fridayclose)
{
	//allows Friday trading up until NYSE 3pm; close trades and don't allow after this
	if(fridayclose && dow() == FRIDAY && lhour(ET) >= 15) 
		{
			exitLong("*");
			exitShort("*");
			return 1; //condition met; indicate no further trades
		}
	return 0; //condition not met; safe to take new trades
}
function hourOpen(int hourblockstart, int hourblockend)
{
	//blocks new open trades between selected hours
	//uses NYSE time, including DST
	if ( (lhour(ET) >= hourblockstart) && (lhour(ET) < hourblockend) )
		return 0; //between blocked hours, do not allow trade opens
	else
		return 1; //no conditions met, allow trades by default
}
function todayOpenCombo(var dayopencombo)
{
	//allows optimizer to specify the best combo of days for opens
	//bit position 0 = Monday
	//bit position 1 = Tuesday
	//bit position 2 = Wednesday
	//bit position 3 = Thursday
	//bit position 4 = Friday
	//bit position 5 = Sunday
	//given a combination #, the function will return whether
	//current dow() is in the combination

	int dayopencombobits = dayopencombo+.5; //truncate to rounded int
	int today = dow() - 1; //Mon is 0
	if (today == 6) today = 5; //bump Sun to 5 (no Sat, keep binary range 0-63)

	if (dayopencombobits & (1 << today)) return 1; //current dow() is in the combo
		else return 0; //current dow() not in combo, do not allow trade opens
}
function todayCloseCombo(var dayclosecombo)
{
	//allows optimizer to specify the best combo of days to close by NYSE 4pm
	//bit position 0 = Monday
	//bit position 1 = Tuesday
	//bit position 2 = Wednesday
	//bit position 3 = Thursday
	//bit position 4 = Friday
	//bit position 5 = Sunday
	//given a combination #, the function will determine if we are beyond
	//a combo close time, close all trades if necessary, and return 1
	//if no further trades allowed today

	int dayclosecombobits = dayclosecombo+.5; //truncate to rounded int
	int today = dow() - 1; //Mon is 0
	if (today == 6) today = 5; //bump Sun to 5 (no Sat, keep binary range 0-63)

	if ((dayclosecombobits & (1 << today)) && lhour(ET) >= 16) 
	{
		exitLong("*");
		exitShort("*");
		return 1; //current dow() is in the combo; indicate no further trades
	}
	else return 0; //current dow() not in combo, safe to take new trades
}
function marketOpenCombo(var marketopencombo)
{
	//allows optimizer to specify best markets to initiate trades
	//bit position 0 = New York 8am-5pm Eastern
	//bit position 1 = Sydney 5pm-2am Eastern
	//bit position 2 = Tokyo 7pm-4am Eastern
	//bit position 3 = London 3am-12pm Eastern
	//given a combination #, the function will determine if current time is within
	//a market part of the combination (returns 1 to allow trading if true)
	
	int marketcombobits = marketopencombo+.5; //truncate to rounded int
	if ( (lhour(ET) >=8) && (lhour(ET) <17) && (marketcombobits & (1 << 0)) ) return 1; //inside New York
	if ( (lhour(ET) >=17) || (lhour(ET) <2) && (marketcombobits & (1 << 1)) ) return 1; //inside Sydney
	if ( (lhour(ET) >=19) || (lhour(ET) <4) && (marketcombobits & (1 << 2)) ) return 1; //inside Tokyo
	if ( (lhour(ET) >=3) && (lhour(ET) <12) && (marketcombobits & (1 << 3)) ) return 1; //inside London
	return 0; //default - current market not in combination, don't allow trade opens
}
function checkModifiers()
{
	int reversedir = 0; //default normal trade direction (0) unless specified otherwise
	int fridayclose = 0; //enforce auto-close and no trades after NYSE 3pm Friday
	int hourblockstart = 0; //block trade opens beginning at NY hour
	int hourblockend = 0; //block trade opens ending at NY hour
	int dayopencombo = 63;//optimize(61,1,63,1); //combo of days to open; 63=every day
	int dayclosecombo = 0; //combo of days to close after NYSE 4pm; 0=none; 63=every day
	int marketopencombo = 15; //optimize(3,1,15,1); //combo of markets to allow trade opens; 15=every market

	if ( (!fridayClose(fridayclose) //close NYSE 3pm on Friday
		|| !todayCloseCombo(dayclosecombo) ) //close NYSE 4pm on selected days
		&& todayOpenCombo(dayopencombo) //open on selected days only
		&& marketOpenCombo(marketopencombo) //open during selected markets only
		&& hourOpen(hourblockstart,hourblockend) ) //open during selected hours only
			return 1; //ok to place new trades
	else
		return 0; //no trade, restricted by a modifier	
}
function run()
{
	//Parameters
  	set(PARAMETERS);
	StartDate = 20080101;
	EndDate = 20131220;
	BarPeriod = 60; // optimize(60,60,1440,60);
	int maxtrades = 1;
	
	if(is(TESTMODE)) NumSampleCycles = 3; //oversampling on Test only, not Train
	if (Train) { RollLong = 0; RollShort = 0; } //help prevent asymmetry in parameters & profit factors
	DataSplit = 70; //70% training, 30% OOS test
	NumWFOCycles = 5;
	int maxtrades = 1;

	//require minimum 30 trades per WFO cycle or stop training
	static int LastWFOCycle = 0, LastNumTrades = 0;
	if(Train && (WFOCycle != LastWFOCycle) )
	{
		if(LastNumTrades > 0 and LastNumTrades < 30)
		{
			char tradecount[100];
			sprintf(tradecount,"Not enough trades per cycle: %d",LastNumTrades);
			quit(tradecount);
		}
	LastWFOCycle = WFOCycle;
	}
	LastNumTrades = NumWinTotal+NumLossTotal;
	
	//edge trading logic
  var  BarsPassed = optimize(820,500,1500, 10);
  
  vars Price = series(price());
  vars Trend = series(LowPass(Price,BarsPassed));

  Stop = optimize(5,1,15,1,-5)*ATR(100);
   
  if (checkModifiers())
  {
  		if(valley(Trend))
   	   reverseLong(maxtrades);
 		else if(peak(Trend))
   		reverseShort(maxtrades);
  }
}


As you can see, I have not optimised any of the modifiers. I seem to have lost all the returns once I plugged in the modifiers. I will leave it as it is and investigate tomorrow. A really fun learning experience.