Auf GitHub ansehen

ABE BE CCI Engulfing-Strategie

Diese StockSharp-Strategie portiert den MetaTrader 5 Expertenberater Expert_ABE_BE_CCI (Ordner MQL/306). Das Original EA kombiniert bullische/bearische Engulfing-Kerzenmuster mit einem Commodity Channel Index (CCI)-Bestätigungsmodul und einer festen Lot-Geldverwaltung. Die C#-Implementierung behält die gleiche Entscheidungslogik bei und nutzt gleichzeitig die von StockSharp bereitgestellten Abonnement- und Indikatorbindungen auf hoher Ebene.

Die Engine überwacht abgeschlossene Kerzen im ausgewählten Zeitrahmen, berechnet einen gleitenden Durchschnitt der Kerzenkörper, einen Durchschnitt der Schlusskurse und einen CCI mit konfigurierbarem Zeitraum. Bullische oder bärische Engulfing-Muster werden nur akzeptiert, wenn die Kerzenkörper den aktuellen Durchschnitt überschreiten und der Mittelpunkt der verschlungenen Kerze auf der richtigen Seite des gleitenden Durchschnitts liegt, was die MQL CCandlePattern-Prüfungen nachahmt. Long-Trades erfordern ein bullisches Engulfing plus CCI unter dem überverkauften Schwellenwert, während Short-Trades die Spiegelbedingung mit CCI über dem überkauften Schwellenwert erfordern. Positionsausgänge spiegeln die EA-„Abstimmungs“-Logik wider: CCI Überschreitungen von ±ExitLevel neutralisieren offene Positionen unabhängig von der Richtung.

Arbeitsablauf

  1. Abonnieren Sie den konfigurierten Kerzentyp und berechnen Sie:
    • Kerzenkörperdurchschnitt über BodyAveragePeriod Balken.
    • Gleitender Durchschnitt der Schlusskurse im selben Fenster.
    • Rohstoffkanalindex mit der Länge CciPeriod.
  2. Für jede fertige Kerze:
    • Stellen Sie sicher, dass die vorherige Kerze einen umhüllten Balken mit entgegengesetzter Farbe bildet.
    • Überprüfen Sie, ob der einhüllende Körper größer als der Durchschnitt des Rollkörpers ist und über die vorherige Öffnung hinaus schließt, indem Sie die MQL-Filter replizieren.
    • Bestätigen Sie den Trendkontext, indem Sie den Mittelpunkt der vorherigen Kerze mit dem gleitenden Durchschnitt des Schlusskurses vergleichen.
    • Bestätigen Sie die Dynamik mit CCI vs. EntryOversoldLevel oder EntryOverboughtLevel.
  3. Trades verwalten:
    • Wenn die bullischen Bedingungen übereinstimmen und keine Long-Position aktiv ist, schließen Sie Short-Positionen und kaufen Sie das konfigurierte Volumen.
    • Wenn die rückläufigen Bedingungen übereinstimmen und kein Short aktiv ist, schließen Sie Long-Positionen und verkaufen Sie das konfigurierte Volumen.
    • Überwachen Sie CCI auf Exits: Jede Kreuzung unter +ExitLevel oder über -ExitLevel schließt Long-Positionen, während Kreuzungen über -ExitLevel oder unter +ExitLevel Short-Positionen schließen, was der 40-Punkte-Abstimmungslogik von EA entspricht.

Standardparameter

Name Standard Beschreibung
CciPeriod 49 Länge des Commodity Channel Index-Indikators.
BodyAveragePeriod 11 Fenster zur Mittelung der Kerzenkörpergröße und des Mittelwerts des Schlusskurses.
EntryOversoldLevel -50 CCI-Schwellenwert, der bullische Engulfing-Setups bestätigt.
EntryOverboughtLevel 50 CCI-Schwellenwert, der die bärischen Engulfing-Setups bestätigt.
ExitLevel 80 Absolutes CCI-Niveau, das bei Überschreiten Positionsausstiege auslöst.
CandleType 1 Stunde Für das Kerzenabonnement verwendeter Zeitrahmen.

Notizen

  • Die Volumenverarbeitung spiegelt typische StockSharp-Konvertierungen wider: Volume definiert die Basisauftragsgröße; Gegenüberliegende Positionen werden vor dem Umkehren abgeflacht.
  • Trailing- und Money-Management-Komponenten (TrailingNone, MoneyFixedLot) aus dem Paket MQL werden nicht neu erstellt; Die Auftragsgröße von StockSharp deckt bereits das Verhalten bei festen Losen ab.
  • Alle Kommentare im Code sind auf Englisch, Tabulatoren werden zum Einrücken verwendet und es werden keine Indikatorwerte über GetValue abgerufen, gemäß den Repository-Richtlinien.
namespace StockSharp.Samples.Strategies;

using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// ABE BE CCI strategy: Engulfing pattern with CCI confirmation.
/// Bullish engulfing + negative CCI for long, bearish engulfing + positive CCI for short.
/// </summary>
public class AbeBeCciStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _cciPeriod;
	private readonly StrategyParam<decimal> _entryLevel;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private readonly List<ICandleMessage> _candles = new();
	private decimal _prevCci;
	private bool _hasPrevCci;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
	public decimal EntryLevel { get => _entryLevel.Value; set => _entryLevel.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public AbeBeCciStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_cciPeriod = Param(nameof(CciPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("CCI Period", "CCI period", "Indicators");
		_entryLevel = Param(nameof(EntryLevel), 100m)
			.SetDisplay("Entry Level", "CCI threshold for entry", "Signals");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_candles.Clear();
		_prevCci = 0m;
		_hasPrevCci = false;
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_candles.Clear();
		_hasPrevCci = false;
		_candlesSinceTrade = SignalCooldownCandles;
		var cci = new CommodityChannelIndex { Length = CciPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(cci, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		_candles.Add(candle);
		if (_candles.Count > 5)
			_candles.RemoveAt(0);

		if (_candles.Count >= 2)
		{
			var curr = _candles[^1];
			var prev = _candles[^2];

			var bullishEngulfing = prev.OpenPrice > prev.ClosePrice
				&& curr.ClosePrice > curr.OpenPrice
				&& curr.OpenPrice <= prev.ClosePrice
				&& curr.ClosePrice >= prev.OpenPrice;

			var bearishEngulfing = prev.ClosePrice > prev.OpenPrice
				&& curr.OpenPrice > curr.ClosePrice
				&& curr.OpenPrice >= prev.ClosePrice
				&& curr.ClosePrice <= prev.OpenPrice;

			if (bullishEngulfing && cciValue < -EntryLevel && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (bearishEngulfing && cciValue > EntryLevel && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		if (_hasPrevCci)
		{
			if (Position > 0 && _prevCci > EntryLevel && cciValue < EntryLevel && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
			else if (Position < 0 && _prevCci < -EntryLevel && cciValue > -EntryLevel && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevCci = cciValue;
		_hasPrevCci = true;
	}
}