Esta estrategia utiliza tres medias móviles simples (rápida, media, lenta) para identificar la dirección del tendencia. Se abre una posición larga cuando la MA rápida cruza por encima de la MA media y tanto la MA rápida como la MA media están por encima de la MA lenta en las barras actual y anterior. Se abre una posición corta cuando la MA rápida cruza por debajo de la MA media y tanto la MA rápida como la MA media están por debajo de la MA lenta en las barras actual y anterior.
Las posiciones se protegen con niveles de take profit, stop loss y trailing stop opcional. Las órdenes se ejecutan a precios de mercado.
Parámetros
Volume – tamaño de la orden.
Fast Period – período de la SMA rápida.
Middle Period – período de la SMA media.
Slow Period – período de la SMA lenta.
Take Profit – distancia al objetivo de beneficio en unidades de precio.
Stop Loss – distancia al stop de protección en unidades de precio.
Trailing Stop – distancia para la activación del trailing stop en unidades de precio.
Candle Type – marco temporal de las velas usadas para los cálculos.
Señales
Compra – la MA rápida cruza por encima de la MA media y ambas MAs permanecen por encima de la MA lenta.
Venta – la MA rápida cruza por debajo de la MA media y ambas MAs permanecen por debajo de la MA lenta.
Protecciones
Los niveles de take profit y stop loss se establecen en la entrada.
Cuando está habilitado, el trailing stop mueve el stop de protección en la dirección de la operación a medida que el precio avanza.
Notas
Esta es una conversión directa de la estrategia MQL original a StockSharp usando la API de alto nivel e indicadores integrados.
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>
/// Three moving averages crossover strategy.
/// </summary>
public class Up3x1KrohaborDStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _middlePeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevMiddle;
private bool _isInitialized;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int MiddlePeriod { get => _middlePeriod.Value; set => _middlePeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Up3x1KrohaborDStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "MA Settings");
_middlePeriod = Param(nameof(MiddlePeriod), 26)
.SetGreaterThanZero()
.SetDisplay("Middle Period", "Middle EMA period", "MA Settings");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "MA Settings");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevMiddle = 0;
_isInitialized = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastMa = new ExponentialMovingAverage { Length = FastPeriod };
var middleMa = new ExponentialMovingAverage { Length = MiddlePeriod };
var slowMa = new ExponentialMovingAverage { Length = SlowPeriod };
SubscribeCandles(CandleType)
.Bind(fastMa, middleMa, slowMa, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal middle, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!_isInitialized)
{
_prevFast = fast;
_prevMiddle = middle;
_isInitialized = true;
return;
}
var crossUp = _prevFast <= _prevMiddle && fast > middle;
var crossDown = _prevFast >= _prevMiddle && fast < middle;
_prevFast = fast;
_prevMiddle = middle;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class up3x1_krohabor_d_strategy(Strategy):
def __init__(self):
super(up3x1_krohabor_d_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 12) \
.SetDisplay("Fast Period", "Fast EMA period", "MA Settings")
self._middle_period = self.Param("MiddlePeriod", 26) \
.SetDisplay("Middle Period", "Middle EMA period", "MA Settings")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetDisplay("Slow Period", "Slow EMA period", "MA Settings")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_fast = 0.0
self._prev_middle = 0.0
self._is_initialized = False
@property
def fast_period(self):
return self._fast_period.Value
@property
def middle_period(self):
return self._middle_period.Value
@property
def slow_period(self):
return self._slow_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(up3x1_krohabor_d_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_middle = 0.0
self._is_initialized = False
def OnStarted2(self, time):
super(up3x1_krohabor_d_strategy, self).OnStarted2(time)
fast_ma = ExponentialMovingAverage()
fast_ma.Length = self.fast_period
middle_ma = ExponentialMovingAverage()
middle_ma.Length = self.middle_period
slow_ma = ExponentialMovingAverage()
slow_ma.Length = self.slow_period
self.SubscribeCandles(self.candle_type).Bind(fast_ma, middle_ma, slow_ma, self.process_candle).Start()
def process_candle(self, candle, fast, middle, slow):
if candle.State != CandleStates.Finished:
return
fv = float(fast)
mv = float(middle)
if not self._is_initialized:
self._prev_fast = fv
self._prev_middle = mv
self._is_initialized = True
return
cross_up = self._prev_fast <= self._prev_middle and fv > mv
cross_down = self._prev_fast >= self._prev_middle and fv < mv
self._prev_fast = fv
self._prev_middle = mv
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()
def CreateClone(self):
return up3x1_krohabor_d_strategy()