I've been playing around with OptimalF and I'm pretty excited about how well this script seems to be shaping up. I'd really appreciate if you could look through this script and give me some pointers. It's pretty basic (based on Workshop 5) but I've added some extra logic.

Please let me know if you think there is something wrong with the way I've used OptimalF here because to me this makes good sense. However, being a n00b, I don't want to be caught by a "gotcha!" that burns me down the line.

(Separately, when I tried to run this loop across all the pairs for training, it gave me an "out of memory" error after about the 16th pair. I'd like to know if this is referring to physical RAM that needs to be increased, or a limitation of Zorro. For now I've limited the number of pairs to avoid this out-of-memory error.)

----
My understanding of OptimalF factors is that it is run across the entire test period. One way I look at these results is to be able to identify which pairs/directions could be profitable, and those which simply are not. By throwing ALL of the pairs at this script for training, my intent is to identify which pair/direction combos could make money using this particular script logic. Once you identify those, then you could use OptimalF to actually weight those pair combos to calculate optimal margin per trade.

So here was my logic in this:
1) First run training across all the pairs and do not impose any restrictions. Calculate OptimalF simply for the purpose of determining which pair/direction combos could be profitable;

2) Then in testing/trading, utilize that information to ONLY trade those combos that are known to be profitable (I don't care about combos that don't have a proven track record);

2a) I took this step a little further and divided the OptimalF information into 3 categories: known win, known big win, and known very big win. Using this information I've allowed multiple trade entries IF the setup should occur again;

3) In this phase, which I haven't explored yet... I would take those cream-of-crop combos from step #2 and apply OptimalF factors to each trade, allowing more risk to known-profitable combos;

Here is the script I'm working with, along with some stat info so far:
Quote:
Walk-Forward Test Workshop5_3_dusktrader portfolio - performance report

Simulation period 25.04.2002-10.06.2013
Test period 04.11.2008-10.06.2013
WFO test cycles 4 x 1843 bars (63 weeks)
Training cycles 5 x 10443 bars (360 weeks)
Lookback time 500 bars (17 weeks)
Assumed slippage 10.0 sec

Gross win/loss 5932$ / -2901$ (+30442p)
Average profit 659$/year, 55$/month, 2.54$/day
Max drawdown -186$ 6% (MAE -480$ 16%)
Total down time 28% (TAE 91%)
Max down time 60 weeks from Mar 2012
Largest margin 213$
Trade volume 292501$ (63624$/year)
Transaction costs -93$ spr, -13$ slp, 274$ rol
Capital required 363$

Number of trades 292 (64/year, 2/week, 1/day)
Percent winning 52%
Max win/loss 232$ / -91$
Avg trade profit 10$ 104.3p (+39$ / -21$)
Avg trade slippage -0.04$ -0.4p (+0.03$ / -0.12$)
Avg trade bars 151 (+237 / -56)
Max trade bars 1926 (66 weeks)
Time in market 600%
Max open trades 10
Max loss streak 10 (uncorrelated 8)

Annual return 440%
Profit factor 2.04 (PRR 1.73)
Sharpe ratio 1.44
Kelly criterion 1.13
OptimalF .174
Ulcer index 4%
Prediction error 33%

Portfolio analysis OptF ProF Win/Loss Cycles

AUDCAD avg .137 1.84 16/17 .//\
AUDJPY avg .193 2.87 11/20 /\\/
AUDUSD avg .042 1.21 15/23 //\/
CHFJPY avg .189 1.63 68/52 X//X
EURUSD avg .233 2.68 43/27 ///\

AUDCAD:L .137 1.84 16/17 .//\
AUDCAD:S .000 ---- 0/0 ....
AUDJPY:L .193 2.87 11/20 /\\/
AUDJPY:S .000 ---- 0/0 ....
AUDUSD:L .042 1.21 15/23 //\/
AUDUSD:S .000 ---- 0/0 ....
CHFJPY:L .123 1.40 32/30 \///
CHFJPY:S .255 1.94 36/22 ///\
EURUSD:L .131 2.26 15/13 ///\
EURUSD:S .334 3.19 28/14 ///\


Code:
// Workshop 5: Counter trend trading, optimized ////////////////

