Auf GitHub ansehen

iCHO Trend CCIDualOnMA Filterstrategie

Diese Strategie ist ein High-Level-StockSharp-Port des MetaTrader-Expertenberaters „iCHO Trend CCIDualOnMA Filter“. Es kombiniert einen Chaikin-Oszillator-Nulllinienregimefilter mit einer dualen Commodity Channel Index (CCI)-Bestätigung, die auf einer geglätteten Preisreihe berechnet wird. Das Ergebnis ist ein Trendfolge-Ansatz, der auf Momentum-Verschiebungen reagiert, aber dennoch eine Momentum-Bestätigung durch das Paar CCI erfordert, bevor ein Handel eingeleitet wird.

Handelslogik

  1. Chaikin-Oszillatorkern – die Akkumulations-/Verteilungslinie wird durch zwei konfigurierbare gleitende Durchschnitte geglättet. Ihr Unterschied spiegelt den Chaikin-Oszillator wider. Kreuze über/unter Null signalisieren eine Änderung des vorherrschenden Kapitalflusses.
  2. Dualer CCI-Filter – beide CCI-Instanzen verwenden dieselbe Preiseingabe mit gleitendem Durchschnitt und Glättung, aber unterschiedliche Lookback-Zeiträume. Bei einem langen Setup muss sich der schnelle CCI vom negativen Bereich erholen und den langsamen CCI überschreiten, während der Chaikin-Oszillator über Null bleibt. Ein kurzer Aufbau spiegelt diese Bedingungen wider.
  3. Optionale Umkehrung – das Original EA bietet eine „Umkehr“-Flagge, die Long- und Short-Signale vertauscht. Der Port behält dieses Verhalten bei, sodass die gleichen Regeln für Gegentrendtests verwendet werden können.
  4. Positionsverwaltung – optionale Flags schließen das Gegenrisiko, bevor eine neue Position eröffnet wird, und beschränken die Strategie auf eine einzige offene Position. Zur Nachahmung der MetaTrader-Implementierung wird eine Ein-Trade-pro-Barren-Regel durchgesetzt.
  5. Sitzungsfilter – Der Handel kann auf ein benutzerdefiniertes Intraday-Fenster beschränkt werden, einschließlich Wrap-Around-Sitzungen, die über Mitternacht hinausgehen.

Parameter

Parameter Beschreibung
FastChaikinLength Schnelle gleitende Durchschnittsperiode, die im Chaikin-Oszillator verwendet wird.
SlowChaikinLength Langsame gleitende Durchschnittsperiode, die im Chaikin-Oszillator verwendet wird.
ChaikinMethod Methode des gleitenden Durchschnitts (einfach, exponentiell, geglättet, linear gewichtet), angewendet auf die Akkumulations-/Verteilungslinie.
FastCciLength Rückblick auf den Fast Commodity Channel Index.
SlowCciLength Rückblick auf den langsamen Commodity Channel Index.
MaLength Länge des gleitenden Vorverarbeitungsdurchschnitts, der die CCIs speist.
MaMethod Methode des gleitenden Durchschnitts, die zur Vorverarbeitung des Preises verwendet wird, bevor er die CCIs erreicht.
MaPrice Preisart (Schluss, Eröffnung, Hoch, Tief, Median, typisch, gewichtet), die vor den CCIs geglättet wird.
UseClosedBar Verarbeiten Sie nur vollständig fertige Kerzen (Standardeinstellung: wahr, identisch mit SignalsBarCurrent=bar_1 im EA).
ReverseSignals Tauschen Sie Long- und Short-Logik aus.
CloseOpposite Schließen Sie eine offene Position in die entgegengesetzte Richtung, bevor Sie eine neue eröffnen.
OnlyOnePosition Erlauben Sie immer nur eine einzige offene Position.
TradeMode Beschränken Sie die Ausführung auf Longs, Shorts oder beides (BuyOnly, SellOnly, BuyAndSell).
UseTimeFilter Aktivieren Sie den Handelssitzungsfilter.
StartHour, StartMinute, EndHour, EndMinute Sitzungsgrenzen (einschließlich Beginn, ausschließlich Ende), ausgedrückt in Austauschzeit. Wrap-Around-Sitzungen werden unterstützt.
CandleType Zeitrahmen des Kerzenabonnements, das die Indikatoren speist.

Notizen

  • Die Strategie verwendet nur SubscribeCandles-Bindungen und integrierte Indikatoren auf hoher Ebene. Es sind keine benutzerdefinierten Puffer oder historischen Anforderungen erforderlich.
  • Alle preisbasierten Berechnungen verwenden die gleiche Vorverarbeitung des gleitenden Durchschnitts wie der Indikator MetaTrader CCIDualOnMA, indem sie den Indikator CCI mit einer geglätteten Preisreihe versorgen.
  • Die Standardparameter reproduzieren die ursprünglichen EA-Standardwerte: Chaikin 3/10 EMA, CCI Perioden 14 und 50, 12-Perioden-SMA-Vorverarbeitung und ein Handelsfenster von 10:01 bis 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;
	}
}