Стратегия ICT Master Suite Trading IQ
Стратегия ICT Master Suite торгует пробои дневных максимумов и минимумов. При закрытии цены выше максимума сессии открывается длинная позиция, при закрытии ниже минимума — короткая. Позиции сопровождаются трейлинг-стопом на основе ATR.
Подробности
- Условия входа:
- Цена закрывается выше текущего максимума сессии (лонг).
- Цена закрывается ниже текущего минимума сессии (шорт).
- Направление: Лонг и шорт.
- Условия выхода:
- Трейлинг-стоп по ATR.
- Стопы: Трейлинг-стоп по ATR.
- Параметры по умолчанию:
AtrPeriod= 14AtrMultiplier= 1.5AllowLong= trueAllowShort= true
- Фильтры:
- Категория: Пробой
- Направление: Оба
- Индикаторы: ATR
- Стопы: Да
- Сложность: Низкая
- Таймфрейм: Внутридневной
- Сезонность: Нет
- Нейросети: Нет
- Дивергенция: Нет
- Уровень риска: Средний
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>
/// ICT Master Suite session breakout strategy.
/// Trades breakouts of the daily session high and low with ATR-based trailing stop.
/// </summary>
public class IctMasterSuiteTradingIqStrategy : Strategy
{
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<decimal> _atrMultiplier;
private readonly StrategyParam<bool> _allowLong;
private readonly StrategyParam<bool> _allowShort;
private readonly StrategyParam<DataType> _candleType;
private decimal _sessionHigh;
private decimal _sessionLow;
private DateTime _sessionDate;
private decimal _entryPrice;
private decimal _stopPrice;
/// <summary>
/// ATR period.
/// </summary>
public int AtrPeriod
{
get => _atrPeriod.Value;
set => _atrPeriod.Value = value;
}
/// <summary>
/// ATR multiplier for stop.
/// </summary>
public decimal AtrMultiplier
{
get => _atrMultiplier.Value;
set => _atrMultiplier.Value = value;
}
/// <summary>
/// Allow long trades.
/// </summary>
public bool AllowLong
{
get => _allowLong.Value;
set => _allowLong.Value = value;
}
/// <summary>
/// Allow short trades.
/// </summary>
public bool AllowShort
{
get => _allowShort.Value;
set => _allowShort.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public IctMasterSuiteTradingIqStrategy()
{
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR calculation period", "Risk Management")
.SetOptimize(5, 30, 1);
_atrMultiplier = Param(nameof(AtrMultiplier), 1.5m)
.SetGreaterThanZero()
.SetDisplay("ATR Multiplier", "ATR multiplier for stop", "Risk Management")
.SetOptimize(1m, 3m, 0.5m);
_allowLong = Param(nameof(AllowLong), true)
.SetDisplay("Allow Long", "Enable long trades", "General");
_allowShort = Param(nameof(AllowShort), true)
.SetDisplay("Allow Short", "Enable short trades", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_sessionHigh = 0m;
_sessionLow = 0m;
_sessionDate = default;
_entryPrice = 0m;
_stopPrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var atr = new ATR { Length = AtrPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(atr, (candle, atrValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (_sessionDate != candle.OpenTime.Date)
{
_sessionDate = candle.OpenTime.Date;
_sessionHigh = candle.HighPrice;
_sessionLow = candle.LowPrice;
return;
}
if (Position <= 0 && AllowLong && candle.ClosePrice > _sessionHigh)
{
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice - atrValue * AtrMultiplier;
BuyMarket();
return;
}
if (Position >= 0 && AllowShort && candle.ClosePrice < _sessionLow)
{
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice + atrValue * AtrMultiplier;
SellMarket();
return;
}
_sessionHigh = Math.Max(_sessionHigh, candle.HighPrice);
_sessionLow = Math.Min(_sessionLow, candle.LowPrice);
if (Position > 0)
{
var newStop = candle.ClosePrice - atrValue * AtrMultiplier;
if (newStop > _stopPrice)
_stopPrice = newStop;
if (candle.LowPrice <= _stopPrice)
SellMarket();
}
else if (Position < 0)
{
var newStop = candle.ClosePrice + atrValue * AtrMultiplier;
if (newStop < _stopPrice)
_stopPrice = newStop;
if (candle.HighPrice >= _stopPrice)
BuyMarket();
}
}).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, atr);
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 AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class ict_master_suite_trading_iq_strategy(Strategy):
def __init__(self):
super(ict_master_suite_trading_iq_strategy, self).__init__()
self._atr_period = self.Param("AtrPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("ATR Period", "ATR calculation period", "Risk Management")
self._atr_multiplier = self.Param("AtrMultiplier", 1.5) \
.SetGreaterThanZero() \
.SetDisplay("ATR Multiplier", "ATR multiplier for stop", "Risk Management")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(240))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._session_high = 0.0
self._session_low = 0.0
self._session_date = None
self._entry_price = 0.0
self._stop_price = 0.0
@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_master_suite_trading_iq_strategy, self).OnReseted()
self._session_high = 0.0
self._session_low = 0.0
self._session_date = None
self._entry_price = 0.0
self._stop_price = 0.0
def OnStarted2(self, time):
super(ict_master_suite_trading_iq_strategy, self).OnStarted2(time)
atr = AverageTrueRange()
atr.Length = self._atr_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(atr, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, atr)
self.DrawOwnTrades(area)
def OnProcess(self, candle, atr_val):
if candle.State != CandleStates.Finished:
return
atr_v = float(atr_val)
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
current_date = candle.OpenTime.Date
mult = float(self._atr_multiplier.Value)
if self._session_date is None or self._session_date != current_date:
self._session_date = current_date
self._session_high = high
self._session_low = low
return
if self.Position <= 0 and close > self._session_high:
self._entry_price = close
self._stop_price = self._entry_price - atr_v * mult
self.BuyMarket()
return
if self.Position >= 0 and close < self._session_low:
self._entry_price = close
self._stop_price = self._entry_price + atr_v * mult
self.SellMarket()
return
if high > self._session_high:
self._session_high = high
if low < self._session_low:
self._session_low = low
if self.Position > 0:
new_stop = close - atr_v * mult
if new_stop > self._stop_price:
self._stop_price = new_stop
if low <= self._stop_price:
self.SellMarket()
elif self.Position < 0:
new_stop = close + atr_v * mult
if new_stop < self._stop_price:
self._stop_price = new_stop
if high >= self._stop_price:
self.BuyMarket()
def CreateClone(self):
return ict_master_suite_trading_iq_strategy()