Esta estratégia é uma conversão direta para StockSharp do consultor especialista MACD "Sensitive" para MetaTrader 5. Combina cruzamentos do MACD com ferramentas de gestão de risco configuráveis (stop loss fixo, take profit e trailing stops baseados em pips). O algoritmo funciona exclusivamente em velas concluídas e usa a API de alto nível para assinar o período desejado.
Indicadores e Dados
MACD (Moving Average Convergence Divergence) – configurado com comprimentos de EMA rápida, lenta e de sinal independentes.
Velas – período selecionável pelo usuário fornecido através do parâmetro CandleType.
Condições de Entrada
Uma nova vela deve fechar para evitar ruído intrabarra.
Os valores do MACD são processados a partir da vinculação do indicador:
macd representa a linha principal do MACD.
signal é a linha de sinal (EMA da diferença do MACD).
Requisitos de entrada comprada:
O MACD cruza acima da linha de sinal (macd > signal enquanto os valores anteriores satisfaziam macd < signal).
O MACD permanece em território negativo (macd < 0).
A magnitude absoluta do MACD é maior que MacdOpenLevel * Point, garantindo um deslocamento significativo.
Não há posição comprada ativa (posição líquida é menor ou igual a zero). Os vendidos existentes são revertidos enviando a quantidade necessária.
Os requisitos de entrada vendida espelham a configuração comprada:
O MACD cruza abaixo da linha de sinal permanecendo positivo.
A magnitude absoluta do MACD excede o limiar configurado.
Não existe posição vendida aberta (posição líquida é maior ou igual a zero). Os comprados existentes são nivelados antes de abrir o vendido.
Gestão de Saída
Take Profit: Uma vez aberta a operação, a estratégia armazena um nível alvo definido por TakeProfitPips. Se a máxima de uma vela comprada ou a mínima de uma vela vendida atingir este nível, a posição é fechada a mercado.
Stop Loss: Um stop de proteção é calculado a partir de StopLossPips. Para comprados, uma queda do preço ao nível de stop aciona uma saída a mercado. Os vendidos reagem a subidas do preço que atingem o stop.
Trailing Stop: Quando TrailingStopPips é diferente de zero, o algoritmo ativa uma lógica de trailing depois que o preço avança pelo menos TrailingStopPips + TrailingStepPips pips a partir da entrada. Os movimentos subsequentes ajustam o nível de stop mantendo sempre a distância de trailing especificada a partir do último fechamento. O passo de trailing deve ser positivo sempre que o trailing stop estiver habilitado; caso contrário, a estratégia para com uma mensagem de erro.
Quando não há posição ativa, as variáveis de rastreamento internas são redefinidas para se preparar para a próxima operação.
Dimensionamento de Posição
As quantidades das ordens são controladas pelo parâmetro de estratégia integrado Volume (padrão: 0.1). As reversões adicionam automaticamente o valor absoluto da posição atual ao volume desejado para mudar de direção em uma única ordem de mercado.
Parâmetros
Parâmetro
Descrição
Padrão
FastLength
Período da EMA rápida utilizado pela linha principal do MACD.
12
SlowLength
Período da EMA lenta utilizado pela linha principal do MACD.
26
SignalLength
Período da EMA de sinal para o MACD.
9
MacdOpenLevel
Magnitude mínima do MACD (em pontos de preço) necessária para acionar operações.
3
StopLossPips
Distância do stop de proteção em pips.
35
TakeProfitPips
Distância de take-profit em pips.
75
TrailingStopPips
Distância de trailing stop em pips (0 desabilita o trailing).
5
TrailingStepPips
Distância adicional que o preço deve percorrer antes de o trailing stop ser atualizado.
5
CandleType
Tipo de vela fonte (período).
Velas de 1 minuto
Volume
Volume da ordem, expresso em lotes/contratos dependendo do instrumento.
0.1
Notas Adicionais
Os valores de pips e pontos do MACD são derivados do passo de preço do instrumento e sua precisão decimal. O código ajusta os símbolos forex de 3 e 5 dígitos escalando o tamanho do pip de acordo.
Todos os comentários dentro do código fonte estão escritos em inglês, e a implementação usa apenas as APIs de alto nível do StockSharp de acordo com as diretrizes do projeto.
A estratégia evita intencionalmente o gerenciamento de preenchimentos parciais e assume que as ordens de mercado são preenchidas imediatamente ao executar no simulador ou no trading real. Salvaguardas adicionais podem ser adicionadas se necessário.
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>
/// Sensitive MACD Trailing strategy. Uses EMA crossover (5/15).
/// </summary>
public class SensitiveMacdTrailingStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast;
private decimal? _prevSlow;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public SensitiveMacdTrailingStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 5).SetGreaterThanZero().SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 15).SetGreaterThanZero().SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevSlow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null; _prevSlow = null;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
var prevAbove = _prevFast.Value > _prevSlow.Value;
var currAbove = fast > slow;
_prevFast = fast; _prevSlow = slow;
if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class sensitive_macd_trailing_strategy(Strategy):
def __init__(self):
super(sensitive_macd_trailing_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 5) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 15) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(sensitive_macd_trailing_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(sensitive_macd_trailing_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_slow = None
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fv
self._prev_slow = sv
return
prev_above = self._prev_fast > self._prev_slow
curr_above = fv > sv
self._prev_fast = fv
self._prev_slow = sv
if not prev_above and curr_above and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif prev_above and not curr_above and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return sensitive_macd_trailing_strategy()