Mother of Dragons trading strategy…
01/21/2020 at 11:47 AM #117373
Well, I had to call it something, right?
Attached is the first code I’ve put together that ‘seems to work’. Survives all manner of WF tests: 70-30, 50-50, 30-70 – however you want to chop it.
Also does well in Vonasi’s robustness tester, Random 10-10. I tried hitting it with a very big hammer but still performs well.
Uses a combination of HullMA and Supertrend on the 2h TF to define the primary trend, then another HullMA + trailing stop on a 5m TF to control entry and exit.
The 5m TF doesn’t give us much in the backtest but it does well in clear uptrends and downtrends. Just that choppy bit in March 2019 where it couldn’t cope. I hate to see whole month where a strategy doesn’t come good, but one out of 16 is not too shabby.
It runs around the clock so I’ve allowed for a spread of 3.3, calculated for IG as: (6.5 x 2.4 + 6.5 x 1.6 + 2 x 9.8 + 9 x 3.8)/24
All backtesting was done with MM disabled but I ran the final optimization with it turned on just to demonstrate the boost it gives. Starts with position size = 1 and by the end of the run when equity has trebled, it’s placing position size of ~3.4, so more or less in keeping with standard practise. Also reduces position size in bad patches.
Credit where credit is due: Vonasi wrote the Money Management part and coded the HullMA for me. The trailing stop I believe is Nicolas’ work – big thanks to both!
But the really cool thing about this strategy is that the equity graph draws a perfect profile of Daenerys Targaryen! You might have to squint a bit, but if you can’t see Daenerys then you haven’t optimized correctly.
All comments, suggestions, mods etc welcome!123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135// DJI 5mDEFPARAM CumulateOrders = False // Cumulating positions deactivatedDEFPARAM preloadbars = 5000Capital = 10000MinSize = 1 //The minimum position size allowed for the instrument.MM1stType = 0 //Starting type of moneymanagement. Set to 0 for level stakes. Set to 1 for increasing stake size as profits increase and decreasing stake size as profits decrease. Set to 2 for increasing stake size as profits increase with stake size never being decreased.MM2ndType = 1 //Type of money management to switch to after TradesQtyForSwitch number of trades and ProfitNeededForSwitch profit has occurredTradesQtyForSwitch = 15 //Quantity of trades required before switching to second money management choice.ProfitNeededForSwitch = 2 //% profit needed before allowing a money management type change to MM2ndType.DrawdownNeededToSwitch = 8 //% draw down from max equity needed before money management type is changed back to MM1stType.DrawdownNeededToQuit = 25 //% draw down from max equity needed to stop strategyOnce MoneyManagement = MM1stTypeEquity = Capital + StrategyProfitmaxequity = max(equity,maxequity)if equity < maxequity * (1 - (DrawdownNeededToSwitch/100)) thenenoughtrades = 0tradecount = 0moneymanagement = MM1stTypeendifif equity < maxequity * (1 - (DrawdownNeededToQuit/100)) thenquitendifif not EnoughTrades thenif abs(countofposition) > abs(countofposition) thentradecount = tradecount + 1endifif tradecount > TradesQtyForSwitch and maxequity >= Capital * (1 + (ProfitNeededForSwitch/100)) thenEnoughTrades = 1MoneyManagement = MM2ndTypeendifendifIF MoneyManagement = 1 THENPositionSize = Max(MinSize, Equity * (MinSize/Capital))ENDIFIF MoneyManagement = 2 THENPositionSize = Max(LastSize, Equity * (MinSize/Capital))LastSize = PositionSizeENDIFIF MoneyManagement <> 1 and MoneyManagement <> 2 THENPositionSize = MinSizeENDIFPositionSize = Round(PositionSize*100)PositionSize = PositionSize/100// Size of POSITIONSPositionSizeLong = 1 * positionsizePositionSizeShort = 1 * positionsizeTIMEFRAME(120 minutes)Period= 520inner = 2*weightedaverage[round( Period/2)](typicalprice)-weightedaverage[Period](typicalprice)HULLa = weightedaverage[round(sqrt(Period))](inner)c1 = HULLa > HULLac2 = HULLa < HULLaindicator1 = SuperTrend[5,21]c3 = (close > indicator1)c4 = (close < indicator1)TIMEFRAME(5 minutes)Periodb= 60innerb = 2*weightedaverage[round( Periodb/2)](typicalprice)-weightedaverage[Periodb](typicalprice)HULLb = weightedaverage[round(sqrt(Periodb))](innerb)c5 = HULLb > HULLbc6 = HULLb < HULLb// Conditions to enter long positionsIF c1 AND C3 AND C5 THENBUY PositionSizeLong CONTRACT AT MARKETSET STOP %LOSS 2.1SET TARGET %PROFIT 1ENDIF// Conditions to enter short positionsIF c2 AND C4 AND C6 THENSELLSHORT PositionSizeShort CONTRACT AT MARKETSET STOP %LOSS 1.2SET TARGET %PROFIT 1ENDIF//trailing stop functiontrailingstart = 84 //trailing will start @trailinstart points profittrailingstep = 3 //trailing step to move the "stoploss"//reset the stoploss valueIF NOT ONMARKET THENnewSL=0ENDIF//manage long positionsIF LONGONMARKET THEN//first move (breakeven)IF newSL=0 AND close-tradeprice(1)>=trailingstart*pipsize THENnewSL = tradeprice(1)+trailingstep*pipsizeENDIF//next movesIF newSL>0 AND close-newSL>=trailingstep*pipsize THENnewSL = newSL+trailingstep*pipsizeENDIFENDIF//manage short positionsIF SHORTONMARKET THEN//first move (breakeven)IF newSL=0 AND tradeprice(1)-close>=trailingstart*pipsize THENnewSL = tradeprice(1)-trailingstep*pipsizeENDIF//next movesIF newSL>0 AND newSL-close>=trailingstep*pipsize THENnewSL = newSL-trailingstep*pipsizeENDIFENDIF//stop order to exit the positionsIF newSL>0 THENSELL AT newSL STOPEXITSHORT AT newSL STOPENDIF//************************************************************************
01/21/2020 at 11:57 AM #11737901/21/2020 at 12:09 PM #11738201/21/2020 at 3:15 PM #117408
You are coming out with good work @nonetheless!
Even ‘compiling’ others snippets needs a flair (and you deffo have it! ) but also effort and enthusiasm and time in front of the screen. Even more so with the WF and robustness testing you are doing.
Many Thanks for Sharing!
1 user thanked author for this post.01/21/2020 at 3:52 PM #11741201/21/2020 at 5:09 PM #117415
The robustness test results look good. Just need to check if you added the TRADEON condition correctly as it is a strategy that can reverse position direction.
It should be added like this:1234567891011121314// Conditions to enter long positionsIF (shortonmarket or (not onmarket and tradeon)) and c1 AND C3 AND C5 THENBUY PositionSizeLong CONTRACT AT MARKETSET STOP %LOSS 2.1SET TARGET %PROFIT 1ENDIF// Conditions to enter short positionsIF (longonmarket or (not onmarket and tradeon)) and c2 AND C4 AND C6 THENSELLSHORT PositionSizeShort CONTRACT AT MARKETSET STOP %LOSS 1.2SET TARGET %PROFIT 1ENDIF01/21/2020 at 5:27 PM #11741701/21/2020 at 11:09 PM #117467
We have to be careful when analysing the results of robustness tests of strategies that reverse position as the robustness test is some what diluted. In an extreme example of dilution a strategy could open a trade on the first bar and then reverse position repeatedly until the last bar in a data sample. This robustness test would only tell us how good an idea it was to open a trade on the first bar! All of our robustness tests will in reality be something between that very diluted test and the ideal robustness test that completely randomly opens and closes trades and never reverses positions.
What I’m basically trying to say is that a robustness test on a strategy that reverses positions will never be as robust a test as a robustness test on a strategy that does not reverse positions and so we can’t say the results are better because we are not comparing eggs with eggs!01/22/2020 at 12:12 AM #11747601/23/2020 at 12:01 AM #11757801/23/2020 at 12:34 AM #117581
Because the MM is set to quit the whole thing after 25% drawdown … which is bad bad bad!
Try it withMM1stType = 0MM2ndType = 0
(disables the MM)And/or raise DrawdownNeededToQuit = 25 to 50 just so it will complete the run.
1 user thanked author for this post.01/23/2020 at 12:58 AM #11758301/23/2020 at 8:38 AM #117593
Thanks for the OOS 200k test Francesco. The strategy doesn’t completely fail but it is not a total success by a long way. That OOS equity curve would be one that most people would soon give up trading.
There are quite a few variables in the strategy that are most likely curve fitted especially when they are given values like 84 and 2.1. I see eight variables and that is quite a lot in my mind:
- A long take profit %
- A short take profit %
- A long stop loss %
- A short stop loss %
I would start by removing the trailing stop as personally I think these are very easy to curve fit and rarely bring any performance benefit. Then I would plot charts of each other variable for a range of values to see how important their actual value is and whether it is majorly fitted or standing on a cliff edge. Sometimes it is a combination of optimised variables which is where 3D charts come in useful. Roll on being able to use v11 more easily!
I would also consider removing the short part of the strategy as the DJI is a long only index in my mind and this removes two variables straight away from the curve fit.01/23/2020 at 8:49 AM #11759601/23/2020 at 11:05 AM #117615