Auf GitHub ansehen

SMC Trader Camel CCI MACD Strategie

Überblick

Diese Strategie ist eine StockSharp-Portierung des MetaTrader 4-Expertenberaters "Steve Cartwright Trader Camel CCI MACD". Es reproduziert die ursprüngliche Handelslogik basierend auf einem exponentiellen gleitenden Durchschnittskanal im Kamelstil. ein MACD-Trendfilter und Schwellenwerte für den Commodity Channel Index (CCI). Trades werden nach Abschluss ausgeführt Kerzen, um deterministisches Verhalten sicherzustellen und nahe am Bar-für-Bar-Workflow der MQL-Version zu bleiben.

Handelslogik

  1. Indikatoren
    • Zwei exponentielle gleitende Durchschnitte (EMA) mit derselben Periode werden auf Kerzenhochs und -tiefs angewendet, um das zu bilden Kamelkanal. Ein Ausbruch des vorherigen Schlusskurses über diese Hüllkurven hinaus signalisiert die Stärke des Momentums.
    • Ein Standard-MACD-Indikator (schneller EMA, langsamer EMA und Signallinie) wird verwendet, um die zugrunde liegende Trendrichtung zu bestätigen.
    • Ein CCI-Indikator validiert die Momentumstärke anhand der standardmäßig überkauften/überverkauften Niveaus von ±100.
  2. Lange Einträge
    • Der vorherige Kerzenschluss liegt über dem Kamelhoch EMA.
    • Der vorherige MACD-Hauptwert liegt über Null und über der Signallinie.
    • Der vorherige CCI-Wert liegt über dem positiven Schwellenwert.
    • Es ist keine aktive Position offen und es erfolgte kein Ausstieg innerhalb des aktuellen Candle-Zeitrahmens (verhindert einen schnellen Wiedereinstieg).
  3. Kurze Einträge
    • Der vorherige Kerzenschluss liegt unter dem Kameltief EMA.
    • Der vorherige MACD-Hauptwert liegt unter Null und unterhalb der Signallinie.
    • Der vorherige CCI-Wert liegt unter dem negativen Schwellenwert.
    • Gleiche flache Positions- und Abklingbedingungen wie bei langen Setups.
  4. Ausgänge
    • Long-Positionen werden geschlossen, wenn der vorherige MACD-Hauptwert die Signallinie unterschreitet oder wenn der vorherige CCI Der Wert fällt unter den positiven Schwellenwert.
    • Short-Positionen werden geschlossen, wenn der vorherige MACD-Hauptwert die Signallinie überschreitet.
    • Nach jedem Austritt wird vor neuen Eintritten eine Abklingzeit von einer Kerzendauer erzwungen.

Die Strategie handelt höchstens einmal pro Balken, da jede Entscheidung auf Daten der zuvor abgeschlossenen Kerze basiert.

Parameter

Parameter Beschreibung Standard
CandleType Kerzendatentyp/Zeitrahmen, der für alle Indikatoren verwendet wird. 1-stündiger Zeitrahmen
CamelLength Länge des Hoch-/Tief-EMA-Kanals. 34
CciPeriod Länge des CCI-Filters. 20
MacdFastPeriod Schnelle EMA-Länge für MACD. 12
MacdSlowPeriod Langsame EMA-Länge für MACD. 26
MacdSignalPeriod Signalglättungszeitraum für MACD. 9
CciThreshold Absoluter CCI-Pegel, der für Einträge überschritten werden muss (symmetrisch angewendet). 100

Alle Parameter sind dank der SetOptimize-Aufrufe durch den StockSharp-Optimierer optimierbar.

Risikomanagement

  • Bestellungen werden über BuyMarket und SellMarket gesendet, wobei die Strategieeigenschaft Volume geerbt wird.
  • StartProtection() ist aktiviert, um standardmäßige StockSharp-Schutzhelfer zu initialisieren.
  • Im ursprünglichen Algorithmus ist kein fester Stop-Loss oder Take-Profit definiert; Exits basieren ausschließlich auf Indikatorsignalen.

Diagramme

Die Strategie zeichnet automatisch die Kamel-Indikatoren EMA-Kanal, MACD und CCI zusammen mit eigenen Trades auf. Dies repliziert die visuellen Hinweise, die in der MT4-Implementierung verwendet wurden.

