Auf GitHub ansehen

LCS MACD Händlerstrategie

Diese Strategie ist eine StockSharp-Portierung des Expertenberaters „LCS-MACD-Trader“ MetaTrader 4. Es handelt mit MACD-Überkreuzungen, die unterhalb/über der Nulllinie auftreten, und erfordert optional eine Bestätigung vom Stochastic-Oszillator. Die Logik spiegelt auch die ursprünglichen Tageszeitfilter und die Trailing-Stop/Break-Even-Verwaltung im MetaTrader-Stil wider.

Wie es funktioniert

  • Long-Einträge werden ausgelöst, wenn die MACD-Linie ihre Signallinie überschreitet, während beide unter Null bleiben. Wenn der stochastische Filter aktiviert ist, muss die %D-Linie innerhalb des angegebenen Lookbacks über %K gelegen haben und die aktuelle Kerze muss anzeigen, dass %D wieder unter %K fällt.
  • Short-Einträge werden ausgelöst, wenn die MACD-Linie ihre Signallinie unterschreitet, während beide über Null bleiben. Bei aktiviertem stochastischen Filter muss die %D-Linie kürzlich unter %K gelegen haben und steigt nun wieder darüber an.
  • Der Handel ist nur innerhalb von drei konfigurierbaren Intraday-Fenstern zulässig, die die EA-Einstellungen replizieren.
  • Take-Profit-, Stop-Loss-, Break-Even- und Trailing-Stop-Abstände werden in Pips ausgedrückt und anhand der Punktgröße des Instruments umgerechnet.
  • Es wird nur eine Nettoposition pro Richtung gepflegt (StockSharp Netting). Positionsstapelung ist bis zu MaxOrders Losen zulässig; Gegensignale warten, bis die aktuelle Nettoposition durch das Risikomanagement geschlossen wird.

Parameter

Name Beschreibung Standard
CandleType Für Indikatorberechnungen verwendete Kerzenserien. 15-minütiger Zeitrahmen
FastEmaPeriod Schnelle EMA-Periode im MACD. 12
SlowEmaPeriod Langsamer EMA Zeitraum im MACD. 26
SignalPeriod Signalleitungsperiode im MACD. 9
UseStochasticFilter Erfordern eine stochastische Bestätigung vor der Eingabe. wahr
BarsToCheckStochastic Maximal geschlossene Balken seit der entgegengesetzten stochastischen Beziehung. 5
StochasticKPeriod Lookback-Länge von %K. 5
StochasticDPeriod Glättungslänge von %D. 3
StochasticSlowing Zusätzliche Glättung auf %K angewendet. 3
TradeVolume Pro Eintrag verwendete Losgröße. 0,1
TakeProfitPips Take-Profit-Distanz in Pips. 100
StopLossPips Stop-Loss-Distanz in Pips. 100
MaxOrders Maximale gestapelte Einträge pro Richtung. 5
EnableTrailing Aktivieren Sie die Trailing-Stop-Logik im MetaTrader-Stil. falsch
TrailingActivationPips Vor Beginn des Trailings ist ein Gewinn erforderlich. 50
TrailingDistancePips Vom Trailing Stop aufrechterhaltener Abstand. 25
BreakEvenActivationPips Erforderlicher Gewinn, um den Stop auf die Gewinnschwelle zu bringen. 25
BreakEvenOffsetPips Beim Platzieren des Break-Even-Stopps werden zusätzliche Pips hinzugefügt. 1
Session1Start/End, Session2Start/End, Session3Start/End Intraday-Handelsfenster. 08:15-08:35, 13:45-14:42, 22:15-22:45

Notizen

  • Die Strategie geht von einem Netting-Konto aus. Es schließt bestehende Positionen über die konfigurierten Risikoregeln, anstatt gegenläufige Aufträge wie die ursprüngliche MT4-Version abzusichern.
  • Bei der Pip-Konvertierung wird die Punktgröße des Instruments verwendet. Bei 5-stelligen FX-Symbolen skaliert die Logik die Pip-Werte automatisch um 10, um der Multiplikatoreinstellung EA zu entsprechen.
  • Die Trailing-Stop- und Break-Even-Logik wird an fertigen Kerzen ausgewertet und verwendet das Hoch/Tief jedes Balkens, um tickbasiertes MetaTrader-Verhalten zu emulieren.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// LCS MACD Trader: MACD zero-line cross with RSI filter and ATR stops.
/// </summary>
public class LcsMacdTraderStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastEmaLength;
	private readonly StrategyParam<int> _slowEmaLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevMacd;
	private decimal _entryPrice;

	public LcsMacdTraderStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_fastEmaLength = Param(nameof(FastEmaLength), 12)
			.SetDisplay("Fast EMA", "Fast EMA period.", "Indicators");

		_slowEmaLength = Param(nameof(SlowEmaLength), 26)
			.SetDisplay("Slow EMA", "Slow EMA period.", "Indicators");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

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

	public int FastEmaLength
	{
		get => _fastEmaLength.Value;
		set => _fastEmaLength.Value = value;
	}

	public int SlowEmaLength
	{
		get => _slowEmaLength.Value;
		set => _slowEmaLength.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

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

		_prevMacd = 0;
		_entryPrice = 0;
	}

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

		_prevMacd = 0;
		_entryPrice = 0;

		var fastEma = new ExponentialMovingAverage { Length = FastEmaLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, rsi, atr, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal, decimal rsiVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var macd = fastVal - slowVal;

		if (_prevMacd == 0 || atrVal <= 0)
		{
			_prevMacd = macd;
			return;
		}

		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || macd < 0)
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || macd > 0)
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		if (Position == 0)
		{
			if (macd > 0 && _prevMacd <= 0 && rsiVal > 45)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (macd < 0 && _prevMacd >= 0 && rsiVal < 55)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevMacd = macd;
	}
}