A Estratégia Test MACD é uma conversão fiel do expert advisor TestMACD do MetaTrader para a API de alto nível do StockSharp. Ela usa o indicador Moving Average Convergence Divergence (MACD) para detectar mudanças de momentum e executa operações sempre que a linha MACD cruza a linha de sinal em candles fechados. A estratégia opera em um único instrumento e timeframe fornecido pelo parâmetro CandleType.
Lógica de negociação
Assinar dados de candles definidos por CandleType e calcular um indicador MACD com períodos rápido, lento e de sinal configuráveis.
Monitorar a diferença de valor MACD (MACD - Signal) em cada candle concluído.
Disparar uma entrada altista quando a diferença muda de sinal de não positiva para positiva, indicando que a linha MACD cruzou acima da linha de sinal. Qualquer exposição vendida é fechada antes de abrir a posição comprada.
Disparar uma entrada baixista quando a diferença muda de sinal de não negativa para negativa, indicando que a linha MACD cruzou abaixo da linha de sinal. Qualquer exposição comprada é fechada antes de abrir a posição vendida.
Todas as ordens são emitidas a mercado com volume fixo configurado por TradeVolume.
Cada entrada é automaticamente protegida com níveis de stop-loss e take-profit expressos em passos de preço para replicar a gestão de risco baseada em pontos do expert original.
Gestão de risco
Distâncias de stop-loss e take-profit espelham as entradas do MetaTrader e são fornecidas em passos de preço. Se o ativo não tiver informação PriceStep, a estratégia usa distâncias absolutas de preço com MinPriceStep ou 1 como multiplicador.
Ordens protetoras são criadas uma vez, quando a estratégia inicia, via StartProtection, garantindo que se apliquem a cada operação posterior sem reconfiguração.
Parâmetros
Parâmetro
Descrição
Padrão
FastPeriod
Comprimento da EMA rápida usada nos cálculos MACD.
12
SlowPeriod
Comprimento da EMA lenta usada nos cálculos MACD.
24
SignalPeriod
Comprimento da EMA de sinal para suavização MACD.
9
StopLossPoints
Distância do stop-loss expressa em passos de preço.
90
TakeProfitPoints
Distância do take-profit expressa em passos de preço.
110
TradeVolume
Volume fixo para todas as ordens a mercado.
1
CandleType
Tipo de dados de candles e timeframe assinados pela estratégia.
Timeframe de 30 minutos
Notas de uso
Anexe a estratégia a um ativo antes de iniciá-la para que PriceStep e MinPriceStep estejam disponíveis.
Garanta que dados de mercado sejam fornecidos para o CandleType selecionado; caso contrário o indicador MACD não se formará e não haverá negociação.
A estratégia registra cada evento de cruzamento, facilitando rastrear decisões de negociação durante backtests.
Detalhes de conversão
As classes originais do MetaTrader CSignalMACD, CTrailingNone e CMoneyFixedLot são substituídas por binding de indicadores StockSharp e mecanismos StartProtection.
A lógica de ExtStateMACD, que verificava cruzamentos MACD, é representada por um detector de mudança de sinal na diferença MACD entre candles concluídos consecutivos.
A gestão monetária é simplificada para um parâmetro de volume fixo, muito semelhante ao comportamento de lote fixo de CMoneyFixedLot quando o sizing percentual está desativado.
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()