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
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.
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.
Invertieren Sie optional das Crossover-Signal, wenn ReverseSignals aktiviert ist, um in die entgegengesetzte Richtung zu handeln.
Wenn CloseOnSignal aktiviert ist, schließen Sie sofort jede gegnerische Position, bevor Sie bei dem neuen Signal eine neue eingeben.
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;
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
from StockSharp.Algo.Indicators import SimpleMovingAverage
class x_bug_strategy(Strategy):
def __init__(self):
super(x_bug_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle type", "Primary timeframe used for signals.", "General")
self._fast_period = self.Param("FastPeriod", 5) \
.SetDisplay("Fast MA period", "Length of the fast moving average.", "Indicators")
self._slow_period = self.Param("SlowPeriod", 14) \
.SetDisplay("Slow MA period", "Length of the slow moving average.", "Indicators")
self._reverse_signals = self.Param("ReverseSignals", False) \
.SetDisplay("Reverse signals", "Invert buy and sell directions.", "Trading")
self._prev_fast = None
self._prev_slow = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
@property
def ReverseSignals(self):
return self._reverse_signals.Value
def OnStarted2(self, time):
super(x_bug_strategy, self).OnStarted2(time)
from System import Decimal
self.Volume = Decimal(0.001)
self._prev_fast = None
self._prev_slow = None
self._slow_ma = SimpleMovingAverage()
self._slow_ma.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._slow_ma, self.ProcessCandle).Start()
def ProcessCandle(self, candle, slow_val):
if candle.State != CandleStates.Finished:
return
if not self._slow_ma.IsFormed:
return
from System import Decimal
sv = Decimal(float(slow_val))
fast_value = candle.ClosePrice
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fast_value
self._prev_slow = sv
return
signal = 0
if fast_value > sv and self._prev_fast <= self._prev_slow:
signal = 1
elif fast_value < sv and self._prev_fast >= self._prev_slow:
signal = -1
self._prev_fast = fast_value
self._prev_slow = sv
if signal == 0:
return
if self.ReverseSignals:
signal = -signal
if signal > 0 and self.Position <= 0:
self.BuyMarket()
elif signal < 0 and self.Position >= 0:
self.SellMarket()
def OnReseted(self):
super(x_bug_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def CreateClone(self):
return x_bug_strategy()