GitHub で見る

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;
	}
}