Стратегия ICT Bread and Butter Sell-Setup
Стратегия отслеживает максимумы и минимумы сессий Лондона, Нью-Йорка и Азии и торгует заранее определённые сетапы.
Детали
- Условия входа:
- NY Short: цена делает новый максимум выше лондонского и свеча закрывается медвежьей в сессии NY.
- London Close Buy: между 10:30 и 13:00 цена закрывается ниже минимума Лондона.
- Asia Short: во время азиатской сессии цена закрывается выше азиатского максимума.
- Long/Short: обе стороны.
- Условия выхода:
- Для каждой сделки используются стоп-лосс и тейк-профит в тиках.
- Стопы: Да.
- Значения по умолчанию:
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()