Высокоуровневая портированная версия эксперта MetaTrader 4 simplefx2.mq4 (Simple FX 2.0).
Торгует пересечением быстрой и медленной простых скользящих средних по закрытым свечам.
Держит только одну позицию и переворачивается при смене доминирующего тренда.
Логика торговли
Формирует свечи выбранного таймфрейма.
Рассчитывает две простые скользящие средние (быструю и медленную) по ценам закрытия свечей.
Подтверждает бычий тренд, когда и текущая, и предыдущая свечи показывают, что быстрая SMA находится выше медленной. Медвежий тренд подтверждается, когда обе свечи показывают обратное соотношение.
Если подтверждённый тренд отличается от сохранённого состояния, стратегия закрывает противоположную позицию и немедленно открывает рыночную сделку в направлении нового тренда с заданным объёмом.
Дополнительно можно задать уровни стоп-лосса и тейк-профита в шагах цены; они реализуются через сервис защиты StockSharp и повторяют настройки из MT4.
Стратегия работает только с завершёнными свечами и не реагирует на внутрисвечные тики, что обеспечивает максимальное соответствие оригинальному эксперту. Для каждого входа в позицию в журнал записывается поясняющее сообщение.
Параметры
Имя
Описание
Значение по умолчанию
Диапазон оптимизации
ShortPeriod
Период быстрой простой скользящей средней.
50
10 → 150 шаг 5
LongPeriod
Период медленной простой скользящей средней.
200
50 → 400 шаг 10
Volume
Объём рыночной заявки при входе.
0.1
0.1 → 2 шаг 0.1
StopLossPoints
Расстояние стоп-лосса в шагах цены (0 отключает).
0
—
TakeProfitPoints
Расстояние тейк-профита в шагах цены (0 отключает).
0
—
CandleType
Таймфрейм свечей для анализа.
1 час
—
Отличия от версии MT4
Файл simplefx.dat больше не нужен: направление тренда хранится во внутреннем состоянии стратегии.
Параметры скольжения, комментария, magic number и цветов стрелок не перенесены, т.к. маршрутизация заявок в StockSharp устроена иначе.
Уровни стоп-лосса и тейк-профита задаются в шагах цены. При необходимости скорректируйте их под размер пункта у вашего брокера.
В любой момент времени открыта только одна позиция. Перед переворотом вызывается ClosePosition(), что гарантирует чистый переход между long и short.
Как использовать
Выберите инструмент и настройте желаемый таймфрейм свечей.
Отредактируйте периоды скользящих средних и параметры управления рисками.
Запустите стратегию — она подпишется на свечи, будет отслеживать смену тренда и совершать рыночные сделки после подтверждённого пересечения на двух последовательных свечах.
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>
/// Simple FX crossover strategy.
/// Uses fast and slow SMA crossover for trend detection.
/// Buys on golden cross, sells on death cross.
/// </summary>
public class SimpleFxCrossoverStrategy : Strategy
{
private readonly StrategyParam<int> _shortPeriod;
private readonly StrategyParam<int> _longPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevShort;
private decimal _prevLong;
private bool _hasPrev;
public int ShortPeriod { get => _shortPeriod.Value; set => _shortPeriod.Value = value; }
public int LongPeriod { get => _longPeriod.Value; set => _longPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SimpleFxCrossoverStrategy()
{
_shortPeriod = Param(nameof(ShortPeriod), 10)
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_longPeriod = Param(nameof(LongPeriod), 30)
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevShort = 0m;
_prevLong = 0m;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new SimpleMovingAverage { Length = ShortPeriod };
var slow = new SimpleMovingAverage { Length = LongPeriod };
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)
{
_prevShort = fast;
_prevLong = slow;
_hasPrev = true;
return;
}
var crossUp = _prevShort <= _prevLong && fast > slow;
var crossDown = _prevShort >= _prevLong && fast < slow;
if (crossUp && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevShort = fast;
_prevLong = slow;
}
}