Estrategia de Rompimiento del Máximo/Mínimo Previo
Estrategia de rompimiento que monitorea el máximo y mínimo de la vela anterior en el marco temporal elegido. Se abre una posición larga cuando la nueva vela cierra por encima del máximo previo, mientras que se abre una posición corta cuando el cierre cae por debajo del mínimo previo. Un stop trailing y un take profit fijo gestionan el riesgo y aseguran las ganancias.
El método busca capturar movimientos direccionales fuertes tras la consolidación. Los stops trailing mantienen el riesgo ajustado a medida que el precio se mueve en la dirección favorable.
Detalles
- Criterios de entrada:
- Largo:
Close > PreviousHigh - Corto:
Close < PreviousLow
- Largo:
- Largo/Corto: Ambos
- Criterios de salida:
- Stop loss o take profit
- Stops: Absolutos con trailing usando
StopLossyTakeProfit - Valores predeterminados:
StopLoss= 50mTakeProfit= 1000mCandleType= TimeSpan.FromHours(4).TimeFrame()
- Filtros:
- Categoría: Seguimiento de tendencia
- Dirección: Ambos
- Indicadores: Ninguno
- Stops: Sí (trailing)
- Complejidad: Principiante
- Marco temporal: Largo plazo
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that trades breakouts of the previous candle's high or low.
/// The strategy uses a trailing stop and take profit for risk management.
/// </summary>
public class PreviousHighLowBreakoutStrategy : Strategy
{
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cooldownCandles;
private decimal _previousHigh;
private decimal _previousLow;
private bool _isFirstCandle = true;
private int _cooldown;
/// <summary>
/// Stop loss in price points.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Take profit in price points.
/// </summary>
public decimal TakeProfit
{
get => _takeProfit.Value;
set => _takeProfit.Value = value;
}
/// <summary>
/// Candle type for strategy calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Cooldown period between trades in candles.
/// </summary>
public int CooldownCandles
{
get => _cooldownCandles.Value;
set => _cooldownCandles.Value = value;
}
/// <summary>
/// Initializes strategy parameters.
/// </summary>
public PreviousHighLowBreakoutStrategy()
{
_stopLoss = Param(nameof(StopLoss), 50m)
.SetGreaterThanZero()
.SetDisplay("Stop Loss", "Stop loss in price points", "Risk Management");
_takeProfit = Param(nameof(TakeProfit), 1000m)
.SetGreaterThanZero()
.SetDisplay("Take Profit", "Take profit in price points", "Risk Management");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Time frame for candles", "General");
_cooldownCandles = Param(nameof(CooldownCandles), 300)
.SetDisplay("Cooldown", "Cooldown between trades in candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_previousHigh = default;
_previousLow = default;
_isFirstCandle = true;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ProcessCandle).Start();
StartProtection(
new Unit(StopLoss, UnitTypes.Absolute),
new Unit(TakeProfit, UnitTypes.Absolute));
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
if (_isFirstCandle)
{
_previousHigh = candle.HighPrice;
_previousLow = candle.LowPrice;
_isFirstCandle = false;
return;
}
if (_cooldown > 0)
{
_cooldown--;
_previousHigh = candle.HighPrice;
_previousLow = candle.LowPrice;
return;
}
var price = candle.ClosePrice;
if (price > _previousHigh && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
_cooldown = CooldownCandles;
}
else if (price < _previousLow && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
_cooldown = CooldownCandles;
}
_previousHigh = candle.HighPrice;
_previousLow = candle.LowPrice;
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Strategies import Strategy
class previous_high_low_breakout_strategy(Strategy):
def __init__(self):
super(previous_high_low_breakout_strategy, self).__init__()
self._stop_loss = self.Param("StopLoss", 50.0) \
.SetDisplay("Stop Loss", "Stop loss in price points", "Risk Management")
self._take_profit = self.Param("TakeProfit", 1000.0) \
.SetDisplay("Take Profit", "Take profit in price points", "Risk Management")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Time frame for candles", "General")
self._cooldown_candles = self.Param("CooldownCandles", 300) \
.SetDisplay("Cooldown", "Cooldown between trades in candles", "General")
self._previous_high = 0.0
self._previous_low = 0.0
self._is_first_candle = True
self._cooldown = 0
@property
def StopLoss(self):
return self._stop_loss.Value
@StopLoss.setter
def StopLoss(self, value):
self._stop_loss.Value = value
@property
def TakeProfit(self):
return self._take_profit.Value
@TakeProfit.setter
def TakeProfit(self, value):
self._take_profit.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def CooldownCandles(self):
return self._cooldown_candles.Value
@CooldownCandles.setter
def CooldownCandles(self, value):
self._cooldown_candles.Value = value
def OnStarted2(self, time):
super(previous_high_low_breakout_strategy, self).OnStarted2(time)
self.SubscribeCandles(self.CandleType) \
.Bind(self.ProcessCandle) \
.Start()
self.StartProtection(
stopLoss=Unit(self.StopLoss, UnitTypes.Absolute),
takeProfit=Unit(self.TakeProfit, UnitTypes.Absolute)
)
def ProcessCandle(self, candle):
if candle.State != CandleStates.Finished:
return
if self._is_first_candle:
self._previous_high = float(candle.HighPrice)
self._previous_low = float(candle.LowPrice)
self._is_first_candle = False
return
if self._cooldown > 0:
self._cooldown -= 1
self._previous_high = float(candle.HighPrice)
self._previous_low = float(candle.LowPrice)
return
price = float(candle.ClosePrice)
if price > self._previous_high and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._cooldown = self.CooldownCandles
elif price < self._previous_low and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._cooldown = self.CooldownCandles
self._previous_high = float(candle.HighPrice)
self._previous_low = float(candle.LowPrice)
def OnReseted(self):
super(previous_high_low_breakout_strategy, self).OnReseted()
self._previous_high = 0.0
self._previous_low = 0.0
self._is_first_candle = True
self._cooldown = 0
def CreateClone(self):
return previous_high_low_breakout_strategy()