A estratégia X MAN recria a lógica central do MetaTrader consultor especialista X_MAN.mq4 dentro do StockSharp API de alto nível. O sistema negocia rompimentos impulsionados por uma média móvel ponderada linear rápida e lenta (LWMA), enquanto filtra entradas com impulso de vários períodos de tempo e uma confirmação mensal MACD. Ele foi projetado para negociações de continuação de tendência que são acionadas somente quando o impulso e a estrutura da tendência se alinham.
Lógica de negociação
Filtro de tendência principal – Dois LWMAs calculados no período primário selecionado devem ser separados por pelo menos o DistancePoints configurável. Uma configuração longa exige que o LWMA rápido esteja acima do LWMA lento nessa margem, enquanto uma configuração curta precisa que o LWMA lento domine.
Confirmação de Momentum – A estratégia assina uma série de velas de prazo mais alto e a alimenta em um indicador de momentum. A distância absoluta das últimas três leituras de impulso do valor neutro (100) deve exceder o limite de compra ou venda correspondente pelo menos uma vez para permitir a negociação nessa direção.
MACD Filtro – Uma série de velas mensais gera um padrão (12, 26, 9) MACD. As negociações longas são permitidas apenas quando a linha MACD está acima da linha de sinal, e as negociações curtas exigem a relação oposta.
Execução de Ordens – Quando todos os filtros concordam, a estratégia entra usando ordens de mercado. As posições serão invertidas somente se a configuração oposta aparecer e a posição atual for plana ou na direção oposta.
Parâmetros
Parâmetro
Descrição
CandleType
Prazo primário usado para os cálculos LWMA.
HigherCandleType
Prazo maior alimentando o filtro de momentum.
MacdCandleType
Prazo para confirmação de MACD (mensal por padrão).
FastMaPeriod
Comprimento do LWMA rápido.
SlowMaPeriod
Comprimento do LWMA lento.
MomentumPeriod
Janela de lookback do oscilador de momento.
MomentumBuyThreshold
Distância mínima de 100 necessária para impulso de alta.
MomentumSellThreshold
Distância mínima de 100 necessária para impulso de baixa.
DistancePoints
Separação mínima entre o LWMA rápido e lento, expressa em faixas de preço.
TakeProfitPoints
Distância protetora opcional de lucro em pontos.
StopLossPoints
Distância de stop loss de proteção opcional em pontos.
Todos os parâmetros são expostos por meio do StrategyParam<T> para que possam ser otimizados no StockSharp Designer ou configurados em tempo de execução.
Gestão de risco
Se TakeProfitPoints ou StopLossPoints for maior que zero, a estratégia ativa o módulo de proteção integrado de StockSharp usando saídas de mercado. Nenhuma lógica adicional de rastreamento ou ponto de equilíbrio do especialista original MQL foi implementada ainda.
Diferenças do especialista original
A implementação do MetaTrader lidou com paradas de capital, movimentos de equilíbrio e opções complexas de gerenciamento de dinheiro. Esta conversão concentra-se nos principais filtros direcionais e entradas de mercado; a gestão de dinheiro em nível de carteira é intencionalmente omitida.
O dimensionamento do pedido é delegado ao ambiente de hospedagem. A lógica original do lote-expoente não é reproduzida.
Alertas, notificações por e-mail e modificações manuais de trailing stop não estão incluídos.
Essas mudanças mantêm a estratégia concisa e aproveitam o API de alto nível de API, preservando o conceito de negociação principal.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// X-MAN strategy: Stochastic + SMA trend filter.
/// </summary>
public class XManStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smaPeriod;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
public XManStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_smaPeriod = Param(nameof(SmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("SMA Period", "SMA period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = SmaPeriod };
var rsi = new RelativeStrengthIndex { Length = 14 };
decimal? prevClose = null;
decimal? prevSma = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, rsi, (candle, smaVal, rsiVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
if (prevClose.HasValue && prevSma.HasValue)
{
var crossUp = prevClose.Value <= prevSma.Value && close > smaVal;
var crossDown = prevClose.Value >= prevSma.Value && close < smaVal;
if (crossUp && rsiVal < 70 && Position <= 0)
BuyMarket();
else if (crossDown && rsiVal > 30 && Position >= 0)
SellMarket();
}
prevClose = close;
prevSma = smaVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
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 SimpleMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class x_man_strategy(Strategy):
def __init__(self):
super(x_man_strategy, self).__init__()
self._sma_period = self.Param("SmaPeriod", 20) \
.SetDisplay("SMA Period", "SMA period", "Indicators")
self._sma = None
self._rsi = None
self._prev_close = None
self._prev_sma = None
@property
def sma_period(self):
return self._sma_period.Value
def OnReseted(self):
super(x_man_strategy, self).OnReseted()
self._sma = None
self._rsi = None
self._prev_close = None
self._prev_sma = None
def OnStarted2(self, time):
super(x_man_strategy, self).OnStarted2(time)
self._sma = SimpleMovingAverage()
self._sma.Length = self.sma_period
self._rsi = RelativeStrengthIndex()
self._rsi.Length = 14
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._sma, self._rsi, self._process_candle)
subscription.Start()
def _process_candle(self, candle, sma_value, rsi_value):
if candle.State != CandleStates.Finished:
return
if not self._sma.IsFormed or not self._rsi.IsFormed:
return
close = float(candle.ClosePrice)
sma_val = float(sma_value)
rsi_val = float(rsi_value)
if self._prev_close is not None and self._prev_sma is not None:
cross_up = self._prev_close <= self._prev_sma and close > sma_val
cross_down = self._prev_close >= self._prev_sma and close < sma_val
if cross_up and rsi_val < 70.0 and self.Position <= 0:
self.BuyMarket()
elif cross_down and rsi_val > 30.0 and self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_sma = sma_val
def CreateClone(self):
return x_man_strategy()