Auf GitHub ansehen

Divergenz MACD Stochastic Strategie

Diese Strategie erstellt den MetaTrader 5 Expert Advisor "Divergence EA pip sl tp" im StockSharp-Framework neu. Der Algorithmus sucht nach klassischen Abweichungen zwischen der Preisbewegung und dem MACD-Histogramm und validiert das Signal dann mit einem überkauften/überverkauften Stochastic-Oszillatorfilter, bevor er Umkehrgeschäfte eröffnet.

Handelslogik

  1. Abonnieren Sie die durch den Parameter CandleType ausgewählten primären Zeitrahmenkerzen.
  2. Berechnen Sie das MACD-Histogramm (MACD line - Signal line) und die Stochastic %K/%D-Werte für jede fertige Kerze.
  3. Verfolgen Sie die letzten beiden Swing-Hochs und -Tiefs der Preis- und Histogrammwerte.
  4. Bearische Divergenz: Ein neues höheres Preishoch, begleitet von einem niedrigeren MACD-Histogramm-Höhepunkt und Stochastic %K über StochasticUpperLevel, löst eine Short-Position aus oder kehrt eine bestehende Long-Position um.
  5. Bulnische Divergenz: Ein neues niedrigeres Preistief mit einem höheren MACD-Histogrammtief und %K unter StochasticLowerLevel eröffnet oder kehrt sich in eine Long-Position um.
  6. Optionale Schutzmaßnahmen TakeProfitSteps und StopLossSteps werden in StockSharp Schritteinheiten umgewandelt und einmalig aktiviert, wenn die Strategie startet.

Hinweise zur Implementierung

  • Gebaut mit StockSharp High-Level-API unter Verwendung eines einzelnen Kerzenabonnements, das an die Indikatoren MovingAverageConvergenceDivergenceSignal und StochasticOscillator gebunden ist.
  • Behält den Divergenzstatus bei, ohne Indikator-GetValue-Helfer aufzurufen, und entspricht den Konvertierungsrichtlinien.
  • Die Diagrammintegration zeigt Preiskerzen, MACD- und Stochastic-Linien an, wenn ein Diagrammbereich verfügbar ist.
  • Positionen werden umgekehrt, indem die absolute aktuelle Positionsgröße zur Basis Volume addiert wird, wodurch sofortige Richtungsänderungen nach bestätigten Divergenzen sichergestellt werden.

Parameter

Parameter Beschreibung Standard
CandleType Für Divergenzberechnungen verwendeter Zeitrahmen. 1-Stunden-Kerzen
MacdFastLength, MacdSlowLength, MacdSignalLength MACD EMA Längen, die die ursprünglichen EA-Eingaben replizieren. 26.12.9
MacdDivergenceThreshold Minimale Histogrammdifferenz zwischen aufeinanderfolgenden Schwankungen, die zur Bestätigung der Divergenz erforderlich ist. 0,0005
StochasticLength Schnelle %K-Periode des Stochastic-Oszillators. 50
StochasticSlowK, StochasticSlowD Zusätzliche %K/%D-Glättungslängen, die die EA-Konfiguration widerspiegeln. 9 / 9
StochasticUpperLevel, StochasticLowerLevel Überkauft- und Überverkauft-Filter zur Validierung bärischer/bullischer Setups. 80/20
TakeProfitSteps, StopLossSteps Optionale Schutzabstände, ausgedrückt in Preisschritten (0 deaktiviert die Stufe). 50

