ProRealCode - Trading & Coding with ProRealTime™
I added lines 9 and 10 for settings, then lines 29-32 and lines 49-52 for the code to manage the additional percentage.
nonetheless, what algo is it you are using in your pictures? MOD?
Thank you Roberto for the kind help! I have just updated my code with this and trimmed some parameters so now it is up in the Demo, will be interesting to see the result in the coming weeks. Thanks!
a try to cover a position on the trailingstop of robertogozzi
Basically it uses the levels of Donchian if the trade is triggered. If the trailing stop is not triggered, it uses previous determined lows before the trade to exit, with in consideration to a minimum distance to the tradeprice.
Also has a second exit method if above is not triggered and the lines are narrow. If it crosses the top line for a long and retraces back to the lowest it exits too, again with in consideration of a minimum distance between max & min levels
With this, most likely with mistakes, I hope that if the market reverse there is an alternative way to exit the trade before going to the stoploss.
Instead of a fixed amount to start the trailingstop, it uses now a %. Pipsize is left out on the part I added. I’am unsure if it is * or /. What I added can be disabled.
once trailingstop=1
once useDonchian =1 // if breakeven is not triggered
if trailingstop then
if ts2sensitivity=1 then
ts2sensitivitylong=close
ts2sensitivityshort=close
elsif ts2sensitivity=2 then
ts2sensitivitylong=high
ts2sensitivityshort=low
endif
once hdp1=close
once ldp1=close
once hdp2=close
once ldp2=close
once hdp3=close
once ldp3=close
// below; 0 = disable minimumdistance critera
mdist=((tradeprice(1)/100)*0.09)
mdist2=((tradeprice(1)/100)*0.09)
if longonmarket and (shortonmarket[1] or not onmarket[1]) or shortonmarket and (longonmarket[1] or not onmarket[1]) then
once flag=0
hdp1=highest[7](high)[1]
ldp1=lowest[7](low)[1]
hdp2=highest[14](high)[1]
ldp2=lowest[14](low)[1]
hdp3=highest[21](high)[1]
ldp3=lowest[21](low)[1]
maxrun=max(hdp1,hdp2)
maxrun2=max(maxrun,hdp3)
minrun=min(ldp1,ldp2)
minrun2=min(minrun,ldp3)
endif
if not onmarket or ((longonmarket and shortonmarket[1]) or (longonmarket[1] and shortonmarket)) then
trailstart2 = 0.1 //% start trailing profits from this point
basepercent = 0.2 //20.0% profit percentage to keep when setting berakeven
stepsize = 2 //10 pip chunks to increase percentage
percentinc = 0.1 //10.0% percent increment after each stepsize chunk
barnumber = 10 //10 add further % so trades don't keep running too long
barpercent = 0.1 //10% add this additional percentage every barnumber bars
roundto = 0 //-0.5 rounds lower, +0.4 higher, 0 defaults prt behaviour
pricedistance = 10 * pipsize //7 minimun distance from current price
y1 = 0 //reset to 0
y2 = 0 //reset to 0
profitpercent = basepercent //reset to desired default value
tradebar = barindex
trailstart = ((close/100)*trailstart2)
ts2sensitivity= 2
elsif longonmarket then
if ts2sensitivitylong > (tradeprice(1) + (y1 * pipsize)) then
x1 = (ts2sensitivitylong - tradeprice(1)) / pipsize
if x1 >= trailstart then
diff1 = abs(trailstart - x1)
chunks1 = max(0,round((diff1 / stepsize) + roundto))
profitpercent = basepercent + (basepercent * (chunks1 * percentinc))
barcount = barindex - tradebar
if barcount mod barnumber = 0 then
profitpercent = profitpercent + barpercent
endif
profitpercent = max(profitpercent[1],min(100,profitpercent))
y1 = max(x1 * profitpercent, y1)
endif
else
if useDonchian then
if (tradeprice(1)-ldp1)>mdist and close crosses under ldp1 then
sell at market
endif
if (tradeprice(1)-ldp2)>mdist and close crosses under ldp2 then
sell at market
endif
if (tradeprice(1)-ldp3)>mdist and close crosses under ldp3 then
sell at market
endif
if high crosses over maxrun2 then
flag=1
endif
if flag=1 and low crosses under minrun2 and maxrun2-minrun2>mdist2 then
sell at market
endif
endif
endif
elsif shortonmarket then
if ts2sensitivityshort < (tradeprice(1) - (y2 * pipsize)) then
x2 = (tradeprice(1) - ts2sensitivityshort) / pipsize
if x2 >= trailstart then
diff2 = abs(trailstart - x2)
chunks2 = max(0,round((diff2 / stepsize) + roundto))
profitpercent = basepercent + (basepercent * (chunks2 * percentinc))
barcount = barindex - tradebar
if barcount mod barnumber = 0 then
profitpercent = profitpercent + barpercent
endif
profitpercent = max(profitpercent[1],min(100,profitpercent))
y2 = max(x2 * profitpercent, y2)
endif
else
if useDonchian then
if hdp1-tradeprice(1)>mdist and close crosses over hdp1 then
exitshort at market
endif
if hdp2-tradeprice(1)>mdist and close crosses over hdp2 then
exitshort at market
endif
if hdp3-tradeprice(1)>mdist and close crosses over hdp3 then
exitshort at market
endif
if low crosses under minrun2 then
flag=1
endif
if flag=1 and high crosses over maxrun2 and maxrun2-minrun2>mdist2 then
exitshort at market
endif
endif
endif
endif
if y1 then
sellprice = tradeprice(1) + (y1 * pipsize)
if abs(ts2sensitivitylong - sellprice) > pricedistance then
if ts2sensitivitylong >= sellprice then
sell at sellprice stop
else
sell at sellprice limit
endif
else
sell at market
endif
endif
if y2 then
exitprice = tradeprice(1) - (y2 * pipsize)
if abs(ts2sensitivityshort - exitprice) > pricedistance then
if ts2sensitivityshort <= exitprice then
exitshort at exitprice stop
else
exitshort at exitprice limit
endif
else
exitshort at market
endif
endif
endif
graphonprice hdp1
graphonprice ldp1
graphonprice hdp2
graphonprice ldp2
graphonprice hdp3
graphonprice ldp3
I am running this on a 5min strategy. My trailing has started but every 50 min (barnumber 10×5(min) the stop does not move up additional 10% (barpercent). Why though?
TrailStart = 11 //30 Start trailing profits from this point
BasePerCent = 0.07 //20.0% Profit percentage to keep when setting BerakEven
StepSize = 10 //10 Pip chunks to increase Percentage
PerCentInc = 0.07 //10.0% PerCent increment after each StepSize chunk
BarNumber = 10 //10 Add further % so that trades don't keep running too long
BarPerCent = 0.100 //10% Add this additional percentage every BarNumber bars
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
(I am using Robertos code)
This works correctly with your settings:
defparam cumulateorders = false
p = 100
t = 0
if close crosses over average[p,t](close) then
buy at market
elsif close crosses under average[p,t](close) then
sellshort at market
endif
set target pprofit 500
//
IF Not OnMarket THEN
//
// when NOT OnMarket reset values to default values
TrailStart = 11 //30 Start trailing profits from this point
BasePerCent = 0.07 //20.0% Profit percentage to keep when setting BerakEven
StepSize = 10 //10 Pip chunks to increase Percentage
PerCentInc = 0.07 //10.0% PerCent increment after each StepSize chunk
BarNumber = 10 //10 Add further % so that trades don't keep running too long
BarPerCent = 0.100 //10% Add this additional percentage every BarNumber bars
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
TradeBar = BarIndex + 1
ELSIF LongOnMarket AND close > (TradePrice + (y1 * pipsize)) THEN //LONG positions
//
// compute the value of the Percentage of profits, if any, to lock in for LONG trades
//
x1 = (close - tradeprice) / 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
// compute number of bars elapsed and add an additionl percentage
// (this percentage is different from PerCentInc, since it's a direct percentage, not a Percentage of BasePerCent)
// (if BasePerCent is 20% and this is 10%, the whole percentage will be 30%, not 22%)
BarCount = BarIndex - TradeBar
IF BarCount MOD BarNumber = 0 THEN
ProfitPerCent = ProfitPerCent + BarPerCent
ENDIF
//
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 close < (TradePrice - (y2 * pipsize)) THEN //SHORT positions
//
// compute the value of the Percentage of profits, if any, to lock in for SHORT trades
//
x2 = (tradeprice - close) / 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
// compute number of bars elapsed and add an additionl percentage
// (this percentage is different from PerCentInc, since it's a direct percentage, not a Percentage of BasePerCent)
// (if BasePerCent is 20% and this is 10%, the whole percentage will be 30%, not 22%)
BarCount = BarIndex - TradeBar
IF BarCount MOD BarNumber = 0 THEN
ProfitPerCent = ProfitPerCent + BarPerCent
ENDIF
//
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
IF y1 THEN //Place pending STOP order when y1 > 0 (LONG positions)
SellPrice = Tradeprice + (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 = Tradeprice - (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
graph BasePerCent
graph ProfitPerCent
graph BarCount//(barIndex - tradeindex)
graph close - TradePrice
graphonprice SellPrice coloured(255,0,0,255)
graphonprice ExitPrice coloured(0,255,0,255)
graph BarPerCent
I was tired that day, Thanks Roberto!
I like the trailing and it works well. I get the best results in backtest from having a low PerCentInc it mostly depends on some trades which have ran over 5% (1000 euro), meaning I dont run the strategy with a TP. MFE is in most of the times therefor very far away from the actual Abs Perf.
The conclusion I have came with is that this trailing would be better if I added some more exits with it for example positions ends when trend is not so strong anymore or others and there for end its position.
Maybe this can save someones time. Good luck!
Hi
apologies if this is obvious to the pros out there, but im still getting to grips with trailing stops.
lets say I usually have a fixed TP of 75 pips.
However, instead of closing at 75, im happy to let it run, up to say…. 150 pips (or some other indicator) but I want to make sure I take a minimum of 50 pips profit if it reverses… can I use this code for that and what settings would I need?
Thanks!
In your case you’d better use the code snippet at https://www.prorealcode.com/blog/trading/complete-trailing-stop-code-function/ (linesd 17 – 56) replacing lines 19 and 20 with, say, 75 and 50.
Exactly what I needed.. many thanks Robert – And Nicolas for the code.
Ciao Roberto, would this work with cumulative orders? by changing tradeprice to positionprice? or does it need more than that?
nonetheless, it’s actually a bit more complex, because each new bar it might have accumulated more or less positions, so the previous trailing exit, if any, needs to be adjusted. It will keep the older one if it grants greater profits.
This is the new code dealing with accumulation of positions. I suggest that it be used in ANY case, though, since it will operate correctly even when not accumulating, it will simply never detect different position sizes and PositionPrice will match TradePrice:
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
//
TrailStart = 30 //30 Start trailing profits from this point
BasePerCent = 0.200 //20.0% Profit percentage to keep when setting BerakEven
StepSize = 10 //10 Pip chunks to increase Percentage
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
ExitPrice = 9999999
ELSE
//------------------------------------------------------
// --- Update Stop Loss after accumulating new positions
//------------------------------------------------------
PositionCount = max(PositionCount,abs(CountOfPosition))
//
// update Stop Loss only when PositionCount 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 LongOnMarket THEN
q1 = PositionPrice + ((close - 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 - close) * 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 close > (TradePrice + (y1 * pipsize)) THEN //LONG positions
//
// compute the value of the Percentage of profits, if any, to lock in for LONG trades
//
x1 = (close - tradeprice) / 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 close < (TradePrice - (y2 * pipsize)) THEN //SHORT positions
//
// compute the value of the Percentage of profits, if any, to lock in for SHORT trades
//
x2 = (tradeprice - close) / 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,Tradeprice + (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,Tradeprice - (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
Roberto, you are a megastar. I was just in the middle of trying to work it out for myself but it was making my head hurt.
Hugely appreciate all the work you put in here!
BTW, I have been using this to make it work as a % trailing start:
n = (tradeprice*ts)/100 // ts = % trailing start
TrailStart = n // Start trailing profits from this point
So presumably I now change tradeprice to positionprice ?
BreakEven & Trailing Profit: complete function
This topic contains 137 replies,
has 23 voices, and was last updated by Wim
6 months, 3 weeks ago.
| Forum: | ProOrder: Automated Strategies & Backtesting |
| Language: | English |
| Started: | 03/18/2019 |
| Status: | Active |
| Attachments: | 25 files |
The information collected on this form is stored in a computer file by ProRealCode to create and access your ProRealCode profile. This data is kept in a secure database for the duration of the member's membership. They will be kept as long as you use our services and will be automatically deleted after 3 years of inactivity. Your personal data is used to create your private profile on ProRealCode. This data is maintained by SAS ProRealCode, 407 rue Freycinet, 59151 Arleux, France. If you subscribe to our newsletters, your email address is provided to our service provider "MailChimp" located in the United States, with whom we have signed a confidentiality agreement. This company is also compliant with the EU/Swiss Privacy Shield, and the GDPR. For any request for correction or deletion concerning your data, you can directly contact the ProRealCode team by email at privacy@prorealcode.com If you would like to lodge a complaint regarding the use of your personal data, you can contact your data protection supervisory authority.