Estrategia basada en el indicador Color Step XCCX. El indicador mide la desviación del precio respecto a una media suavizada y traza dos líneas escalonadas. Se abre una operación larga cuando la línea rápida cae por debajo de la línea lenta. Se abre una operación corta cuando la línea rápida sube por encima de la línea lenta.
Detalles
Criterios de entrada:
Largo: la línea rápida cruza por debajo de la línea lenta
Corto: la línea rápida cruza por encima de la línea lenta
Largo/Corto: Ambos
Criterios de salida:
Largo: la línea rápida cruza por encima de la línea lenta
Corto: la línea rápida cruza por debajo de la línea lenta
Stops: Ninguno
Valores predeterminados:
DPeriod = 30
MPeriod = 7
StepSizeFast = 5
StepSizeSlow = 30
CandleType = TimeSpan.FromHours(4).TimeFrame()
Filtros:
Categoría: Tendencia
Dirección: Ambos
Indicadores: Custom, EMA
Stops: No
Complejidad: Intermedio
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>
/// Strategy based on EMA deviation crossover (XCCX concept).
/// Uses fast/slow EMA crossover for trend direction signals.
/// </summary>
public class ColorStepXccxStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevFast;
private decimal? _prevSlow;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorStepXccxStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 7)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Indicator");
_slowPeriod = Param(nameof(SlowPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevSlow = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
SubscribeCandles(CandleType)
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevFast is null || _prevSlow is null)
{
_prevFast = fastValue;
_prevSlow = slowValue;
return;
}
var crossUp = _prevFast < _prevSlow && fastValue > slowValue;
var crossDown = _prevFast > _prevSlow && fastValue < slowValue;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fastValue;
_prevSlow = slowValue;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class color_step_xccx_strategy(Strategy):
def __init__(self):
super(color_step_xccx_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 7) \
.SetDisplay("Fast Period", "Fast EMA period", "Indicator")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetDisplay("Slow Period", "Slow EMA period", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_fast = None
self._prev_slow = None
@property
def FastPeriod(self):
return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, value):
self._fast_period.Value = value
@property
def SlowPeriod(self):
return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, value):
self._slow_period.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(color_step_xccx_strategy, self).OnStarted2(time)
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
self.SubscribeCandles(self.CandleType) \
.Bind(fast, slow, self.ProcessCandle) \
.Start()
def ProcessCandle(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast_value)
slow_val = float(slow_value)
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fast_val
self._prev_slow = slow_val
return
cross_up = self._prev_fast < self._prev_slow and fast_val > slow_val
cross_down = self._prev_fast > self._prev_slow and fast_val < slow_val
if cross_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif cross_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def OnReseted(self):
super(color_step_xccx_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def CreateClone(self):
return color_step_xccx_strategy()