Estratégia Xit de Cruzamento de Três MA
Esta estratégia é uma recriação em StockSharp do assessor especializado MetaTrader 5 XIT_THREE_MA_CROSS.mq5. Ela alinha três médias móveis, verifica a separação de momentum do MACD e dimensiona posições a partir de limites de risco baseados em ATR. O método é seguidor de tendência com confirmação de momentum e visa oscilações de médio prazo em pares de moedas líquidos ou índices.
Visão geral
- Regime de mercado: Funciona melhor em instrumentos que têm tendência por múltiplas velas no período selecionado.
- Indicadores:
- Médias móviles lenta, intermediária e rápida (tipo selecionável pelo usuário) avaliadas no período de trading.
- MACD (baseado em EMA) para direção de momentum e distância entre a linha MACD e a sinal.
- Dois cálculos de ATR (mesma comprimento, períodos independentes) usados para projetar distâncias de stop-loss e take-profit.
- Direção da ordem: Bidirecional. O motor pode abrir tanto operações compradas quanto vendidas.
- Dimensionamento de posição: Calculado a partir do percentual de risco configurado e a distância de stop baseada em ATR. Quando os metadados do instrumento estão incompletos, a estratégia recorre à propriedade
Volume padrão.
Lógica de trading
Entrada comprada
Uma posição comprada é aberta quando todas as condições abaixo são verdadeiras em uma vela terminada:
- A linha MACD aumenta em comparação com a barra anterior (
MACD[t] > MACD[t-1]).
- A linha de sinal MACD aumenta em comparação com a barra anterior.
- A linha MACD excede a linha de sinal em pelo menos
MacdTriggerPoints * PriceStep.
- A média móvel intermediária sobe vs o valor anterior.
- A média móvel rápida sobe vs o valor anterior.
- A MA intermediária está acima da MA lenta.
- A MA rápida está acima da MA intermediária.
- Ambos os valores de ATR estão disponíveis para definir distâncias de stop e alvo.
Entrada vendida
As regras do lado vendido espelham a configuração comprada com comparações invertidas:
- A linha MACD diminui em comparação com a barra anterior.
- A linha de sinal MACD diminui em comparação com a barra anterior.
- A linha de sinal é maior que a linha MACD em pelo menos
MacdTriggerPoints * PriceStep.
- A MA intermediária cai em comparação com a vela anterior.
- A MA rápida cai em comparação com a vela anterior.
- A MA intermediária está abaixo da MA lenta.
- A MA rápida está abaixo da MA intermediária.
- Ambas as séries ATR entregaram um valor terminado.
Lógica de saída
- Posições compradas fecham quando a MA rápida cai abaixo da MA intermediária, ou o preço atinge os níveis de stop/take-profit baseados em ATR.
- Posições vendidas fecham quando a MA rápida cruza acima da MA intermediária, ou os limites ATR são tocados.
- Após fechar uma posição, o algoritmo aguarda a próxima vela antes de avaliar novas entradas, seguindo o comportamento do EA original.
Gestão de risco
- Stop Loss: A distância é igual ao último valor ATR de
AtrStopCandleType. Para comprados, o preço de stop é Entry - ATR, para vendidos é Entry + ATR.
- Take Profit: A distância é igual ao valor ATR de
AtrTakeCandleType. Os alvos são espelhados em relação ao preço de entrada.
- Percentual de risco: A estratégia estima a perda monetária por unidade a partir da distância de stop. Se
PriceStep e PriceStepCost são conhecidos, o risco por contrato usa avaliação de tick. Caso contrário, a distância de preço bruta é usada. Tamanho da posição é RiskPercent% do valor atual do portfólio dividido pelo risco por unidade, arredondado para baixo ao VolumeStep mais próximo.
Parâmetros
| Nome |
Descrição |
Padrão |
CandleType |
Período principal para cálculos de médias móveis e MACD. |
Velas de 1 hora |
SlowMaLength / IntermediateMaLength / FastMaLength |
Períodos das médias móveis. |
60 / 14 / 4 |
SlowMaType, IntermediateMaType, FastMaType |
Famílias de médias móveis (Simples, Exponencial, Suavizado, Ponderado). |
Simples |
MacdFastLength, MacdSlowLength, MacdSignalLength |
Comprimentos de EMA rápida, lenta e sinal MACD. |
12 / 26 / 9 |
MacdTriggerPoints |
Distância mínima entre MACD e seu sinal, medida em pontos do instrumento. Convertida usando PriceStep. |
7 |
AtrLength |
Período para ambos os indicadores ATR. |
14 |
AtrTakeCandleType / AtrStopCandleType |
Períodos para séries ATR de take-profit e stop-loss. |
Velas de 4 horas |
RiskPercent |
Percentual do valor atual do portfólio arriscado em cada operação. |
10% |
Notas de uso
- Anexe a estratégia a um valor com
PriceStep, PriceStepCost e VolumeStep precisos para obter dimensionamento de posição preciso.
- Certifique-se de que os dados históricos estejam disponíveis para cada período subscrito (
CandleType, AtrTakeCandleType, AtrStopCandleType). Valores ATR ausentes adiarão entradas.
- O algoritmo opera em velas completamente fechadas e ignora flutuações intrabar, refletindo a lógica MetaTrader original de buscar buffers de indicadores atuais e anteriores.
- Modifique os tipos de média móvel se o mercado alvo favorecer filtros mais suaves ou mais rápidos.
Arquivos
CS/XitThreeMaCrossStrategy.cs – Implementação C# com API de alto nível StockSharp, incluindo subscrições ATR e dimensionamento de risco.
README_ru.md – Descrição em russo da estratégia.
README_zh.md – Tradução para o chinês da documentação.
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>
/// Triple MA alignment strategy.
/// </summary>
public class XitThreeMaCrossStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _midPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast;
private decimal? _prevMid;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int MidPeriod
{
get => _midPeriod.Value;
set => _midPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public XitThreeMaCrossStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast MA period", "Indicators");
_midPeriod = Param(nameof(MidPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Mid Period", "Medium MA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow MA (trend filter)", "Indicators");
Volume = 0.1m;
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevMid = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null;
_prevMid = null;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var mid = new SimpleMovingAverage { Length = MidPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, mid, slow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, mid);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal midVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevFast == null || _prevMid == null)
{
_prevFast = fastVal;
_prevMid = midVal;
return;
}
var buySignal = fastVal > midVal && midVal > slowVal;
var sellSignal = fastVal < midVal && midVal < slowVal;
if (buySignal && Position <= 0)
{
if (Position < 0)
BuyMarket(Math.Abs(Position));
BuyMarket(Volume);
}
else if (sellSignal && Position >= 0)
{
if (Position > 0)
SellMarket(Position);
SellMarket(Volume);
}
_prevFast = fastVal;
_prevMid = midVal;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class xit_three_ma_cross_strategy(Strategy):
def __init__(self):
super(xit_three_ma_cross_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 Period", "Fast MA period", "Indicators")
self._mid_period = self.Param("MidPeriod", 20) \
.SetDisplay("Mid Period", "Medium MA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetDisplay("Slow Period", "Slow MA (trend filter)", "Indicators")
self._prev_fast = None
self._prev_mid = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def MidPeriod(self):
return self._mid_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(xit_three_ma_cross_strategy, self).OnReseted()
self._prev_fast = None
self._prev_mid = None
def OnStarted2(self, time):
super(xit_three_ma_cross_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_mid = None
fast = SimpleMovingAverage()
fast.Length = self.FastPeriod
mid = SimpleMovingAverage()
mid.Length = self.MidPeriod
slow = SimpleMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, mid, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, mid)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, mid_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
mv = float(mid_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_mid is None:
self._prev_fast = fv
self._prev_mid = mv
return
buy_signal = fv > mv and mv > sv
sell_signal = fv < mv and mv < sv
if buy_signal and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif sell_signal and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fv
self._prev_mid = mv
def CreateClone(self):
return xit_three_ma_cross_strategy()