Esta estrategia reproduce los MetaTrader 5 expertos "Expert_AML_CCI" dentro del marco de alto nivel StockSharp. El robot original
combina el patrón de velas japonesas "Meeting Lines" con un filtro de índice de canales de productos básicos (CCI) y utiliza el Asesor Experto
motor para ponderar los votos alcistas y bajistas. El puerto StockSharp mantiene la misma lógica de confirmación, traduce la vela
detección de patrones en aritmética pura de velas y expone todos los umbrales como parámetros fáciles de optimizar.
como funciona
Fuente de datos: la estrategia se suscribe a una serie de velas de marco temporal configurable (velas de 30 minutos de forma predeterminada) usando
SubscribeCandles. Cada vela terminada se envía junto con el valor CCI sincronizado a través del Bind de alto nivel.
pipeline, por lo que no se requiere gestión manual de indicadores.
Indicador central: un único CommodityChannelIndex con período CciPeriod refleja el oscilador MetaTrader. Sus valores son
almacenado en caché internamente para comparar las dos lecturas completadas más recientes, replicando las llamadas CCI(1) y CCI(2) de MQL.
Lógica de vela: los métodos auxiliares reconstruyen las comprobaciones de "Líneas de encuentro alcistas" y "Líneas de encuentro bajistas". ellos calculan
el promedio móvil de las longitudes del cuerpo sobre AverageBodyPeriod velas (predeterminado 3) y aplica el cuerpo largo y el cierre igual
requisitos del filtro original CML_CCI. Debido a que StockSharp entrega velas completas, el patrón se evalúa exactamente
cuando se cierra la segunda vela del patrón, el mismo momento en que el experto MQL emite su voto de 80 puntos.
Reglas de entrada –
Las posiciones largas requieren una formación de líneas de reunión alcistas y el último valor CCI completado para permanecer por debajo o igual a
LongEntryCciLevel (-50 por defecto). Si hay un corto opuesto abierto, el tamaño de la orden incluye automáticamente el valor absoluto
de la posición actual para invertir la dirección, coincidiendo con el comportamiento EA.
Las posiciones cortas reflejan la lógica: un patrón bajista de Líneas de Encuentro más un valor de CCI superior o igual a ShortEntryCciLevel
(+50 por defecto).
Reglas de salida: en lugar de las ponderaciones de votación del Asesor Experto, el puerto utiliza órdenes de aplanamiento explícitas. Posiciones cerradas
cuando el CCI cruza la banda extrema definida por ExtremeCciLevel (80 por defecto):
Los cortos salen cuando el CCI salta hacia arriba a través de −Extreme o vuelve a caer por debajo de +Extreme.
Los largos salen cuando el CCI cae por debajo de +Extreme o atraviesa −Extreme.
Estas reglas reflejan la rama de voto 40 dentro de LongCondition y ShortCondition en la clase de señal MQL.
Gestión de riesgos: la estrategia deja paradas de protección a quien llama. Es compatible con StockSharp's StartProtection
ayuda si es necesario adjuntar externamente un stop-loss o take-profit.
Parámetros
Parámetro
Descripción
Predeterminado
CandleType
Marco temporal de las velas fuente.
plazo de 30 minutos
CciPeriod
Longitud del índice del canal de productos básicos.
18
AverageBodyPeriod
Número de velas utilizadas para calcular el tamaño corporal promedio para la validación del patrón.
3
LongEntryCciLevel
Nivel de sobreventa que confirma Líneas de Encuentro alcistas.
−50
ShortEntryCciLevel
Nivel de sobrecompra que confirma Líneas de Encuentro bajistas.
+50
ExtremeCciLevel
Banda extrema absoluta para cruces de salida CCI.
80
Todos los parámetros numéricos exponen rangos de optimizador idénticos a los valores predeterminados de EA para que la estrategia se pueda ajustar a través de StockSharp
herramientas de optimización.
Notas de uso
Adjunte la estrategia a un valor y establezca el Volume deseado antes de comenzar.
Opcionalmente, modifique los umbrales para que coincidan con el perfil de administración de dinero original o para ajustar la sensibilidad.
La integración del gráfico dibuja velas, la curva CCI y ejecuta operaciones para una validación visual rápida de la detección de patrones.
Al centrarse en la misma combinación de vela+CCI, esta implementación StockSharp ofrece una versión fiel del Experto
Advisor mientras se mantiene dentro del estilo recomendado de alto nivel API.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Meeting Lines + CCI strategy.
/// Buys on bullish meeting lines with low CCI, sells on bearish meeting lines with high CCI.
/// </summary>
public class AmlCciMeetingLinesStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<decimal> _cciLow;
private readonly StrategyParam<decimal> _cciHigh;
private ICandleMessage _prevCandle;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public decimal CciLow { get => _cciLow.Value; set => _cciLow.Value = value; }
public decimal CciHigh { get => _cciHigh.Value; set => _cciHigh.Value = value; }
public AmlCciMeetingLinesStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
_cciLow = Param(nameof(CciLow), -50m)
.SetDisplay("CCI Low", "CCI level for bullish entry", "Signals");
_cciHigh = Param(nameof(CciHigh), 50m)
.SetDisplay("CCI High", "CCI 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 cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cciValue)
{
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;
// Bullish meeting lines
if (prevBearish && currBullish && closesNear && cciValue < CciLow && 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;
// Bearish meeting lines
if (prevBullish && currBearish && closesNear2 && cciValue > CciHigh && 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, Math
from StockSharp.Messages import CandleStates
from StockSharp.Algo.Indicators import CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class aml_cci_meeting_lines_strategy(Strategy):
"""
Meeting Lines + CCI strategy.
Buys on bullish meeting lines with low CCI, sells on bearish meeting lines with high CCI.
"""
def __init__(self):
super(aml_cci_meeting_lines_strategy, self).__init__()
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._cci_period = self.Param("CciPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("CCI Period", "CCI period", "Indicators")
self._cci_low = self.Param("CciLow", -50.0) \
.SetDisplay("CCI Low", "CCI level for bullish entry", "Signals")
self._cci_high = self.Param("CciHigh", 50.0) \
.SetDisplay("CCI High", "CCI level for bearish entry", "Signals")
self._prev_open = None
self._prev_close = None
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
@property
def CciPeriod(self): return self._cci_period.Value
@CciPeriod.setter
def CciPeriod(self, v): self._cci_period.Value = v
@property
def CciLow(self): return self._cci_low.Value
@CciLow.setter
def CciLow(self, v): self._cci_low.Value = v
@property
def CciHigh(self): return self._cci_high.Value
@CciHigh.setter
def CciHigh(self, v): self._cci_high.Value = v
def OnReseted(self):
super(aml_cci_meeting_lines_strategy, self).OnReseted()
self._prev_open = None
self._prev_close = None
def OnStarted2(self, time):
super(aml_cci_meeting_lines_strategy, self).OnStarted2(time)
self._prev_open = None
self._prev_close = None
cci = CommodityChannelIndex()
cci.Length = self.CciPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(cci, self.ProcessCandle).Start()
def ProcessCandle(self, candle, cci_value):
if candle.State != CandleStates.Finished:
return
c_open = float(candle.OpenPrice)
c_close = float(candle.ClosePrice)
if self._prev_open is not None and self._prev_close is not None:
avg_body = (abs(c_close - c_open) + abs(self._prev_close - self._prev_open)) / 2.0
if avg_body > 0:
prev_bearish = self._prev_open > self._prev_close
curr_bullish = c_close > c_open
closes_near = abs(c_close - self._prev_close) < avg_body * 0.3
if prev_bearish and curr_bullish and closes_near and cci_value < self.CciLow and self.Position <= 0:
self.BuyMarket()
prev_bullish = self._prev_close > self._prev_open
curr_bearish = c_open > c_close
closes_near2 = abs(c_close - self._prev_close) < avg_body * 0.3
if prev_bullish and curr_bearish and closes_near2 and cci_value > self.CciHigh and self.Position >= 0:
self.SellMarket()
self._prev_open = c_open
self._prev_close = c_close
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return aml_cci_meeting_lines_strategy()