Ver en GitHub

Estrategia CCI Woodies

Descripción general

Esta estrategia opera basándose en el cruce de dos líneas del Índice de Canal de Materias Primas (CCI) derivadas del método CCI de Woodies. Se calculan un CCI rápido y un CCI lento en el marco temporal especificado. Cuando la línea rápida cruza por debajo de la línea lenta, se abre una posición larga y se cierra cualquier posición corta. Cuando la línea rápida cruza por encima de la línea lenta, se abre una posición corta y se cierra cualquier posición larga.

Parámetros

  • FastPeriod – longitud del indicador CCI rápido.
  • SlowPeriod – longitud del indicador CCI lento.
  • CandleType – marco temporal de las velas utilizadas para los cálculos.
  • InvertSignals – si está habilitado, las reglas de compra y venta se intercambian.
  • TakeProfitPoints – objetivo de beneficio en puntos de precio.
  • StopLossPoints – límite de pérdida en puntos de precio.

Notas

La estrategia usa la API de alto nivel de StockSharp. Los indicadores se vinculan mediante Bind, y el control de riesgos se gestiona con StartProtection usando niveles de stop-loss y take-profit.

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 Woodies crossover strategy.
/// Buys when the fast CCI crosses below the slow CCI and sells on the opposite crossover.
/// </summary>
public class CciWoodiesStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _isInitialized;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public CciWoodiesStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 6)
			.SetDisplay("Fast CCI Period", "Period for fast CCI", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 14)
			.SetDisplay("Slow CCI Period", "Period for slow CCI", "Indicators");

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

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_isInitialized = false;
	}

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

		_prevFast = 0;
		_prevSlow = 0;
		_isInitialized = false;

		var fastCci = new CommodityChannelIndex { Length = FastPeriod };
		var slowCci = new CommodityChannelIndex { Length = SlowPeriod };

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

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (!_isInitialized)
		{
			_prevFast = fast;
			_prevSlow = slow;
			_isInitialized = true;
			return;
		}

		var crossDown = _prevFast > _prevSlow && fast <= slow;
		var crossUp = _prevFast < _prevSlow && fast >= slow;

		if (crossDown && Position <= 0)
			BuyMarket();
		else if (crossUp && Position >= 0)
			SellMarket();

		_prevFast = fast;
		_prevSlow = slow;
	}
}