Auf GitHub ansehen

X-Bug-Strategie

Überblick

Die X-Bug-Strategie ist ein gleitendes Durchschnitts-Crossover-System, das vom gleichnamigen Expert Advisor MQL4 übernommen wurde. Es vergleicht zwei einfache gleitende Durchschnitte, die auf der Grundlage des mittleren Kerzenpreises berechnet wurden. Wenn der schnelle Durchschnitt den langsamen Durchschnitt über- oder unterschreitet, eröffnet die Strategie eine Position in Richtung des Crossovers. Die Implementierung reproduziert die ursprünglichen Expert Advisor-Funktionen, einschließlich optionaler Signalumkehr, automatischer Positionsschließung bei entgegengesetzten Signalen und Pip-basierten Schutzaufträgen.

Handelslogik

  1. Abonnieren Sie den konfigurierten Kerzentyp (standardmäßig Ein-Minuten-Kerzen) und berechnen Sie zwei einfache gleitende Durchschnitte: eine schnelle Linie und eine langsame Linie. Die Durchschnittswerte verwenden den Medianpreis und respektieren die konfigurierten Indikatorverschiebungen.
  2. Erkennen Sie einen bullischen Crossover, wenn der aktuelle schnelle Wert über dem langsamen Wert liegt, während der schnelle Wert zwei Balken zuvor unter dem langsamen Wert lag. Erkennen Sie einen bearischen Crossover anhand der gegenteiligen Bedingung.
  3. Invertieren Sie optional das Crossover-Signal, wenn ReverseSignals aktiviert ist, um in die entgegengesetzte Richtung zu handeln.
  4. Wenn CloseOnSignal aktiviert ist, schließen Sie sofort jede gegnerische Position, bevor Sie bei dem neuen Signal eine neue eingeben.
  5. Gehen Sie Long-Positionen bei bullischen Signalen und Short-Positionen bei bärischen Signalen ein. Die Strategie vermeidet das Stapeln von Positionen in die gleiche Richtung; Es wird nur gehandelt, wenn die aktuelle Position flach ist oder mit dem Signal übereinstimmt.

Risikomanagement

  • StopLossPips – legt einen absoluten Schutzstopp in Pips fest. Der Stop wird in ganzen Pips ausgedrückt; Bruchpreise (5- oder 3-stellige Kurse) werden automatisch durch Umrechnung des Pip-Werts mithilfe der Wertpapierpreisstufe gehandhabt.
  • TakeProfitPips – konfiguriert die Gewinnzieldistanz in Pips.
  • TrailingStopPips – wenn UseTrailingStop aktiviert ist, wird ein Trailing Stop aktiviert, der bei der konfigurierten Pip-Distanz beginnt, sobald die Position in den Gewinnbereich übergeht. Der nachgestellte Schritt entspricht der nachgestellten Distanz und repliziert die ursprüngliche MetaTrader-Logik.
  • Alle Schutzanordnungen werden über StartProtection mit Marktaustritten verwaltet, um die Parität mit dem MQL4-Experten aufrechtzuerhalten.

Parameter

Parameter Beschreibung Standard
OrderVolume Basishandelsvolumen, das für Markteintritte verwendet wird. 0.1
StopLossPips Stop-Loss-Distanz, gemessen in Pips; zum Deaktivieren auf 0 setzen. 70
TakeProfitPips Take-Profit-Distanz, gemessen in Pips; zum Deaktivieren auf 0 setzen. 5000
UseTrailingStop Aktiviert oder deaktiviert die Trailing-Stop-Verwaltung. true
TrailingStopPips Nachlaufdistanz in Pips. 90
FastPeriod Periode des schnellen gleitenden Durchschnitts. 1
FastShift Balken zur Verschiebung des sich schnell bewegenden Durchschnitts vor der Auswertung von Signalen. 0
SlowPeriod Periode des langsamen gleitenden Durchschnitts. 14
SlowShift Balken zur Verschiebung des langsam gleitenden Durchschnitts vor der Auswertung von Signalen. 10
CloseOnSignal Schließen Sie eine gegnerische Position sofort, wenn ein neues Signal erscheint. true
ReverseSignals Kehren Sie die Signalrichtung um, um entgegen der Kreuzung zu handeln. false
AppliedPrice Den gleitenden Durchschnitten zugeführte Kerzenpreisquelle. Median
CandleType Kerzendatentyp zur Signalgenerierung. 1 minute Zeitrahmen

Notizen

  • Die Pip-Umrechnung multipliziert den Preisschritt mit 10 für Symbole, die mit 5 oder 3 Dezimalstellen angegeben werden, was dem ursprünglichen Verhalten des Expert Advisors entspricht.
  • Es wird kein Python-Port bereitgestellt. In diesem Verzeichnis ist nur die C#-Strategie enthalten.
  • Trailing Stops, Stopps und Ziele sind optional. Setzen Sie die entsprechenden Pip-Werte auf Null, um sie zu deaktivieren.
namespace StockSharp.Samples.Strategies;

using System;
using System.Collections.Generic;

using Ecng.Common;

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

/// <summary>
/// Moving average crossover strategy converted from the MQL4 expert "X bug".
/// Uses fast and slow SMA crossover for signal generation.
/// </summary>
public class XBugStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<bool> _reverseSignals;
	private readonly StrategyParam<DataType> _candleType;

	private SimpleMovingAverage _slowMa;
	private decimal? _prevFast;
	private decimal? _prevSlow;
	private int _cooldown;
	private int _candleCount;

	public XBugStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Fast MA period", "Length of the fast moving average.", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Slow MA period", "Length of the slow moving average.", "Indicators");

		_reverseSignals = Param(nameof(ReverseSignals), false)
			.SetDisplay("Reverse signals", "Invert buy and sell directions.", "Trading");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle type", "Primary timeframe used for signals.", "General");
	}

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

	public bool ReverseSignals
	{
		get => _reverseSignals.Value;
		set => _reverseSignals.Value = value;
	}

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

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnReseted()
	{
		base.OnReseted();
		_slowMa = default;
		_prevFast = null;
		_prevSlow = null;
		_cooldown = 0;
		_candleCount = 0;
	}

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

		Volume = 0.001m;
		_prevFast = null;
		_prevSlow = null;
		_cooldown = 0;
		_candleCount = 0;

		_slowMa = new SimpleMovingAverage { Length = SlowPeriod };

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

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

		if (!_slowMa.IsFormed)
			return;

		_candleCount++;
		if (_cooldown > 0)
		{
			_cooldown--;
			return;
		}

		// Use close price as the "fast" value (period=1 effectively)
		var fastValue = candle.ClosePrice;

		if (_prevFast is null || _prevSlow is null)
		{
			_prevFast = fastValue;
			_prevSlow = slowValue;
			return;
		}

		var signal = 0;
		if (fastValue > slowValue && _prevFast.Value <= _prevSlow.Value)
			signal = 1;
		else if (fastValue < slowValue && _prevFast.Value >= _prevSlow.Value)
			signal = -1;

		_prevFast = fastValue;
		_prevSlow = slowValue;

		if (signal == 0)
			return;

		if (ReverseSignals)
			signal = -signal;

		if (signal > 0 && Position <= 0)
		{
			BuyMarket();
			_cooldown = 100;
		}
		else if (signal < 0 && Position >= 0)
		{
			SellMarket();
			_cooldown = 100;
		}
	}
}