One question I do have is... why is Profit Factor and OptimalF different when training with only 1 pair vs. several in a loop? I'm sure there is a reason -- I'd just like to understand it better.

My understanding is that -- the way this loop is written -- when training, it should calculate parameters and OptimalF for each pair individually. Therefore, why do the stats appear differently (ie, Profit Factor and OptimalF) when comparing the individual train vs. the group train?

I individually trained each pair, then selected these top-6 performers. Then I put them together in a loop and trained again:

Quote:
Walk-Forward Test Workshop5_3cream_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 7786$ / -3523$ (+44413p)
Average profit 927$/year, 77$/month, 3.57$/day
Max drawdown -244$ 6% (MAE -473$ 11%)
Total down time 30% (TAE 94%)
Max down time 35 weeks from Aug 2012
Largest margin 310$
Trade volume 362564$ (78864$/year)
Transaction costs -107$ spr, -18$ slp, 336$ rol
Capital required 507$

Number of trades 322 (71/year, 2/week, 1/day)
Percent winning 48%
Max win/loss 331$ / -127$
Avg trade profit 13$ 137.9p (+50$ / -21$)
Avg trade slippage -0.06$ -0.6p (+0.03$ / -0.14$)
Avg trade bars 138 (+224 / -57)
Max trade bars 1397 (48 weeks)
Time in market 603%
Max open trades 12
Max loss streak 10 (uncorrelated 9)

Annual return 470%
Profit factor 2.21 (PRR 1.89)
Sharpe ratio 1.53
Kelly criterion 1.27
OptimalF .185
Ulcer index 4%
Prediction error 31%

Portfolio analysis OptF ProF Win/Loss Cycles

AUDJPY avg .193 2.87 11/20 /\\/
CHFJPY avg .189 1.63 68/52 X//X
EURAUD avg .206 2.67 14/39 //\\
EURNZD avg .049 1.57 3/8 ///\
EURUSD avg .233 2.68 43/27 ///\
GBPAUD avg .191 1.98 17/20 \/\/

AUDJPY:L .193 2.87 11/20 /\\/
AUDJPY:S .000 ---- 0/0 ....
CHFJPY:L .123 1.40 32/30 \///
CHFJPY:S .255 1.94 36/22 ///\
EURAUD:L .000 ---- 0/0 ....
EURAUD:S .206 2.67 14/39 //\\
EURNZD:L .000 ---- 0/0 ....
EURNZD:S .049 1.57 3/8 ///\
EURUSD:L .131 2.26 15/13 ///\
EURUSD:S .334 3.19 28/14 ///\
GBPAUD:L .000 ---- 0/0 ....
GBPAUD:S .191 1.98 17/20 \/\/


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","AUDJPY","CHFJPY","GBPAUD","EURAUD","EURNZD")))
	{	
		// 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 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;
}