function reverseShort(int MaxTrades)
{
	// update the stops and profit targets of open trades
	if(Stop > 0) exitShort(0,priceClose()+Stop);
	if(TakeProfit > 0) exitShort(0,-(priceClose()-TakeProfit));
 
	// if MaxTrades is not reached, open a new trade
	if(NumOpenShort < MaxTrades)
	{
		// reinvest the square root of profits
		//var MarginShort = sqrt(WinShort-LossShort)*OptimalFShort;
		//Margin = clamp(MarginShort, 5, 300); //max $300 per trade
		enterShort();
	}

	// otherwise, close all opposite trades
	else if(!mode(HEDGING)) exitLong();
	return 0;
}

function reverseLong(int MaxTrades)
{
	// update the stops and profit targets of open trades
	if(Stop > 0) exitLong(0,priceClose()-Stop);
	if(TakeProfit > 0) exitLong(0,-(priceClose()+TakeProfit));
 
	// if MaxTrades is not reached, open a new trade
	if(NumOpenLong < MaxTrades)
	{
		// reinvest the square root of profits
		//var MarginLong = sqrt(WinLong-LossLong)*OptimalFLong;
		//Margin = clamp(MarginLong, 5, 300); //max $300 per trade
		enterLong(); }

	//otherwise, close all opposite trades
	else if(!mode(HEDGING)) exitShort();
	return 0;
}

function run()
{
	set(PARAMETERS+FACTORS+NFA);  // generate and use optimized parameters
	BarPeriod = 240;	// 4 hour bars
	LookBack = 500;
	StartDate = 2002;
	//EndDate = 2009;
	NumWFOCycles = 5; // activate WFO

	if(ReTrain) {
		UpdateDays = -1;	// update price data from the server 
		SelectWFO = -1;	// select the last cycle for re-optimization
	}

// portfolio loop
	while(asset(loop("EURUSD","AUDCAD","AUDCHF","AUDJPY","AUDNZD","AUDUSD","CADJPY","CHFJPY")))
		//"EURAUD","EURCAD","EURCHF","EURDKK","EURGBP","EURJPY","EURNZD","GBPAUD","GBPCAD","GBPCHF",
		//"GBPJPY","GBPNZD","GBPUSD","NZDCHF","NZDCHF","NZDUSD","USDCAD","USDCHF","USDJPY")))
	{	
		// calculate the buy/sell signal
		vars Price = series(price());
		vars DomPeriod = series(DominantPeriod(Price,30));
		var LowPeriod = LowPass(DomPeriod,500);
		vars HP = series(HighPass(Price,LowPeriod*optimize(1,0.5,2)));
		vars Signal = series(Fisher(HP,500));
		var Threshold = optimize(1,0.5,2,0.1);

		Stop = optimize(4,2,8) * ATR(100);
		Trail = 4*ATR(100);

		//when training, force all trades so we can get see what would be profitable via OptimalF
		if(is(TRAINMODE))
		{
			if(crossUnder(Signal,-Threshold)) reverseLong(1);
			else if(crossOver(Signal,Threshold)) reverseShort(1);
		}

		//when testing/trading only trade those known profitable via OptimalF
		if(is(TESTMODE) || (TRADEMODE)) 
		{
			//Allow more long trades for known-more-profitable
			if(crossUnder(Signal,-Threshold) && (OptimalFLong >= .15)) reverseLong(3); //known very big win
			else if(crossUnder(Signal,-Threshold) && (OptimalFLong >= .1)) reverseLong(2); //known big win
			else if(crossUnder(Signal,-Threshold) && (OptimalFLong >= .001)) reverseLong(1); //known win
	
			//Allow more short trades for known-more-profitable
			else if(crossOver(Signal,Threshold) && (OptimalFShort >= .15)) reverseShort(3); //known very big win
			else if(crossOver(Signal,Threshold) && (OptimalFShort >= .1)) reverseShort(2); //known big win
			else if(crossOver(Signal,Threshold) && (OptimalFShort >= .001)) reverseShort(1); //known win
		}

	} //while loop

	PlotWidth = 1000;
	PlotHeight1 = 600;
}