Diese Strategie repliziert den MetaTrader Experten „Expert Advisor spezifischer Tag und Uhrzeit“.
Es platziert Kauf- und/oder Verkaufsaufträge zu einem geplanten Zeitstempel und entfernt optional jedes Engagement zu einem anderen Zeitstempel.
Die StockSharp-Version behält das ursprüngliche Risikomanagementverhalten bei, einschließlich optionaler Trailing Stops und Break-Even-Bewegungen.
Kernlogik
Planung
OpenTime – Zeitpunkt, an dem Bestellungen erstellt werden.
CloseTime – Zeitpunkt, an dem Positionen abgeflacht werden und ausstehende Aufträge entfernt werden können.
Beide Prüfungen akzeptieren ein Ein-Minuten-Fenster, das dem im MT4-Code verwendeten TimeToString(..., TIME_MINUTES)-Vergleich entspricht.
Auftragserteilung
OrderPlacement wählt zwischen Markt-, Stop- oder Limit-Orders.
OpenBuyOrders / OpenSellOrders aktivieren Sie die gewünschten Richtungen.
OrderDistancePoints gleicht den Preis ausstehender Aufträge um eine Anzahl von Punkten (Pips) aus.
PendingExpireMinutes storniert ausstehende Orders automatisch, wenn ihr Gültigkeitsfenster endet.
Volumenverwaltung
LotSizing = Manual sendet das feste ManualVolume.
LotSizing = Automatic berechnet das Volumen aus dem aktuellen Portfoliowert und der Vertragsgröße des Instruments:
volume = (portfolio / contractSize) * RiskFactor.
Das Ergebnis wird an Security.VolumeStep ausgerichtet und zwischen MinVolume/MaxVolume eingeklemmt, sofern verfügbar.
Schutzlogik
StopLossPoints und TakeProfitPoints übersetzen die ursprünglichen punktbasierten Distanzen mithilfe der Pip-Größe des Instruments in absolute Preise.
TrailingStopEnabled + TrailingStepPoints und BreakEvenEnabled verschieben den Schutzstopp genau wie das MQL-Skript, wobei Bid/Ask-Aktualisierungen als Auslöser verwendet werden.
Wenn Stop-Loss- oder Take-Profit-Bedingungen erreicht werden, wird die Position mit einer Marktorder geschlossen, was das MT4-Verhalten widerspiegelt, bei dem Stops auf einen neuen Preis geändert werden.
Abschlussphase
Wenn CloseOwnOrders oder CloseAllOrders aktiviert ist, verlässt die Strategie jede offene Position im Schließfenster.
DeletePendingOrders entfernt gleichzeitig alle verbleibenden ausstehenden Bestellungen.
Parameter
Name
Beschreibung
OpenTime, CloseTime
UTC-Zeitstempel für den Markteintritt und -austritt.
OrderPlacement
Markt-, Stop- oder Limit-Auftragserteilung.
OpenBuyOrders, OpenSellOrders
Anweisungen zur Aktivierung.
TakeProfitPoints, StopLossPoints
Schutzabstände ausgedrückt in Punkten (0 deaktiviert).
TrailingStopEnabled, TrailingStepPoints
Aktivieren Sie den Trailing Stop und legen Sie den Mindestvorschub fest, bevor Sie ihn verschieben.
BreakEvenEnabled, BreakEvenAfterPoints
Verschieben Sie den Stop auf die Gewinnschwelle, sobald der Gewinn den Schwellenwert überschreitet.
OrderDistancePoints
Offset, der für ausstehende Orders verwendet wird.
Steuern Sie, wie Positionen und ausstehende Aufträge am Ende geschlossen werden.
Notizen
Die Klasse befindet sich im Namespace StockSharp.Samples.Strategies mit Tabulatoreinzug, wie in den Projektrichtlinien erforderlich.
Level1-Daten werden verwendet, um die Gebots-/Brief-sensitive Logik aus der MQL-Version (Trailing Stop, ausstehende Auftragserteilung) zu reproduzieren.
MagicNumber-Einstellungen von MT4 sind nicht erforderlich, da StockSharp bereits Strategieaufträge isoliert.
Nutzung
Kompilieren Sie das Projekt über AlgoTrading.sln und hängen Sie die Strategie an ein Wertpapier-/Portfoliopaar an.
Passen Sie den Zeitplan, die Auftragsart und die Risikoparameter nach Bedarf an.
Starten Sie die Strategie vor OpenTime; Bestellungen werden automatisch versendet, sobald das Fenster beginnt.
Lassen Sie die Strategie bis nach CloseTime laufen, wenn Sie möchten, dass der automatische Reduzierungsschritt ausgelöst wird.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Specific Day Time strategy: SMA crossover with time filter.
/// Trades only during specific hours, using fast/slow SMA crossover.
/// </summary>
public class SpecificDayTimeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _tradeHour;
private readonly StrategyParam<int> _cooldownBars;
private int _cooldown;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int TradeHour { get => _tradeHour.Value; set => _tradeHour.Value = value; }
public int CooldownBars { get => _cooldownBars.Value; set => _cooldownBars.Value = value; }
public SpecificDayTimeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 8)
.SetGreaterThanZero()
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
_tradeHour = Param(nameof(TradeHour), 12)
.SetDisplay("Trade Hour", "Hour when entries are allowed", "Trading")
.SetRange(0, 23);
_cooldownBars = Param(nameof(CooldownBars), 8)
.SetGreaterThanZero()
.SetDisplay("Cooldown Bars", "Bars to wait between orders", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_cooldown = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_cooldown = 0;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished) return;
if (_cooldown > 0)
_cooldown--;
var bullishTrend = fastValue > slowValue;
var bearishTrend = fastValue < slowValue;
if (_cooldown == 0 && candle.OpenTime.Hour == TradeHour)
{
if (bullishTrend && Position <= 0)
{
BuyMarket();
_cooldown = CooldownBars;
}
else if (bearishTrend && Position >= 0)
{
SellMarket();
_cooldown = CooldownBars;
}
}
else if (_cooldown == 0)
{
if (Position > 0 && bearishTrend)
{
SellMarket();
_cooldown = CooldownBars;
}
else if (Position < 0 && bullishTrend)
{
BuyMarket();
_cooldown = CooldownBars;
}
}
}
}