A estratégia MA2CCI transporta o clássico consultor especialista MetaTrader construído em torno da interação de duas médias móveis simples (SMA) e o índice de canal de commodities (CCI). Ele filtra as negociações usando a linha zero CCI e aplica paradas de proteção derivadas do Average True Range (ATR). O sistema foi projetado para entradas de acompanhamento de tendências com reação rápida a reversões.
A versão StockSharp mantém a lógica de negociação original enquanto adapta o gerenciamento de risco ao ambiente .NET. O dimensionamento da posição segue uma regra de risco por mil com um fator de redução adicional que reduz o tamanho da negociação após perdas consecutivas. Cada entrada anexa um stop orientado à volatilidade que reflete a distância ATR usada na implementação MQL.
Lógica de negociação
Indicadores
Rápido SMA com comprimento padrão 4.
Lento SMA com comprimento padrão 8.
Filtro CCI usando lookback de 4 períodos.
ATR com período 4 para colocação de stop.
Condições de entrada
Longa: o SMA rápido cruza acima do SMA lento e a barra finalizada anterior mostra CCI subindo até zero (de negativo para positivo).
Curto: o rápido SMA cruza abaixo do lento SMA e a barra anterior mostra CCI caindo de zero (de positivo para negativo).
Exit Conditions
O cruzamento oposto SMA fecha posições abertas mesmo que nenhuma nova negociação seja iniciada.
stop ATR: as posições longas saem quando o preço cai para entry - ATR; as posições curtas saem quando o preço sobe para entry + ATR.
Gestão de risco
O volume base do pedido é configurável; por padrão 0,1 lote (ou equivalente cambial).
O dimensionamento dinâmico opcional dimensiona o volume para free capital * MaxRiskPerThousand / 1000 quando os dados do portfólio estão disponíveis.
Após mais de uma perda consecutiva, o tamanho da posição é reduzido linearmente em losses / DecreaseFactor do volume calculado.
As paradas de volatilidade dependem da vela finalizada mais recente; picos intrabar além dos níveis de stop desencadeiam uma saída do mercado no próximo tick da estratégia.
Parâmetros
Nome
Descrição
Padrão
CandleType
Prazo de trabalho para todos os indicadores.
Velas de 1 hora
OrderVolume
Tamanho mínimo de negociação quando o dimensionamento baseado em risco não estiver disponível.
0,1
FastMaPeriod
Período do jejum SMA.
4
SlowMaPeriod
Período da lentidão SMA.
8
CciPeriod
Período do filtro CCI.
4
AtrPeriod
ATR comprimento para cálculo de parada.
4
MaxRiskPerThousand
Fração de capital livre alocado por negociação (por 1.000 unidades).
0,02
DecreaseFactor
Divisor usado para diminuir o volume após sequências perdidas.
3
Notas
A estratégia processa apenas velas finalizadas, garantindo uma decisão por barra semelhante ao EA original que usava Volume[0] > 1 como portão.
Os níveis de stop são simulados internamente em vez de registrar ordens de stop de câmbio; isso corresponde ao comportamento da versão MetaTrader que dependia do fechamento do mercado quando os limites de ATR foram atingidos.
Ative gráficos dentro do StockSharp Designer para visualizar SMA, CCI e negociações executadas usando os auxiliares de desenho integrados.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// MA2CCI Classic strategy - dual SMA crossover with CCI zero-line filter.
/// Buys when fast SMA crosses above slow SMA and CCI above zero.
/// Sells when fast SMA crosses below slow SMA and CCI below zero.
/// </summary>
public class Ma2CciClassicStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Ma2CciClassicStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 12)
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 26)
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetDisplay("CCI Period", "CCI lookback", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevFast = 0m; _prevSlow = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow, decimal cci)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_prevFast <= _prevSlow && fast > slow && cci > 0 && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (_prevFast >= _prevSlow && fast < slow && cci < 0 && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fast; _prevSlow = slow;
}
}
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, CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
class ma2_cci_classic_strategy(Strategy):
def __init__(self):
super(ma2_cci_classic_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 12).SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 26).SetDisplay("Slow SMA", "Slow SMA period", "Indicators")
self._cci_period = self.Param("CciPeriod", 14).SetDisplay("CCI Period", "CCI lookback", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
@property
def fast_period(self): return self._fast_period.Value
@property
def slow_period(self): return self._slow_period.Value
@property
def cci_period(self): return self._cci_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(ma2_cci_classic_strategy, self).OnReseted()
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
def OnStarted2(self, time):
super(ma2_cci_classic_strategy, self).OnStarted2(time)
self._has_prev = False
fast = SimpleMovingAverage(); fast.Length = self.fast_period
slow = SimpleMovingAverage(); slow.Length = self.slow_period
cci = CommodityChannelIndex(); cci.Length = self.cci_period
sub = self.SubscribeCandles(self.candle_type)
sub.Bind(fast, slow, cci, self.process_candle).Start()
def process_candle(self, candle, fast, slow, cci):
if candle.State != CandleStates.Finished: return
f = float(fast); s = float(slow); c = float(cci)
if not self._has_prev: self._prev_fast = f; self._prev_slow = s; self._has_prev = True; return
if self._prev_fast <= self._prev_slow and f > s and c > 0 and self.Position <= 0:
if self.Position < 0: self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and f < s and c < 0 and self.Position >= 0:
if self.Position > 0: self.SellMarket()
self.SellMarket()
self._prev_fast = f; self._prev_slow = s
def CreateClone(self): return ma2_cci_classic_strategy()