Notizen

  • Der Abklingzeit-Timer verwendet die von CandleType.Arg abgeleitete Kerzendauer. Stellen Sie sicher, dass CandleType ein enthält TimeSpan-Argument, wenn Sie den Zeitrahmen ändern.
  • Da alle Entscheidungen auf den Werten des vorherigen Balkens basieren, spiegelt die Reihenfolge der Operationen die iMACD, iCCI wider. und iMA (mit Shift=1) ruft in der Quelle EA auf.
namespace StockSharp.Samples.Strategies;

using System;
using System.Collections.Generic;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

/// <summary>
/// Strategy combining CCI and MACD signal crossover with EMA trend filter.
/// Buy when MACD crosses above signal with CCI positive and price above EMA.
/// Sell when MACD crosses below signal with CCI negative and price below EMA.
/// </summary>
public class SmcTraderCamelCciMacd1Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _macdFastPeriod;
	private readonly StrategyParam<int> _macdSlowPeriod;
	private readonly StrategyParam<int> _macdSignalPeriod;
	private readonly StrategyParam<int> _cciPeriod;

	private decimal? _prevMacdMain;
	private decimal? _prevMacdSignal;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
	public int MacdFastPeriod { get => _macdFastPeriod.Value; set => _macdFastPeriod.Value = value; }
	public int MacdSlowPeriod { get => _macdSlowPeriod.Value; set => _macdSlowPeriod.Value = value; }
	public int MacdSignalPeriod { get => _macdSignalPeriod.Value; set => _macdSignalPeriod.Value = value; }
	public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }

	public SmcTraderCamelCciMacd1Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");

		_emaLength = Param(nameof(EmaLength), 34)
			.SetDisplay("EMA Length", "Trend EMA period", "Indicators");

		_macdFastPeriod = Param(nameof(MacdFastPeriod), 12)
			.SetDisplay("MACD Fast", "Fast EMA for MACD", "Indicators");

		_macdSlowPeriod = Param(nameof(MacdSlowPeriod), 26)
			.SetDisplay("MACD Slow", "Slow EMA for MACD", "Indicators");

		_macdSignalPeriod = Param(nameof(MacdSignalPeriod), 9)
			.SetDisplay("MACD Signal", "Signal line period", "Indicators");

		_cciPeriod = Param(nameof(CciPeriod), 20)
			.SetDisplay("CCI Period", "CCI period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevMacdMain = null;
		_prevMacdSignal = null;
	}

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

		_prevMacdMain = null;
		_prevMacdSignal = null;

		var ema = new ExponentialMovingAverage { Length = EmaLength };
		var macd = new MovingAverageConvergenceDivergenceSignal
		{
			Macd =
			{
				ShortMa = { Length = MacdFastPeriod },
				LongMa = { Length = MacdSlowPeriod }
			},
			SignalMa = { Length = MacdSignalPeriod }
		};
		var cci = new CommodityChannelIndex { Length = CciPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(macd, cci, ema, ProcessCandle)
			.Start();
	}

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

		if (!macdValue.IsFinal || !cciValue.IsFinal || !emaValue.IsFinal)
			return;

		if (macdValue is not MovingAverageConvergenceDivergenceSignalValue macdData)
			return;

		if (macdData.Macd is not decimal macdMain || macdData.Signal is not decimal macdSignal)
			return;

		var cci = cciValue.ToDecimal();
		var emaVal = emaValue.ToDecimal();

		if (_prevMacdMain is not decimal prevMain || _prevMacdSignal is not decimal prevSignal)
		{
			_prevMacdMain = macdMain;
			_prevMacdSignal = macdSignal;
			return;
		}

		var macdBullCross = prevMain <= prevSignal && macdMain > macdSignal;
		var macdBearCross = prevMain >= prevSignal && macdMain < macdSignal;

		// Long: MACD bullish cross + CCI > 0 + price above EMA
		if (Position <= 0 && macdBullCross && cci > 0 && candle.ClosePrice > emaVal)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Short: MACD bearish cross + CCI < 0 + price below EMA
		else if (Position >= 0 && macdBearCross && cci < 0 && candle.ClosePrice < emaVal)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevMacdMain = macdMain;
		_prevMacdSignal = macdSignal;
	}
}