Auf GitHub ansehen

XDPO Kerzen-Strategie

Diese Strategie ist eine Konvertierung des originalen MQL5-Expertenberaters Exp_XDPOCandle. Sie erstellt synthetische Kerzen, indem zwei aufeinanderfolgende exponentielle gleitende Durchschnitte auf die Eröffnungs- und Schlusskurse angewendet werden. Die Farbe der resultierenden Kerze (bullish, bearish oder neutral) bestimmt die Handelsentscheidungen.

Strategielogik

  1. Jede eingehende Marktkerze wird zweimal geglättet:
    • Die erste Glättung verwendet eine EMA der Länge FastLength.
    • Die zweite Glättung wendet eine weitere EMA der Länge SlowLength auf das Ergebnis der ersten an.
  2. Wenn der geglättete Schlusskurs über dem geglätteten Eröffnungskurs liegt, gilt die Kerze als bullish.
  3. Wenn der geglättete Schlusskurs unter dem geglätteten Eröffnungskurs liegt, gilt die Kerze als bearish.
  4. Die Strategie eröffnet eine Long-Position, wenn eine bullische Kerze nach einer nicht-bullischen erscheint. Sie eröffnet eine Short-Position, wenn eine bearische Kerze nach einer nicht-bearischen erscheint.
  5. Bestehende entgegengesetzte Positionen werden automatisch durch Umkehrung über Marktorders geschlossen.

Parameter

Name Beschreibung
FastLength Länge der ersten EMA, die auf die Preise angewendet wird.
SlowLength Länge der zweiten EMA, die auf das Ergebnis der ersten EMA angewendet wird.
CandleType Der Zeitrahmen und Kerzentyp für die Berechnung.

Verwendung

  1. Verbinden Sie die Strategie mit einem Instrument in der StockSharp-Umgebung.
  2. Konfigurieren Sie die Parameter bei Bedarf. Standardwerte sind auf die Originaleinstellungen des Experten abgestimmt.
  3. Starten Sie die Strategie. Sie abonniert den angegebenen Kerzentyp und handelt bei Farbwechseln der geglätteten Kerzen.

Hinweise

  • Das Risikomanagement wird durch StartProtection() mit Standardeinstellungen gehandhabt. Passen Sie Volume und Schutzparameter extern nach Bedarf an.
  • Dieses Repository enthält derzeit nur die C#-Version; der Python-Port ist nicht verfügbar.
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;



/// <summary>
/// XDPO candle strategy that trades on color changes of double smoothed candles.
/// </summary>
public class XdpoCandleStrategy : Strategy
{
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _emaOpen1;
	private decimal? _emaOpen2;
	private decimal? _emaClose1;
	private decimal? _emaClose2;
	private int? _previousColor;

	/// <summary>
	/// Length of the first exponential moving average.
	/// </summary>
	public int FastLength
	{
		get => _fastLength.Value;
		set => _fastLength.Value = value;
	}

	/// <summary>
	/// Length of the second exponential moving average.
	/// </summary>
	public int SlowLength
	{
		get => _slowLength.Value;
		set => _slowLength.Value = value;
	}

	/// <summary>
	/// Candle type used for calculations.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Initializes a new instance of <see cref="XdpoCandleStrategy"/>.
	/// </summary>
	public XdpoCandleStrategy()
	{
		_fastLength = Param(nameof(FastLength), 12)
			.SetGreaterThanZero()
			.SetDisplay("Fast Length", "Length of the first EMA", "Parameters")
			;

		_slowLength = Param(nameof(SlowLength), 5)
			.SetGreaterThanZero()
			.SetDisplay("Slow Length", "Length of the second EMA", "Parameters")
			;

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

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

		_emaOpen1 = _emaOpen2 = _emaClose1 = _emaClose2 = null;
		_previousColor = null;
	}

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

		var warmup = new StockSharp.Algo.Indicators.ExponentialMovingAverage { Length = FastLength };
		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(warmup, ProcessCandle)
			.Start();

	}

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

		var open1 = CalcEma(candle.OpenPrice, ref _emaOpen1, FastLength);
		var open2 = CalcEma(open1, ref _emaOpen2, SlowLength);
		var close1 = CalcEma(candle.ClosePrice, ref _emaClose1, FastLength);
		var close2 = CalcEma(close1, ref _emaClose2, SlowLength);

		var color = open2 < close2 ? 2 : open2 > close2 ? 0 : 1;
		var goLong = color == 2 && _previousColor != 2;
		var goShort = color == 0 && _previousColor != 0;

		if (IsFormedAndOnlineAndAllowTrading())
		{
			if (goLong && Position <= 0)
				BuyMarket();
			else if (goShort && Position >= 0)
				SellMarket();
		}

		_previousColor = color;
	}

	private static decimal CalcEma(decimal price, ref decimal? prev, int length)
	{
		var k = 2m / (length + 1m);
		var result = prev.HasValue ? price * k + prev.Value * (1m - k) : price;
		prev = result;
		return result;
	}
}