Test MACD — это точная конвертация советника MetaTrader TestMACD на платформу StockSharp с использованием высокоуровневого API. Стратегия применяет индикатор MACD для отслеживания смены импульса и совершает сделки, когда основная линия MACD пересекает сигнальную на закрытии свечи. Инструмент и таймфрейм задаются параметром CandleType.
Логика торговли
Подписаться на свечные данные типа CandleType и рассчитать индикатор MACD с настраиваемыми периодами быстрой, медленной и сигнальной EMA.
На каждой завершённой свече анализировать разницу между значениями MACD и сигнальной линии.
При переходе разницы из неположительной области в положительную открыть длинную позицию: это означает, что MACD пересёк сигнальную линию снизу вверх. Перед открытием лонга ликвидируются активные короткие позиции.
При переходе разницы из неотрицательной области в отрицательную открыть короткую позицию: MACD пересёк сигнальную линию сверху вниз. Перед открытием шорта закрываются все лонги.
Заявки отправляются по рынку фиксированным объёмом, который задаётся параметром TradeVolume.
Для каждой сделки автоматически выставляются стоп-лосс и тейк-профит в шагах цены, что воспроизводит точечную систему управления риском исходного советника.
Управление рисками
Дистанции стоп-лосса и тейк-профита задаются в шагах цены. Если у инструмента нет данных PriceStep, стратегия использует MinPriceStep или единицу в качестве множителя и работает с абсолютными значениями.
Защита активируется один раз при запуске стратегии через StartProtection, поэтому все последующие сделки автоматически используют те же настройки.
Параметры
Параметр
Описание
Значение по умолчанию
FastPeriod
Период быстрой EMA в MACD.
12
SlowPeriod
Период медленной EMA в MACD.
24
SignalPeriod
Период сигнальной EMA в MACD.
9
StopLossPoints
Расстояние стоп-лосса в шагах цены.
90
TakeProfitPoints
Расстояние тейк-профита в шагах цены.
110
TradeVolume
Фиксированный объём заявок.
1
CandleType
Тип и таймфрейм свечей для расчётов.
30-минутный таймфрейм
Рекомендации по использованию
Перед запуском привяжите стратегию к конкретному инструменту, чтобы были доступны PriceStep и MinPriceStep.
Убедитесь в наличии данных по выбранному CandleType; без них индикатор MACD не сформируется и торговля не начнётся.
В журнале фиксируются все события пересечения, что помогает анализировать решения стратегии при тестировании.
Особенности конвертации
Классы MetaTrader CSignalMACD, CTrailingNone и CMoneyFixedLot заменены механизмами подписки на индикаторы StockSharp и защитой через StartProtection.
Функция ExtStateMACD, определявшая момент пересечения линий MACD, преобразована в проверку смены знака разницы между значениями на соседних закрытых свечах.
Управление капиталом сведено к фиксированному объёму, что наиболее близко к поведению CMoneyFixedLot без процентной надстройки.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Test MACD strategy: MACD histogram zero-cross.
/// Buys when MACD histogram crosses above zero.
/// Sells when MACD histogram crosses below zero.
/// </summary>
public class TestMacdStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public TestMacdStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var macd = new MovingAverageConvergenceDivergenceSignal
{
Macd = { ShortMa = { Length = 12 }, LongMa = { Length = 26 } },
SignalMa = { Length = 9 }
};
decimal? prevHistogram = null;
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(macd, (candle, macdVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (macdVal.IsEmpty)
return;
var v = (MovingAverageConvergenceDivergenceSignalValue)macdVal;
if (v.Macd is not decimal macdDec || v.Signal is not decimal signalDec)
return;
var histogram = macdDec - signalDec;
if (prevHistogram.HasValue)
{
if (prevHistogram.Value <= 0m && histogram > 0m && Position <= 0)
BuyMarket();
else if (prevHistogram.Value >= 0m && histogram < 0m && Position >= 0)
SellMarket();
}
prevHistogram = histogram;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, macd);
DrawOwnTrades(area);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import MovingAverageConvergenceDivergenceSignal
from StockSharp.Algo.Strategies import Strategy
class test_macd_strategy(Strategy):
def __init__(self):
super(test_macd_strategy, self).__init__()
self._prev_histogram = None
self._macd = None
def OnReseted(self):
super(test_macd_strategy, self).OnReseted()
self._prev_histogram = None
self._macd = None
def OnStarted2(self, time):
super(test_macd_strategy, self).OnStarted2(time)
self._macd = MovingAverageConvergenceDivergenceSignal()
self._macd.Macd.ShortMa.Length = 12
self._macd.Macd.LongMa.Length = 26
self._macd.SignalMa.Length = 9
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.BindEx(self._macd, self._process_candle)
subscription.Start()
def _process_candle(self, candle, macd_val):
if candle.State != CandleStates.Finished:
return
if not self._macd.IsFormed:
return
macd_v = float(macd_val.Macd)
signal_v = float(macd_val.Signal)
histogram = macd_v - signal_v
if self._prev_histogram is not None:
if self._prev_histogram <= 0.0 and histogram > 0.0 and self.Position <= 0:
self.BuyMarket()
elif self._prev_histogram >= 0.0 and histogram < 0.0 and self.Position >= 0:
self.SellMarket()
self._prev_histogram = histogram
def CreateClone(self):
return test_macd_strategy()