La Estrategia de IMF experta en ALD replica el MetaTrader 5 asesores expertos "Expert_AML_MFI" utilizando la API de alto nivel de StockSharp. Se centra en el patrón de velas Meeting Lines y valida cada señal con el oscilador Money Flow Index (MFI). La estrategia mantiene automáticamente las estadísticas de velas necesarias, identifica reversiones alcistas o bajistas y gestiona las posiciones abiertas cada vez que la IMF cruza los umbrales de sobreventa o sobrecompra.
Lógica de trading
Preparación de velas: la estrategia se suscribe al período de tiempo seleccionado (H1 por defecto) y mantiene las dos últimas velas completadas junto con el promedio móvil de los cuerpos de las velas. El tamaño medio del cuerpo se calcula mediante un SimpleMovingAverage aplicado al tamaño absoluto del cuerpo de la vela, reflejando la implementación de MT5.
Detección de patrones: dos ayudantes especializados reconocen Líneas de encuentro alcistas y Líneas de encuentro bajistas:
Configuración alcista: una vela bajista larga seguida de una vela alcista larga que cierra cerca del cierre anterior (dentro del 10% del cuerpo promedio).
Configuración bajista: una vela alcista larga seguida de una vela bajista larga con precios de cierre similares.
Confirmación de MFI: el valor de MFI anterior debe estar por debajo del nivel de entrada alcista (predeterminado 40) para operaciones largas o por encima del nivel de entrada bajista (predeterminado 60) para operaciones cortas.
Gestión de posición – se realiza un seguimiento de las dos últimas lecturas del MFI para detectar cruces de los niveles de sobreventa (30) y sobrecompra (70):
Un cruce por encima de cualquiera de los niveles sale de las posiciones cortas.
Un cruce por debajo del nivel de sobreventa o por encima del nivel de sobrecompra sale de las posiciones largas.
Ejecución de la orden: cuando se produce un patrón válido y una confirmación de la MFI, la estrategia cierra cualquier exposición opuesta y abre una nueva posición en el mercado con el volumen base configurado.
Parámetros
Nombre
Descripción
Predeterminado
CandleType
Plazo utilizado para la suscripción de velas.
plazo de 1 hora
MfiPeriod
Número de barras del oscilador MFI.
12
BodyAveragePeriod
Longitud de la ventana para el cálculo del tamaño corporal promedio.
4
BullishEntryLevel
Valor máximo de MFI permitido para entradas alcistas.
40
BearishEntryLevel
Valor mínimo de MFI requerido para entradas bajistas.
60
OversoldLevel
Nivel de sobreventa utilizado para señales de salida.
30
OverboughtLevel
Nivel de sobrecompra utilizado para señales de salida.
70
TradeVolume
Volumen de orden base aplicado a nuevas operaciones.
1
Todos los parámetros se pueden optimizar directamente dentro de StockSharp Designer gracias a los contenedores StrategyParam.
Indicadores y visuales
Índice de flujo de dinero: vinculado a la suscripción de vela para su confirmación y mostrado en el gráfico cuando un área del gráfico está disponible.
Promedio móvil simple de cuerpos de velas: solo para uso interno, que reproduce el cálculo del cuerpo promedio MT5.
Notas
La estrategia llama a StartProtection() una vez para habilitar las funciones de protección de posición integradas.
Los comandos comerciales utilizan los ayudantes BuyMarket y SellMarket para aplanar la posición actual antes de abrir una nueva, coincidiendo con el comportamiento del asesor experto MetaTrader.
No se proporciona ningún puerto Python de acuerdo con los requisitos del proyecto.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Meeting Lines + MFI strategy.
/// Buys on bullish meeting lines with low MFI, sells on bearish meeting lines with high MFI.
/// </summary>
public class ExpertAmlMfiStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _mfiPeriod;
private readonly StrategyParam<decimal> _mfiLow;
private readonly StrategyParam<decimal> _mfiHigh;
private ICandleMessage _prevCandle;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int MfiPeriod { get => _mfiPeriod.Value; set => _mfiPeriod.Value = value; }
public decimal MfiLow { get => _mfiLow.Value; set => _mfiLow.Value = value; }
public decimal MfiHigh { get => _mfiHigh.Value; set => _mfiHigh.Value = value; }
public ExpertAmlMfiStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_mfiPeriod = Param(nameof(MfiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("MFI Period", "MFI period", "Indicators");
_mfiLow = Param(nameof(MfiLow), 40m)
.SetDisplay("MFI Low", "MFI level for bullish entry", "Signals");
_mfiHigh = Param(nameof(MfiHigh), 60m)
.SetDisplay("MFI High", "MFI level for bearish entry", "Signals");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCandle = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCandle = null;
var mfi = new MoneyFlowIndex { Length = MfiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(mfi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal mfiValue)
{
if (candle.State != CandleStates.Finished) return;
if (_prevCandle != null)
{
var avgBody = (Math.Abs(candle.ClosePrice - candle.OpenPrice) +
Math.Abs(_prevCandle.ClosePrice - _prevCandle.OpenPrice)) / 2m;
if (avgBody > 0)
{
var prevBearish = _prevCandle.OpenPrice > _prevCandle.ClosePrice;
var currBullish = candle.ClosePrice > candle.OpenPrice;
var closesNear = Math.Abs(candle.ClosePrice - _prevCandle.ClosePrice) < avgBody * 0.3m;
if (prevBearish && currBullish && closesNear && mfiValue < MfiLow && Position <= 0)
BuyMarket();
var prevBullish = _prevCandle.ClosePrice > _prevCandle.OpenPrice;
var currBearish = candle.OpenPrice > candle.ClosePrice;
var closesNear2 = Math.Abs(candle.ClosePrice - _prevCandle.ClosePrice) < avgBody * 0.3m;
if (prevBullish && currBearish && closesNear2 && mfiValue > MfiHigh && Position >= 0)
SellMarket();
}
}
_prevCandle = candle;
}
}
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 MoneyFlowIndex
from StockSharp.Algo.Strategies import Strategy
class expert_aml_mfi_strategy(Strategy):
def __init__(self):
super(expert_aml_mfi_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._mfi_period = self.Param("MfiPeriod", 14)
self._mfi_low = self.Param("MfiLow", 40.0)
self._mfi_high = self.Param("MfiHigh", 60.0)
self._prev_candle = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def MfiPeriod(self):
return self._mfi_period.Value
@MfiPeriod.setter
def MfiPeriod(self, value):
self._mfi_period.Value = value
@property
def MfiLow(self):
return self._mfi_low.Value
@MfiLow.setter
def MfiLow(self, value):
self._mfi_low.Value = value
@property
def MfiHigh(self):
return self._mfi_high.Value
@MfiHigh.setter
def MfiHigh(self, value):
self._mfi_high.Value = value
def OnReseted(self):
super(expert_aml_mfi_strategy, self).OnReseted()
self._prev_candle = None
def OnStarted2(self, time):
super(expert_aml_mfi_strategy, self).OnStarted2(time)
self._prev_candle = None
mfi = MoneyFlowIndex()
mfi.Length = self.MfiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(mfi, self._process_candle).Start()
def _process_candle(self, candle, mfi_value):
if candle.State != CandleStates.Finished:
return
mfi_val = float(mfi_value)
if self._prev_candle is not None:
avg_body = (abs(float(candle.ClosePrice) - float(candle.OpenPrice))
+ abs(float(self._prev_candle.ClosePrice) - float(self._prev_candle.OpenPrice))) / 2.0
if avg_body > 0:
prev_bearish = float(self._prev_candle.OpenPrice) > float(self._prev_candle.ClosePrice)
curr_bullish = float(candle.ClosePrice) > float(candle.OpenPrice)
closes_near = abs(float(candle.ClosePrice) - float(self._prev_candle.ClosePrice)) < avg_body * 0.3
if prev_bearish and curr_bullish and closes_near and mfi_val < self.MfiLow and self.Position <= 0:
self.BuyMarket()
prev_bullish = float(self._prev_candle.ClosePrice) > float(self._prev_candle.OpenPrice)
curr_bearish = float(candle.OpenPrice) > float(candle.ClosePrice)
closes_near2 = abs(float(candle.ClosePrice) - float(self._prev_candle.ClosePrice)) < avg_body * 0.3
if prev_bullish and curr_bearish and closes_near2 and mfi_val > self.MfiHigh and self.Position >= 0:
self.SellMarket()
self._prev_candle = candle
def CreateClone(self):
return expert_aml_mfi_strategy()