Estrategia de ruptura construida alrededor del indicador de canal personalizado CandleStop. El sistema calcula continuamente bandas de máximo-máximo y mínimo-mínimo retrasadas, espera a que una vela completada cierre más allá de esas bandas y luego reacciona en la siguiente barra. Opcionalmente impone una vida máxima de posición y utiliza stops de protección basados en puntos.
Detalles
Criterios de entrada: La vela completada anterior cierra por encima del canal superior retrasado (para largos) o por debajo del canal inferior retrasado (para cortos), mientras la barra actual permanece de vuelta dentro del canal para evitar dobles disparadores.
Largo/Corto: Lógica simétrica para operaciones largas y cortas con indicadores de habilitación independientes.
Criterios de salida: Las rupturas CandleStop de color opuesto cierran posiciones existentes; la salida opcional basada en tiempo cierra operaciones que permanecen abiertas más allá del número configurado de minutos.
Stops: Utiliza niveles de stop-loss y take-profit basados en el paso del mercado mediante StartProtection.
Valores predeterminados:
OrderVolume = 1
UpTrailPeriods = 5, UpTrailShift = 5
DownTrailPeriods = 5, DownTrailShift = 5
SignalBar = 1
StopLossPoints = 1000, TakeProfitPoints = 2000
MaxPositionMinutes = 1920
CandleType = marco temporal de 8 horas
Filtros:
Categoría: Ruptura
Dirección: Ambos
Indicadores: Canales retrasados CandleStop
Stops: Sí
Complejidad: Intermedio
Marco temporal: Multi-hora
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Medio
Parámetros
OrderVolume: Cantidad para cada entrada de mercado cuando se abre una nueva posición.
EnableLongEntry / EnableShortEntry: Interruptores que permiten deshabilitar nuevos largos o cortos de forma independiente.
CloseLongOnBearishBreak / CloseShortOnBullishBreak: Si cerrar posiciones existentes cuando aparece el color de ruptura CandleStop opuesto.
EnableTimeExit: Activa el filtro de tiempo máximo de mantenimiento.
MaxPositionMinutes: Número de minutos antes de que una operación abierta se cierre a la fuerza; establecer en cero para deshabilitar incluso cuando EnableTimeExit es verdadero.
UpTrailPeriods y UpTrailShift: Longitud de lookback y desplazamiento hacia atrás para el canal CandleStop alcista. El desplazamiento retrasa la banda estilo Donchian en varias barras para emular el timing del indicador original.
DownTrailPeriods y DownTrailShift: Parámetros equivalentes para el canal bajista.
SignalBar: Índice de la barra inspeccionada para el color de ruptura (1 = vela completada anterior). La siguiente barra más antigua se usa como confirmación, igual que en la versión MQL.
StopLossPoints / TakeProfitPoints: Distancias de stop de protección expresadas en pasos de precio. Se pasan a StartProtection para gestionar automáticamente las salidas.
CandleType: Serie de velas primaria utilizada para la estrategia. Por defecto un marco temporal de 8 horas para coincidir con el script fuente.
Notas de implementación
Los valores del canal se calculan con los indicadores Highest y Lowest combinados con Shift para reproducir las bandas retrasadas del indicador CandleStop original.
Los colores de señal se almacenan en un buffer circular para imitar las llamadas CopyBuffer de la estrategia MQL y evitar entradas duplicadas en velas consecutivas.
Antes de colocar órdenes, la estrategia verifica las salidas basadas en tiempo, cierra posiciones opuestas si es necesario, y luego emite nuevas órdenes de mercado usando el volumen configurado.
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>
/// CandleStop channel breakout strategy.
/// Uses Highest/Lowest channel to detect breakouts and trades on direction changes.
/// </summary>
public class CandleStopSystemTmPlusStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _period;
private decimal? _prevUpper;
private decimal? _prevLower;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int Period
{
get => _period.Value;
set => _period.Value = value;
}
public CandleStopSystemTmPlusStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_period = Param(nameof(Period), 10)
.SetGreaterThanZero()
.SetDisplay("Period", "Channel lookback period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevUpper = null;
_prevLower = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevUpper = null;
_prevLower = null;
var highest = new Highest { Length = Period };
var lowest = new Lowest { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, highest);
DrawIndicator(area, lowest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal upper, decimal lower)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevUpper = upper;
_prevLower = lower;
return;
}
var close = candle.ClosePrice;
if (_prevUpper == null || _prevLower == null)
{
_prevUpper = upper;
_prevLower = lower;
return;
}
// Breakout above previous upper channel
if (close > _prevUpper.Value && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Breakdown below previous lower channel
else if (close < _prevLower.Value && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevUpper = upper;
_prevLower = lower;
}
}
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.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class candle_stop_system_tm_plus_strategy(Strategy):
def __init__(self):
super(candle_stop_system_tm_plus_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._period = self.Param("Period", 10) \
.SetDisplay("Period", "Channel lookback period", "Indicators")
self._prev_upper = None
self._prev_lower = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def Period(self):
return self._period.Value
def OnReseted(self):
super(candle_stop_system_tm_plus_strategy, self).OnReseted()
self._prev_upper = None
self._prev_lower = None
def OnStarted2(self, time):
super(candle_stop_system_tm_plus_strategy, self).OnStarted2(time)
self._prev_upper = None
self._prev_lower = None
highest = Highest()
highest.Length = self.Period
lowest = Lowest()
lowest.Length = self.Period
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawIndicator(area, lowest)
self.DrawOwnTrades(area)
def _on_process(self, candle, upper_value, lower_value):
if candle.State != CandleStates.Finished:
return
uv = float(upper_value)
lv = float(lower_value)
close = float(candle.ClosePrice)
if self._prev_upper is None or self._prev_lower is None:
self._prev_upper = uv
self._prev_lower = lv
return
# Breakout above previous upper channel
if close > self._prev_upper and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Breakdown below previous lower channel
elif close < self._prev_lower and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_upper = uv
self._prev_lower = lv
def CreateClone(self):
return candle_stop_system_tm_plus_strategy()