This strategy uses three simple moving averages (fast, middle, slow) to identify trend direction. A long position is opened when the fast MA crosses above the middle MA and both fast and middle MAs are above the slow MA on the current and previous bars. A short position is opened when the fast MA crosses below the middle MA and both fast and middle MAs are below the slow MA on the current and previous bars.
Positions are protected with take profit, stop loss and optional trailing stop levels. Orders are executed at market prices.
Parameters
Volume – order size.
Fast Period – period of the fast SMA.
Middle Period – period of the middle SMA.
Slow Period – period of the slow SMA.
Take Profit – distance to the profit target in price units.
Stop Loss – distance to the protective stop in price units.
Trailing Stop – distance for trailing stop activation in price units.
Candle Type – timeframe of the candles used for calculations.
Signals
Buy – fast MA crosses above middle MA and both fast and middle MAs stay above the slow MA.
Sell – fast MA crosses below middle MA and both fast and middle MAs stay below the slow MA.
Protections
Take profit and stop loss levels are set on entry.
When enabled, trailing stop moves the protective stop in the trade direction as price advances.
Notes
This is a direct conversion of the original MQL strategy into StockSharp using the high level API and built‑in indicators.
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()