A 5/8 EMA estratégia de proteção cruzada replica o MetaTrader consultor especialista 5_8macrossv2.mq4 comparando duas médias móveis configuráveis no mesmo símbolo. Um cruzamento de alta da média móvel rápida acima da lenta abre posições longas, enquanto um cruzamento de baixa abre posições curtas. A versão portada segue StockSharp padrões de alto nível e adiciona gerenciamento opcional de take-profit, stop-loss e trailing-stop.
Lógica de negociação
Duas médias móveis são calculadas na assinatura da vela selecionada. Por padrão, uma MM exponencial de 5 períodos sobre preços de fechamento é comparada a uma MM exponencial de 8 períodos sobre preços de abertura.
Quando a MM rápida cruza acima da MM lenta na última vela finalizada, a estratégia abre ou reverte para uma posição longa. Se uma posição curta estiver ativa, seu volume será incluído na nova ordem de compra de mercado para mudar de direção.
Quando a MM rápida cruza abaixo da MM lenta, a estratégia abre ou reverte para uma posição curta usando a mesma lógica de normalização de volume.
Os parâmetros de deslocamento MA emulam o deslocamento horizontal original. Valores positivos atrasam o sinal por esse número de velas fechadas; valores negativos são arredondados para zero porque os valores deslocados para frente não estão disponíveis em dados em tempo real.
Gestão de risco
As distâncias de Take-profit e stop-loss são expressas em pips (etapas de preço). Quando uma posição longa é aberta, os níveis de proteção são colocados acima e abaixo do preço de entrada, respectivamente; os espelhos lógicos para shorts.
Trailing stop (também em pips) estreita constantemente o nível de proteção à medida que o preço se move a favor da posição. Para posições compradas, o trailing stop apenas se move para cima; para shorts, ele apenas se move para baixo.
Se qualquer condição de proteção for atendida em uma vela finalizada (take-profit de altos acertos, stop-loss de acertos baixos ou nível de trailing), a estratégia sai da posição com uma ordem de mercado e redefine seu estado interno.
Parâmetros
Nome
Tipo
Padrão
Descrição
TradeVolume
decimal
0.1
Volume de pedidos para novas entradas. A estratégia adiciona o tamanho absoluto da posição ao reverter.
TakeProfitPips
decimal
40
Distância da entrada em pips para fechamento da posição com lucro. Defina como 0 para desativar.
StopLossPips
decimal
0
Distância da entrada em pips para stop loss de proteção. Defina como 0 para desativar.
TrailingStopPips
decimal
0
Distância do trailing-stop em pips. Defina como 0 para desativar.
FastPeriod
int
5
Período da média móvel rápida.
FastShift
int
-1
Mudança horizontal para o MA rápido. Valores negativos são tratados como zero nesta porta.
FastMethod
MovingAverageMethod
Exponential
Algoritmo de suavização para MA rápido (Simple, Exponencial, Smoothed, LinearWeighted).
FastPrice
AppliedPrice
Close
Preço da vela usado para o MA rápido.
SlowPeriod
int
8
Período da média móvel lenta.
SlowShift
int
0
Deslocamento horizontal para o MA lento.
SlowMethod
MovingAverageMethod
Exponential
Algoritmo de suavização para MA lento.
SlowPrice
AppliedPrice
Open
Preço da vela usado para o MA lento.
CandleType
DataType
TimeSpan.FromMinutes(30).TimeFrame()
Série de velas usadas para cálculos.
Notas
A conversão mantém a lógica focada nas velas finalizadas para evitar sinais prematuros.
Trailing stops e metas de lucro são calculadas com Security.PriceStep; se um símbolo não o definir, os parâmetros de risco permanecem inativos.
A versão Python é omitida intencionalmente de acordo com os requisitos da tarefa.
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>
/// 5/8 MA Cross Protect strategy - EMA(5) and EMA(8) crossover.
/// Buys when EMA(5) crosses above EMA(8).
/// Sells when EMA(5) crosses below EMA(8).
/// </summary>
public class FiveEightMaCrossProtectStrategy : 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 FiveEightMaCrossProtectStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 8)
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevFast = 0m; _prevSlow = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevSlow = slow;
_hasPrev = true;
return;
}
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
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 five_eight_ma_cross_protect_strategy(Strategy):
def __init__(self):
super(five_eight_ma_cross_protect_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 5).SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 8).SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
@property
def fast_period(self): return self._fast_period.Value
@property
def slow_period(self): return self._slow_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(five_eight_ma_cross_protect_strategy, self).OnReseted()
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
def OnStarted2(self, time):
super(five_eight_ma_cross_protect_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self.fast_period
slow = ExponentialMovingAverage()
slow.Length = self.slow_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self.process_candle).Start()
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished: return
f = float(fast); s = float(slow)
if not self._has_prev:
self._prev_fast = f; self._prev_slow = s; self._has_prev = True; return
if self._prev_fast <= self._prev_slow and f > s and self.Position <= 0:
if self.Position < 0: self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and f < s and self.Position >= 0:
if self.Position > 0: self.SellMarket()
self.SellMarket()
self._prev_fast = f; self._prev_slow = s
def CreateClone(self): return five_eight_ma_cross_protect_strategy()