La estrategia Session Breakout replica el asesor experto MetaTrader "Session breakout". Mira la sesión matutina europea.
y mide su rango de precios. Cuando ese rango es lo suficientemente estrecho, la estrategia se prepara para negociar rupturas durante los EE.UU.
sesión de la tarde usando el nivel alto de StockSharp API. La implementación exige como máximo una entrada larga y una corta por día.
Y adjunta automáticamente órdenes de protección (stop loss y takeprofit) a cada posición.
Lógica comercial
Restablezca el estado al comienzo de cada día de negociación y omita los fines de semana. Los lunes son opcionales y están controlados por un parámetro.
Realice un seguimiento de las velas terminadas durante la sesión europea (predeterminada de 06:00 a 12:00) y registre el máximo más alto y el mínimo más bajo.
Al inicio de la sesión de EE. UU., el rango capturado se clasifica como "pequeño" cuando su ancho es menor que SmallSessionThreshol dPips.
Si el rango es pequeño, monitoree las velas de la sesión de EE. UU. (predeterminado de 12:00 a 16:00) y espere hasta que al menos una barra de EE. UU. se haya cerrado (Eu ropeSessionStartHour + 5 to EuropeSessionStartHour + 10).
Una ruptura larga se activa cuando toda la vela se mantiene por encima del máximo europeo más un buffer configurable (BreakoutBuffer Pipas). Una ruptura breve requiere que la vela se mantenga por debajo del mínimo europeo menos el colchón.
Después de entrar en una posición, la estrategia fija niveles de stop-loss y take-profit expresados en pips y evita ene adicionales.
Intenta en la misma dirección durante el resto del día.
Parámetros
Parámetro
Descripción
Volume
Volumen de órdenes utilizado tanto para rupturas largas como cortas.
EuropeSessionStartHour
Hora en la que comienza el seguimiento del alcance europeo.
EuropeSessionEndHour
Hora en la que se detiene el seguimiento del alcance europeo.
UsSessionStartHour
Hora que marca el inicio de la ventana de sesiones de EE.UU.
UsSessionEndHour
Hora que marca el final de la ventana de sesiones de EE.UU.
SmallSessionThresholdPips
Ancho máximo (en pips) para que el rango europeo califique como squeeze.
BreakoutBufferPips
Se agregó un búfer adicional por encima o por debajo del rango antes de desencadenar rupturas.
TradeOnMonday
Permite operar los lunes. Siempre se saltan los fines de semana.
TakeProfitPips
Distancia entre el precio de entrada y el nivel de obtención de beneficios.
StopLossPips
Distancia entre el precio de entrada y el nivel de stop-loss.
CandleType
Serie de velas utilizadas para todos los cálculos (velas de 15 minutos por defecto).
Notas
El tamaño del pip se deriva del instrumento PriceStep. Ajuste los parámetros basados en pips para que coincidan con la especificación del contrato.
s del valor seleccionado.
Debido a que las órdenes se generan cuando se cierra una vela calificada, los llenados ocurren al precio de cierre de esa vela en las pruebas retrospectivas. Liv
Los rellenos pueden variar dependiendo de las condiciones del mercado.
Sólo se puede abrir una operación larga y una corta por día. La lógica refleja el comportamiento original del asesor experto al usar S
Ayudantes de gestión de riesgos basados en posiciones de tockSharp.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Session breakout strategy that tracks a range during first hours and trades breakouts later.
/// Accumulates high/low during range hours (0-8), then trades breakouts during active hours (8-20).
/// </summary>
public class SessionBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _rangeStartHour;
private readonly StrategyParam<int> _rangeEndHour;
private readonly StrategyParam<int> _tradeEndHour;
private readonly StrategyParam<DataType> _candleType;
private DateTime _currentDate;
private decimal? _rangeHigh;
private decimal? _rangeLow;
private bool _rangeComplete;
private bool _tradedToday;
public int RangeStartHour { get => _rangeStartHour.Value; set => _rangeStartHour.Value = value; }
public int RangeEndHour { get => _rangeEndHour.Value; set => _rangeEndHour.Value = value; }
public int TradeEndHour { get => _tradeEndHour.Value; set => _tradeEndHour.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SessionBreakoutStrategy()
{
_rangeStartHour = Param(nameof(RangeStartHour), 0)
.SetDisplay("Range Start", "Hour to start tracking range", "Sessions");
_rangeEndHour = Param(nameof(RangeEndHour), 8)
.SetDisplay("Range End", "Hour to stop tracking range", "Sessions");
_tradeEndHour = Param(nameof(TradeEndHour), 20)
.SetDisplay("Trade End", "Hour to stop trading", "Sessions");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_currentDate = default;
_rangeHigh = null;
_rangeLow = null;
_rangeComplete = false;
_tradedToday = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_currentDate = default;
_rangeHigh = null;
_rangeLow = null;
_rangeComplete = false;
_tradedToday = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var candleDate = candle.OpenTime.Date;
var hour = candle.OpenTime.Hour;
// Reset on new day
if (candleDate != _currentDate)
{
_currentDate = candleDate;
_rangeHigh = null;
_rangeLow = null;
_rangeComplete = false;
_tradedToday = false;
}
// Build range during accumulation hours
if (hour >= RangeStartHour && hour < RangeEndHour)
{
if (_rangeHigh == null || candle.HighPrice > _rangeHigh)
_rangeHigh = candle.HighPrice;
if (_rangeLow == null || candle.LowPrice < _rangeLow)
_rangeLow = candle.LowPrice;
return;
}
// Mark range as complete
if (!_rangeComplete && hour >= RangeEndHour && _rangeHigh != null && _rangeLow != null)
_rangeComplete = true;
if (!_rangeComplete || _rangeHigh == null || _rangeLow == null)
return;
// Trade during active hours
if (hour >= RangeEndHour && hour < TradeEndHour)
{
// Breakout above range high - buy
if (Position <= 0 && candle.ClosePrice > _rangeHigh.Value && !_tradedToday)
{
if (Position < 0)
BuyMarket();
BuyMarket();
_tradedToday = true;
}
// Breakout below range low - sell
else if (Position >= 0 && candle.ClosePrice < _rangeLow.Value && !_tradedToday)
{
if (Position > 0)
SellMarket();
SellMarket();
_tradedToday = true;
}
}
// Close at end of day
if (hour >= TradeEndHour && Position != 0)
{
if (Position > 0)
SellMarket();
else
BuyMarket();
}
}
}
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
from datatype_extensions import *
from indicator_extensions import *
class session_breakout_strategy(Strategy):
def __init__(self):
super(session_breakout_strategy, self).__init__()
self._range_start = self.Param("RangeStartHour", 0).SetDisplay("Range Start", "Hour to start tracking range", "Sessions")
self._range_end = self.Param("RangeEndHour", 8).SetDisplay("Range End", "Hour to stop tracking range", "Sessions")
self._trade_end = self.Param("TradeEndHour", 20).SetDisplay("Trade End", "Hour to stop trading", "Sessions")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))).SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(session_breakout_strategy, self).OnReseted()
self._current_date = None
self._range_high = None
self._range_low = None
self._range_complete = False
self._traded_today = False
def OnStarted2(self, time):
super(session_breakout_strategy, self).OnStarted2(time)
self._current_date = None
self._range_high = None
self._range_low = None
self._range_complete = False
self._traded_today = False
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(self.OnProcess).Start()
def OnProcess(self, candle):
if candle.State != CandleStates.Finished:
return
candle_date = candle.OpenTime.Date
hour = candle.OpenTime.Hour
if self._current_date is None or candle_date != self._current_date:
self._current_date = candle_date
self._range_high = None
self._range_low = None
self._range_complete = False
self._traded_today = False
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if hour >= self._range_start.Value and hour < self._range_end.Value:
if self._range_high is None or high > self._range_high:
self._range_high = high
if self._range_low is None or low < self._range_low:
self._range_low = low
return
if not self._range_complete and hour >= self._range_end.Value and self._range_high is not None and self._range_low is not None:
self._range_complete = True
if not self._range_complete or self._range_high is None or self._range_low is None:
return
if hour >= self._range_end.Value and hour < self._trade_end.Value:
if self.Position <= 0 and close > self._range_high and not self._traded_today:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._traded_today = True
elif self.Position >= 0 and close < self._range_low and not self._traded_today:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._traded_today = True
if hour >= self._trade_end.Value and self.Position != 0:
if self.Position > 0:
self.SellMarket()
else:
self.BuyMarket()
def CreateClone(self):
return session_breakout_strategy()