Die Strategie ist eine direkte Portierung des MetaTrader 4-Expertenberaters up3x1_Premium_2vM. Es handelt ein einzelnes Symbol und hält zu jedem Zeitpunkt höchstens eine Position offen. Die Einträge basieren auf einer Kombination aus geglätteten gleitenden Durchschnitten, starken Kerzenbereichen und einem täglichen Mitternachts-Breakout-Filter. Das Risiko wird durch feste Take-Profit- und Stop-Loss-Abstände gesteuert, die in Preispunkten ausgedrückt werden, während ein optionaler Trailing-Stop das Verhalten des ursprünglichen EA reproduziert, der die Stops kontinuierlich verschärft, sobald sich der Markt zugunsten der Position bewegt.
Wie es funktioniert
Der primäre Zeitrahmen ist konfigurierbar; Der EA verwendete ursprünglich den Diagrammzeitrahmen. Zwei geglättete gleitende Durchschnitte (SMMA) mit den Perioden 12 und 26 sind unter Verwendung des typischen Preises an das Kerzenabonnement gebunden.
Ein separater täglicher Kerzenstrom erstellt die D1-Daten neu, die von der MQL-Logik für den Mitternachts-Breakout-Filter und für den einfachen gleitenden 10-Perioden-Tagesdurchschnitt verwendet werden.
Im flachen Zustand wertet die Strategie die beiden vorherigen fertigen Kerzen und die zwischengespeicherten SMMA-Werte aus:
Long-Bias: Entweder kreuzt der schnelle SMMA den langsamen SMMA, während beide Eröffnungen steigen, oder die letzte Kerze zeigt einen bullischen Körper oberhalb der konfigurierten Bereichsschwellen, oder die letzte Tageskerze schließt bullisch nach einer großen Spanne. Der ursprüngliche EA verglich auch den täglichen SMA mit dem Briefkurs; Da die Bedingung immer als wahr ausgewertet wird, wird sie aus Kompatibilitätsgründen beibehalten.
Short-Bias: Symmetrische Bedingungen der Long-Regeln unter Verwendung rückläufiger Bereiche und Crossovers.
Wenn eine Long-Bedingung erfüllt ist, wird ein Marktkauf ausgegeben; andernfalls, wenn eine Short-Bedingung erfüllt ist, wird ein Marktverkauf platziert. Die angefragte Losgröße wird vor Abgabe der Bestellung auf die Sicherheitsvolumenstufe normiert.
Während eine Position offen ist, überwacht die Strategie die schnellen/langsamen SMMA-Werte der vorherigen Kerze. Wenn ihre absolute Differenz unter ConvergenceTolerance fällt, wird die Position geschlossen, wodurch die Gleichheitsprüfung im Fachberater reproduziert wird.
Das abschließende Modul verfolgt den durchschnittlichen Einstiegspreis. Sobald der Preis die Trailing-Distanz überschreitet, wird das Stop-Level erhöht, um die konfigurierte Lücke aufrechtzuerhalten. Durch Berühren dieser Ebene wird die Position sofort geschlossen, wodurch die wiederholten OrderModify-Anrufe von MQL nachgeahmt werden.
Parameter
Name
Standard
Beschreibung
CandleType
TimeFrame(1h)
Primärer Zeitrahmen für Einträge.
FastMaPeriod
12
Länge des schnellen geglätteten gleitenden Durchschnitts (typischer Preis).
SlowMaPeriod
26
Länge des langsam geglätteten gleitenden Durchschnitts (typischer Preis).
RangeThreshold
0.0060
Mindestkerzenbereich, der für den Impulsfilter erforderlich ist.
BodyThreshold
0.0050
Mindestgröße des Kerzenkörpers für die Bereichsbedingung.
DailyRangeThreshold
0.0060
Mindestabstand zwischen Öffnung und Schließung der letzten Tageskerze für den Mitternachts-Breakout-Filter.
TakeProfitPoints
150
Take-Profit-Distanz ausgedrückt in Preispunkten. Zum Deaktivieren auf 0 setzen.
StopLossPoints
100
Stop-Loss-Distanz, ausgedrückt in Preispunkten. Zum Deaktivieren auf 0 setzen.
TrailingStopPoints
10
Abstand zwischen Preis und Trailing Stop. Auf 0 setzen, um das Nachstellen zu deaktivieren.
TradeVolume
0.05
Für Marktaufträge verwendete Losgröße vor der Volumennormalisierung.
ConvergenceTolerance
0.00001
Maximale Differenz zwischen den SMMAs, die die Positionsauflösung auslöst.
Notizen
Die Strategie behält die ursprüngliche EA-Eigenart bei, bei der der tägliche SMA-Vergleich immer wahr ist und die Funktionsparität mit der MQL-Quelle garantiert.
Stop-Loss- und Take-Profit-Orders werden über StartProtection registriert und passen sich daher automatisch an die Schrittgröße des Brokers an, sofern verfügbar.
Die abschließende Logik erfordert sowohl einen positiven TrailingStopPoints-Wert als auch einen gültigen Security.PriceStep. Wenn eine der Informationen fehlt, wird der Stopp nicht nachgezogen.
Die Volumennormalisierung berücksichtigt die Austauschbeschränkungen (VolumeStep, VolumeMin, VolumeMax). Negative Werte für TradeVolume können verwendet werden, um eine prozentuale Größenanpassung zu emulieren, sobald benutzerdefinierte Logik hinzugefügt wird.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Up3x1Premium2VmStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
private int _cooldownRemaining;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Up3x1Premium2VmStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 20).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 80).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_cooldownCandles = Param(nameof(CooldownCandles), 100).SetDisplay("Cooldown", "Candles between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = default;
_prevSlow = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
_cooldownRemaining = 0;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevFast = fast;
_prevSlow = slow;
return;
}
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevFast = fast;
_prevSlow = slow;
}
}