The strategy trades NASDAQ 100 only during the first two and last hours of the session. It uses EMA trend confirmation, RSI, ATR and VWAP filters with ATR based trailing and break-even stops.
Details
Entry Criteria:
Long: Price above short EMA, short EMA above long EMA, both EMAs rising, RSI above 50 and price above VWAP during peak session hours.
Short: Opposite conditions.
Long/Short: Long and short.
Exit Criteria:
ATR based trailing stop or break-even stop.
Time based exit after configurable number of bars or EMA trend reversal.
Stops: ATR trailing with break-even.
Default Values:
Long EMA = 21
Short EMA = 9
RSI = 14
ATR = 14
Trail ATR Mult = 1.5
Initial SL Mult = 0.5
Break-even ATR Mult = 1.5
Time Exit Bars = 20
Filters:
Category: Intraday
Direction: Both
Indicators: EMA, RSI, ATR, VWAP
Stops: Trailing
Complexity: Advanced
Timeframe: Any
Seasonality: No
Neural networks: No
Divergence: No
Risk level: Medium
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Nasdaq100PeakHoursStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Nasdaq100PeakHoursStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame());
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = 14 };
var slow = new ExponentialMovingAverage { Length = 40 };
var rsi = new RelativeStrengthIndex { Length = 14 };
var prevF = 0m; var prevS = 0m; var init = false;
var lastSignal = DateTimeOffset.MinValue;
var cooldown = TimeSpan.FromMinutes(120);
var sub = SubscribeCandles(CandleType);
sub.Bind(fast, slow, rsi, (c, f, s, r) =>
{
if (c.State != CandleStates.Finished || !fast.IsFormed || !slow.IsFormed || !rsi.IsFormed) return;
if (!init) { prevF = f; prevS = s; init = true; return; }
if (c.OpenTime - lastSignal >= cooldown)
{
if (prevF <= prevS && f > s && r > 50 && Position <= 0) { BuyMarket(); lastSignal = c.OpenTime; }
else if (prevF >= prevS && f < s && r < 50 && Position > 0) { SellMarket(); lastSignal = c.OpenTime; }
}
prevF = f; prevS = s;
}).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, sub); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class nasdaq_100_peak_hours_strategy(Strategy):
def __init__(self):
super(nasdaq_100_peak_hours_strategy, self).__init__()
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle type", "Primary timeframe.", "General")
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(nasdaq_100_peak_hours_strategy, self).OnReseted()
self._prev_f = 0
self._prev_s = 0
self._init = False
self._last_signal = None
self._cooldown = TimeSpan.FromMinutes(120)
def OnStarted2(self, time):
super(nasdaq_100_peak_hours_strategy, self).OnStarted2(time)
self._prev_f = 0
self._prev_s = 0
self._init = False
self._last_signal = None
self._cooldown = TimeSpan.FromMinutes(120)
fast = ExponentialMovingAverage()
fast.Length = 14
slow = ExponentialMovingAverage()
slow.Length = 40
rsi = RelativeStrengthIndex()
rsi.Length = 14
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(fast, slow, rsi, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def OnProcess(self, candle, f, s, r):
if candle.State != CandleStates.Finished:
return
if not self._init:
self._prev_f = f
self._prev_s = s
self._init = True
return
if self._last_signal is not None and (candle.OpenTime - self._last_signal) < self._cooldown:
pass
else:
if self._prev_f <= self._prev_s and f > s and r > 50 and self.Position <= 0:
self.BuyMarket()
self._last_signal = candle.OpenTime
elif self._prev_f >= self._prev_s and f < s and r < 50 and self.Position > 0:
self.SellMarket()
self._last_signal = candle.OpenTime
self._prev_f = f
self._prev_s = s
def CreateClone(self):
return nasdaq_100_peak_hours_strategy()