|
3 registered members (Quad, TipmyPip, Grant),
5,429
guests, and 3
spiders. |
|
Key:
Admin,
Global Mod,
Mod
|
|
|
Using OptimalF to help pick the best combos
#427185
08/04/13 23:46
08/04/13 23:46
|
Joined: Jul 2013
Posts: 522
dusktrader
OP
User
|
OP
User
Joined: Jul 2013
Posts: 522
|
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: 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 ///\
// 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;
}
|
|
|
Re: Using OptimalF to help pick the best combos
[Re: dusktrader]
#427187
08/05/13 02:13
08/05/13 02:13
|
Joined: Jul 2013
Posts: 522
dusktrader
OP
User
|
OP
User
Joined: Jul 2013
Posts: 522
|
FYI the exact out-of-memory error is: Error 060: out of memory: TR I checked the memory usage of Zorro.exe when this occurred, and it was 1,455,020 K (1.4 gig) This VM has plenty of RAM left for use, so I'm not sure why it's complaining at this point. I can also give it more RAM if you think that would help. The out-of-memory condition happens at the beginning of Walk[1] Loop[16] Loop [16] p3 step 12: 5.71 => 1.13 48/45 Loop [16] p3 step 13: 6.28 => 1.18 50/41 Loop [16] p3 step 14: 6.90 => 1.27 48/38 Loop [16] p3 step 15: 7.59 => 1.29 52/34 Loop [16] p3 step 16: 8.00 => 1.20 52/34 Selected p3[14] = 6.93 => 1.23
GBPAUD:: 0.604 1.70 6.93=> 1.717 . Error 060 - out of memory: TR 91.8 MB (1355.7 MB total) Cancelled Time 00:07:21
|
|
|
Re: Using OptimalF to help pick the best combos
[Re: jcl]
#427207
08/05/13 09:46
08/05/13 09:46
|
Joined: Jul 2013
Posts: 522
dusktrader
OP
User
|
OP
User
Joined: Jul 2013
Posts: 522
|
I'm getting this out-of-memory error consistently at the same location during this training. Is there a way to force Zorro to do a garbage-collect (for example inbetween WFO cycles)? I did a little research and it seems my platform cannot exceed 4gig RAM (Win2003 Standard) due to a Microsoft limitation  Do you have another suggestion for how to reduce memory usage to avoid this situation? The only other thing I can think is to break it into separate scripts, each with less total pairs to be tested. EDIT: in reading further, it seems that all 32-bit systems have some sort of limit-per-executable of about 1.5-2gigs of RAM. It would be nice if tasks like training and/or WFO cycles could be spawned off to other Zorros. The actual trading of the script wouldn't be memory intensive, but training is.
Last edited by dusktrader; 08/05/13 10:05.
|
|
|
Re: Using OptimalF to help pick the best combos
[Re: dusktrader]
#427230
08/05/13 13:07
08/05/13 13:07
|
acidburn
Unregistered
|
acidburn
Unregistered
|
Yep that's what I was going to do... train in 2 steps and merge. But, I think the spawning idea would still work as well. My understanding is that 32-bit applications are limited to mem usage of 1.5-2.0 gig (mine crashed around 1.5, and that is also what I read some other people were saying)
You're right about this, 32bit architecture has some inherent unavoidable limitations. That's why we're generally moving towards 64bit which should be good for a long time. Even Linux can't allocate more than approx. 2.5GB for the 32bit userspace programs. I'd like Zorro to be 64bit eventually. Eventhough it would mean that my XP demo setup would become obsolete, but 64bit is so much more powerful and faster. Makes a lot of sense for a backtesting application. A native Linux 64bit Zorro? I'd kill for it! 
|
|
|
Re: Using OptimalF to help pick the best combos
[Re: ]
#427231
08/05/13 13:25
08/05/13 13:25
|
Joined: Jul 2013
Posts: 522
dusktrader
OP
User
|
OP
User
Joined: Jul 2013
Posts: 522
|
FYI I manually combined the .par and .fac files and tried to just TEST the script... but it still consumed the max memory. Next I will try assembling a custom .par and .fac with only the cream-of-the-crop pairs. Zorro 1.13.1 Trading Automaton Made with Gamestudio by oP group 2013
Workshop5_3trade_dusktrader compiling.............. assets.................. Error 060 - out of memory: TIC 95.5 MB (1451.7 MB total) Cancelled Time 00:03:55
|
|
|
Re: Using OptimalF to help pick the best combos
[Re: dusktrader]
#427243
08/05/13 14:26
08/05/13 14:26
|
Joined: Jul 2013
Posts: 522
dusktrader
OP
User
|
OP
User
Joined: Jul 2013
Posts: 522
|
Ok here is a nice improvement (I think). Again... PLEASE poke holes in this, let me know where you think it would not be wise to trade. I sorted the .fac file by OptimalF value from highest to lowest. Then I picked the top 16 performing pairs (16 seems to be the limit for training before running out of memory). Walk-Forward Test Workshop5_3cream_dusktrader portfolio - performance report
Simulation period 21.05.2010-25.07.2013 Test period 02.04.2012-25.07.2013 WFO test cycles 4 x 527 bars (18 weeks) Training cycles 5 x 2986 bars (103 weeks) Lookback time 500 bars (17 weeks) Assumed slippage 10.0 sec
Gross win/loss 2646$ / -1320$ (+13585p) Average profit 1011$/year, 84$/month, 3.89$/day Max drawdown -131$ 10% (MAE -283$ 21%) Total down time 13% (TAE 94%) Max down time 18 weeks from Sep 2012 Largest margin 453$ Trade volume 254483$ (194117$/year) Transaction costs -74$ spr, -7.47$ slp, 28$ rol Capital required 651$
Number of trades 216 (165/year, 4/week, 1/day) Percent winning 49% Max win/loss 178$ / -49$ Avg trade profit 6.14$ 62.9p (+25$ / -12$) Avg trade slippage -0.03$ -0.4p (+0.03$ / -0.10$) Avg trade bars 96 (+133 / -60) Max trade bars 929 (32 weeks) Time in market 990% Max open trades 18 Max loss streak 9 (uncorrelated 8)
Annual return 509% Profit factor 2.00 (PRR 1.65) Sharpe ratio 1.82 Kelly criterion 2.11 OptimalF .344 Ulcer index 8% Prediction error 37%
Portfolio analysis OptF ProF Win/Loss Cycles
AUDCAD avg .170 1.23 25/23 /XXX AUDJPY avg .534 5.26 17/8 /\X/ CHFJPY avg .265 1.93 3/5 \\// EURAUD avg .111 1.26 10/21 /\X/ EURCHF avg .119 1.15 7/8 \\\/ EURDKK avg .999 3.98 5/3 ./\/ EURGBP avg .502 3.90 3/1 \/// EURJPY avg .293 3.10 6/9 \\// GBPAUD avg .304 1.54 20/25 \/X/ GBPCHF avg .591 2.15 7/5 .//\ GBPJPY avg .126 1.45 3/2 \//\
AUDCAD:L .196 1.24 14/12 /\/\ AUDCAD:S .144 1.23 11/11 //\/ AUDJPY:L .760 8.67 13/3 .\// AUDJPY:S .308 3.41 4/5 /\\/ CHFJPY:L .265 1.93 3/5 \\// CHFJPY:S .000 ---- 0/0 .... EURAUD:L .094 1.16 5/7 /\// EURAUD:S .128 1.33 5/14 /\\/ EURCHF:L .170 1.21 4/3 \\\/ EURCHF:S .068 1.09 3/5 .\\/ EURDKK:L .999 3.98 5/3 ./\/ EURDKK:S .000 ---- 0/0 .... EURGBP:L .502 3.90 3/1 \/// EURGBP:S .000 ---- 0/0 .... EURJPY:L .293 3.10 6/9 \\// EURJPY:S .000 ---- 0/0 .... GBPAUD:L .182 1.34 8/12 \/\/ GBPAUD:S .426 1.75 12/13 \/// GBPCHF:L .668 2.39 5/3 .//\ GBPCHF:S .515 1.71 2/2 .//\ GBPJPY:L .126 1.45 3/2 \//\ GBPJPY:S .000 ---- 0/0 ....
// 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("EURDKK","GBPCHF","EURUSD","GBPJPY","GBPNZD","AUDJPY","AUDCAD","EURJPY",
"CHFJPY","EURGBP","GBPCAD","GBPAUD","EURAUD","EURCHF","EURNZD","NZDCHF")))
{
// 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;
}
|
|
|
|