Ver no GitHub

Estratégia Clássica MA2CCI

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

  1. 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.
  2. 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.
  3. 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;
	}
}