ProRealCode - Trading & Coding with ProRealTime™
Hello,
A work in progress strategy based on a simple mean reversion idea inspired by Kevin Davey that I have adapted from a daily to a 15 minute timeframe. It looks for low volume and low price over N bars, then goes long. Only two entry criteria and one initial filter, and works well but needs improving.
The focus at this stage is to work on reducing the Drawdown, and potentially the number of trades, by use of an entry filter. Thought I would share this early version in the hope that people might have some useful ideas for a suitable filter.
NASDAQ
15m
Spread 2
Thank you,
S
With screenshot that was dropped
Really impressive, thanks for sharing! 🙂
Wow. Impressing. No short entrys?
//================================================
// Code: TEST KD3 Mean Reverting v1
// Source: https://www.youtube.com/watch?v=D_P_XqB5nHs
// Entry Strategy #3 Mean REverting
// Author: Kevin Davey
// Version 1
// Index: NASDAQ
// TF: 15 min
// TZ: Europe
// Notes: v1.1 Long Olny
// Notes: v1.2 Entry Filter (optimised to 150 MA)
// Notes: v1.3 Day of week - do not trade Friday's
//
// Pending Test Short side
// Reduce Drawdown (Long Entry Filter)
//================================================
DEFPARAM CUMULATEORDERS = FALSE
//Risk Management
PositionSize=1
//=== Entry Filter ===
//Filter 1
indicator1=average[150,7]
F1 = close>indicator1
//Range Parameters
Nbars=15
Pbars=10
//Entry Criteria
indicator1 = Volume
c1 = (indicator1 < indicator1[Nbars])
// Conditions to enter long positions
If close > lowest[Pbars](low) and c1 and opendayofweek <> 5 and F1 then
Buy PositionSize CONTRACTS AT MARKET
ENDIF
// Conditions to enter short positions
//IF rrange>2*stdrange+avgrange and close<close[10] THEN
//SELLSHORT PositionSize CONTRACTS AT MARKET
//ENDIF
// Stops and targets
SET STOP LOSS 100 //50
SET TARGET PROFIT 175 //50
//FOR STOPLOSS MANNGEMENT
// Conditions to enter long positions
startBreakeven = 30
PointsToKeep = 12
IF NOT ONMARKET THEN
breakevenLevel=0
ENDIF
// --- BUY SIDE ---
//test if the price have moved favourably of "startBreakeven" points already
IF LONGONMARKET AND close-tradeprice(1)>=startBreakeven*pipsize THEN
//calculate the breakevenLevel
breakevenLevel = tradeprice(1)+PointsToKeep*pipsize
ENDIF
//place the new stop orders on market at breakevenLevel
IF breakevenLevel>0 THEN
SELL AT breakevenLevel STOP
ENDIF
//************************************************************************
IF longonmarket and barindex-tradeindex>1600 and close<positionprice then
sell at market
endif
IF shortonmarket and barindex-tradeindex>1800 and close>positionprice then
exitshort at market
endif
//===================================
myrsiM5=rsi[14](close)
//
if myrsiM5<30 and barindex-tradeindex>1 and longonmarket and close>positionprice then
sell at market
endif
if myrsiM5>70 and barindex-tradeindex>1 and shortonmarket and close<positionprice then
exitshort at market
endif
//===================================
once openStrongLong = 0
once openStrongShort = 0
if (time <= 090000 or time >= 210000) then
openStrongLong = 0
openStrongShort = 0
endif
//detect strong direction for market open
once rangeOK = 30
once tradeMin = 2500
IF (time >= 090500) AND (time <= 090500 + tradeMin) AND ABS(close - open) > rangeOK THEN
IF close > open and close > open[1] THEN
openStrongLong = 1
openStrongShort = 0
ENDIF
IF close < open and close < open[1] THEN
openStrongLong = 0
openStrongShort = 1
ENDIF
ENDIF
once bollperiod = 20
once bollMAType = 1
once s = 2
bollMA = average[bollperiod, bollMAType](close)
STDDEV = STD[bollperiod]
bollUP = bollMA + s * STDDEV
bollDOWN = bollMA - s * STDDEV
IF bollUP = bollDOWN THEN
bollPercent = 50
ELSE
bollPercent = 100 * (close - bollDOWN) / (bollUP - bollDOWN)
ENDIF
once trendPeriod = 80
once trendPeriodResume = 10
once trendGap = 4
once trendResumeGap = 4
if not onmarket then
fullySupported = 0
fullyResisteded = 0
endif
//Market supported in the wrong direction
IF shortonmarket AND fullySupported = 0 AND summation[trendPeriod](bollPercent > 50) >= trendPeriod - trendGap THEN
fullySupported = 1
ENDIF
//Market pull back but continue to be supported
IF shortonmarket AND fullySupported = 1 AND bollPercent[trendPeriodResume + 1] < 0 AND summation[trendPeriodResume](bollPercent > 50) >= trendPeriodResume - trendResumeGap THEN
exitshort at market
ENDIF
//Market resisted in wrong direction
IF longonmarket AND fullyResisteded = 0 AND summation[trendPeriod](bollPercent < 50) >= trendPeriod - trendGap THEN
fullyResisteded = 1
ENDIF
//Market pull back but continue to be resisted
IF longonmarket AND fullyResisteded = 1 AND bollPercent[trendPeriodResume + 1] > 100 AND summation[trendPeriodResume](bollPercent < 50) >= trendPeriodResume - trendResumeGap THEN
sell at market
ENDIF
//Started real wrong direction
once strongTrend = 60
once strongPeriod = 4
once strongTrendGap = 2
IF shortonmarket and openStrongLong and barindex - tradeindex < 12 and summation[strongPeriod](bollPercent > strongTrend) = strongPeriod - strongTrendGap then
exitshort at market
ENDIF
IF longonmarket and openStrongShort and barindex - tradeindex < 12 and summation[strongPeriod](bollPercent < 100 - strongTrend) = strongPeriod - strongTrendGap then
sell at market
ENDIF
//SET STOP $LOSS stoploss
One thing you might want to look at is the section starting at line 73 above. In a 10 year backtest no trades have gone to 1600 bars so those values are doing nothing. This is also the case for the Breakout code you posted.
This is the snippet I use for that function, closes very long-running positions whether they’re winning or losing. You have to optimise for b1 and b2 (b3, b4 for short).
//EXIT ZOMBIE TRADE
EZT = 1
if EZT then
IF longonmarket and (barindex-tradeindex(1)>= b1 and positionperf>0) or (barindex-tradeindex(1)>= b2 and positionperf<0) then
sell at market
endif
IF shortonmarket and (barindex-tradeindex(1)>= b3 and positionperf>0) or (barindex-tradeindex(1)>= b4 and positionperf<0) then
exitshort at market
endif
endif
whats the different between B1 and B2 flr longmarket?
b1 if it’s winning, b2 if it’s losing.
but I should add that this isn’t always advantageous, you should also try switching it off, with some algos it’s better to just let them run.
B1 is for pp > 0 and B2 is for pp < 0.
I have successfully used above on several of my Algos from my early coding days, I will get back on it again, now I see you’re using it Nonetheless! 🙂
I also optimised using broad values for positionperf (in lieu of 0 as above).
but I should add that this isn’t always advantageous, you should also try switching it off, with some algos it’s better to just let them run.
Without this remark I already wanted to add :
I have attempted so many means of exiting because of too long “useless” trades. They always and always net lose. Otherwise this will be highly subject to curve fitting, IMO.
BUT
Only last week I applied a “strange” means for this : let shrink the SL per bar (or once in the so many, also OK). This seems counterproductive, but the contrary appears true. This starts with allowing for a higher SL (avoid peaks at entry) which is psychologically good. Next the losses because or running into the SL in practice are not that high at all. But moreover, this works out. For me it does …
Warning : I am almost sure that we should not change the StopLoss per bar because the broker may not like that. Eh, *if* possible at all. So it needs to be your own exit (like the example code in the earlier post) and NOT changing the StopLoss each time.
Visualisation of what I was saying : when blue and yellow meet, it’s over.
One thing you might want to look at is the section starting at line 73 above. In a 10 year backtest no trades have gone to 1600 bars so those values are doing nothing. This is also the case for the Breakout code you posted.
This is the snippet I use for that function, closes very long-running positions whether they’re winning or losing. You have to optimise for b1 and b2 (b3, b4 for short).
12345678910 //EXIT ZOMBIE TRADEEZT = 1if EZT thenIF longonmarket and (barindex–tradeindex(1)>= b1 and positionperf>0) or (barindex–tradeindex(1)>= b2 and positionperf<0) thensell at marketendifIF shortonmarket and (barindex–tradeindex(1)>= b3 and positionperf>0) or (barindex–tradeindex(1)>= b4 and positionperf<0) thenexitshort at marketendifendif
Thank you very much, I shall add this in and retest. Much appreciated.
I also optimised using broad values for positionperf (in lieu of 0 as above).
Would u like to show an example
I played a bit with the strategy, on DAX 1€, 200K units, 5 min-TF (mtf), changing just TP & SL and slightly the Trailing Stop to use PointsToKeep as sort of a trailing step. Performance is nice and WF is around 25%. I also commented out exiting on RSI:
//================================================
//https://www.prorealcode.com/topic/nasdaq-mean-reversion/
//
// Code: TEST KD3 Mean Reverting v1.3
// Source: https://www.youtube.com/watch?v=D_P_XqB5nHs
// Entry Strategy #3 Mean REverting
// Author: Kevin Davey
// Version 1
// Index: DAX (ex NASDAQ)
// TF: 15 min
// TZ: Europe
// Notes: v1.1 Long Olny
// Notes: v1.2 Entry Filter (optimised to 150 MA)
// Notes: v1.3 Day of week - do not trade Friday's
//
// Pending Test Short side
// Reduce Drawdown (Long Entry Filter)
//================================================
DEFPARAM CUMULATEORDERS = FALSE
Timeframe(2h,UpdateOnClose) //1h
//Risk Management
nLots=1
//=== Entry Filter ===
//Filter 1
indicator1 = average[150,7] //150,7
F1 = close>indicator1
F2 = close<indicator1
//Range Parameters
Nbars = 15 //15
Pbars = 10 //10
//Entry Criteria
indicator1 = Volume
c1 = (indicator1 < indicator1[Nbars])
// Conditions to enter long positions
If close > lowest[Pbars](low) and c1 and opendayofweek <> 5 and F1 and Not OnMarket then
Buy nLots CONTRACTS AT MARKET
ENDIF
// Conditions to enter short positions
If close < highest[Pbars](high) and c1 and opendayofweek <> 5 and F2 and Not OnMarket then
//SELLSHORT nLots CONTRACTS AT MARKET
ENDIF
// Stops and targets
SET STOP pLOSS 50 //50
SET TARGET pPROFIT 70 //75
once openStrongLong = 0
once openStrongShort = 0
if (time <= 090000 or time >= 210000) then //090000 - 210000
openStrongLong = 0
openStrongShort = 0
endif
//detect strong direction for market open
once rangeOK = 30
once tradeMin = 2500
IF (time >= 090500) AND (time <= 090500 + tradeMin) AND ABS(close - open) > rangeOK THEN
IF close > open and close > open[1] THEN
openStrongLong = 1
openStrongShort = 0
ENDIF
IF close < open and close < open[1] THEN
openStrongLong = 0
openStrongShort = 1
ENDIF
ENDIF
once bollperiod = 20
once bollMAType = 1
once s = 2
bollMA = average[bollperiod, bollMAType](close)
STDDEV = STD[bollperiod]
bollUP = bollMA + s * STDDEV
bollDOWN = bollMA - s * STDDEV
IF bollUP = bollDOWN THEN
bollPercent = 50
ELSE
bollPercent = 100 * (close - bollDOWN) / (bollUP - bollDOWN)
ENDIF
once trendPeriod = 80
once trendPeriodResume = 10
once trendGap = 4
once trendResumeGap = 4
if not onmarket then
fullySupported = 0
fullyResisteded = 0
endif
//Market supported in the wrong direction
IF shortonmarket AND fullySupported = 0 AND summation[trendPeriod](bollPercent > 50) >= trendPeriod - trendGap THEN
fullySupported = 1
ENDIF
//Market pull back but continue to be supported
IF shortonmarket AND fullySupported = 1 AND bollPercent[trendPeriodResume + 1] < 0 AND summation[trendPeriodResume](bollPercent > 50) >= trendPeriodResume - trendResumeGap THEN
exitshort at market
ENDIF
//Market resisted in wrong direction
IF longonmarket AND fullyResisteded = 0 AND summation[trendPeriod](bollPercent < 50) >= trendPeriod - trendGap THEN
fullyResisteded = 1
ENDIF
//Market pull back but continue to be resisted
IF longonmarket AND fullyResisteded = 1 AND bollPercent[trendPeriodResume + 1] > 100 AND summation[trendPeriodResume](bollPercent < 50) >= trendPeriodResume - trendResumeGap THEN
sell at market
ENDIF
//Started real wrong direction
once strongTrend = 60 //60
once strongPeriod = 4 //4
once strongTrendGap = 2 //2
IF shortonmarket and openStrongLong and barindex - tradeindex < 12 and summation[strongPeriod](bollPercent > strongTrend) = strongPeriod - strongTrendGap then
exitshort at market
ENDIF
IF longonmarket and openStrongShort and barindex - tradeindex < 12 and summation[strongPeriod](bollPercent < 100 - strongTrend) = strongPeriod - strongTrendGap then
sell at market
ENDIF
//SET STOP $LOSS stoploss
Timeframe(default) //5 min
// Breakeven & Trailing Stop
startBreakeven = 25 //25
PointsToKeep = 5 //5
Distance = 6 //6
//
IF NOT ONMARKET THEN
breakevenLevel=0
ENDIF
//
// --- BUY SIDE ---
//test if the price have moved favourably of "startBreakeven" points already
IF LONGONMARKET AND close-tradeprice(1)>=(startBreakeven*pipsize+PointsToKeep*pipsize) and breakevenlevel = 0 THEN
//calculate the breakevenLevel
breakevenLevel = tradeprice(1)+PointsToKeep*pipsize
ENDIF
IF LONGONMARKET AND close-breakevenlevel>=(startBreakeven*pipsize) and breakevenlevel > 0 THEN
breakevenLevel = breakevenlevel+PointsToKeep*pipsize
ENDIF
//place the new stop orders on market at breakevenLevel
IF breakevenLevel>0 THEN
IF close > (breakevenlevel + Distance) THEN
SELL AT breakevenLevel STOP
IF close < (breakevenlevel - Distance) THEN
SELL AT breakevenLevel LIMIT
ELSE
SELL AT Market
ENDIF
ENDIF
ENDIF
//************************************************************************
ONCE MaxBars = 305 //305
//
IF longonmarket and barindex-tradeindex>MaxBars then//and close<positionprice then
sell at market
endif
IF shortonmarket and barindex-tradeindex>MaxBars then//and close>positionprice then
exitshort at market
endif
//===================================
myrsiM5=rsi[14](close)
//
if myrsiM5<30 and barindex-tradeindex>1 and longonmarket and close>positionprice then
//sell at market
endif
if myrsiM5>70 and barindex-tradeindex>1 and shortonmarket and close<positionprice then
//exitshort at market
endif
//===================================
@samsampop, what is the result about kevin’s initial strategy on daily timeframe ? thx
NASDAQ Mean Reversion
This topic contains 37 replies,
has 14 voices, and was last updated by MauroPro
3 years, 9 months ago.
| Forum: | ProOrder support |
| Language: | English |
| Started: | 08/23/2021 |
| Status: | Active |
| Attachments: | 14 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.