BreakEven & Trailing Profit: complete function

Viewing 15 posts - 61 through 75 (of 138 total)
  • Author
    Posts
  • #165998 quote
    robertogozzi
    Moderator
    Master

    PositionPrice should be used instead of TradePrice, but the % modification suggested by nonetheless doesn’t work actually, because you should also change the lines where TrailStart is used to compare with the current price.

    I coded it with pips in my mind, so the code would need some in-depth modifications to work with percentages.

    #166002 quote
    nonetheless
    Participant
    Master

    I would have thought that

    ts = (positionprice*pc)/100   // % trailing start
    TrailStart    = ts          // Start trailing profits from this point

    would simply create a value for TrailStart, and then any further reference to TrailStart will relate to that value, no?

    #166008 quote
    robertogozzi
    Moderator
    Master

    Line 56, for example, compares pips. It should be changed to compare percentages.

    I think it woukd be better to convert a percentage into pips, in line 14:

    TrailStart = (close / PipSize) * pc / 100

    this will compute a percentage of the current price, before entering a trade, and convert it into pips.

    You may also use your Equity instead of close, and change the expression:

    TrailStart = (MyEquity / PipValue) * pc / 100

    You can also use such expression for StepSize.

    PriceDistance should be left as is, since it has no relation with risk and percentages.

    With such minor modifications you will accommodate for percentages without modifying the logic of the code.

    #166017 quote
    nonetheless
    Participant
    Master

    Sorry Roberto, I still don’t get it. 🤔

    If pc = 0.25 and positionprice = 32000, then TrailStart will be 80

    How is this different from simply entering TrailStart = 80 without the % calculation ?

    Where Line 56 refers to TrailStart it would just read 80 and work with that … wouldn’t it?

    #166023 quote
    robertogozzi
    Moderator
    Master

    Your assumption is correct because you are using SP500 o Nasdaq, or any other index with a price/pip ratio of 1. Try applying that percentage to, say, Aud/Chf which is 0.7167 with a price/pip ratio of 1/10000th!

    If you want to use some code for your personal use you can do whatever you want because that suits your needs and you know what it does, but to make a code portable it must be coded so that it can be used on every  instrument.

    marcoram and nonetheless thanked this post
    #166027 quote
    nonetheless
    Participant
    Master

    Ok, now I see what you’re getting at – and of course it makes total sense if you want to cross over into forex.

    TBH, I mostly use the original version (from page 1), still gets great results when not using cumulative orders.

    robertogozzi thanked this post
    #166092 quote
    robertogozzi
    Moderator
    Master

    This is the new code with the addition of (optional) percentages as above (as suggested by nonetheless). I added a MINSTART to prevent TrailStart from dropping below ZERO when Equity (if you plan to use it) turns negative.

    Define MyEquity somewhere in your code  (even to ZERO if you don’t plan to use it):

    //------------------------------------------------------------------------------------------------------------------------------------------------
    //                     Trailing Start
    //------------------------------------------------------------------------------------------------------------------------------------------------
    ONCE UseCLOSE = 1                                 //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 = 0                            //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)
    //
    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  = 0.25        //0.25%  to start triggering Trailing Stop       (when UsePerCentage=1)
       StepPerCent   = 50          //50%    (of the 0.25% above) as a Trqiling 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
          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   = 0.200       //20.0%  Profit percentage to keep when setting BerakEven
       //
       StepSize      = 10          //10     Pip chunks to increase Percentage
       IF UsePerCentage THEN
          StepSize   = TrailStart * StepPerCent / 100
       ENDIF
       //
       PerCentInc    = 0.100       //10.0%  PerCent increment after each StepSize chunk
       RoundTO       = -0.5        //-0.5   rounds always to Lower integer,   +0.4 rounds always to Higher integer,     0 defaults PRT behaviour
       PriceDistance = 7 * pipsize //7      minimun 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 >= TrailStart THEN                                                //      go ahead only if N+ pips
          Diff2         = abs(TrailStart - 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
    nonetheless, Roger, marcoram and Midlanddave thanked this post
    #166094 quote
    nonetheless
    Participant
    Master

    That’s a great addition. With forward testing it won’t matter that much whether you use % or points, but with backtesting up to 10 years ago, when index levels were a third or a quarter of what they are now, I think % is essential to get an accurate impression of past performance.

    robertogozzi thanked this post
    #181081 quote
    paisantrader
    Participant
    Senior

    This one is seriously amazing. Great work!

    My brain is getting fried. I was trying theoretically to come up with the solution before I tried to change the code, but I’m stuck.

    What I want to achieve is to add a target at let’s say 2%. The trailing starts at 0.2%. The closer it gets to the 2%, the tighter the trailing stop is. So theoretically, when you hit 2%, it’s basically a TP.

    Any ideas?

    #181123 quote
    robertogozzi
    Moderator
    Master

    I decided to code a new one, instead of changing the above code (tested on DAX, Daily TF):

    Avg = average[100,0](close)
    IF not OnMarket THEN
       IF close CROSSES OVER Avg THEN
          BUY AT MARKET
       ELSIF close CROSSES UNDER Avg THEN
          SELLSHORT AT MARKET
       ENDIF
       SL = close / 100 * 2      //2% SL
       SET STOP LOSS SL
    ENDIF
    //
    // incremental Trailing Stop (based on Percentages)
    //
    NewTrade         = (OnMarket AND Not OnMarket[1]) OR (LongOnMarket AND ShortOnMarket[1]) OR (LongOnMarket[1] AND ShortOnMarket)
    //
    IF Not OnMarket OR NewTrade THEN //reset to default values when a new trade has been opened
       PerCentTP     = 2.0           //2.0%  is TP
       PerCentStart  = 0.2           //0.2%  is the Trailing Stop trigger level
       PerCentStep   = 0.2           //0.2%  is each subsequent step
       PerCentSaved  = 0.1           //0.1%  is how much profit has to be saved when trailing starts and every step
       Multiplier    = 1.5           //1.5   is how much PerCentSaved is incremented each trailing step
       //                                    1.5 is a 50% increment, so that:
       //                                         0.1%   becomes 0.15%,   then
       //                                         0.15%  becomes 0.225%,  then
       //                                         0.225% becomes 0.3375%, etc...
       Distance      = 6             //6     pip distance from current price (if required by the broker)
       MySL          = 0
       ProfitPerCent = 0
    ENDIF
    IF OnMarket THEN
       IF MySL = 0 THEN
          PCent      = PositionPrice * PerCentTP    / 100
          PStart     = PositionPrice * PerCentStart / 100
          PStep      = PositionPrice * PerCentStep  / 100
          PSaved     = PositionPrice * PerCentSaved / 100
       ENDIF
       //
       // check if Trailing Stop has to be triggered
       //
       IF MySL = 0 THEN
          IF LongOnMarket THEN
             IF (close - PositionPrice) >= PStart THEN
                MySL   = min(close,PositionPrice + PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ELSIF ShortOnMarket THEN
             IF (PositionPrice - close) >= PStart THEN
                MySL   = max(close,PositionPrice - PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ENDIF
       ELSE
          //
          // check if another Step has been triggered
          //
          IF LongOnMarket THEN
             IF (close - MySL) >= PStep THEN
                MySL   = min(close,MySL + PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ELSIF ShortOnMarket THEN
             IF (MySL - close) >= PStep THEN
                MySL   = max(close,MySL - PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ENDIF
       ENDIF
       //
       // place Pending STOP orders
       //
       IF MySL > 0 THEN
          IF (MySL = close) OR (abs(MySL - close) < Distance) THEN //exit immediately in case MySL has reached
             //                                                      the current price or there's not enough DISTANCE
             SELL      AT MARKET
             EXITSHORT AT MARKET
          ELSE
             SELL      AT MySL STOP
             EXITSHORT AT MySL STOP
          ENDIF
       ENDIF
    ENDIF
    //
    graphonprice PositionPrice       coloured(0,0,0,255)      AS "Entry"
    graphonprice MySL                coloured(0,128,0,155)    AS "Trailing Stop"
    IF LongOnMarket THEN
       graphonprice PositionPrice - SL  coloured(255,0,0,255) AS "Stop Loss"
    ELSE
       graphonprice PositionPrice + SL  coloured(255,0,0,255) AS "Stop Loss"
    ENDIF
    graph PCent  coloured(0,0,0,255)
    graph PStart coloured(0,0,255,255)
    graph PStep  coloured(0,128,0,155)
    graph PSaved coloured(255,0,0,255)
    graph positionperf * positionprice / pipsize              AS "Gain"
    paisantrader and thanked this post
    #181124 quote
    paisantrader
    Participant
    Senior

    Holy smokes! You are amazing!

    Will give it a try today. I think it will work great for some of the strategies that hold for longer and are in quite high profits. With the old one, the gap between the SL and current price was getting bigger and bigger, so it gave back quite a lot of the profit.

    Thank you!

    #181127 quote
    GraHal
    Participant
    Master

    Link to code above added as Log 310 here …

    Snippet Link Library

    robertogozzi thanked this post
    #181465 quote
    murre87
    Participant
    Senior

    robertogozzi u are an amazing coder. But for us others it would be very intresting to get an explantion in text for how ur trailingcode works.  Whats hapens when and why. What is and how to use minstart MyEquity and so on.

    #181474 quote
    robertogozzi
    Moderator
    Master

    This is the same code as above (test code not included), with more comments:

    // NewTrade is true whenever a new trade is opened, be it:
    //
    //   - a trade when there was none previously
    //   - a trade that has changed direction due to a Stop & Reverse (it's Long and previously was Short and viceversa)
    //
    // This will be useful to reset variables to their initial values after a trade has been opened.
    //
    NewTrade         = (OnMarket AND Not OnMarket[1]) OR (LongOnMarket AND ShortOnMarket[1]) OR (LongOnMarket[1] AND ShortOnMarket)
    //
    // Reset variables to their initial value when a new trade shows
    //
    IF Not OnMarket OR NewTrade THEN //reset to default values when a new trade has been opened (or none is OnMarket)
       PerCentTP     = 2.0           //2.0%  is TP
       PerCentStart  = 0.2           //0.2%  is the Trailing Stop trigger level
       PerCentStep   = 0.2           //0.2%  is each subsequent step
       PerCentSaved  = 0.1           //0.1%  is how much profit has to be saved when trailing starts and every step
       Multiplier    = 1.5           //1.5   is how much PerCentSaved is incremented each trailing step
       //                                    1.5 is a 50% increment, so that:
       //                                         0.1%   becomes 0.15%,   then
       //                                         0.15%  becomes 0.225%,  then
       //                                         0.225% becomes 0.3375%, etc...
       Distance      = 6             //6     pip distance from current price (if required by the broker)
       MySL          = 0
       ProfitPerCent = 0
    ENDIF
    //
    // The trailing stop can operate only when OnMarket
    //
    IF OnMarket THEN
       //
       // before the trailing stop is triggered some calculations need to be done, accordin to settings
       //
       IF MySL = 0 THEN
          PCent      = PositionPrice * PerCentTP    / 100
          PStart     = PositionPrice * PerCentStart / 100
          PStep      = PositionPrice * PerCentStep  / 100
          PSaved     = PositionPrice * PerCentSaved / 100
       ENDIF
       //
       // check if Trailing Stop has to be triggered
       //
       IF MySL = 0 THEN
          IF LongOnMarket THEN
             IF (close - PositionPrice) >= PStart THEN
                MySL   = min(close,PositionPrice + PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ELSIF ShortOnMarket THEN
             IF (PositionPrice - close) >= PStart THEN
                MySL   = max(close,PositionPrice - PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ENDIF
       ELSE
          //
          // check if another Step has been triggered
          //
          IF LongOnMarket THEN
             IF (close - MySL) >= PStep THEN
                MySL   = min(close,MySL + PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ELSIF ShortOnMarket THEN
             IF (MySL - close) >= PStep THEN
                MySL   = max(close,MySL - PSaved)
                PSaved = PSaved * Multiplier
             ENDIF
          ENDIF
       ENDIF
       //
       // place Pending STOP orders
       //
       IF MySL > 0 THEN
          IF (MySL = close) OR (abs(MySL - close) < Distance) THEN //exit immediately in case MySL has reached
             //                                                      the current price or there's not enough DISTANCE
             SELL      AT MARKET
             EXITSHORT AT MARKET
          ELSE
             SELL      AT MySL STOP
             EXITSHORT AT MySL STOP
          ENDIF
       ENDIF
    ENDIF

    if you have more questions don’t hesitate to ask.

    #181477 quote
    murre87
    Participant
    Senior

    Thanks roberto.

    Is their a function abow that does:

    When x% profit sl jumps to x% profit.

    Exemple: When 1% profit sl jumps to 0.1% profit.

    Lets call it “breakeven jump-code” 😊

     

    Would u like to explan MyEquity and how it works and how to use it.

    Sorry for asking so much ☺

Viewing 15 posts - 61 through 75 (of 138 total)
  • You must be logged in to reply to this topic.

BreakEven & Trailing Profit: complete function


ProOrder support

New Reply
Author
Summary

This topic contains 137 replies,
has 23 voices, and was last updated by Wim
5 months, 1 week ago.

Topic Details
Forum: ProOrder support
Language: English
Started: 03/18/2019
Status: Active
Attachments: 25 files
Logo Logo
Loading...