Simple Moving Average Crossover Strategy
Forums › ProRealTime English forum › ProOrder support › Simple Moving Average Crossover Strategy
- This topic has 95 replies, 12 voices, and was last updated 1 year ago by CRISRJ.
-
-
03/30/2022 at 7:31 PM #19079903/30/2022 at 7:48 PM #190800
There are different versions of Roberto’s Trp. I used the version on page 4 (rif: 165976): https://www.prorealcode.com/topic/breakeeven-trailing-profit/page/4/
Roberto, is there a better one for this TS?
03/30/2022 at 9:29 PM #19081103/30/2022 at 9:56 PM #190812looks interesting, thanks for sharing.
I tried reworking it on 1m bars but it’s fairly dead before 2018, so here’s a quick treatment on a 5 year backtest. Attached are results for yours and Mauro’s for that same period and you can see that they’re curve-fit to 200k
SP 5m T4 Multi v4.1 is with Roberto’s trail, but I didn’t change any of the values from Mauro’s version, so that could be worth playing with.
More room for improvement, I’m sure
03/30/2022 at 9:57 PM #19081703/30/2022 at 9:58 PM #19082003/30/2022 at 10:12 PM #190821here’s the code for mine, so you can see the changes
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596//30.03.2022 200000k//US500 M5 Spread 0.6//UK Timedefparam preloadbars = 10000defparam CUMULATEORDERS = falsepossize = 5//Tradetime//UK timeh1 = 143000h2 = 220000//Euro time//h1 = 153000//h2 = 230000//adjustment for American Daylight Savings timeADLS =1if ADLS thenDLS =(Date >= 20100314 and date <=20100328) or (Date >= 20101031 and date <=20101107) or (Date >= 20110313 and date <=20110327) or (Date >= 20111030 and date <=20111106) or (Date >= 20120311 and date <=20120325) or (Date >= 20121028 and date <=20121104) or (Date >= 20130310 and date <=20130331) or (Date >= 20131027 and date <=20131103) or (Date >= 20140309 and date <=20140330) or (Date >= 20141026 and date <=20141102) or (Date >= 20150308 and date <=20150329) or (Date >= 20151025 and date <=20151101) or (Date >= 20160313 and date <=20160327) or (Date >= 20161030 and date <=20161106) or (Date >= 20170312 and date <=20170326) or (Date >= 20171030 and date <=20171105) or (Date >= 20180311 and date <=20180325) or (Date >= 20181028 and date <=20181104) or (Date >= 20190310 and date <=20190331) or (Date >= 20191027 and date <=20191103) or (Date >= 20200308 and date <=20200329) or (Date >= 20201025 and date <=20201101) or (Date >= 20210314 and date <=20210328) or (Date >= 20211031 and date <=20211107) or (Date >= 20220313 and date <=20220327) or (Date >= 20221030 and date <=20221106) or (Date >= 20230312 and date <=20230326) or (Date >= 20231029 and date <=20231105) or (Date >= 20240310 and date <=20240331) or (Date >= 20241027 and date <=20241103)If DLS thenTradetime = time >=h1-10000 and time <h2-10000elsif not DLS thenTradetime = time >=h1 and time <h2endifendifif not ADLS thenTradetime = time >=h1 and time <h2endiftimeframe(8 hour)ma = average[a1,t1](typicalprice)cb1 = ma > ma[1]mb = average[a2,t2](typicalprice)cs1 = mb < mb[1]timeframe(15 minutes)MA1 = average[x1,t3](typicalprice)MA2 = average[x2,t3](typicalprice)MA4 = average[x5,t5](typicalprice)MA5 = average[x6,t5](typicalprice)cb2 = MA1 > MA2 //and MA2 > MA3 //and MA2 > MA2[1]cs2 = MA4 < MA5 //and MA5 < MA5[1]timeframe(default)//M5MAL1 = average[a7,t7](typicalprice)MAL2 = average[a8,t7](typicalprice) //15cb3 = MAL1 crosses over MAL2cs3 = MAL1 crosses under MAL2long = cb1 and cb2 and cb3 //and RangelongD20short = cs1 and cs2 and cs3 //and RangeshortD20// position managementIF Tradetime THENIf long then //not onmarket andBUY possize CONTRACT AT marketSET STOP %LOSS hlSET TARGET %PROFIT glEndIfIf short thensellshort possize CONTRACT AT marketSET STOP %LOSS hsSET TARGET %PROFIT gsEndIfendifIf longonmarket and cs1 thensell at marketendifIf shortonmarket and cb1 thenexitshort at marketendif////////////////////////////////////////03/30/2022 at 10:18 PM #190822Thank you for your work. I’ll compare in peace. But it is interesting to see that a suitable system is created with simple indicators without much magic. I think the “problem” with the Roberto Trail is that it uses points instead of percent. I suspect. And that before 2018 the S&P500 was worth half what it is today. Of course, the fluctuations were much smaller than today.
03/30/2022 at 10:28 PM #190823the Roberto Trail is that it uses points instead of percent
this version has a % option:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146//RGTS2ONCE RGTS2 = 1if RGTS2 thenONCE UseCLOSE = 0 //1=use CLOSE, 0=use High/LowsrcH = close //defaults to CLOSEsrcL = close //defaults to CLOSEIF UseCLOSE = 0 THENsrcH = highsrcL = lowENDIFONCE UsePerCentage = 1 //0=use Pips (default), 1=use PercentagesONCE UseEquity = 0 //0=use price (default), 1=use current Equity (initial Capital + StrategyProfit, as defined by variable MyEquity)MyEquity = 0DirectionSwitch = (LongOnMarket AND ShortOnMarket[1]) OR (LongOnMarket[1] AND ShortOnMarket) //True when there's been a change in the direction (likely to be due to a Stop & Reverse)//IF Not OnMarket OR DirectionSwitch THEN//// when NOT OnMarket or thare's been a change in direction, reset values to their default settings//StartPerCent = pc //0.25 = 0.25% to start triggering Trailing Stop (when UsePerCentage=1)StartPerCentShort = pcsStepPerCent = spc //50 = 50% (of the 0.25% above) as a Trailing Step (when UsePerCentage=1) (set to 100 to make StepSize=TrailStart, set to 200 to make it twice TrailStart)//TrailStart = 30 //30 Start trailing profits from this point (when UsePerCentage=0)MinStart = 10 //10 Minimum value for TrailStart (when UseEquity=1, to prevent TrailStart from dropping below ZERO when Equity turns negative)IF UsePerCentage THENTrailStart = (close / PipSize) * StartPerCent / 100 //use current price (CLOSE) for calculationsTrailStartShort = (close / PipSize) * StartPerCentShort / 100IF UseEquity THEN //alternative calculations using EQUITYTrailStart = Max(MinStart,(MyEquity / PipValue) * StartPerCent / 100) //MyEquity is the variable (feel free to use a different name) retaining your current equityENDIFENDIF//BasePerCent = bpc //0.08 - 0.2 Profit percentage to keep when setting BerakEven//StepSize = ss //5 - 15 Pip chunks to increase PercentageIF UsePerCentage THENStepSize = TrailStart * StepPerCent / 100ENDIF//PerCentInc = pci //0.06 - 0.14 PerCent increment after each StepSize chunkRoundTO = rnd //-0.5 rounds always to Lower integer, +0.4 rounds always to Higher integer, 0 defaults PRT behaviourPriceDistance = IG * pipsize //IG minimum distance from current pricey1 = 0 //reset to 0y2 = 0 //reset to 0ProfitPerCent = BasePerCent //reset to desired default value//PositionCount = 0SellPrice = 0SellPriceX = 0ExitPrice = 9999999ExitPriceX = 9999999ELSE//------------------------------------------------------// --- Update Stop Loss after accumulating new positions//------------------------------------------------------//PositionCount = max(PositionCount,abs(CountOfPosition))//// update Stop Loss only when PositionPrice has changed (actually when increased, we don't move it if there's been some positions exited)////IF PositionCount <> PositionCount[1] AND (ExitPrice + SellPrice)<>9999999 THEN //go on only if Trailing Stop had already started trailingIF PositionPrice <> PositionPrice[1] AND (ExitPrice + SellPrice) <> 9999999 THEN //go on only if Trailing Stop had already started trailingIF LongOnMarket THENq1 = PositionPrice + ((srcH - PositionPrice) * ProfitPerCent) //calculate new SLSellPriceX = max(max(SellPriceX,SellPrice),q1)SellPrice = max(max(SellPriceX,SellPrice),PositionPrice + (y1 * pipsize)) //set exit price to whatever grants greater profits, comopared to the previous oneELSIF ShortOnMarket THENr1 = PositionPrice - ((PositionPrice - srcL) * ProfitPerCent) //calculate new SLExitPriceX = min(min(ExitPriceX,ExitPrice),r1)ExitPrice = min(min(ExitPriceX,ExitPrice),PositionPrice - (y2 * pipsize)) //set exit price to whatever grants greater profits, comopared to the previous oneENDIFENDIF// --- Update ENDENDIF//IF LongOnMarket AND srcH > (PositionPrice + (y1 * pipsize)) THEN //LONG positions//// compute the value of the Percentage of profits, if any, to lock in for LONG trades//x1 = (srcH - PositionPrice) / pipsize //convert price to pipsIF x1 >= TrailStart THEN // go ahead only if N+ pipsDiff1 = abs(TrailStart - x1) //difference from current profit and TrailStartChunks1 = max(0,round((Diff1 / StepSize) + RoundTO)) //number of STEPSIZE chunksProfitPerCent = BasePerCent + (BasePerCent * (Chunks1 * PerCentInc)) //compute new size of ProfitPerCentProfitPerCent = max(ProfitPerCent[1],min(100,ProfitPerCent)) //make sure ProfitPerCent doess not exceed 100%y1 = max(x1 * ProfitPerCent, y1) //y1 = % of max profitENDIFELSIF ShortOnMarket AND srcL < (PositionPrice - (y2 * pipsize)) THEN //SHORT positions//// compute the value of the Percentage of profits, if any, to lock in for SHORT trades//x2 = (PositionPrice - srcL) / pipsize //convert price to pipsIF x2 >= TrailStartShort THEN // go ahead only if N+ pipsDiff2 = abs(TrailStartShort - x2) //difference from current profit and TrailStartChunks2 = max(0,round((Diff2 / StepSize) + RoundTO)) //number of STEPSIZE chunksProfitPerCent = BasePerCent + (BasePerCent * (Chunks2 * PerCentInc)) //compute new size of ProfitPerCentProfitPerCent = max(ProfitPerCent[1],min(100,ProfitPerCent)) //make sure ProfitPerCent doess not exceed 100%y2 = max(x2 * ProfitPerCent, y2) //y2 = % of max profitENDIFENDIF//------------------------------------------------------------------------------// manage actual Exit, if needed//------------------------------------------------------------------------------IF y1 THEN //Place pending STOP order when y1 > 0 (LONG positions)SellPrice = max(SellPrice,PositionPrice + (y1 * pipsize)) //convert pips to price//// check the minimun distance between ExitPrice and current price//IF abs(close - SellPrice) > PriceDistance THEN//// place either a LIMIT or STOP pending order according to current price positioning//IF close >= SellPrice THENSELL AT SellPrice STOPELSESELL AT SellPrice LIMITENDIFELSE////sell AT MARKET when EXITPRICE does not meet the broker's minimun distance from current price//SELL AT MarketENDIFENDIFIF y2 THEN //Place pending STOP order when y2 > 0 (SHORT positions)ExitPrice = min(ExitPrice,PositionPrice - (y2 * pipsize)) //convert pips to price//// check the minimun distance between ExitPrice and current price//IF abs(close - ExitPrice) > PriceDistance THEN//// place either a LIMIT or STOP pending order according to current price positioning//IF close <= ExitPrice THENEXITSHORT AT ExitPrice STOPELSEEXITSHORT AT ExitPrice LIMITENDIFELSE////ExitShort AT MARKET when EXITPRICE does not meet the broker's minimun distance from current price//EXITSHORT AT MarketENDIFENDIFENDIF03/30/2022 at 11:33 PM #19082403/31/2022 at 12:07 AM #190825I mostly use this one (above) – has a few more options and usually gives better results. I added a separate TrailStartShort as it often helps to have different values there.
03/31/2022 at 12:19 AM #19082603/31/2022 at 9:43 AM #190839Thanks for sharing nonetheless
Agree with you that % is better than fixed. Given the change in index value over the last 2 years I tend to optimise over a more recent data set to have something more relevant going forwards.
03/31/2022 at 12:53 PM #190855I once again looked at my original version and installed lightweight filter …
In the H4 time frame I installed a new noTrade-filter that should prevent the strategy enters a covered or oversold market. In addition, I added an entrance timer who should find out if there is a better price after the Ma-Cross.
All small changes, but … more Profit, Smaller Drawdown.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191//31.03.2022 200000k//US500 M5 Spread 0.6//German Timedefparam preloadbars = 10000defparam CUMULATEORDERS = falsepossize = 5timeframe(4hour, updateonclose)myRSI = RSI[rs](close)noTradeL = myRSI > rsonoTradeS = myRSI < rsutimeframe(15minute, updateonclose)RangeMAD5 = average[480,0](close) //Wochentrend Daily MA5RangelongD5 = close > RangeMAD5RangeshortD5 = close < RangeMAD5RangeMAD20 = average[1920,0](close) //"Monatstrend" Daily MA20RangelongD20 = RangeMAD5 > RangeMAD20RangeshortD20 = RangeMAD5 < RangeMAD20MA1 = average[x1,0](close)MA2 = average[x2,0](close)//MA3 = average[x3,0](close)MA4 = average[x5,1](close)MA5 = average[x6,1](close)longA = MA1 > MA2 //and MA2 > MA3 //and MA2 > MA2[1]shortA = MA4 < MA5 //and MA5 < MA5[1]MAL1 = average[5,0](close)MAL2 = average[15,0](close) //15longB = MAL1 crosses over MAL2shortB = MAL1 crosses under MAL2timeframe(default)//M5long = RangelongD5 and longB[t1] and longA and not noTradeL //and RangelongD20short = RangeshortD5 and shortB[t2] and shortA and not noTradeS //and RangeshortD20Exit1 = RangeshortD5Exit2 = RangelongD5// trading windowONCE BuyTime = 110000ONCE SellTime = 213000ONCE BuyTime2 = 150000ONCE SellTime2 = 213000// position managementIF Time >= buyTime AND Time <= SellTime THENIf long then //not onmarket andBUY possize CONTRACT AT marketSET STOP %LOSS hlSET TARGET %PROFIT glEndIfendifIF Time >= buyTime2 AND Time <= SellTime2 THENIf short thensellshort possize CONTRACT AT marketSET STOP %LOSS hsSET TARGET %PROFIT gsEndIfendifIf longonmarket and Exit1 thensell at marketendifIf shortonmarket and Exit2 thenexitshort at marketendifif time = 223000 then //223000//sell at marketexitshort at marketendifif time = 225500 and dayofweek=5 then //225500sell at marketexitshort at marketendif////////////////////////////////////////// %trailing stop function incl. cumulative positionsonce trailingstoptype = 1if trailingstoptype then//====================trailingpercentlong = startl // %trailingpercentshort = start // %once acceleratorlong = stepl // typically tst*0.1once acceleratorshort= step // typically tss*0.1ts2sensitivity = 2 // [1] close [2] high/low [3] low/high [4] typicalprice//====================once steppercentlong = (trailingpercentlong/10)*acceleratorlongonce steppercentshort = (trailingpercentshort/10)*acceleratorshortif onmarket thentrailingstartlong = positionprice*(trailingpercentlong/100)trailingstartshort = positionprice*(trailingpercentshort/100)trailingsteplong = positionprice*(steppercentlong/100)trailingstepshort = positionprice*(steppercentshort/100)endifif not onmarket or ((longonmarket and shortonmarket[1]) or (longonmarket[1] and shortonmarket)) thennewsl = 0mypositionprice = 0endifpositioncount = abs(countofposition)if newsl > 0 thenif positioncount > positioncount[1] thenif longonmarket thennewsl = max(newsl,positionprice * newsl / mypositionprice)elsenewsl = min(newsl,positionprice * newsl / mypositionprice)endifendifendifif ts2sensitivity=1 thents2sensitivitylong=closets2sensitivityshort=closeelsif ts2sensitivity=2 thents2sensitivitylong=hights2sensitivityshort=lowelsif ts2sensitivity=3 thents2sensitivitylong=lowts2sensitivityshort=highelsif ts2sensitivity=4 thents2sensitivitylong=(typicalprice)ts2sensitivityshort=(typicalprice)endifif longonmarket thenif newsl=0 and ts2sensitivitylong-positionprice>=trailingstartlong thennewsl = positionprice+trailingsteplong + 0.2endifif newsl>0 and ts2sensitivitylong-newsl>=trailingsteplong thennewsl = newsl+trailingsteplongendifendifif shortonmarket thenif newsl=0 and positionprice-ts2sensitivityshort>=trailingstartshort thennewsl = positionprice-trailingstepshortendifif newsl>0 and newsl-ts2sensitivityshort>=trailingstepshort thennewsl = newsl-trailingstepshortendifendifif barindex-tradeindex>1 thenif longonmarket thenif newsl>0 thensell at newsl stopendifif newsl>0 thenif low crosses under newsl thensell at marketendifendifendifif shortonmarket thenif newsl>0 thenexitshort at newsl stopendifif newsl>0 thenif high crosses over newsl thenexitshort at marketendifendifendifendifmypositionprice = positionpriceendifif (shortonmarket and newsl > 0) or (longonmarket and newsl>0) thenif positioncount > positioncount[1] thenif longonmarket thennewsl = max(newsl,positionprice * newsl / mypositionprice)endifif shortonmarket thennewsl = min(newsl,positionprice * newsl / mypositionprice)endifendifendif//////////////////////////////////////////////////////////////1 user thanked author for this post.
03/31/2022 at 2:04 PM #190862I expect you’ve decided that you don’t really care what happened before your test period, but just in case you’re curious:
-
AuthorPosts
Find exclusive trading pro-tools on