ProRealCode - Trading & Coding with ProRealTime™
Hi All,
Ive been working on a simple EMA crossover strategy that utilises Nicolas’ code for moving a stop loss to breakeven after the trade has moved in our direction by a specified number of points.
I have backtested the system and it gives good results. I am also in the midst of testing it in realtime with demo. Again, it is doing pretty well. However a couple of things have come up that Im struggling to resolve.
When profitable positions close due to an EMA crossover, the remaining stop loss also seems to trigger as soon as another position is entered in the opposite direction. See attached screen shot of 4 executions on the NASDAQ. A long of 10 per point at 7500.4 is opened at 08:42 this is then exited at 11:53 at 7548.7. Because the EMA strategy is always in the market a new position is trigger on the short side but then a buy stop is also trigger just above the original 08:42 entry price at 7500.7. Does anyone have any idea what is going on here?
The full code is posted below.
Thanks for any help.
Roj
// Definition of code parameters
DEFPARAM CumulateOrders = False // Cumulating positions deactivated
EMAfast = 23
EMAslow = 47
//Risk Management
Capital = 20000
Risk = 0.005
StopLossL = abs(close - LOWEST[10](Low)) + 1.5 * pointsize
StopLossS = abs(close - HIGHEST[10](High)) + 1.5 * pointsize
equity = Capital + StrategyProfit
maxrisk = round(equity*Risk)
PositionSizeL = abs(round((maxrisk/StopLossL)/PointValue)*pipsize)
PositionSizeS = abs(round((maxrisk/StopLossS)/PointValue)*pipsize)
// Conditions to enter long positions
indicator1 = ExponentialAverage[EMAfast](close)
indicator2 = ExponentialAverage[EMAslow](close)
c1 = (indicator1 CROSSES OVER indicator2)
IF c1 THEN
BUY PositionSizeL PERPOINT AT MARKET
set stop loss StopLossL
ENDIF
// Conditions to exit long positions
indicator3 = ExponentialAverage[EMAfast](close)
indicator4 = ExponentialAverage[EMAslow](close)
c2 = (indicator3 CROSSES UNDER indicator4)
IF c2 THEN
SELL AT MARKET
ENDIF
// Conditions to enter short positions
indicator5 = ExponentialAverage[EMAfast](close)
indicator6 = ExponentialAverage[EMAslow](close)
c3 = (indicator5 CROSSES UNDER indicator6)
IF c3 THEN
SELLSHORT PositionSizeS PERPOINT AT MARKET
set stop loss StopLossS
ENDIF
// Conditions to exit short positions
indicator7 = ExponentialAverage[EMAfast](close)
indicator8 = ExponentialAverage[EMAslow](close)
c4 = (indicator7 CROSSES OVER indicator8)
IF c4 THEN
EXITSHORT AT MARKET
ENDIF
//trailing stop function
TrailingStart = 10 * pipsize //trailing will start @trailinstart points profit
TrailingStep = 5 * pipsize
//reset the stoploss value
IF NOT ONMARKET THEN
newSL = 0
ENDIF
//manage long positions
IF LONGONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND CLOSE - TRADEPRICE(1) >= TrailingStart THEN
newSL = TRADEPRICE(1) + TrailingStep
ENDIF
ENDIF
//manage short positions
IF SHORTONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND TRADEPRICE(1) - CLOSE[1] >= TrailingStart THEN
newSL = TRADEPRICE(1) - TrailingStep
ENDIF
ENDIF
//stop order to exit the positions
IF newSL > 0 THEN
SELL AT newSL STOP
EXITSHORT AT newSL STOP
ENDIF
At lines 23 and 33 add the condition
AND Not OnMarket
Then move line 10 between lines 23 and 24 and move line 11 between lines 42 and 43.
Thanks.
Are you sure I should add a AND NOT ONMARKET to line 33? That is the condition to sell a long position for profit when the fast EMA crosses below the slow. Don’t we need to be on the market for that condition to be implemented?
Shouldnt AND NOT ONMARKET go to line 42 (i.e. where we enter short)?
Sorry if Ive misunderstood and thanks for your help.
Sorry, you’re right, it’s 23 and 42.
Thanks Roberto.
Ive now trialed the updated code and whilst it does prevent new orders from being immediately closed I think the ‘AND NOT ONMARKET’ command is preventing new orders from being initiated. Because this is an EMA cross over strategy it should be on the market pretty much all of the time (unless the breakeven stop has been triggered at which point we wait for the next crossover). For example we should exit longs when the fast EMA crosses below the the slow EMA and simultaneously flip short. I think the ‘AND NOT ONMARKET’ command when we specify conditions to enter is preventing the strategy from simultaneously flipping sides. Is that correct? Can you explain a bit of your rationale for using the ‘AND NOT ONMARKET’ statement? Any ideas how to resolve this? The update code is pasted below.
// Definition of code parameters
DEFPARAM CumulateOrders = False // Cumulating positions deactivated
EMAfast = 6
EMAslow = 27
//Risk Management
Capital = 20000
Risk = 0.005
equity = Capital + StrategyProfit
maxrisk = round(equity*Risk)
PositionSizeL = abs(round((maxrisk/StopLossL)/PointValue)*pipsize)
PositionSizeS = abs(round((maxrisk/StopLossS)/PointValue)*pipsize)
// Conditions to enter long positions
indicator1 = ExponentialAverage[EMAfast](close)
indicator2 = ExponentialAverage[EMAslow](close)
c1 = (indicator1 CROSSES OVER indicator2)
IF c1 AND NOT ONMARKET THEN
BUY PositionSizeL PERPOINT AT MARKET
StopLossL = abs(close - LOWEST[10](Low)) + 1.5 * pointsize
set stop loss StopLossL
ENDIF
// Conditions to exit long positions
indicator3 = ExponentialAverage[EMAfast](close)
indicator4 = ExponentialAverage[EMAslow](close)
c2 = (indicator3 CROSSES UNDER indicator4)
IF c2 THEN
SELL AT MARKET
ENDIF
// Conditions to enter short positions
indicator5 = ExponentialAverage[EMAfast](close)
indicator6 = ExponentialAverage[EMAslow](close)
c3 = (indicator5 CROSSES UNDER indicator6)
IF c3 AND NOT ONMARKET THEN
SELLSHORT PositionSizeS PERPOINT AT MARKET
StopLossS = abs(close - HIGHEST[10](High)) + 1.5 * pointsize
set stop loss StopLossS
ENDIF
// Conditions to exit short positions
indicator7 = ExponentialAverage[EMAfast](close)
indicator8 = ExponentialAverage[EMAslow](close)
c4 = (indicator7 CROSSES OVER indicator8)
IF c4 THEN
EXITSHORT AT MARKET
ENDIF
//trailing stop function
TrailingStart = 5 * pipsize //trailing will start @trailinstart points profit
TrailingStep = 1 * pipsize
//reset the stoploss value
IF NOT ONMARKET THEN
newSL = 0
ENDIF
//manage long positions
IF LONGONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND CLOSE - TRADEPRICE(1) >= TrailingStart THEN
newSL = TRADEPRICE(1) + TrailingStep
ENDIF
ENDIF
//manage short positions
IF SHORTONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND TRADEPRICE(1) - CLOSE[1] >= TrailingStart THEN
newSL = TRADEPRICE(1) - TrailingStep
ENDIF
ENDIF
//stop order to exit the positions
IF newSL > 0 THEN
SELL AT newSL STOP
EXITSHORT AT newSL STOP
ENDIF
Yes, On Market prevents reversing positions, but it allows to keep your StopLoss at the point it was calculated on entry, otherwise it will change every candle.
But, the issue you were complaining about was probably be due to the very narrow value for your trailing stop settings (5 and 1).
IG requires a minimun stop distance when placing pending orders (the ones you use to trail stop loss).
You’d better use GRAPH to monitor your variables, StopLossL, StopLossS, close and NewSL. so that you can figure out what value they do retain each candlestick.
Thanks Roberto. I will graph and try to figure it out. Im not sure its the SL distance though as I’ve been watching the strategy automatically take trades in realtime on demo mode and it works perfectly, just fails to flip from long to short or vice versa with this new code. It was doing that fine in the previous version without a breakeven stop.
I have one more question if you don’t mind me troubling you…
How would I specify that I don’t want any new positions to be taken between 21:15 and 23:00 (i.e. between the close of the NY session and the open of Sydney)?
No worries about the last Q…
I found:
DEFPARAM FlatBefore = 230000
DEFPARAM FlatAfter = 211500
It’s very difficult your strategy can run as expected, too narrow SL’s that don’t always abide to the required minimum distance.
I rewrote your initial code using only 2 indicators and 2 conditions (the other ones were just duplicate instances), adding GRAPH and GRAPHONPRICE and you can see the value of the GRAPHed variable in the variable windows (c1 & c2) and on the price chart (both SL’s + NewSL):
DEFPARAM CumulateOrders = False // Cumulating positions deactivated
EMAfast = 23
EMAslow = 47
//Risk Management
Capital = 20000
Risk = 0.005
StopLossL = abs(close - LOWEST[10](Low)) + 1.5 * pointsize
StopLossS = abs(close - HIGHEST[10](High)) + 1.5 * pointsize
equity = Capital + StrategyProfit
maxrisk = round(equity*Risk)
PositionSizeL = abs(round((maxrisk/StopLossL)/PointValue)*pipsize)
PositionSizeS = abs(round((maxrisk/StopLossS)/PointValue)*pipsize)
// Conditions to enter long positions
indicator1 = ExponentialAverage[EMAfast](close)
indicator2 = ExponentialAverage[EMAslow](close)
c1 = (indicator1 CROSSES OVER indicator2)
IF c1 THEN
BUY PositionSizeL PERPOINT AT MARKET
set stop loss StopLossL
ENDIF
// Conditions to exit long positions
c2 = (indicator1 CROSSES UNDER indicator2)
IF c2 THEN
SELL AT MARKET
ENDIF
// Conditions to enter short positions
IF c2 THEN
SELLSHORT PositionSizeS PERPOINT AT MARKET
set stop loss StopLossS
ENDIF
// Conditions to exit short positions
IF c1 THEN
EXITSHORT AT MARKET
ENDIF
//trailing stop function
TrailingStart = 10 * pipsize //trailing will start @trailinstart points profit
TrailingStep = 5 * pipsize
//reset the stoploss value
IF NOT ONMARKET THEN
newSL = 0
ENDIF
//manage long positions
IF LONGONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND CLOSE - TRADEPRICE(1) >= TrailingStart THEN
newSL = TRADEPRICE(1) + TrailingStep
ENDIF
ENDIF
//manage short positions
IF SHORTONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND TRADEPRICE(1) - CLOSE[1] >= TrailingStart THEN
newSL = TRADEPRICE(1) - TrailingStep
ENDIF
ENDIF
//stop order to exit the positions
IF newSL > 0 THEN
SELL AT newSL STOP
EXITSHORT AT newSL STOP
ENDIF
//
graphOnPrice StopLossL coloured(255,0,0,255) AS "slL"
graphOnPrice StopLossS coloured(0,128,0,255) AS "slS"
graphOnPrice NewSL coloured(0,0,255,255) AS "NewSL"
graph c1
graph c2
You will see the price as a single flat line identified only by the downward orange arrow of the short trade entered, since I had to shkring the scale 1,000 times to be able to see small values compared to a price of over 7,000.
Thanks Roberto. Im pretty much certain that its not down to the size of the stop loss distance. I ran the strategy over night last night in realtime. It is nicely profitable but is still not behaving as expected. I removed the ‘AND NOT ONMARKET’ command as I didn’t think this makes sense for a strategy that should flip from one side to another. However the issue still remains that when a winning position closes due to an EMA cross the leftover trailing stop the instantly closes the new position that is opened. The periodicity of this is evident from the attached chart which shows the performance over last night. Notice how there’s a gap between each position – i.e. every time it flips the trade is closed, so it essentially skips every other signal due to the leftover breakeven stop.
I feel like the reason this is happening is because there are 2 orders to exit positions; 1 being the EMA crossover and the 2nd being the order from the breakeven stop. Is there something that I can add to the condition for the breakeven stop that will pull it from the market when the current position closes (i.e. the one that it is linked to)? Here’s the code that deals with the command for executing the stop:
//stop order to exit the positions
IF newSL > 0 THEN
SELL AT newSL STOP
EXITSHORT AT newSL STOP
ENDIF
The issue is at line 39, since NewSL requires the status NOT ON MARKET to be detected and it only will the next bar after a trade closes. If you open a new trade after closing another one and there is not at least ONE bar with no trades open, NewSL will retain the same previous value.
Try adding a line with
NewSL = 0
betewwen line 25 and 26, then again between lines 44 and 45.
Thank you Roberto, I’ll give that a try. Just to be clear in which set of code above are you quoting line numbers from? Is it after the ‘ENDIF’ associated with exiting longs and shorts?
Lines in your first post.
I think that might have solved the problem, seems to be doing what its supposed to. I will run it over night and post the full code for the strategy with backtesting results etc if it works. Thanks for your help and patience Roberto.
Hi Roberto,
Sadly the addition of ‘NewSL=0’ at the end of the buy and sell conditions does does not seem to have solved the problem and I still get new orders immediately closed out. This pattern is consistent in the backtest and realtime trading over the course of the day.
Its super frustrating as the addition of the breakeven stop to this strategy really increases its profitability and reduces drawdown – see attached screenshot of walk forward analysis on NQ on m1 timeframe. Ive also added some conditions that use the ATR to determine when to move to breakeven, which works nicely. Just massively frustrating that I cent get it to flip sides when the EMAs cross and we take profits on winning trades.
For reference the most up to date cost is pasted below along with the attached screen shot of the walk forward analysis
// Intraday trend following strategy. Entries and Exits defined by EMA crossovers. Position size determiend by distance to stop loss and percent of equity at risk. Initial stop loss set at recent swing low or high. Profits are protected by a stoploss that moves to breakeven after a defined number of points
// Issues: new flipped positions are immediately closed due to the BE stop which remains on the market after the positon is exited due to EMA crossover
// Definition of code parameters
DEFPARAM CumulateOrders = False // Cumulating positions deactivated
DEFPARAM FlatBefore = 230000
DEFPARAM FlatAfter = 211500
EMAfast = 11
EMAslow = 38
//Risk Management
Capital = 36000
Risk = 0.01
equity = Capital + StrategyProfit
maxrisk = round(equity*Risk)
PositionSizeL = abs(round((maxrisk/StopLossL)/PointValue)*pipsize)
PositionSizeS = abs(round((maxrisk/StopLossS)/PointValue)*pipsize)
// Conditions to enter long positions
indicator1 = ExponentialAverage[EMAfast](close)
indicator2 = ExponentialAverage[EMAslow](close)
c1 = (indicator1 CROSSES OVER indicator2)
IF c1 THEN
BUY PositionSizeL PERPOINT AT MARKET
StopLossL = abs(close - LOWEST[10](Low)) + 1.5 * pointsize
set stop loss StopLossL
ENDIF
// Conditions to exit long positions
indicator3 = ExponentialAverage[EMAfast](close)
indicator4 = ExponentialAverage[EMAslow](close)
c2 = (indicator3 CROSSES UNDER indicator4)
IF c2 THEN
SELL AT MARKET
ENDIF
// Conditions to enter short positions
indicator5 = ExponentialAverage[EMAfast](close)
indicator6 = ExponentialAverage[EMAslow](close)
c3 = (indicator5 CROSSES UNDER indicator6)
IF c3 THEN
SELLSHORT PositionSizeS PERPOINT AT MARKET
StopLossS = abs(close - HIGHEST[10](High)) + 1.5 * pointsize
set stop loss StopLossS
ENDIF
// Conditions to exit short positions
indicator7 = ExponentialAverage[EMAfast](close)
indicator8 = ExponentialAverage[EMAslow](close)
c4 = (indicator7 CROSSES OVER indicator8)
IF c4 THEN
EXITSHORT AT MARKET
ENDIF
//trailing stop function
TrailingStart = AverageTrueRange[10] * pipsize //trailing will start @trailinstart points profit
TrailingStep = 0 * pipsize
//reset the stoploss value
IF NOT ONMARKET THEN
newSL = 0
ENDIF
//manage long positions
IF LONGONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND CLOSE - TRADEPRICE(1) >= TrailingStart THEN
newSL = TRADEPRICE(1) + TrailingStep
ENDIF
ENDIF
//manage short positions
IF SHORTONMARKET THEN
//first move (breakeven)
IF newSL = 0 AND TRADEPRICE(1) - CLOSE[1] >= TrailingStart THEN
newSL = TRADEPRICE(1) - TrailingStep
ENDIF
ENDIF
//stop order to exit the positions
IF newSL > 0 THEN
SELL AT newSL STOP
EXITSHORT AT newSL STOP
ENDIF
EMA crossover with Nicolas' Break even stop loss
This topic contains 19 replies,
has 3 voices, and was last updated by crolakstrading
5 years, 8 months ago.
| Forum: | ProOrder: Automated Strategies & Backtesting |
| Language: | English |
| Started: | 08/07/2019 |
| Status: | Active |
| Attachments: | 4 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.