Estrategia de confirmación de gráficos de sincronización
La estrategia refleja la idea de la utilidad original MQL "SyncCharts" al monitorear dos transmisiones de velas del mismo instrumento y
tomar decisiones comerciales solo cuando ambas corrientes confirman la misma dirección de tendencia. La serie maestra actúa como cuadro de referencia.
(el que un comerciante normalmente ve), mientras que la serie de seguidores representa un gráfico auxiliar (por ejemplo, un marco de tiempo más rápido o
una agregación alternativa). Al obligar a ambas corrientes a ponerse de acuerdo antes de ingresar al mercado, el sistema filtra el ruido proveniente de
Desincronización temporal entre intervalos de gráficos.
La configuración funciona mejor en instrumentos que exhiben una estructura de tendencia de múltiples períodos de tiempo, como futuros sobre índices y pares de divisas líquidos.
Debido a que ambos gráficos deben moverse juntos antes de realizar una operación, las señales falsas se reducen y la estrategia naturalmente limita
exposición durante fases caóticas del mercado cuando los plazos no coinciden o se imprimen nuevas velas en diferentes momentos.
Detalles
Criterios de entrada:
Largo: Tanto el promedio móvil simple (SMA) maestro como el seguidor tienen pendiente ascendente en sus velas terminadas más recientes, y
las marcas de tiempo de esas velas difieren en menos que la tolerancia de sincronización.
Corto: Ambos SMA tienen pendiente descendente y la diferencia de marca de tiempo está dentro de la ventana de tolerancia.
Criterios de salida:
Desincronización horaria: si las últimas velas están separadas por más de la tolerancia permitida, la posición se aplana.
Discrepancia de tendencia: si un SMA sube mientras el otro baja, la posición abierta se cierra inmediatamente.
Paradas: la lógica de aplanamiento implícita actúa como una parada suave. No se envía ninguna parada forzosa por separado.
Largo/Corto: Se intercambian ambas partes.
Valores predeterminados:
Vela maestra: tiempo de 5 minutos.
Vela seguidora: período de 1 minuto.
Duración de SMA: 20 períodos en ambas transmisiones.
Tolerancia de sincronización: 15 segundos entre tiempos de apertura de velas.
Filtros:
Categoría: Confirmación de tendencia / multiplazo.
Dirección: Bidireccional.
Indicadores: SMA (doble flujo).
Paradas: sin parada fija, se aplana automáticamente cuando los gráficos divergen.
Complejidad: Media (multisuscripción con comprobaciones de sincronización).
Plazo: Configurable (intradiario predeterminado).
Estacionalidad: Ninguna.
Redes neuronales: No.
Divergencia: utiliza la divergencia del marco temporal como filtro (requiere acuerdo, no divergencia de precios).
Nivel de riesgo: Moderado debido al requisito de confirmación.
como funciona
Se crean dos suscripciones de velas a través del StockSharp API de alto nivel: una para el gráfico maestro y otra para el seguidor.
Cada feed es procesado por un SMA con la misma longitud, lo que genera un indicador de dirección de tendencia (up si el valor de SMA aumenta frente al
vela anterior, down en caso contrario).
Cada vez que ambas velas terminan, la estrategia verifica que sus marcas de tiempo estén lo suficientemente cerca (diferencia absoluta por debajo del
tolerancia configurada).
Si los gráficos están sincronizados y ambas tendencias apuntan hacia arriba, la estrategia compra (cerrando cualquier corto primero). Si ambas tendencias apuntan hacia abajo,
vende en corto (cerrando cualquier posición larga primero).
Cualquier pérdida de sincronización o desacuerdo de tendencia desencadena un aplanamiento inmediato para mantener la cuenta alineada con los gráficos del
relojes comerciante.
Uso recomendado
Aplicar al mismo instrumento en dos períodos de tiempo diferentes que normalmente se correlacionan (por ejemplo, 5 minutos y 1 minuto, o cada hora y
15 minutos).
Aumente la tolerancia de sincronización si trabaja con fuentes de datos exóticas que imprimen velas con retrasos menores.
Combínelo con un administrador de riesgos externo o un módulo de parada adicional cuando lo implemente en operaciones reales.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Sync Charts Confirmation strategy: dual SMA trend confirmation.
/// Uses fast and slow SMAs to confirm trend direction.
/// Buys when both SMAs trend up, sells when both trend down.
/// </summary>
public class SyncChartsConfirmationStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private bool _wasBullish;
private bool _hasPrevTrend;
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public SyncChartsConfirmationStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 40)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow SMA period", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between signals", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullish = false;
_hasPrevTrend = false;
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevTrend = false;
_candlesSinceTrade = SignalCooldownCandles;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
var isBullish = fast > slow;
if (_hasPrevTrend && isBullish != _wasBullish && _candlesSinceTrade >= SignalCooldownCandles)
{
if (isBullish && Position <= 0)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (!isBullish && Position >= 0)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_wasBullish = isBullish;
_hasPrevTrend = true;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class sync_charts_confirmation_strategy(Strategy):
"""Dual SMA trend confirmation with cooldown."""
def __init__(self):
super(sync_charts_confirmation_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 10).SetGreaterThanZero().SetDisplay("Fast Period", "Fast SMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 40).SetGreaterThanZero().SetDisplay("Slow Period", "Slow SMA period", "Indicators")
self._cooldown = self.Param("SignalCooldownCandles", 6).SetGreaterThanZero().SetDisplay("Signal Cooldown", "Bars to wait between signals", "Trading")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).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(sync_charts_confirmation_strategy, self).OnReseted()
self._was_bullish = False
self._has_prev = False
self._candles_since_trade = self._cooldown.Value
def OnStarted2(self, time):
super(sync_charts_confirmation_strategy, self).OnStarted2(time)
self._was_bullish = False
self._has_prev = False
self._candles_since_trade = self._cooldown.Value
fast = SimpleMovingAverage()
fast.Length = self._fast_period.Value
slow = SimpleMovingAverage()
slow.Length = self._slow_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(fast, slow, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def OnProcess(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
if self._candles_since_trade < self._cooldown.Value:
self._candles_since_trade += 1
is_bullish = fast > slow
if self._has_prev and is_bullish != self._was_bullish and self._candles_since_trade >= self._cooldown.Value:
if is_bullish and self.Position <= 0:
self.BuyMarket()
self._candles_since_trade = 0
elif not is_bullish and self.Position >= 0:
self.SellMarket()
self._candles_since_trade = 0
self._was_bullish = is_bullish
self._has_prev = True
def CreateClone(self):
return sync_charts_confirmation_strategy()