Estrategia de Ruptura del Vela de las 2:45 AM
Esta estrategia intradía monitorea la vela de las 2:45 AM y opera rupturas de su máximo o mínimo dentro de las siguientes pocas barras. Cuando el precio supera el máximo de la vela, entra en una posición larga; cuando el precio cae por debajo del mínimo de la vela, abre una posición corta. Las posiciones se cierran al final de la ventana de observación si no ocurre una ruptura opuesta.
Detalles
- Criterios de entrada:
- Largo: El precio rompe por encima del máximo de la vela de las 2:45 AM dentro de las siguientes
LookForwardBarsvelas. - Corto: El precio rompe por debajo del mínimo de la vela de las 2:45 AM dentro de las siguientes
LookForwardBarsvelas.
- Largo: El precio rompe por encima del máximo de la vela de las 2:45 AM dentro de las siguientes
- Largo/Corto: Ambos.
- Criterios de salida:
- Fin de la ventana de observación o ruptura opuesta.
- Stops: Ninguno.
- Valores predeterminados:
TargetHour= 2TargetMinute= 45LookForwardBars= 2CandleType= velas de 45 minutos
- Filtros:
- Categoría: Ruptura basada en tiempo
- Dirección: Ambos
- Indicadores: Ninguno
- Stops: No
- Complejidad: Bajo
- Marco temporal: Intradía
- Estacionalidad: Sí
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// Candle 2:45 Breakout Strategy.
/// The candle covering TargetHour:TargetMinute (UTC) sets the reference high and low. During the next LookForwardBars candles a
/// close above the high goes long and a close below the low goes short, reversing an opposite position. Any position is
/// closed when the observation window ends.
/// </summary>
public class Candle245BreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _targetHour;
private readonly StrategyParam<int> _targetMinute;
private readonly StrategyParam<int> _lookForwardBars;
private readonly StrategyParam<DataType> _candleType;
private decimal? _refHigh;
private decimal? _refLow;
private int _barsLeft;
/// <summary>
/// Hour of the reference candle (UTC).
/// </summary>
public int TargetHour
{
get => _targetHour.Value;
set => _targetHour.Value = value;
}
/// <summary>
/// Minute of the reference candle.
/// </summary>
public int TargetMinute
{
get => _targetMinute.Value;
set => _targetMinute.Value = value;
}
/// <summary>
/// Candles after the reference candle during which breakouts are traded.
/// </summary>
public int LookForwardBars
{
get => _lookForwardBars.Value;
set => _lookForwardBars.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public Candle245BreakoutStrategy()
{
_targetHour = Param(nameof(TargetHour), 2)
.SetRange(0, 23)
.SetDisplay("Target Hour", "Hour of the reference candle (UTC)", "Session");
_targetMinute = Param(nameof(TargetMinute), 45)
.SetRange(0, 59)
.SetDisplay("Target Minute", "Minute of the reference candle", "Session");
_lookForwardBars = Param(nameof(LookForwardBars), 2)
.SetGreaterThanZero()
.SetDisplay("Look Forward Bars", "Candles after the reference candle during which breakouts are traded", "Trading");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(45).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_refHigh = null;
_refLow = null;
_barsLeft = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_refHigh = null;
_refLow = null;
_barsLeft = 0;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// With frames that do not start exactly at the target time, the candle covering it is the reference.
var target = candle.OpenTime.Date + new TimeSpan(TargetHour, TargetMinute, 0);
var frame = CandleType.Arg is TimeSpan tf ? tf : TimeSpan.Zero;
var isReference = candle.OpenTime == target || (candle.OpenTime < target && target < candle.OpenTime + frame);
if (isReference)
{
_refHigh = candle.HighPrice;
_refLow = candle.LowPrice;
_barsLeft = LookForwardBars;
return;
}
if (_barsLeft <= 0 || _refHigh is not decimal high || _refLow is not decimal low)
return;
_barsLeft--;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (_barsLeft == 0)
{
// The observation window ends with this candle.
if (Position > 0)
SellMarket(Position);
else if (Position < 0)
BuyMarket(-Position);
return;
}
var close = candle.ClosePrice;
if (close > high && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (close < low && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class candle245_breakout_strategy(Strategy):
"""
Candle 2:45 Breakout Strategy.
The candle covering TargetHour:TargetMinute (UTC) sets the reference high and low. During the next LookForwardBars candles a
close above the high goes long and a close below the low goes short, reversing an opposite position. Any position is
closed when the observation window ends.
"""
def __init__(self):
super(candle245_breakout_strategy, self).__init__()
self._target_hour = self.Param("TargetHour", 2).SetRange(0, 23).SetDisplay("Target Hour", "Hour of the reference candle (UTC)", "Session")
self._target_minute = self.Param("TargetMinute", 45).SetRange(0, 59).SetDisplay("Target Minute", "Minute of the reference candle", "Session")
self._look_forward_bars = self.Param("LookForwardBars", 2).SetGreaterThanZero().SetDisplay("Look Forward Bars", "Candles after the reference candle during which breakouts are traded", "Trading")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(45))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._ref_high = None
self._ref_low = None
self._bars_left = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(candle245_breakout_strategy, self).OnReseted()
self._ref_high = None
self._ref_low = None
self._bars_left = 0
def OnStarted2(self, time):
super(candle245_breakout_strategy, self).OnStarted2(time)
self._ref_high = None
self._ref_low = None
self._bars_left = 0
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
# With frames that do not start exactly at the target time, the candle covering it is the reference.
open_time = candle.OpenTime
target = open_time.Date.Add(TimeSpan(self._target_hour.Value, self._target_minute.Value, 0))
arg = self.candle_type.Arg
frame = arg if isinstance(arg, TimeSpan) else TimeSpan.Zero
is_reference = open_time == target or (open_time < target and target < open_time.Add(frame))
if is_reference:
self._ref_high = float(candle.HighPrice)
self._ref_low = float(candle.LowPrice)
self._bars_left = self._look_forward_bars.Value
return
if self._bars_left <= 0 or self._ref_high is None or self._ref_low is None:
return
self._bars_left -= 1
if not self.IsFormedAndOnlineAndAllowTrading():
return
if self._bars_left == 0:
# The observation window ends with this candle.
if self.Position > 0:
self.SellMarket(self.Position)
elif self.Position < 0:
self.BuyMarket(-self.Position)
return
close = float(candle.ClosePrice)
if close > self._ref_high and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif close < self._ref_low and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return candle245_breakout_strategy()