Ver no GitHub

Estratégia CCI Woodies

Visão geral

Esta estratégia opera com base no cruzamento de duas linhas do Índice de Canal de Commodities (CCI) derivadas do método CCI de Woodies. Um CCI rápido e um CCI lento são calculados no período especificado. Quando a linha rápida cruza abaixo da linha lenta, uma posição comprada é aberta e qualquer posição vendida é fechada. Quando a linha rápida cruza acima da linha lenta, uma posição vendida é aberta e qualquer posição comprada é fechada.

Parâmetros

  • FastPeriod – comprimento do indicador CCI rápido.
  • SlowPeriod – comprimento do indicador CCI lento.
  • CandleType – período das velas usadas para os cálculos.
  • InvertSignals – se habilitado, as regras de compra e venda são trocadas.
  • TakeProfitPoints – meta de lucro em pontos de preço.
  • StopLossPoints – limite de perda em pontos de preço.

Notas

A estratégia usa a API de alto nível do StockSharp. Os indicadores são vinculados via Bind, e o controle de risco é gerenciado com StartProtection usando níveis de stop-loss e 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;
	}
}