Стратегия представляет собой перенос экспертного советника MetaTrader 4 «Binario_3» из файла MQL/7658/Binario_3.mq4 в экосистему StockSharp. Исходный робот строит две экспоненциальные средние с периодом 144 по максимумам и минимумам свечи, формируя адаптивный ценовой коридор. При пробое коридора выставляются отложенные стоп-заявки, а управление позицией ведётся с помощью стоп-лоссов, тейк-профитов и опционального трейлинг-стопа.
Версия для StockSharp сохраняет торговую логику, но использует высокоуровневый API платформы:
Подписывается на выбранный поток свечей и пересчитывает обе EMA после закрытия каждой свечи.
Если цена закрытия остаётся внутри канала, создаёт отложенные ордера Buy Stop и Sell Stop на заданном расстоянии от EMA.
Запоминает уровни стоп-лосса и тейк-профита, соответствующие каждой заявке, чтобы применить их сразу после активации ордера.
Следит за котировками уровня Level-1 и закрывает позиции при достижении стопа, цели или дистанции трейлинг-стопа.
Отменяет лишние заявки, когда цена покидает канал либо когда открывается противоположная позиция, что повторяет защитную логику MQL-версии.
Параметры
Имя
Значение по умолчанию
Описание
TakeProfit
850 пунктов
Дополнительное расстояние (в пунктах), добавляемое к цене пробоя при расчёте тейк-профита.
TrailingStop
850 пунктов
Дистанция трейлинг-стопа в пунктах. Значение 0 отключает трейлинг.
PipDifference
25 пунктов
Смещение от EMA при размещении отложенных заявок.
Lots
0.1
Базовый объём сделки, используемый при невозможности рассчитать объём по риску.
MaximumRisk
10
Риск-фактор из оригинального советника. Объём оценивается как max(Lots, Balance * MaximumRisk / 50000).
EmaPeriod
144
Период экспоненциальных средних по максимумам и минимумам.
CandleType
Таймфрейм 1 час
Поток свечей, запускающий расчёт индикаторов и постановку ордеров.
Параметры, заданные в пунктах, преобразуются в реальные ценовые расстояния через шаг цены инструмента (PriceStep). Если шаг не задан, используется значение 1.
Логика торговли
Индикаторы – две ExponentialMovingAverage обрабатывают High и Low свечи. Сигналы появляются только после формирования обеих EMA.
Отложенные заявки – при закрытии внутри канала выставляются:
Sell Stop: EMA(Low) − PipDifference × шаг цены.
Одновременно запоминаются уровни стоп-лосса и тейк-профита для этих ордеров.
Ведение позиции – после открытия позиции противоположный ордер отменяется, а к сделке применяются ранее сохранённые уровни. Котировки Level-1 контролируются для досрочного выхода по стопу, тейку или трейлинг-стопу (TrailingStop × шаг).
Трейлинг-стоп – для длинных позиций уровень подтягивается за лучшей ценой Bid, для коротких – за Ask. Уровень смещается только в сторону прибыли, как и в MetaTrader.
Очистка ордеров – если цена выходит из EMA-канала, обе отложенные заявки отменяются, чтобы избежать случайных входов вне диапазона.
Отличия от MQL-версии
В MetaTrader использовалась функция OrderModify, тогда как в StockSharp закрытие по стопу или тейку выполняется вызовом ClosePosition() при достижении нужной цены.
Трейлинг-стоп реализован внутри стратегии, потому что высокоуровневый API не предоставляет биржевых трейлинг-заявок.
Для расчёта объёма используется баланс портфеля (Portfolio.CurrentValue или Portfolio.BeginValue). При отсутствии данных стратегия использует фиксированное значение Lots.
Перед регистрацией заявок цены нормализуются по шагу цены инструмента.
Рекомендации по использованию
Запускайте стратегию с активной подпиской на Level-1, чтобы логика стопов и трейлинга получала актуальные Bid/Ask значения.
Решения принимаются только по закрытию свечи, поэтому выбранный таймфрейм определяет скорость реакции.
Чтобы отключить трейлинг, установите TrailingStop в 0 — будут использоваться только фиксированные уровни стоп-лосса и тейк-профита.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Binario 3 strategy - fast/slow EMA crossover with momentum confirmation.
/// Buys on bullish EMA crossover, sells on bearish EMA crossover.
/// </summary>
public class Binario3Strategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
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 Binario3Strategy()
{
_fastPeriod = Param(nameof(FastPeriod), 8)
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevFast = 0m; _prevSlow = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevSlow = slow;
_hasPrev = true;
return;
}
var crossUp = _prevFast <= _prevSlow && fast > slow;
var crossDown = _prevFast >= _prevSlow && fast < slow;
if (crossUp && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}