Nutzung

  1. Hängen Sie die Strategie an einen StockSharp-Connector mit einem Wertpapier an, das den ausgewählten Zeitrahmen unterstützt.
  2. Konfigurieren Sie die Positionsgröße über die Basiseigenschaft Volume und passen Sie die Indikatoreinstellungen nach Bedarf an.
  3. Starten Sie die Strategie – Aufträge werden automatisch generiert, wenn die Divergenz- und Stochastic-Bedingungen erfüllt sind.
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Simplified from "Divergence MACD Stochastic" MetaTrader expert.
/// Uses MACD histogram divergence (price vs histogram) with RSI confirmation.
/// MACD is computed manually from two EMAs.
/// </summary>
public class DivergenceMacdStochasticStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _macdFast;
	private readonly StrategyParam<int> _macdSlow;
	private readonly StrategyParam<int> _rsiPeriod;

	// Manual EMA for MACD
	private decimal _fastEma;
	private decimal _slowEma;
	private bool _emaInitialized;
	private int _barCount;
	private decimal _fastMultiplier;
	private decimal _slowMultiplier;

	private readonly decimal[] _macdWindow = new decimal[DivergenceLookback];
	private readonly decimal[] _priceWindow = new decimal[DivergenceLookback];
	private int _windowCount;
	private int _windowIndex;
	private const int DivergenceLookback = 10;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int MacdFast
	{
		get => _macdFast.Value;
		set => _macdFast.Value = value;
	}

	public int MacdSlow
	{
		get => _macdSlow.Value;
		set => _macdSlow.Value = value;
	}

	public int RsiPeriod
	{
		get => _rsiPeriod.Value;
		set => _rsiPeriod.Value = value;
	}

	public DivergenceMacdStochasticStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for divergence detection", "General");

		_macdFast = Param(nameof(MacdFast), 20)
			.SetGreaterThanZero()
			.SetDisplay("MACD Fast", "Fast EMA length", "Indicators");

		_macdSlow = Param(nameof(MacdSlow), 50)
			.SetGreaterThanZero()
			.SetDisplay("MACD Slow", "Slow EMA length", "Indicators");

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period for confirmation", "Indicators");
	}

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

		_windowCount = 0;
		_windowIndex = 0;
		_emaInitialized = false;
		_barCount = 0;
		_fastMultiplier = 2m / (MacdFast + 1);
		_slowMultiplier = 2m / (MacdSlow + 1);

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawOwnTrades(area);
		}
	}

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

		var close = candle.ClosePrice;
		_barCount++;

		// Manual EMA computation
		if (!_emaInitialized)
		{
			_fastEma = close;
			_slowEma = close;
			_emaInitialized = true;
		}
		else
		{
			_fastEma = close * _fastMultiplier + _fastEma * (1 - _fastMultiplier);
			_slowEma = close * _slowMultiplier + _slowEma * (1 - _slowMultiplier);
		}

		if (_barCount < MacdSlow)
			return;

		var macdLine = _fastEma - _slowEma;

		_macdWindow[_windowIndex] = macdLine;
		_priceWindow[_windowIndex] = close;
		_windowIndex = (_windowIndex + 1) % DivergenceLookback;
		if (_windowCount < DivergenceLookback)
			_windowCount++;

		if (_windowCount < DivergenceLookback)
			return;

		var volume = Volume;
		if (volume <= 0)
			volume = 1;

		var oldestIndex = _windowIndex;
		var newestIndex = (_windowIndex + DivergenceLookback - 1) % DivergenceLookback;
		var oldMacd = _macdWindow[oldestIndex];
		var newMacd = _macdWindow[newestIndex];
		var oldPrice = _priceWindow[oldestIndex];
		var newPrice = _priceWindow[newestIndex];

		var minPriceMove = oldPrice * 0.005m;
		// Bullish divergence: price makes lower low but MACD makes higher low.
		var bullishDiv = newPrice < oldPrice - minPriceMove && newMacd > oldMacd;
		// Bearish divergence: price makes higher high but MACD makes lower high.
		var bearishDiv = newPrice > oldPrice + minPriceMove && newMacd < oldMacd;

		if (bullishDiv)
		{
			if (Position <= 0)
				BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
		}
		else if (bearishDiv)
		{
			if (Position >= 0)
				SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
		}
	}

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

		_fastEma = 0;
		_slowEma = 0;
		_emaInitialized = false;
		_barCount = 0;
		_fastMultiplier = 0;
		_slowMultiplier = 0;
		Array.Clear(_macdWindow, 0, _macdWindow.Length);
		Array.Clear(_priceWindow, 0, _priceWindow.Length);
		_windowCount = 0;
		_windowIndex = 0;
	}
}