The up3x1 Krohabor D strategy is a conversion of the MetaTrader 4 expert advisor up3x1_Krohabor_D.mq4. It keeps the original idea of aligning three displaced simple moving averages (SMA) to detect trend continuation breakouts on the active timeframe. The C# implementation uses the high-level StockSharp API with candle subscriptions and indicator bindings, while adapting risk and position management to the .NET environment.
Trading Logic
Three SMAs are calculated on the instrument's closing prices:
Fast SMA (default 24 bars)
Medium SMA (default 60 bars)
Slow SMA (default 120 bars)
Every moving average is shifted forward by a configurable number of completed candles (default 6). The strategy compares the current shifted value and the value from the previous candle for each average.
Long entry requirements:
Both the current and previous slow SMA values stay below the current and previous fast/medium SMA values, indicating bullish separation.
The medium SMA is falling relative to the fast SMA (previous medium above previous fast, current medium below current fast).
Short entry mirrors the long logic with all comparisons reversed.
Only one position can be open at a time. When no position is active the strategy waits for a new entry signal; otherwise it manages exits.
Exit Rules and Protection
Initial protective orders are simulated by monitoring candle highs and lows:
Stop-loss distance is expressed in price steps (default 110 points) and applied once a position is opened.
Take-profit distance uses the same representation (default 5 points).
A trailing stop (default 10 points) activates once unrealised profit exceeds the configured threshold. The stop follows the market in favor of the open position while never retreating.
Moving-average reversal exits close the trade when the fast SMA crosses back through the medium and slow averages, imitating the original EA's closing logic.
Dynamic volume reduction after consecutive losses replicates the MT4 script behaviour: the trade size decreases proportionally to the number of losing trades while respecting a minimum volume floor.
Parameters
Name
Description
FastPeriod
Period of the fast SMA.
MediumPeriod
Period of the medium SMA.
SlowPeriod
Period of the slow SMA.
MaShift
Number of completed candles used to shift all moving averages forward.
Volume
Base order volume for new entries.
MinVolume
Minimum allowed volume after loss-based adjustments.
LossReductionFactor
Divisor applied when shrinking volume after consecutive losing trades.
StopLossPoints
Stop-loss distance measured in price steps.
TakeProfitPoints
Take-profit distance measured in price steps.
TrailingPoints
Trailing-stop distance and activation threshold in price steps.
CandleType
Candle data type (timeframe) used for analysis.
Notes
The strategy uses SubscribeCandles together with Bind to stream indicator outputs, avoiding manual indicator value retrieval.
Stop-loss, take-profit, and trailing behaviour is implemented inside the strategy loop to stay broker-independent. In live trading environments you can replace these blocks with actual protective orders if required.
All comments within the source code are written in English to comply with project guidelines.
No automated tests are provided; use backtesting inside StockSharp to validate parameter sets for your instruments.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Up3x1KrohaborShiftStrategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose; private decimal _prevMid; private bool _hasPrev;
private int _cooldown;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Up3x1KrohaborShiftStrategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 20).SetDisplay("Channel Period", "Channel lookback", "Indicators");
_emaPeriod = Param(nameof(EmaPeriod), 14).SetDisplay("EMA Period", "EMA filter", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = default;
_prevMid = default;
_hasPrev = default;
_cooldown = default;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(highest, lowest, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) return;
var close = candle.ClosePrice;
var mid = (highest + lowest) / 2;
if (!_hasPrev) { _prevClose = close; _prevMid = mid; _hasPrev = true; return; }
if (_cooldown > 0)
{
_cooldown--;
_prevClose = close; _prevMid = mid;
return;
}
if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 6;
}
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 6;
}
_prevClose = close; _prevMid = mid;
}
}