Открыть на GitHub

Стратегия Up3x1 Krohabor Shift

Обзор

up3x1 Krohabor D — это перенос эксперта MetaTrader 4 up3x1_Krohabor_D.mq4 на платформу StockSharp. Стратегия использует три смещённых простых скользящих средних (SMA), чтобы выявлять продолжение тренда на выбранном таймфрейме. Реализация на C# применяет высокоуровневый API StockSharp с подпиской на свечи и привязкой индикаторов, а также адаптированные механизмы управления позицией и рисками.

Логика торговли

  • Рассчитываются три SMA по ценам закрытия:
    • Быстрая SMA (по умолчанию 24 бара)
    • Средняя SMA (по умолчанию 60 баров)
    • Медленная SMA (по умолчанию 120 баров)
  • Каждая средняя сдвигается вперёд на заданное число завершённых свечей (по умолчанию 6), после чего сравниваются текущие и предыдущие значения.
  • Условия для покупки:
    • Медленная SMA (текущая и предыдущая) остаётся ниже быстрых и средних средних, формируя восходящую структуру.
    • Средняя SMA опускается относительно быстрой (предыдущее значение выше, текущее ниже).
  • Условия для продажи полностью зеркальны.
  • В один момент времени открыта только одна позиция. При отсутствии открытых сделок стратегия ждёт сигнала, при наличии — управляет выходом.

Правила выхода и защита

  • Защитные ордера моделируются через анализ экстремумов свечей:
    • Стоп-лосс задаётся в ценовых шагах (по умолчанию 110 пунктов) и активируется сразу после входа.
    • Тейк-профит задаётся аналогично (по умолчанию 5 пунктов).
  • Трейлинг-стоп (по умолчанию 10 пунктов) включается при достижении нужной прибыли и перемещает защитный уровень вслед за ценой.
  • Если быстрая SMA пересекает среднюю и медленную в обратную сторону, позиция закрывается — так же, как в оригинальном советнике.
  • После серии убыточных сделок объём новой позиции уменьшается пропорционально числу убытков, но не опускается ниже заданного минимума.

Параметры

Имя Описание
FastPeriod Период быстрой SMA.
MediumPeriod Период средней SMA.
SlowPeriod Период медленной SMA.
MaShift Количество завершённых свечей для смещения индикаторов.
Volume Базовый объём сделки.
MinVolume Минимальный объём после уменьшения из-за убытков.
LossReductionFactor Делитель, определяющий степень уменьшения объёма после серии убытков.
StopLossPoints Стоп-лосс в ценовых шагах.
TakeProfitPoints Тейк-профит в ценовых шагах.
TrailingPoints Дистанция и порог для трейлинг-стопа в ценовых шагах.
CandleType Тип/таймфрейм свечей для анализа.

Дополнения

  • Используются методы SubscribeCandles и Bind, поэтому не требуется вручную запрашивать значения индикаторов.
  • Защитные уровни реализованы внутри стратегии и могут быть заменены реальными ордерами при подключении к брокеру.
  • Все комментарии в коде приведены на английском языке в соответствии с требованиями репозитория.
  • Автоматические тесты отсутствуют — рекомендуем прогонять стратегию в тестере StockSharp с нужными параметрами.
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;



	}



}