ICT Indicator with Paper Trading Strategy
This strategy stores order block highs and lows and goes long when the close crosses above the latest order block high. The long position is closed when the stored order block low crosses above price.
Details
- Entry Criteria:
- Long: close price crosses above latest order block high.
- Long/Short: Long only.
- Exit Criteria:
- Exit long when order block low crosses above price.
- Stops: No.
- Default Values:
CandleType= TimeSpan.FromMinutes(1).TimeFrame().
- Filters:
- Category: Trend following
- Direction: Long
- Indicators: Price action
- Stops: No
- Complexity: Basic
- Timeframe: Intraday
- Seasonality: No
- Neural networks: No
- Divergence: No
- Risk level: Medium
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Simple ICT order block strategy with paper trading exit.
/// </summary>
public class IctIndicatorWithPaperTradingStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal? _orderBlockHigh;
private decimal? _orderBlockLow;
private decimal? _prevOrderBlockHigh;
private decimal? _prevOrderBlockLow;
private decimal? _prevHigh;
private decimal? _prevPrevHigh;
private decimal? _prevLow;
private decimal? _prevPrevLow;
private decimal? _prevClose;
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="IctIndicatorWithPaperTradingStrategy"/> class.
/// </summary>
public IctIndicatorWithPaperTradingStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_orderBlockHigh = null;
_orderBlockLow = null;
_prevOrderBlockHigh = null;
_prevOrderBlockLow = null;
_prevHigh = null;
_prevPrevHigh = null;
_prevLow = null;
_prevPrevLow = null;
_prevClose = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
StartProtection(null, null);
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevHigh is decimal prevHigh && _prevPrevHigh is decimal prevPrevHigh && prevHigh <= prevPrevHigh && candle.HighPrice > prevHigh)
_orderBlockHigh = candle.HighPrice;
if (_prevLow is decimal prevLow && _prevPrevLow is decimal prevPrevLow && prevLow <= prevPrevLow && candle.LowPrice > prevLow)
_orderBlockLow = candle.LowPrice;
var buySignal = _prevClose is decimal prevClose && _prevOrderBlockHigh is decimal prevObh && _orderBlockHigh is decimal obh && prevClose <= prevObh && candle.ClosePrice > obh;
var sellSignal = _prevClose is decimal prevClose2 && _prevOrderBlockLow is decimal prevObl && _orderBlockLow is decimal obl && prevObl <= prevClose2 && obl > candle.ClosePrice;
if (buySignal && Position <= 0)
BuyMarket();
else if (sellSignal && Position > 0)
SellMarket();
_prevPrevHigh = _prevHigh;
_prevHigh = candle.HighPrice;
_prevPrevLow = _prevLow;
_prevLow = candle.LowPrice;
_prevOrderBlockHigh = _orderBlockHigh;
_prevOrderBlockLow = _orderBlockLow;
_prevClose = candle.ClosePrice;
}
}
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.Strategies import Strategy
class ict_indicator_with_paper_trading_strategy(Strategy):
def __init__(self):
super(ict_indicator_with_paper_trading_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(240))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._order_block_high = None
self._order_block_low = None
self._prev_order_block_high = None
self._prev_order_block_low = None
self._prev_high = None
self._prev_prev_high = None
self._prev_low = None
self._prev_prev_low = None
self._prev_close = None
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(ict_indicator_with_paper_trading_strategy, self).OnReseted()
self._order_block_high = None
self._order_block_low = None
self._prev_order_block_high = None
self._prev_order_block_low = None
self._prev_high = None
self._prev_prev_high = None
self._prev_low = None
self._prev_prev_low = None
self._prev_close = None
def OnStarted2(self, time):
super(ict_indicator_with_paper_trading_strategy, self).OnStarted2(time)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self.OnProcess).Start()
def OnProcess(self, candle):
if candle.State != CandleStates.Finished:
return
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if self._prev_high is not None and self._prev_prev_high is not None:
if self._prev_high <= self._prev_prev_high and high > self._prev_high:
self._order_block_high = high
if self._prev_low is not None and self._prev_prev_low is not None:
if self._prev_low <= self._prev_prev_low and low > self._prev_low:
self._order_block_low = low
buy_signal = (self._prev_close is not None and
self._prev_order_block_high is not None and
self._order_block_high is not None and
self._prev_close <= self._prev_order_block_high and
close > self._order_block_high)
sell_signal = (self._prev_close is not None and
self._prev_order_block_low is not None and
self._order_block_low is not None and
self._prev_order_block_low <= self._prev_close and
self._order_block_low > close)
if buy_signal and self.Position <= 0:
self.BuyMarket()
elif sell_signal and self.Position > 0:
self.SellMarket()
self._prev_prev_high = self._prev_high
self._prev_high = high
self._prev_prev_low = self._prev_low
self._prev_low = low
self._prev_order_block_high = self._order_block_high
self._prev_order_block_low = self._order_block_low
self._prev_close = close
def CreateClone(self):
return ict_indicator_with_paper_trading_strategy()