ICT NY Kill Zone自動売買戦略
フェアバリューギャップとオーダーブロックを使用して、ニューヨークのキルゾーン中に取引する戦略です。
詳細
- エントリー条件: キルゾーン内のフェアバリューギャップとオーダーブロック。
- ロング/ショート: 両方向。
- エグジット条件: ポジション保護。
- ストップ: はい。
- デフォルト値:
StopLoss= 30TakeProfit= 60CandleType= TimeSpan.FromMinutes(5)
- フィルター:
- カテゴリ: ブレイクアウト
- 方向: 両方
- インジケーター: Price Action
- ストップ: はい
- 複雑さ: 基本
- 時間軸: イントラデイ (5m)
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// ICT NY Kill Zone Auto Trading strategy.
/// Inside the New York kill zone (07:00-10:00 New York time, taken as 11:00-14:00 UTC) a bullish fair value gap, where the low of the
/// current candle stays above the high of the candle two bars back, whose first candle is a bearish order block goes long. A bearish
/// fair value gap whose first candle is a bullish order block goes short. An opposite signal reverses the position and every position
/// is protected by a stop loss and take profit in price steps.
/// </summary>
public class IctNyKillZoneAutoTradingStrategy : Strategy
{
private const int _killZoneStartHour = 11;
private const int _killZoneEndHour = 14;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<DataType> _candleType;
private ICandleMessage _prev1;
private ICandleMessage _prev2;
/// <summary>
/// Stop loss in price steps.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Take profit in price steps.
/// </summary>
public decimal TakeProfit
{
get => _takeProfit.Value;
set => _takeProfit.Value = value;
}
/// <summary>
/// Candle type used for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initialize strategy parameters.
/// </summary>
public IctNyKillZoneAutoTradingStrategy()
{
_stopLoss = Param(nameof(StopLoss), 30m)
.SetNotNegative()
.SetDisplay("Stop Loss", "Stop loss in price steps", "Risk Management")
.SetOptimize(10m, 100m, 10m);
_takeProfit = Param(nameof(TakeProfit), 60m)
.SetNotNegative()
.SetDisplay("Take Profit", "Take profit in price steps", "Risk Management")
.SetOptimize(20m, 200m, 10m);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prev1 = null;
_prev2 = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prev1 = null;
_prev2 = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var step = Security?.PriceStep ?? 1m;
StartProtection(
takeProfit: TakeProfit > 0 ? new Unit(TakeProfit * step, UnitTypes.Absolute) : new Unit(),
stopLoss: StopLoss > 0 ? new Unit(StopLoss * step, UnitTypes.Absolute) : new Unit(),
useMarketOrders: true,
isLocalStop: true);
// The stop and take have to see prices between candles, not only at their close.
foreach (var field in new[] { Level1Fields.BestBidPrice, Level1Fields.BestAskPrice })
{
var quotes = new Subscription(DataType.Level1, Security);
quotes.MarketData.BuildField = field;
SubscribeLevel1(quotes).Bind(ObserveProtectionQuote).Start();
}
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ObserveProtectionQuote(Level1ChangeMessage quote)
{
// The high-level handler activates native protection before this callback, also between signal bars.
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var first = _prev2;
_prev2 = _prev1;
_prev1 = candle;
if (first == null || !IsFormedAndOnlineAndAllowTrading())
return;
var hour = candle.OpenTime.Hour;
if (hour < _killZoneStartHour || hour >= _killZoneEndHour)
return;
var bullishFvg = first.HighPrice < candle.LowPrice;
var bearishFvg = first.LowPrice > candle.HighPrice;
var bearishOrderBlock = first.ClosePrice < first.OpenPrice;
var bullishOrderBlock = first.ClosePrice > first.OpenPrice;
if (bullishFvg && bearishOrderBlock && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (bearishFvg && bullishOrderBlock && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Strategies")
clr.AddReference("StockSharp.BusinessEntities")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes, Level1Fields
from StockSharp.BusinessEntities import Subscription
from StockSharp.Algo.Strategies import Strategy
KILL_ZONE_START_HOUR = 11
KILL_ZONE_END_HOUR = 14
class ict_ny_kill_zone_auto_trading_strategy(Strategy):
"""
ICT NY Kill Zone Auto Trading strategy.
Inside the New York kill zone (07:00-10:00 New York time, taken as 11:00-14:00 UTC) a bullish fair value gap, where the low of the
current candle stays above the high of the candle two bars back, whose first candle is a bearish order block goes long. A bearish
fair value gap whose first candle is a bullish order block goes short. An opposite signal reverses the position and every position
is protected by a stop loss and take profit in price steps.
"""
def __init__(self):
super(ict_ny_kill_zone_auto_trading_strategy, self).__init__()
self._stop_loss = self.Param("StopLoss", 30.0).SetNotNegative().SetDisplay("Stop Loss", "Stop loss in price steps", "Risk Management")
self._take_profit = self.Param("TakeProfit", 60.0).SetNotNegative().SetDisplay("Take Profit", "Take profit in price steps", "Risk Management")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles", "General")
self._prev1 = None
self._prev2 = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(ict_ny_kill_zone_auto_trading_strategy, self).OnReseted()
self._prev1 = None
self._prev2 = None
def OnStarted2(self, time):
super(ict_ny_kill_zone_auto_trading_strategy, self).OnStarted2(time)
self._prev1 = None
self._prev2 = None
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
step = Decimal(1)
if self.Security is not None and self.Security.PriceStep is not None:
step = self.Security.PriceStep
tp = Decimal(self._take_profit.Value)
sl = Decimal(self._stop_loss.Value)
take = Unit(tp * step, UnitTypes.Absolute) if tp > 0 else Unit()
stop = Unit(sl * step, UnitTypes.Absolute) if sl > 0 else Unit()
self.StartProtection(take, stop, useMarketOrders=True, isLocalStop=True)
# The stop and take have to see prices between candles, not only at their close.
for field in (Level1Fields.BestBidPrice, Level1Fields.BestAskPrice):
quotes = Subscription(DataType.Level1, self.Security)
quotes.MarketData.BuildField = field
self.SubscribeLevel1(quotes).Bind(self._observe_protection_quote).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _observe_protection_quote(self, quote):
# The high-level handler activates native protection before the callback, including between bars.
pass
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
first = self._prev2
self._prev2 = self._prev1
self._prev1 = candle
if first is None or not self.IsFormedAndOnlineAndAllowTrading():
return
hour = candle.OpenTime.Hour
if hour < KILL_ZONE_START_HOUR or hour >= KILL_ZONE_END_HOUR:
return
bullish_fvg = first.HighPrice < candle.LowPrice
bearish_fvg = first.LowPrice > candle.HighPrice
bearish_order_block = first.ClosePrice < first.OpenPrice
bullish_order_block = first.ClosePrice > first.OpenPrice
if bullish_fvg and bearish_order_block and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif bearish_fvg and bullish_order_block and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return ict_ny_kill_zone_auto_trading_strategy()