Данная стратегия торгует базовым инструментом и хеджирует позицию коррелированным активом. Направление тренда определяется простой скользящей средней (SMA). Когда корреляция между базовым и хеджирующим инструментами достигает заданного порога, открываются позиции по обоим инструментам для формирования нейтрального портфеля.
Принцип работы
Вычисляется тренд базового инструмента с помощью SMA заданной длины.
Корреляция между инструментами измеряется через разницу между ценой и собственной SMA.
Если корреляция достигает ожидаемого уровня, открываются сделки по обоим инструментам. Направление хеджа может совпадать или противоположно базовому в зависимости от настроек.
Позиции автоматически закрываются при достижении общей прибыли.
Параметры
SmaPeriod — период SMA для определения тренда, по умолчанию 20.
CorrelationPeriod — количество значений для расчёта корреляции, по умолчанию 20.
ExpectedCorrelation — минимальная абсолютная корреляция для активации хеджа, по умолчанию 0.8.
ProfitTarget — целевая прибыль в денежных единицах, по умолчанию 30.
CandleType — тип свечей для анализа, по умолчанию тайм‑фрейм 1 минута.
FollowBase — если истина и корреляция положительная, хедж следует направлению базового инструмента.
Индикаторы
SMA
Корреляция (пользовательский расчёт)
Примечания
Это упрощённый порт оригинальной MQL‑стратегии. Перед использованием на реальном рынке настройте параметры управления рисками и капиталом.
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>
/// SMA trend direction strategy.
/// </summary>
public class SmaMultiHedge2Strategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevEma1;
private decimal _prevEma2;
private int _count;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SmaMultiHedge2Strategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend period", "Parameters");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "Parameters");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevEma1 = 0;
_prevEma2 = 0;
_count = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
SubscribeCandles(CandleType)
.Bind(ema, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal)
{
if (candle.State != CandleStates.Finished) return;
_count++;
if (_count < 3)
{
_prevEma2 = _prevEma1;
_prevEma1 = emaVal;
return;
}
var trend = 0;
if (_prevEma2 < _prevEma1 && _prevEma1 < emaVal)
trend = 1;
else if (_prevEma2 > _prevEma1 && _prevEma1 > emaVal)
trend = -1;
_prevEma2 = _prevEma1;
_prevEma1 = emaVal;
if (trend == 1 && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (trend == -1 && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
}
}