Simple Moving Average Crossover Strategy

Viewing 15 posts - 46 through 60 (of 96 total)
  • Author
    Posts
  • #190799 quote
    phoentzs
    Participant
    Master

    Price distance can be set at 2 points with SP500 with a clear conscience.

    #190800 quote
    MauroPro
    Participant
    Veteran

    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?

    #190811 quote
    phoentzs
    Participant
    Master

    Is there a reason why you define TP and SL outside of the if block? Is this better from the encoding or just a coding style?

    #190812 quote
    nonetheless
    Participant
    Master

    looks 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

    T4-Multi-SP500-M5-V3-1.jpg T4-Multi-SP500-M5-V3-1.jpg T4-Multi-SP500-M5-V3-Mauro.jpg T4-Multi-SP500-M5-V3-Mauro.jpg SP-5m-T4-Multi-v4.jpg SP-5m-T4-Multi-v4.jpg SP-5m-T4-Multi-v4.1.jpg SP-5m-T4-Multi-v4.1.jpg
    #190817 quote
    nonetheless
    Participant
    Master
    #190820 quote
    MauroPro
    Participant
    Veteran

    It’s just a coding style, I think the code remains cleaner.

    #190821 quote
    nonetheless
    Participant
    Master

    here’s the code for mine, so you can see the changes

    //30.03.2022  200000k
    //US500 M5 Spread 0.6
    //UK Time
    
    defparam preloadbars = 10000
    defparam CUMULATEORDERS = false
    
    
    possize = 5
    
    //Tradetime
    //UK time
    h1 = 143000
    h2 = 220000
    
    //Euro time
    //h1 = 153000
    //h2 = 230000
    
    
    
    //adjustment for American Daylight Savings time
    ADLS =1
    if ADLS then
    DLS =(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 then
    Tradetime = time >=h1-10000 and time <h2-10000
    elsif not DLS then
    Tradetime = time >=h1 and time <h2
    endif
    endif
    
    if not ADLS then
    Tradetime = time >=h1 and time <h2
    endif
    
    timeframe(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)//M5
    MAL1 = average[a7,t7](typicalprice)
    MAL2 = average[a8,t7](typicalprice) //15
    cb3  = MAL1 crosses over MAL2
    cs3 = MAL1 crosses under MAL2
    
    
    long   =   cb1 and cb2 and cb3     //and RangelongD20
    short  =   cs1 and cs2 and cs3  //and RangeshortD20
    
    
    
     
    // position management
    IF Tradetime THEN
    If long then                           //not onmarket and
    BUY possize CONTRACT AT market
    SET STOP %LOSS hl
    SET TARGET %PROFIT gl
    EndIf
    
    If short then
    sellshort possize CONTRACT AT market
    SET STOP %LOSS hs
    SET TARGET %PROFIT gs
    EndIf
    endif
    
    
    If longonmarket and cs1 then
    sell at market
    endif
    
    If shortonmarket and cb1 then
    exitshort at market
    endif
     
    
    
    ////////////////////////////////////////
    
    #190822 quote
    phoentzs
    Participant
    Master

    Thank 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. 

    #190823 quote
    nonetheless
    Participant
    Master

    the Roberto Trail is that it uses points instead of percent

    this version has a % option:

    //RGTS2
    ONCE RGTS2 = 1
    if RGTS2 then
    
    ONCE UseCLOSE = 0                        //1=use CLOSE,  0=use High/Low
    srcH = close                                      //defaults to CLOSE
    srcL = close                                      //defaults to CLOSE
    IF UseCLOSE = 0 THEN
    srcH = high
    srcL = low
    ENDIF
    ONCE UsePerCentage = 1                            //0=use Pips  (default), 1=use Percentages
    ONCE UseEquity     = 0                            //0=use price (default), 1=use current Equity (initial Capital + StrategyProfit, as defined by variable MyEquity)
    MyEquity = 0
    DirectionSwitch = (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  = pcs
    StepPerCent   = 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 THEN
    TrailStart = (close / PipSize) * StartPerCent / 100    //use current price (CLOSE) for calculations
    TrailStartShort = (close / PipSize) * StartPerCentShort / 100
    IF UseEquity THEN                                             //alternative calculations using EQUITY
    TrailStart = Max(MinStart,(MyEquity / PipValue) * StartPerCent / 100)  //MyEquity is the variable (feel free to use a different name) retaining your current equity
    ENDIF
    ENDIF
    //
    BasePerCent   = bpc //0.08 - 0.2  Profit percentage to keep when setting BerakEven
    //
    StepSize      = ss //5 - 15     Pip chunks to increase Percentage
    IF UsePerCentage THEN
    StepSize   = TrailStart * StepPerCent / 100
    ENDIF
    //
    PerCentInc    = pci //0.06 - 0.14  PerCent increment after each StepSize chunk
    RoundTO       = rnd        //-0.5   rounds always to Lower integer,   +0.4 rounds always to Higher integer,     0 defaults PRT behaviour
    PriceDistance = IG * pipsize //IG minimum distance from current price
    y1            = 0           //reset to 0
    y2            = 0           //reset to 0
    ProfitPerCent = BasePerCent //reset to desired default value
    //PositionCount = 0
    SellPrice     = 0
    SellPriceX    = 0
    ExitPrice     = 9999999
    ExitPriceX    = 9999999
    ELSE
    //------------------------------------------------------
    // --- 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 trailing
    IF PositionPrice <> PositionPrice[1] AND (ExitPrice + SellPrice) <> 9999999 THEN //go on only if Trailing Stop had already started trailing
    IF LongOnMarket THEN
    q1         = PositionPrice + ((srcH - PositionPrice) * ProfitPerCent)      //calculate new SL
    SellPriceX = 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 one
    ELSIF ShortOnMarket THEN
    r1         = PositionPrice - ((PositionPrice - srcL) * ProfitPerCent)      //calculate new SL
    ExitPriceX = 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 one
    ENDIF
    ENDIF
    // --- Update END
    ENDIF
    //
    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 pips
    IF x1 >= TrailStart THEN                                                //    go ahead only if N+ pips
    Diff1         = abs(TrailStart - x1)                                 //difference from current profit and TrailStart
    Chunks1       = max(0,round((Diff1 / StepSize) + RoundTO))           //number of STEPSIZE chunks
    ProfitPerCent = BasePerCent + (BasePerCent * (Chunks1 * PerCentInc)) //compute new size of ProfitPerCent
    ProfitPerCent = max(ProfitPerCent[1],min(100,ProfitPerCent))         //make sure ProfitPerCent doess not exceed 100%
    y1 = max(x1 * ProfitPerCent, y1)                                     //y1 = % of max profit
    ENDIF
    ELSIF 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 pips
    IF x2 >= TrailStartShort THEN                                                //      go ahead only if N+ pips
    Diff2         = abs(TrailStartShort - x2)                                 //difference from current profit and TrailStart
    Chunks2       = max(0,round((Diff2 / StepSize) + RoundTO))           //number of STEPSIZE chunks
    ProfitPerCent = BasePerCent + (BasePerCent * (Chunks2 * PerCentInc)) //compute new size of ProfitPerCent
    ProfitPerCent = max(ProfitPerCent[1],min(100,ProfitPerCent))         //make sure ProfitPerCent doess not exceed 100%
    y2 = max(x2 * ProfitPerCent, y2)                                     //y2 = % of max profit
    ENDIF
    ENDIF
    //------------------------------------------------------------------------------
    //                    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 THEN
    SELL AT SellPrice STOP
    ELSE
    SELL AT SellPrice LIMIT
    ENDIF
    ELSE
    //
    //sell AT MARKET when EXITPRICE does not meet the broker's minimun distance from current price
    //
    SELL AT Market
    ENDIF
    ENDIF
    IF 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 THEN
    EXITSHORT AT ExitPrice STOP
    ELSE
    EXITSHORT AT ExitPrice LIMIT
    ENDIF
    ELSE
    //
    //ExitShort AT MARKET when EXITPRICE does not meet the broker's minimun distance from current price
    //
    EXITSHORT AT Market
    ENDIF
    ENDIF
    ENDIF
    #190824 quote
    phoentzs
    Participant
    Master

    Which do you prefer? This one (Robertos) or your own, which I also use? Both of which are by Roberto in terms of construction. 

    #190825 quote
    nonetheless
    Participant
    Master

    I 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.

    #190826 quote
    phoentzs
    Participant
    Master

    I have found that separate trailing for long and short is important. But the steps must also be separate. Short trades usually have to be secured faster than long trades.

    #190839 quote
    deletedaccount051022
    Participant
    New

    Thanks 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.

    #190855 quote
    phoentzs
    Participant
    Master

    I 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.

    //31.03.2022  200000k
    //US500 M5 Spread 0.6
    //German Time
    
    defparam preloadbars = 10000
    defparam CUMULATEORDERS = false
    
    
    possize = 5
    
    timeframe(4hour, updateonclose)
    myRSI = RSI[rs](close)
    noTradeL = myRSI > rso
    noTradeS = myRSI < rsu
    
    timeframe(15minute, updateonclose)
    RangeMAD5 = average[480,0](close)   //Wochentrend Daily MA5
    RangelongD5  = close > RangeMAD5
    RangeshortD5 = close < RangeMAD5
    
    RangeMAD20 = average[1920,0](close)  //"Monatstrend" Daily MA20
    RangelongD20  = RangeMAD5 > RangeMAD20
    RangeshortD20 = RangeMAD5 < RangeMAD20
    
    
    MA1 = 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) //15
    longB  = MAL1 crosses over MAL2
    shortB = MAL1 crosses under MAL2
    
    
    timeframe(default)//M5
    long   =   RangelongD5 and longB[t1] and longA and not noTradeL    //and RangelongD20
    short  =   RangeshortD5 and shortB[t2] and shortA and not noTradeS  //and RangeshortD20
    Exit1 = RangeshortD5
    Exit2 = RangelongD5
    
    // trading window
    ONCE BuyTime   = 110000
    ONCE SellTime  = 213000
    ONCE BuyTime2  = 150000
    ONCE SellTime2 = 213000
     
    // position management
    IF Time >= buyTime AND Time <= SellTime THEN
    
    If long then                           //not onmarket and
    BUY possize CONTRACT AT market
    SET STOP %LOSS hl
    SET TARGET %PROFIT gl
    EndIf
    
    endif
    
    IF Time >= buyTime2 AND Time <= SellTime2 THEN
    
    If short then
    sellshort possize CONTRACT AT market
    SET STOP %LOSS hs
    SET TARGET %PROFIT gs
    EndIf
    
    endif
    
    If longonmarket and Exit1 then
    sell at market
    endif
    
    If shortonmarket and Exit2 then
    exitshort at market
    endif
     
    
    if time = 223000 then  //223000
    //sell at market
    exitshort at market
    endif
    
    if time = 225500 and dayofweek=5 then  //225500
    sell at market
    exitshort at market
    endif
    
    ////////////////////////////////////////
    // %trailing stop function incl. cumulative positions
    once trailingstoptype = 1
    if trailingstoptype then
    //====================
    trailingpercentlong  = startl // %
    trailingpercentshort = start // %
    once acceleratorlong = stepl // typically tst*0.1
    once acceleratorshort= step // typically tss*0.1
    ts2sensitivity  = 2 // [1] close [2] high/low [3] low/high [4] typicalprice
    //====================
    once steppercentlong  = (trailingpercentlong/10)*acceleratorlong
    once steppercentshort = (trailingpercentshort/10)*acceleratorshort
    if onmarket then
    trailingstartlong = positionprice*(trailingpercentlong/100)
    trailingstartshort = positionprice*(trailingpercentshort/100)
    trailingsteplong = positionprice*(steppercentlong/100)
    trailingstepshort = positionprice*(steppercentshort/100)
    endif
    
    if not onmarket or ((longonmarket and shortonmarket[1]) or (longonmarket[1] and shortonmarket)) then
    newsl           = 0
    mypositionprice = 0
    endif
    positioncount = abs(countofposition)
    if newsl > 0 then
    if positioncount > positioncount[1] then
    if longonmarket then
    newsl = max(newsl,positionprice * newsl / mypositionprice)
    else
    newsl = min(newsl,positionprice * newsl / mypositionprice)
    endif
    endif
    endif
    if ts2sensitivity=1 then
    ts2sensitivitylong=close
    ts2sensitivityshort=close
    elsif ts2sensitivity=2 then
    ts2sensitivitylong=high
    ts2sensitivityshort=low
    elsif ts2sensitivity=3 then
    ts2sensitivitylong=low
    ts2sensitivityshort=high
    elsif ts2sensitivity=4 then
    ts2sensitivitylong=(typicalprice)
    ts2sensitivityshort=(typicalprice)
    endif
    if longonmarket then
    if newsl=0 and ts2sensitivitylong-positionprice>=trailingstartlong then
    newsl = positionprice+trailingsteplong + 0.2
    endif
    if newsl>0 and ts2sensitivitylong-newsl>=trailingsteplong then
    newsl = newsl+trailingsteplong
    endif
    endif
    if shortonmarket then
    if newsl=0 and positionprice-ts2sensitivityshort>=trailingstartshort then
    newsl = positionprice-trailingstepshort
    endif
    if newsl>0 and newsl-ts2sensitivityshort>=trailingstepshort then
    newsl = newsl-trailingstepshort
    endif
    endif
    if barindex-tradeindex>1 then
    if longonmarket then
    if newsl>0 then
    sell at newsl stop
    endif
    if newsl>0 then
    if low crosses under newsl then
    sell at market
    endif
    endif
    endif
    if shortonmarket then
    if newsl>0 then
    exitshort at newsl stop
    endif
    if newsl>0 then
    if high crosses over newsl then
    exitshort at market
    endif
    endif
    endif
    endif
    mypositionprice = positionprice
    endif
    
    if (shortonmarket and newsl > 0) or (longonmarket and newsl>0) then
    if positioncount > positioncount[1] then
    if longonmarket then
    newsl = max(newsl,positionprice * newsl / mypositionprice)
    endif
    if shortonmarket then
    newsl = min(newsl,positionprice * newsl / mypositionprice)
    endif
    endif
    endif
    //////////////////////////////////////////////////////////////
    thanked this post
    T4-Multi-SP500-M5-V3_1.itf T4-Multi-SP500-M5-V3_1.jpg T4-Multi-SP500-M5-V3_1.jpg
    #190862 quote
    nonetheless
    Participant
    Master

    I expect you’ve decided that you don’t really care what happened before your test period, but just in case you’re curious:

    T4-Multi-SP500-M5-V3.1.jpg T4-Multi-SP500-M5-V3.1.jpg
Viewing 15 posts - 46 through 60 (of 96 total)
  • You must be logged in to reply to this topic.

Simple Moving Average Crossover Strategy


ProOrder: Automated Strategies & Backtesting

New Reply
Summary

This topic contains 95 replies,
has 12 voices, and was last updated by CRISRJ
3 years, 1 month ago.

Topic Details
Forum: ProOrder: Automated Strategies & Backtesting
Language: English
Started: 01/26/2022
Status: Active
Attachments: 39 files
Logo Logo
Loading...