Esta estrategia es un port simplificado del ejemplo de MetaTrader Exp_ColorZerolagX10MA.mq5. Utiliza una media móvil exponencial de cero rezago para detectar cambios de pendiente. Cuando la media móvil gira hacia arriba después de decrecer durante dos barras, la estrategia abre o revierte a una posición larga. Por el contrario, cuando la media móvil gira hacia abajo después de aumentar, abre o revierte a una posición corta.
La lógica imita la idea original donde un conjunto combinado de diez medias móviles suavizadas produce una única línea codificada por colores. Aquí reemplazamos ese indicador complejo con el ZeroLagExponentialMovingAverage integrado de StockSharp para mantener la implementación compacta y reutilizable. El sistema trabaja en el marco temporal de velas seleccionado y puede habilitar o deshabilitar acciones individuales (abrir/cerrar largo/corto) mediante parámetros.
Detalles
Criterios de entrada:
Largo: ZLEMA[t-2] > ZLEMA[t-1] y ZLEMA[t] > ZLEMA[t-1].
Corto: ZLEMA[t-2] < ZLEMA[t-1] y ZLEMA[t] < ZLEMA[t-1].
Largo/Corto: Ambas direcciones soportadas.
Criterios de salida:
Las posiciones largas se cierran cuando aparece una señal corta y BuyPosClose está habilitado.
Las posiciones cortas se cierran cuando aparece una señal larga y SellPosClose está habilitado.
Stops: Ninguno por defecto; las salidas dependen de señales opuestas.
Valores predeterminados:
Length = 20.
CandleType = marco temporal de 4 horas.
Todos los indicadores de acción (BuyPosOpen, SellPosOpen, BuyPosClose, SellPosClose) habilitados.
Filtros:
Categoría: Seguimiento de tendencia
Dirección: Ambos
Indicadores: Único
Stops: No
Complejidad: Simple
Marco temporal: Medio plazo
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Medio
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Trend detection strategy based on the slope of a zero lag moving average.
/// </summary>
public class ColorZerolagX10MaStrategy : Strategy
{
private readonly StrategyParam<int> _length;
private readonly StrategyParam<DataType> _candleType;
private decimal _prev1;
private decimal _prev2;
private int _count;
public int Length { get => _length.Value; set => _length.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorZerolagX10MaStrategy()
{
_length = Param(nameof(Length), 20)
.SetDisplay("Length", "MA length", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prev1 = 0;
_prev2 = 0;
_count = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var zlma = new ZeroLagExponentialMovingAverage { Length = Length };
SubscribeCandles(CandleType)
.Bind(zlma, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ma)
{
if (candle.State != CandleStates.Finished)
return;
_count++;
if (_count < 3)
{
_prev2 = _prev1;
_prev1 = ma;
return;
}
// Detect trend turn via slope direction change
var trendUp = _prev1 < _prev2 && ma > _prev1;
var trendDown = _prev1 > _prev2 && ma < _prev1;
if (trendUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (trendDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prev2 = _prev1;
_prev1 = ma;
}
}
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 ZeroLagExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class color_zerolag_x10_ma_strategy(Strategy):
"""
Trend detection strategy based on the slope of a zero lag moving average.
"""
def __init__(self):
super(color_zerolag_x10_ma_strategy, self).__init__()
self._length = self.Param("Length", 20) \
.SetDisplay("Length", "MA length", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev1 = 0.0
self._prev2 = 0.0
self._count = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(color_zerolag_x10_ma_strategy, self).OnReseted()
self._prev1 = 0.0
self._prev2 = 0.0
self._count = 0
def OnStarted2(self, time):
super(color_zerolag_x10_ma_strategy, self).OnStarted2(time)
zlma = ZeroLagExponentialMovingAverage()
zlma.Length = self._length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(zlma, self.on_process).Start()
def on_process(self, candle, ma_val):
if candle.State != CandleStates.Finished:
return
self._count += 1
if self._count < 3:
self._prev2 = self._prev1
self._prev1 = ma_val
return
trend_up = self._prev1 < self._prev2 and ma_val > self._prev1
trend_down = self._prev1 > self._prev2 and ma_val < self._prev1
if trend_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif trend_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev2 = self._prev1
self._prev1 = ma_val
def CreateClone(self):
return color_zerolag_x10_ma_strategy()