Ver en GitHub

Estrategia de filtro iCHO Trend CCIDualOnMA

Esta estrategia es un puerto StockSharp de alto nivel del asesor experto MetaTrader "iCHO Trend CCIDualOnMA Filter". Combina un filtro de régimen de línea cero del oscilador Chaikin con una confirmación dual del índice de canal de productos básicos (CCI) que se calcula sobre una serie de precios suavizada. El resultado es un enfoque de seguimiento de tendencias que reacciona a los cambios de impulso pero aún requiere una confirmación de impulso por parte del par CCI antes de iniciar una operación.

Lógica comercial

  1. Núcleo del oscilador Chaikin: la línea de acumulación/distribución se suaviza mediante dos medias móviles configurables. Su diferencia replica el oscilador Chaikin. Los cruces por encima/por debajo de cero indican un cambio en el flujo de capital dominante.
  2. Filtro dual CCI: ambas instancias CCI utilizan la misma entrada de precio suavizada de promedio móvil pero diferentes períodos retrospectivos. Una configuración larga requiere que el CCI rápido se recupere del territorio negativo y cruce por encima del CCI lento mientras el oscilador Chaikin se mantiene por encima de cero. Una configuración breve refleja estas condiciones.
  3. Inversión opcional: el EA original proporciona un indicador "inverso" que intercambia señales largas y cortas. El puerto mantiene este comportamiento para que se puedan utilizar las mismas reglas para las pruebas de contratendencia.
  4. Gestión de posiciones: las banderas opcionales cierran la exposición opuesta antes de abrir una nueva posición y limitan la estrategia a una única posición abierta. Se aplica una regla de una operación por barra para imitar la implementación de MetaTrader.
  5. Filtro de sesión: las operaciones se pueden restringir a una ventana intradiaria definida por el usuario, incluidas las sesiones envolventes que pasan de la medianoche.

Parámetros

Parámetro Descripción
FastChaikinLength Período de media móvil rápida utilizado dentro del oscilador Chaikin.
SlowChaikinLength Período de media móvil lenta utilizado dentro del oscilador Chaikin.
ChaikinMethod Método de media móvil (simple, exponencial, suavizado, ponderado lineal) aplicado a la línea de acumulación/distribución.
FastCciLength Vista retrospectiva del rápido índice del canal de productos básicos.
SlowCciLength Vista retrospectiva del lento índice del canal de materias primas.
MaLength Longitud de la media móvil de preprocesamiento que alimenta los CCI.
MaMethod Método de media móvil utilizado para preprocesar el precio antes de que llegue a los CCI.
MaPrice Tipo de precio (cierre, apertura, máximo, mínimo, mediana, típico, ponderado) que se suaviza antes de los CCI.
UseClosedBar Procese solo velas completamente terminadas (el valor predeterminado es verdadero, idéntico a SignalsBarCurrent=bar_1 en EA).
ReverseSignals Intercambia lógica larga y corta.
CloseOpposite Cierre una posición abierta en la dirección opuesta antes de ingresar a una nueva.
OnlyOnePosition Permita solo una posición abierta en cualquier momento.
TradeMode Restrinja la ejecución a posiciones largas, cortas o ambas (BuyOnly, SellOnly, BuyAndSell).
UseTimeFilter Habilite el filtro de sesión de negociación.
StartHour, StartMinute, EndHour, EndMinute Límites de la sesión (incluido el inicio, excluyendo el final) expresados en tiempo de intercambio. Se admiten sesiones integrales.
CandleType Plazo de suscripción de velas que alimenta los indicadores.

Notas

  • La estrategia utiliza sólo enlaces SubscribeCandles de alto nivel e indicadores integrados; no se requieren buffers personalizados ni solicitudes históricas.
  • Todos los cálculos basados en precios adoptan el mismo preprocesamiento de promedio móvil que el indicador MetaTrader CCIDualOnMA alimentando el CCI con una serie de precios suavizada.
  • Los parámetros predeterminados reproducen los valores predeterminados originales de EA: Chaikin 3/10 EMA, CCI períodos 14 y 50, preprocesamiento de SMA de 12 períodos y una ventana de negociación de 10:01 a 15:02.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Combines a Chaikin oscillator zero-line filter with CCI confirmation.
/// Buys when Chaikin crosses above zero and CCI is rising, sells on opposite.
/// </summary>
public class iCHO_Trend_CCIDualOnMA_FilterStrategy : Strategy
{
	private readonly StrategyParam<int> _cciLength;
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<decimal> _cciLevel;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal? _prevCci;
	private decimal? _prevPrevCci;
	private int _candlesSinceTrade;

	public int CciLength
	{
		get => _cciLength.Value;
		set => _cciLength.Value = value;
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public decimal CciLevel
	{
		get => _cciLevel.Value;
		set => _cciLevel.Value = value;
	}

	public int SignalCooldownCandles
	{
		get => _signalCooldownCandles.Value;
		set => _signalCooldownCandles.Value = value;
	}

	public iCHO_Trend_CCIDualOnMA_FilterStrategy()
	{
		_cciLength = Param(nameof(CciLength), 14)
			.SetGreaterThanZero()
			.SetDisplay("CCI Length", "CCI period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Primary candle series", "Data");

		_cciLevel = Param(nameof(CciLevel), 100m)
			.SetDisplay("CCI Level", "CCI threshold for entry", "Indicators");

		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between entries", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevCci = null;
		_prevPrevCci = null;
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevCci = null;
		_prevPrevCci = null;
		_candlesSinceTrade = SignalCooldownCandles;

		var cci = new CommodityChannelIndex { Length = CciLength };

		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 (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (_prevCci.HasValue && _prevPrevCci.HasValue)
		{
			if (_prevPrevCci.Value < -CciLevel && _prevCci.Value < -CciLevel && cciValue > -CciLevel && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (_prevPrevCci.Value > CciLevel && _prevCci.Value > CciLevel && cciValue < CciLevel && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevPrevCci = _prevCci;
		_prevCci = cciValue;
	}
}