Auf GitHub ansehen

CaiChannel System Digit-Strategie

Diese Strategie ist ein vereinfachter StockSharp-Port des MetaTrader-Experten i-CAiChannel System Digit.

Der Algorithmus überwacht einen Volatilitätskanal, der aus einem gleitenden Durchschnitt und einer Standardabweichung (Bollinger Bänder) aufgebaut ist. Wenn eine Kerze außerhalb des Kanals schließt und die nächste Kerze wieder zurückkehrt, handelt die Strategie in Richtung des Wiedereintritts.

Parameter

  • Length – Periode des gleitenden Durchschnitts.
  • Width – Standardabweichungsmultiplikator.
  • Candle Type – Zeitrahmen für die Verarbeitung.

Handelslogik

  1. Kerzen des gewählten Zeitrahmens abonnieren.
  2. Bollinger Bänder mit den angegebenen Parametern berechnen.
  3. Wenn die vorherige Kerze über dem oberen Band schloss und die aktuelle Kerze wieder innerhalb schließt, Long gehen.
  4. Wenn die vorherige Kerze unter dem unteren Band schloss und die aktuelle Kerze wieder innerhalb schließt, Short gehen.
  5. Die Position wird umgekehrt, wenn das entgegengesetzte Signal auftritt.

Alle Signale werden nur auf abgeschlossenen Kerzen generiert.

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>
/// CAiChannel System Digit strategy using Bollinger Bands.
/// Buys when price returns inside from above the upper band.
/// Sells when price returns inside from below the lower band.
/// </summary>
public class CaiChannelSystemDigitStrategy : Strategy
{
	private readonly StrategyParam<int> _length;
	private readonly StrategyParam<decimal> _width;
	private readonly StrategyParam<DataType> _candle;
	private bool _prevUp;
	private bool _prevDown;

	public int Length { get => _length.Value; set => _length.Value = value; }
	public decimal Width { get => _width.Value; set => _width.Value = value; }
	public DataType CandleType { get => _candle.Value; set => _candle.Value = value; }

	public CaiChannelSystemDigitStrategy()
	{
		_length = Param(nameof(Length), 12).SetGreaterThanZero();
		_width = Param(nameof(Width), 2m).SetGreaterThanZero();
		_candle = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame());
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevUp = false;
		_prevDown = false;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevUp = false;
		_prevDown = false;

		var bb = new BollingerBands { Length = Length, Width = Width };

		var sub = SubscribeCandles(CandleType);
		sub.BindEx(bb, Process).Start();

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

	private void Process(ICandleMessage candle, IIndicatorValue bbVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (bbVal is not IBollingerBandsValue bb || bb.UpBand is not decimal up || bb.LowBand is not decimal down)
			return;

		if (_prevUp && candle.ClosePrice <= up && Position <= 0)
			BuyMarket();
		else if (_prevDown && candle.ClosePrice >= down && Position >= 0)
			SellMarket();

		_prevUp = candle.ClosePrice > up;
		_prevDown = candle.ClosePrice < down;
	}
}