Hello,
This strategy will look for a new highs (or lows for shorts) over the last N candles and, in conjunction with 2 x entry filters will take a position. I also added the volatility filter provided by JS in a recent post – thank you, this helped improve overall performance.
Filter for too high volatility
I had originally developed this strategy to run on a daily time frame, but have found that it runs just as well on lower time frames. 5 minutes is the lowest setting I would consider.
Risk Mgt – For initial Profit Target and Stop Loss it uses a simple ATR methodology, with a hard $ value as a backstop to the downside. The trailing stop is taken from another great strategy posted on this great site.
For the walk forward results in the screenshots provided the settings were as follows, running on an EU timezone;
Capital 10k
Position size 1
Spread 2.6
NASDAQ
5 min
Further testing:
1 – Need to optimise the short side as it doesn’t perform as well as the longs do. Will test different look back periods to try and improve this.
2 – Try to reduce how much the strategy gives back overall looking at the Losses Only metric and reflected in the Gain/Loss Ratio, without curve fitting.
All observations, feedback and questions are always welcome.
Thank you
//==========================================================================================================
// Code: INCUBATOR Jump
// Source: General research
// Version 3
// Index: NASDAQ
// TF: 5 min (adapted from Daily)
// TZ: EU
// Spread: 2.6
// Notes: v1.1 Core strategy, Long only
// v2.1 Added Short entry
// v3.1 Applied Entry Filter on 60 and 30 minute timeframe
// v3.2 19/11/21 Optimised Trailing Stop for 5 minute timeframe (Entry Filter and Criteria remain the same)
// Added Volatility filter to avoid enter trades during choppy marekt conditions
// Author: JS
// https://www.prorealcode.com/topic/filter-for-too-high-volatility/#post-180817
//==========================================================================================================
DEFPARAM CUMULATEORDERS = false
//Risk Management
PositionSize=1
sl = PositionSize *110 //1100
entry3pbase = (HIGHEST[16](High)+LOWEST[16](Low)) / 2
off = 2 * AverageTrueRange[15](Close)
//Filter Filter
Timeframe(60 MINUTES)
indicator1 = average[300] //175
CB1 = close > indicator1
CS1 = close < indicator1
Timeframe(30 MINUTES)
indicator2 = ADX[14] //14
CB2 = (indicator2 >= 20)
CS2 = (indicator2 <= 20)
//Volatility Filter: Avoid entry during choppy markets
xPVolatility = (Std[3](Close) / Close) * 100
F1 = xPVolatility < 0.29
//GRAPH xPVolatility
//Entry Criteria
IF NOT LongOnMarket AND Close>Close[24] AND CB1 AND CB2 and opendayofweek <>5 THEN
BUY PositionSize CONTRACTS AT entry3pbase + off STOP
ENDIF
IF NOT ShortOnMarket AND Close<Close[24] AND CS1 AND CS2 and opendayofweek <>2 AND F1 THEN
SELLSHORT PositionSize CONTRACTS AT entry3pbase - off STOP
ENDIF
//Break even
breakevenPercent = 0.2
PointsToKeep = 15
startBreakeven = tradeprice(1)*(breakevenpercent/100)
once breakeven = 1//1 on - 0 off
//reset the breakevenLevel when no trade are on market
if breakeven>0 then
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 THEN
//calculate the breakevenLevel
breakevenLevel = tradeprice(1)+PointsToKeep
ENDIF
//place the new stop orders on market at breakevenLevel
IF breakevenLevel>0 THEN
SELL AT breakevenLevel STOP
ENDIF
// --- end of BUY SIDE ---
IF SHORTONMARKET AND tradeprice(1)-close>startBreakeven THEN
//calculate the breakevenLevel
breakevenLevel = tradeprice(1)-PointsToKeep
ENDIF
//place the new stop orders on market at breakevenLevel
IF breakevenLevel>0 THEN
EXITSHORT AT breakevenLevel STOP
ENDIF
endif
//--------------------------------------------------------------------------------------------------------------------------------------------------
// trailing atr stop
once trailingstoptype = 1 // trailing stop - 0 off, 1 on
once tsincrements = .1 //05 // set to 0 to ignore tsincrements
once tsminatrdist = 5
once tsatrperiod = 14 // ts atr parameter
once tsminstop = 12 // ts minimum stop distance
once tssensitivity = 1 // [0]close;[1]high/low
if trailingstoptype then
if barindex=tradeindex then
trailingstoplong = 3 // ts atr distance
trailingstopshort = 3 // ts atr distance
else
if longonmarket then
if tsnewsl>0 then
if trailingstoplong>tsminatrdist then
if tsnewsl>tsnewsl[1] then
trailingstoplong=trailingstoplong
else
trailingstoplong=trailingstoplong-tsincrements
endif
else
trailingstoplong=tsminatrdist
endif
endif
endif
if shortonmarket then
if tsnewsl>0 then
if trailingstopshort>tsminatrdist then
if tsnewsl<tsnewsl[1] then
trailingstopshort=trailingstopshort
else
trailingstopshort=trailingstopshort-tsincrements
endif
else
trailingstopshort=tsminatrdist
endif
endif
endif
endif
tsatr=averagetruerange[tsatrperiod]((close/10))/1000
//tsatr=averagetruerange[tsatrperiod]((close/1)) // (forex)
tgl=round(tsatr*trailingstoplong)
tgs=round(tsatr*trailingstopshort)
if not onmarket or ((longonmarket and shortonmarket[1]) or (longonmarket[1] and shortonmarket)) then
tsmaxprice=0
tsminprice=close
tsnewsl=0
endif
if tssensitivity then
tssensitivitylong=high
tssensitivityshort=low
else
tssensitivitylong=close
tssensitivityshort=close
endif
if longonmarket then
tsmaxprice=max(tsmaxprice,tssensitivitylong)
if tsmaxprice-tradeprice(1)>=tgl*pointsize then
if tsmaxprice-tradeprice(1)>=tsminstop then
tsnewsl=tsmaxprice-tgl*pointsize
else
tsnewsl=tsmaxprice-tsminstop*pointsize
endif
endif
endif
if shortonmarket then
tsminprice=min(tsminprice,tssensitivityshort)
if tradeprice(1)-tsminprice>=tgs*pointsize then
if tradeprice(1)-tsminprice>=tsminstop then
tsnewsl=tsminprice+tgs*pointsize
else
tsnewsl=tsminprice+tsminstop*pointsize
endif
endif
endif
if longonmarket then
if tsnewsl>0 then
sell at tsnewsl stop
endif
if tsnewsl>0 then
if low crosses under tsnewsl then
sell at market // when stop is rejected
endif
endif
endif
if shortonmarket then
if tsnewsl>0 then
exitshort at tsnewsl stop
endif
if tsnewsl>0 then
if high crosses over tsnewsl then
exitshort at market // when stop is rejected
endif
endif
endif
endif
if onmarket then
if dayofweek=0 and (hour=0 and minute>=57) and abs(dopen(0)-dclose(1))>50 and positionperf(0)>0 then
if shortonmarket and close>dopen(0) then
exitshort at market
endif
if longonmarket and close<dopen(0) then
sell at market
endif
endif
endif
//==== ATR Profit Target & Stop Loss ====
atrperiod = 20
atr = AverageTrueRange[atrperiod]
p = 7 //6
l = 8 //7 optimised to 4
set target profit p*atr
set stop ploss l*atr
SET STOP $LOSS sl
Hi. Great coding. I will try the Volatility filter
How does the daily TF-code look like?
Would u like to explain this 🙂
if onmarket then
if dayofweek=0 and (hour=0 and minute>=57) and abs(dopen(0)-dclose(1))>50 and positionperf(0)>0 then
if shortonmarket and close>dopen(0) then
exitshort at market
endif
if longonmarket and close<dopen(0) then
sell at market
endif
endif
endif
if you want to run this on a 5min TF, surely you need to add Timeframe(default) somewhere? like just above the volatility?
also, might be improved to keep the entry within the NDQ open hours
Tradetime = time >=143000 and time <210000//UK
in the ATR trail you want:
once tsminstop = 4
as that’s a given by IG
this is what I get on 1m bar BT
Is this the backtest with ur adjustments, nonetheless?
no, that’s the original. i haven’t done any other tests, just my first thoughts.
Hi
My apologies, I see I posted the wrong code for the strategy you see in the screenshots. Will rectify when I get back.
Working this on to a 15 min time frame. The 1M back test shows the downside testing lower time frame strategies on the standard 200k bars, and you don’t get to see how it performs through periods of real market stress.
There is something there. I might try having a go at creating a 15 min version myself. Higher time frames are definitely the way forward.