Ver no GitHub

Estratégia FT CCI

Esta estratégia é um port para StockSharp do consultor especialista do MetaTrader 5 "FT_CCI (barabashkakvn's edition)". Usa o Commodity Channel Index (CCI) para capturar reversões bruscas quando o oscilador se afasta muito de sua média. O sistema espelha a lógica original: quando o CCI perfura a banda inferior, ele muda para comprado, e quando perfura a banda superior, muda para vendido. Os valores opcionais de stop-loss e take-profit são inseridos em pips e convertidos automaticamente em deslocamentos de preço.

Visão Geral

  • Indicador principal: Commodity Channel Index com um período de suavização configurável (padrão 14).
  • Viés: Comprado/Vendido simétrico. A estratégia mantém no máximo uma posição líquida e reverte em sinais opostos.
  • Execução: Ordens de mercado no fechamento das velas concluídas do período selecionado.
  • Gestão de risco: Distâncias opcionais de stop-loss e take-profit expressas em pips. Se qualquer valor for zero, a proteção correspondente é desativada.
  • Período padrão: Velas de 30 minutos (espelha a seleção de Period() no especialista original).

Como funciona

Configuração comprada

  1. Subscrever às velas concluídas do período selecionado.
  2. Atualizar o indicador CCI com valores de preço típico.
  3. Quando o último valor do CCI estiver no ou abaixo do limiar inferior configurado (padrão -210):
    • Fechar qualquer exposição vendida aberta.
    • Entrar ou adicionar a uma posição comprada usando o volume de negociação configurado.
  4. Manter a posição até que uma configuração vendida oposta acione, ocorra um evento de stop-loss/take-profit ou a estratégia seja parada manualmente.

Configuração vendida

  1. Monitorar os mesmos valores de CCI em velas concluídas.
  2. Quando o indicador estiver no ou acima do limiar superior (padrão +210):
    • Fechar qualquer exposição comprada aberta.
    • Entrar ou adicionar a uma posição vendida usando o volume configurado.
  3. Manter a posição vendida até que uma condição comprada oposta acione ou ordens de proteção fechem a negociação.

Gestão de negociações

  • As distâncias de stop-loss e take-profit são definidas em pips. A estratégia os multiplica pelo tamanho de pip detectado (passo de preço, multiplicado por 10 para símbolos forex de 3 e 5 dígitos) para obter um deslocamento de preço absoluto antes de ativar o StartProtection integrado do StockSharp.
  • Como a proteção é aplicada uma vez no início, qualquer nova posição herda imediatamente os mesmos valores de stop e alvo relativos ao seu preço de execução.
  • Os giros de posição são executados por ordens de mercado dimensionadas em volume configurado + |posição atual|, garantindo que reverter uma posição tanto fecha a exposição atual quanto abre a nova em uma única transação.

Parâmetros

Nome Descrição
Candle Type Período usado para cálculos e geração de sinal.
Trade Volume Tamanho do lote para novas posições. Usado junto com o valor da posição atual para dimensionar negociações de reversão.
CCI Period Comprimento de suavização do Commodity Channel Index.
CCI Upper Threshold Nível de CCI que aciona entradas vendidas.
CCI Lower Threshold Nível de CCI que aciona entradas compradas.
Stop Loss (pips) Distância ao stop de proteção em pips. Definir como 0 para desativar.
Take Profit (pips) Distância ao alvo de lucro em pips. Definir como 0 para desativar.

Todos os parâmetros suportam otimização através do gerenciador de parâmetros do StockSharp.

Uso recomendado

  • Funciona melhor em pares forex líquidos e índices onde velas de 30 minutos a 4 horas produzem extremos de CCI pronunciados.
  • Os limiares de ±210 recriam os padrões do FT_CCI. Valores mais baixos tornam o sistema mais reativo; valores mais altos focam apenas nas reversões mais extremas.
  • Certifique-se de que os metadados do instrumento expõem um PriceStep válido. O conversor de pips depende desse valor para traduzir pips em deslocamentos de preço.
  • A estratégia assume um modelo de conta de compensação (posição líquida única). Para contas de cobertura, defina o volume de negociação adequadamente para que as reversões aplainassem completamente a negociação anterior.

Notas

  • O indicador deve estar completamente formado antes que qualquer sinal de negociação seja considerado. As primeiras velas são ignoradas até que o CCI tenha dados suficientes para emitir valores válidos.
  • As ordens de stop-loss e take-profit são opcionais. Deixá-las em zero reproduz o comportamento original do consultor especialista que dependia exclusivamente de sinais opostos para saídas.
  • Adicione a estratégia a um gráfico no StockSharp para visualizar velas, o indicador CCI e negociações executadas; essas ajudas visuais são habilitadas automaticamente na implementação em C#.
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// CCI breakout strategy. Opens long when CCI drops below lower band, shorts when above upper band.
/// </summary>
public class FtCciStrategy : Strategy
{
	private readonly StrategyParam<int> _cciPeriod;
	private readonly StrategyParam<decimal> _upperThreshold;
	private readonly StrategyParam<decimal> _lowerThreshold;
	private readonly StrategyParam<DataType> _candleType;

	public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
	public decimal UpperThreshold { get => _upperThreshold.Value; set => _upperThreshold.Value = value; }
	public decimal LowerThreshold { get => _lowerThreshold.Value; set => _lowerThreshold.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public FtCciStrategy()
	{
		_cciPeriod = Param(nameof(CciPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("CCI Period", "Averaging period for CCI", "Indicator");

		_upperThreshold = Param(nameof(UpperThreshold), 210m)
			.SetDisplay("CCI Upper", "CCI level for short entries", "Indicator");

		_lowerThreshold = Param(nameof(LowerThreshold), -210m)
			.SetDisplay("CCI Lower", "CCI level for long entries", "Indicator");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle Type", "General");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var cci = new CommodityChannelIndex { Length = CciPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(cci, ProcessCandle).Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, cci);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal cciValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (cciValue <= LowerThreshold && Position <= 0)
			BuyMarket();
		else if (cciValue >= UpperThreshold && Position >= 0)
			SellMarket();

		// Exit when CCI returns to zero
		if (Position > 0 && cciValue >= 0)
			SellMarket();
		else if (Position < 0 && cciValue <= 0)
			BuyMarket();
	}
}