Esta estrategia utiliza una media móvil de retardo cero (ZLMA) para detectar reversiones de tendencia. Abre posiciones largas cuando la ZLMA gira hacia arriba y abre posiciones cortas cuando la ZLMA gira hacia abajo. Las posiciones existentes se cierran cuando la pendiente del indicador se revierte.
Parámetros
Length: Período de la media móvil de retardo cero.
Candle Type: Marco temporal para las velas utilizadas por la estrategia.
Open Buy: Activar la apertura de posiciones largas.
Open Sell: Activar la apertura de posiciones cortas.
Close Buy: Cerrar posiciones largas cuando la ZLMA gira hacia abajo.
Close Sell: Cerrar posiciones cortas cuando la ZLMA gira hacia arriba.
Lógica
Suscribirse a las velas del marco temporal seleccionado.
Calcular la media móvil de retardo cero.
Rastrear los dos últimos valores de la ZLMA para determinar la dirección de la pendiente.
Si la pendiente cambia de bajista a alcista, cerrar posiciones cortas y abrir una posición larga.
Si la pendiente cambia de alcista a bajista, cerrar posiciones largas y abrir una posición corta.
Este sencillo enfoque sigue el cambio de color de la media móvil de retardo cero para capturar posibles reversiones de tendencia.
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>
/// Strategy that follows ZLEMA direction changes for trend signals.
/// </summary>
public class ColorZeroLagMaStrategy : Strategy
{
private readonly StrategyParam<int> _length;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevZlma;
private decimal _prevPrevZlma;
private int _count;
public int Length { get => _length.Value; set => _length.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorZeroLagMaStrategy()
{
_length = Param(nameof(Length), 12)
.SetGreaterThanZero()
.SetDisplay("Length", "ZLEMA length", "Indicator");
_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();
_prevZlma = 0;
_prevPrevZlma = 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 zlmaValue)
{
if (candle.State != CandleStates.Finished)
return;
_count++;
if (_count < 3)
{
_prevPrevZlma = _prevZlma;
_prevZlma = zlmaValue;
return;
}
// Buy when ZLEMA turns up
var turnUp = _prevZlma < _prevPrevZlma && zlmaValue > _prevZlma;
// Sell when ZLEMA turns down
var turnDown = _prevZlma > _prevPrevZlma && zlmaValue < _prevZlma;
if (turnUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (turnDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevPrevZlma = _prevZlma;
_prevZlma = zlmaValue;
}
}
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_zero_lag_ma_strategy(Strategy):
"""
Strategy that follows ZLEMA direction changes for trend signals.
"""
def __init__(self):
super(color_zero_lag_ma_strategy, self).__init__()
self._length = self.Param("Length", 12) \
.SetDisplay("Length", "ZLEMA length", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_zlma = 0.0
self._prev_prev_zlma = 0.0
self._count = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(color_zero_lag_ma_strategy, self).OnReseted()
self._prev_zlma = 0.0
self._prev_prev_zlma = 0.0
self._count = 0
def OnStarted2(self, time):
super(color_zero_lag_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, zlma_val):
if candle.State != CandleStates.Finished:
return
self._count += 1
if self._count < 3:
self._prev_prev_zlma = self._prev_zlma
self._prev_zlma = zlma_val
return
turn_up = self._prev_zlma < self._prev_prev_zlma and zlma_val > self._prev_zlma
turn_down = self._prev_zlma > self._prev_prev_zlma and zlma_val < self._prev_zlma
if turn_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif turn_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_prev_zlma = self._prev_zlma
self._prev_zlma = zlma_val
def CreateClone(self):
return color_zero_lag_ma_strategy()