ICT Bread and Butter Sell-Setup 策略
该策略跟踪伦敦、纽约和亚洲交易时段的高点和低点,并根据预定义条件进行交易。
细节
- 入场条件:
- 纽约做空:价格在纽约时段创下高于伦敦高点的新高且收出看跌蜡烛。
- 伦敦收盘买入:10:30 到 13:00 之间价格收于伦敦低点之下。
- 亚洲做空:亚洲时段价格收于亚洲高点之上。
- 多空方向:双向。
- 出场条件:
- 每笔交易使用以跳动为单位的止损和止盈。
- 止损:是。
- 默认值:
ShortStopTicks= 10ShortTakeTicks= 20BuyStopTicks= 10BuyTakeTicks= 20AsiaStopTicks= 10AsiaTakeTicks= 15CandleType= TimeSpan.FromMinutes(1).TimeFrame().
- 筛选:
- 类别:Price action
- 方向:双向
- 指标:Price action
- 止损:是
- 复杂度:基础
- 时间框架:日内
- 季节性:否
- 神经网络:否
- 背离:否
- 风险级别:中等
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// ICT Bread and Butter Sell-Setup strategy.
/// Tracks session highs and lows and trades specific setups around them.
/// </summary>
public class IctBreadAndButterSellSetupStrategy : Strategy
{
private readonly StrategyParam<int> _shortStopTicks;
private readonly StrategyParam<int> _shortTakeTicks;
private readonly StrategyParam<int> _buyStopTicks;
private readonly StrategyParam<int> _buyTakeTicks;
private readonly StrategyParam<int> _asiaStopTicks;
private readonly StrategyParam<int> _asiaTakeTicks;
private readonly StrategyParam<DataType> _candleType;
private decimal _londonHigh;
private decimal _londonLow;
private decimal _nyHigh;
private decimal _nyLow;
private decimal _asiaHigh;
private decimal _asiaLow;
private bool _inLondon;
private bool _inNy;
private bool _inAsia;
/// <summary>
/// Stop loss ticks for NY short entry.
/// </summary>
public int ShortStopTicks
{
get => _shortStopTicks.Value;
set => _shortStopTicks.Value = value;
}
/// <summary>
/// Take profit ticks for NY short entry.
/// </summary>
public int ShortTakeTicks
{
get => _shortTakeTicks.Value;
set => _shortTakeTicks.Value = value;
}
/// <summary>
/// Stop loss ticks for London close buy.
/// </summary>
public int BuyStopTicks
{
get => _buyStopTicks.Value;
set => _buyStopTicks.Value = value;
}
/// <summary>
/// Take profit ticks for London close buy.
/// </summary>
public int BuyTakeTicks
{
get => _buyTakeTicks.Value;
set => _buyTakeTicks.Value = value;
}
/// <summary>
/// Stop loss ticks for Asia sell entry.
/// </summary>
public int AsiaStopTicks
{
get => _asiaStopTicks.Value;
set => _asiaStopTicks.Value = value;
}
/// <summary>
/// Take profit ticks for Asia sell entry.
/// </summary>
public int AsiaTakeTicks
{
get => _asiaTakeTicks.Value;
set => _asiaTakeTicks.Value = value;
}
/// <summary>
/// The type of candles to use for strategy calculation.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public IctBreadAndButterSellSetupStrategy()
{
_shortStopTicks = Param(nameof(ShortStopTicks), 10)
.SetGreaterThanZero()
.SetDisplay("Short Stop Ticks", "Stop loss ticks for NY short entry", "Risk Management")
.SetOptimize(5, 30, 5);
_shortTakeTicks = Param(nameof(ShortTakeTicks), 20)
.SetGreaterThanZero()
.SetDisplay("Short Take Profit Ticks", "Take profit ticks for NY short entry", "Risk Management")
.SetOptimize(10, 50, 5);
_buyStopTicks = Param(nameof(BuyStopTicks), 10)
.SetGreaterThanZero()
.SetDisplay("Buy Stop Ticks", "Stop loss ticks for London close buy", "Risk Management")
.SetOptimize(5, 30, 5);
_buyTakeTicks = Param(nameof(BuyTakeTicks), 20)
.SetGreaterThanZero()
.SetDisplay("Buy Take Profit Ticks", "Take profit ticks for London close buy", "Risk Management")
.SetOptimize(10, 50, 5);
_asiaStopTicks = Param(nameof(AsiaStopTicks), 10)
.SetGreaterThanZero()
.SetDisplay("Asia Stop Ticks", "Stop loss ticks for Asia sell entry", "Risk Management")
.SetOptimize(5, 30, 5);
_asiaTakeTicks = Param(nameof(AsiaTakeTicks), 15)
.SetGreaterThanZero()
.SetDisplay("Asia Take Profit Ticks", "Take profit ticks for Asia sell entry", "Risk Management")
.SetOptimize(5, 40, 5);
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_inLondon = false;
_inNy = false;
_inAsia = false;
_londonHigh = _londonLow = 0m;
_nyHigh = _nyLow = 0m;
_asiaHigh = _asiaLow = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var time = candle.OpenTime;
var date = time.Date;
var sessionNyOpen = new DateTime(date.Year, date.Month, date.Day, 8, 20, 0);
var sessionLondon = new DateTime(date.Year, date.Month, date.Day, 2, 0, 0);
var sessionAsia = new DateTime(date.Year, date.Month, date.Day, 19, 0, 0);
var sessionEnd = new DateTime(date.Year, date.Month, date.Day, 16, 0, 0);
var londonCloseStart = new DateTime(date.Year, date.Month, date.Day, 10, 30, 0);
var londonCloseEnd = new DateTime(date.Year, date.Month, date.Day, 13, 0, 0);
if (time >= sessionLondon && time < sessionNyOpen)
{
if (!_inLondon)
{
_londonHigh = candle.HighPrice;
_londonLow = candle.LowPrice;
_inLondon = true;
}
else
{
_londonHigh = Math.Max(_londonHigh, candle.HighPrice);
_londonLow = Math.Min(_londonLow, candle.LowPrice);
}
}
else
{
_inLondon = false;
}
if (time >= sessionNyOpen && time < sessionEnd)
{
if (!_inNy)
{
_nyHigh = candle.HighPrice;
_nyLow = candle.LowPrice;
_inNy = true;
}
else
{
_nyHigh = Math.Max(_nyHigh, candle.HighPrice);
_nyLow = Math.Min(_nyLow, candle.LowPrice);
}
}
else
{
_inNy = false;
}
if (time >= sessionAsia && time < sessionLondon)
{
if (!_inAsia)
{
_asiaHigh = candle.HighPrice;
_asiaLow = candle.LowPrice;
_inAsia = true;
}
else
{
_asiaHigh = Math.Max(_asiaHigh, candle.HighPrice);
_asiaLow = Math.Min(_asiaLow, candle.LowPrice);
}
}
else
{
_inAsia = false;
}
var judasSwing = candle.HighPrice >= _londonHigh && time >= sessionNyOpen && time < sessionEnd;
var shortEntry = judasSwing && candle.ClosePrice < candle.OpenPrice;
if (shortEntry && Position >= 0)
{
SellMarket();
}
var londonCloseBuy = time >= londonCloseStart && time <= londonCloseEnd && candle.ClosePrice < _londonLow;
if (londonCloseBuy && Position <= 0)
{
BuyMarket();
}
var asiaSell = time >= sessionAsia && time < sessionLondon && candle.ClosePrice > _asiaHigh;
if (asiaSell && Position >= 0)
{
SellMarket();
}
}
}
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_bread_and_butter_sell_setup_strategy(Strategy):
def __init__(self):
super(ict_bread_and_butter_sell_setup_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._london_high = 0.0
self._london_low = 0.0
self._ny_high = 0.0
self._ny_low = 0.0
self._asia_high = 0.0
self._asia_low = 0.0
self._in_london = False
self._in_ny = False
self._in_asia = False
@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_bread_and_butter_sell_setup_strategy, self).OnReseted()
self._in_london = False
self._in_ny = False
self._in_asia = False
self._london_high = 0.0
self._london_low = 0.0
self._ny_high = 0.0
self._ny_low = 0.0
self._asia_high = 0.0
self._asia_low = 0.0
def OnStarted2(self, time):
super(ict_bread_and_butter_sell_setup_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
t = candle.OpenTime
hour = t.Hour
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
if 2 <= hour < 8:
if not self._in_london:
self._london_high = high
self._london_low = low
self._in_london = True
else:
if high > self._london_high:
self._london_high = high
if low < self._london_low:
self._london_low = low
else:
self._in_london = False
if 8 <= hour < 16:
if not self._in_ny:
self._ny_high = high
self._ny_low = low
self._in_ny = True
else:
if high > self._ny_high:
self._ny_high = high
if low < self._ny_low:
self._ny_low = low
else:
self._in_ny = False
if hour >= 19 or hour < 2:
if not self._in_asia:
self._asia_high = high
self._asia_low = low
self._in_asia = True
else:
if high > self._asia_high:
self._asia_high = high
if low < self._asia_low:
self._asia_low = low
else:
self._in_asia = False
judas_swing = high >= self._london_high and 8 <= hour < 16
short_entry = judas_swing and close < open_p
if short_entry and self.Position >= 0:
self.SellMarket()
london_close_buy = 10 <= hour <= 13 and close < self._london_low
if london_close_buy and self.Position <= 0:
self.BuyMarket()
asia_sell = (hour >= 19 or hour < 2) and close > self._asia_high
if asia_sell and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return ict_bread_and_butter_sell_setup_strategy()