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()