Ver en GitHub

Estrategia KWAN CCC

Descripción general

La estrategia KWAN CCC reproduce el experto MetaTrader Exp_KWAN_CCC.mq5 utilizando la API de alto nivel de StockSharp. El sistema deriva señales de trading de un oscilador personalizado construido de la siguiente manera:

  1. Calcular el oscilador Chaikin (diferencia entre las medias móviles rápida y lenta de la línea de acumulación/distribución).
  2. Multiplicar el valor de Chaikin por el Commodity Channel Index (CCI).
  3. Dividir el resultado por el valor del indicador Momentum. Cuando el Momentum es cero, el script sustituye un valor constante de 100 para evitar la división por cero, exactamente como el código original.
  4. Suavizar la serie resultante con el método XMA seleccionado por el usuario.
  5. Detectar la pendiente de la serie suavizada. Las barras en alza se colorean con 0, las barras en baja con 2, y el resto con 1.

Cuando el color cambia de 0 a cualquier otro valor, la estrategia cierra cortos y abre una posición larga. Cuando el color cambia de 2 a cualquier otro valor, cierra largos y abre un corto. Esto refleja la lógica implementada en el experto MQL, incluido el desplazamiento de señal opcional (SignalBar).

Reglas de trading

  • Entrada larga: el color en la barra en SignalBar + 1 es igual a 0 y la barra en SignalBar es diferente de 0.
  • Entrada corta: el color en la barra en SignalBar + 1 es igual a 2 y la barra en SignalBar es diferente de 2.
  • Salida larga: habilitada cuando EnableLongExits = true y se activa la condición de entrada corta.
  • Salida corta: habilitada cuando EnableShortExits = true y se activa la condición de entrada larga.
  • Las órdenes de stop protector y objetivo se crean a través de StartProtection usando desplazamientos de precio absolutos derivados de StopLossPoints y TakeProfitPoints multiplicados por el PriceStep del instrumento.

Parámetros

Parámetro Descripción
OrderVolume Tamaño de orden base utilizado al abrir una nueva posición.
CandleType Marco temporal para todos los cálculos de indicadores. El valor predeterminado es 1 hora.
FastPeriod / SlowPeriod Longitudes de las medias móviles dentro del oscilador Chaikin.
ChaikinMethod Tipo de media móvil (simple, exponencial, suavizada, ponderada) aplicada a la línea de acumulación/distribución.
CciPeriod Período del Commodity Channel Index.
MomentumPeriod Período del indicador Momentum.
SmoothingMethod Método de suavizado XMA mapeado desde las opciones originales. JurX, Parabolic y T3 recurren a Jurik MA; Vidya usa un suavizado adaptativo basado en el Oscilador de Momentum de Chande; Adaptive usa Kaufman AMA.
SmoothingLength Número de barras utilizadas por el filtro de suavizado seleccionado.
SmoothingPhase Parámetro adicional utilizado por métodos específicos (p. ej., longitud CMO de VIDYA, período lento de AMA).
SignalBar Desplazamiento (en barras completadas) utilizado para evaluar las transiciones de color. 1 reproduce el valor predeterminado de MetaTrader.
EnableLongEntries / EnableShortEntries Permitir o bloquear la apertura de nuevas posiciones en la dirección correspondiente.
EnableLongExits / EnableShortExits Permitir o bloquear el cierre de posiciones impulsado por el indicador.
StopLossPoints / TakeProfitPoints Stop protector/objetivo medido en pasos de precio (establecer en cero para deshabilitar).

Notas de implementación

  • La estrategia solo actúa sobre velas terminadas y usa el helper Bind de StockSharp para transmitir datos de velas a los indicadores.
  • La lista de métodos de suavizado refleja la implementación XMA de la biblioteca original. Los métodos no disponibles en StockSharp se mapean a la alternativa más cercana, como se indica en la tabla de parámetros.
  • La entrada VolumeType de MetaTrader se omite porque las velas de StockSharp ya encapsulan la información de volumen total utilizada por la línea de acumulación/distribución.
  • La gestión del dinero en el experto original dependía de helpers personalizados de dimensionamiento de lotes. La conversión asume un volumen fijo especificado por OrderVolume.

Consejos de uso

  • Asegúrese de que el instrumento proporcione datos de volumen significativos si el comportamiento del oscilador Chaikin es importante. Para instrumentos ilíquidos, considere aumentar MomentumPeriod para reducir el ruido.
  • Al optimizar los parámetros de suavizado, combine SmoothingLength y SmoothingPhase con cuidado: las combinaciones extremas pueden retrasar las señales considerablemente.
  • Los valores protectores predeterminados (StopLossPoints = 1000, TakeProfitPoints = 2000) corresponden a grandes desplazamientos. Ajústelos para que coincidan con el tamaño del tick del instrumento.
namespace StockSharp.Samples.Strategies;

using System;

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

/// <summary>
/// Strategy converted from the KWAN_CCC expert advisor.
/// Uses CCI and Momentum to detect trend transitions.
/// Enters long when CCI turns up while momentum is positive,
/// enters short when CCI turns down while momentum is negative.
/// </summary>
public class KwanCccStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _cciPeriod;

	private decimal _prevCci;
	private decimal _prevClose;
	private bool _initialized;

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

	public int CciPeriod
	{
		get => _cciPeriod.Value;
		set => _cciPeriod.Value = value;
	}

	public KwanCccStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for calculations", "General");

		_cciPeriod = Param(nameof(CciPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("CCI Period", "CCI length", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevCci = 0m;
		_prevClose = 0m;
		_initialized = false;
	}

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

		_prevCci = 0m;
		_prevClose = 0m;
		_initialized = false;

		var cci = new CommodityChannelIndex { Length = CciPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription
			.Bind(cci, (ICandleMessage candle, decimal cciValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (!_initialized)
				{
					_prevCci = cciValue;
					_prevClose = candle.ClosePrice;
					_initialized = true;
					return;
				}

				var closeUp = candle.ClosePrice > _prevClose;
				var closeDown = candle.ClosePrice < _prevClose;

				// Buy when CCI crosses into positive territory and price confirms the move.
				if (_prevCci <= 0m && cciValue > 0m && closeUp && Position <= 0)
				{
					BuyMarket();
				}
				// Sell when CCI crosses into negative territory and price confirms the move.
				else if (_prevCci >= 0m && cciValue < 0m && closeDown && Position >= 0)
				{
					SellMarket();
				}

				_prevCci = cciValue;
				_prevClose = candle.ClosePrice;
			})
			.Start();

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