La estrategia X MAN recrea la lógica central del MetaTrader asesor experto X_MAN.mq4 dentro dla API de alto nivel de StockSharp. El sistema negocia rupturas impulsadas por un promedio móvil ponderado lineal (LWMA) rápido y lento mientras filtra entradas con impulso de múltiples períodos de tiempo y una confirmación mensual MACD. Está diseñado para operaciones de continuación de tendencias que se activan sólo cuando el impulso y la estructura de la tendencia se alinean.
Lógica de trading
Filtro de tendencia principal: dos LWMA calculadas en el período de tiempo principal seleccionado deben estar separadas por al menos el DistancePoints configurable. Una configuración larga requiere que el LWMA rápido esté por encima del LWMA lento por ese margen, mientras que una configuración corta necesita que el LWMA lento domine.
Confirmación de impulso: la estrategia se suscribe a una serie de velas con períodos de tiempo más altos y la introduce en un indicador de impulso. La distancia absoluta de las últimas tres lecturas de impulso desde el valor neutral (100) debe exceder el umbral de compra o venta correspondiente al menos una vez para permitir operar en esa dirección.
MACD Filtro: una serie de velas mensuales genera un estándar (12, 26, 9) MACD. Las operaciones largas se permiten solo cuando la línea MACD está por encima de la línea de señal, y las operaciones cortas requieren la relación opuesta.
Ejecución de órdenes: cuando todos los filtros coinciden, la estrategia ingresa utilizando órdenes de mercado. Las posiciones se invierten sólo si aparece la configuración opuesta y la posición actual es plana o está en la dirección opuesta.
Parámetros
Parámetro
Descripción
CandleType
Periodo de tiempo principal utilizado para los cálculos de LWMA.
HigherCandleType
Marco de tiempo más alto que alimenta el filtro de impulso.
MacdCandleType
Plazo para la confirmación MACD (mensual por defecto).
FastMaPeriod
Longitud de la LWMA rápida.
SlowMaPeriod
Duración de la LWMA lenta.
MomentumPeriod
Ventana retrospectiva del oscilador de impulso.
MomentumBuyThreshold
Se requiere una distancia mínima desde 100 para un impulso alcista.
MomentumSellThreshold
Se requiere una distancia mínima de 100 para el impulso bajista.
DistancePoints
Separación mínima entre LWMA rápida y lenta expresada en puntos de precio.
TakeProfitPoints
Distancia protectora opcional de toma de ganancias en puntos.
StopLossPoints
Distancia de parada de pérdida de protección opcional en puntos.
Todos los parámetros se exponen a través de StrategyParam<T> para que puedan optimizarse dentro de StockSharp Designer o configurarse en tiempo de ejecución.
Gestión del riesgo
Si TakeProfitPoints o StopLossPoints es mayor que cero, la estrategia habilita el módulo de protección integrado de StockSharp utilizando salidas de mercado. Aún no se ha implementado ninguna lógica adicional de seguimiento o equilibrio del experto original MQL.
Diferencias con el experto original
La implementación de MetaTrader manejó paradas de acciones, movimientos de equilibrio y opciones complejas de administración de dinero. Esta conversión se centra en los filtros direccionales principales y las entradas al mercado; Se omite intencionalmente la gestión del dinero a nivel de cartera.
El tamaño del pedido se delega al entorno de alojamiento. La lógica original del exponente del lote no se reproduce.
No se incluyen alertas, notificaciones por correo electrónico ni modificaciones manuales del trailing-stop.
Estos cambios mantienen la estrategia concisa y aprovechan el alto nivel API de StockSharp al tiempo que preservan el concepto comercial 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()