Esta estratégia reproduz o MetaTrader 5 especialista "Expert_AML_CCI" dentro da estrutura de alto nível StockSharp. O robô original
combina o padrão de vela japonês "Meeting Lines" com um filtro Commodity Channel Index (CCI) e usa o Expert Advisor
motor para ponderar votos de alta e baixa. A porta StockSharp mantém a mesma lógica de confirmação, traduz o castiçal
detecção de padrões em pura aritmética de velas e expõe todos os limites como parâmetros amigáveis ao otimizador.
Como funciona
Fonte de dados – A estratégia assina uma série de velas de período configurável (velas de 30 minutos por padrão) usando
SubscribeCandles. Cada vela finalizada é despachada junto com o valor CCI sincronizado por meio do Bind de alto nível
pipeline, portanto, nenhum gerenciamento manual de indicadores é necessário.
Indicador principal – Um único CommodityChannelIndex com período CciPeriod espelha o oscilador MetaTrader. Seus valores são
armazenado em cache internamente para comparar as duas leituras concluídas mais recentes, replicando as chamadas CCI(1) e CCI(2) de MQL.
Lógica de velas – Os métodos auxiliares reconstroem as verificações de "Linhas de reunião de alta" e "Linhas de reunião de baixa". Eles calculam
a média móvel dos comprimentos do corpo sobre AverageBodyPeriod velas (padrão 3) e aplicar o corpo longo e o fechamento igual
requisitos do filtro CML_CCI original. Como StockSharp entrega velas concluídas, o padrão é avaliado com exatidão
quando a segunda vela do padrão fecha – no mesmo momento em que o especialista MQL dá seu voto de 80 pontos.
Regras de entrada –
As posições longas exigem uma formação de linhas de reunião de alta e o último valor concluído de CCI permanece abaixo ou igual a
LongEntryCciLevel (−50 por padrão). Se uma posição curta oposta estiver aberta, o tamanho da ordem inclui automaticamente o valor absoluto
da posição atual para mudar de direção, correspondendo ao comportamento EA.
As posições curtas refletem a lógica: um padrão de linhas de encontro de baixa mais um valor CCI acima ou igual a ShortEntryCciLevel
(+50 por padrão).
Regras de saída – Em vez dos pesos de voto do Expert Advisor, a porta usa ordens de achatamento explícitas. As vagas estão fechadas
quando o CCI cruza a banda extrema definida por ExtremeCciLevel (80 por padrão):
Os shorts saem quando o CCI salta para cima em −Extreme ou cai abaixo de +Extreme.
As compras saem quando CCI cai abaixo de +Extremo ou mergulha em −Extremo.
Essas regras refletem a ramificação de voto 40 dentro de LongCondition e ShortCondition na classe de sinal MQL.
Gerenciamento de riscos – A estratégia deixa paradas de proteção para quem chama. É compatível com StockSharp do StartProtection
ajudante se um stop-loss ou take-profit precisar ser anexado externamente.
Parâmetros
Parâmetro
Descrição
Padrão
CandleType
Período das velas de origem.
Período de 30 minutos
CciPeriod
Comprimento do Índice de Canal de Commodities.
18
AverageBodyPeriod
Número de velas usadas para calcular o tamanho médio do corpo para validação do padrão.
3
LongEntryCciLevel
Nível de sobrevenda que confirma linhas de reunião de alta.
−50
ShortEntryCciLevel
Nível de sobrecompra que confirma linhas de encontro de baixa.
+50
ExtremeCciLevel
Banda extrema absoluta para cruzamentos de saída CCI.
80
Todos os parâmetros numéricos expõem intervalos de otimizador idênticos aos padrões de EA para que a estratégia possa ser ajustada por meio de StockSharp
ferramentas de otimização.
Notas de uso
Anexe a estratégia a um título e defina o Volume desejado antes de começar.
Opcionalmente, ajuste os limites para corresponder ao perfil original de gerenciamento de dinheiro ou para ajustar a sensibilidade.
A integração do gráfico desenha velas, a curva CCI e executa negociações para validação visual rápida da detecção de padrão.
Ao focar na mesma combinação de vela + CCI, esta implementação StockSharp oferece uma versão fiel do Expert
Consultor enquanto permanece dentro do estilo API de alto nível recomendado.
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()