Стратегия повторяет систему "радуги" скользящих средних из исходного эксперта MQL.
Используются одиннадцать экспоненциальных средних вместе с фильтрами MACD и ADX.
Принцип работы
Расчёт EMA(2), EMA(3), EMA(5), EMA(8), EMA(13), EMA(21), EMA(34), EMA(55), EMA(89), EMA(144) и EMA(233) по ценам закрытия.
Расчёт MACD (быстрый, медленный, сигнал) и использование сигнальной линии.
Расчёт ADX для оценки силы тренда.
Покупка, когда:
Сигнальная линия MACD выше нуля.
Все EMA расположены по возрастанию (каждая более быстрая выше более медленной).
Значение ADX выше порога.
Продажа, когда:
Сигнальная линия MACD ниже нуля.
Все EMA расположены по убыванию.
Значение ADX выше порога.
Позиция разворачивается при появлении противоположного сигнала.
Параметры
Имя
Описание
FastMacd
Период быстрой EMA для MACD.
SlowMacd
Период медленной EMA для MACD.
SignalPeriod
Период сигнальной линии MACD.
AdxPeriod
Период индикатора ADX.
AdxThreshold
Минимальное значение ADX для входа.
CandleType
Таймфрейм свечей.
Примечания
Используются рыночные заявки BuyMarket и SellMarket.
Одновременно открыта только одна позиция; противоположный сигнал приводит к развороту.
Мартингейл из оригинальной версии не реализован.
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>
/// EMA rainbow trend following strategy.
/// </summary>
public class MagnaRapaxCopperStrategy : 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 MagnaRapaxCopperStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 13)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 34)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
SubscribeCandles(CandleType)
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevFast = fastVal;
_prevSlow = slowVal;
_hasPrev = true;
return;
}
var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fastVal;
_prevSlow = slowVal;
}
}