Die Close Profit End Of Week-Strategie automatisiert das MetaTrader-Skript Closeprofitendofweek.mq5. Die Strategie überwacht das zugewiesene Instrument und verlässt freitags nach einer konfigurierbaren Cut-Off-Zeit jede profitable Position. Das Ziel besteht darin, schwebende Gewinne zu sichern, bevor das Wochenend-Gap-Risiko auftritt.
Ursprüngliches MQL-Verhalten
Der Quell-Expert Advisor hat kontinuierlich Positionen über den Timer-Handler abgefragt. Immer wenn die Serverzeit mit Freitag und der konfigurierten Endzeit übereinstimmte, wurden alle offenen Positionen auf dem gehandelten Symbol durchlaufen. Jede Position mit positivem Gewinn wurde über eine Marktorder geschlossen. Kryptosymbole wurden ausdrücklich ausgeschlossen, da sie ohne Wochenendpausen gehandelt werden.
StockSharp Implementierung
Der C#-Port behält die gleiche Schutzlogik bei, während er das High-Level-API von StockSharp verwendet:
Abonniert nur eine konfigurierbare Kerzenserie, um regelmäßige Zeitaktualisierungen zu erhalten.
Überprüft jede fertige Kerze und stellt sicher, dass es sich um einen Freitag handelt, dessen Schlusszeit nach dem benutzerdefinierten Cut-off liegt.
Greift auf das verbundene Portfolio zu, um die Nettoposition für das Strategiesymbol auszuwerten.
Erteilt für jedes noch offene profitable Engagement eine Marktorder in die entgegengesetzte Richtung.
Überspringt die Routine vollständig, wenn das Instrument als Krypto-Asset klassifiziert ist.
Parameter
Name
Beschreibung
Standard
StartTradeTime
Beginn des Überwachungsfensters (aus Gründen der Parität mit den MQL-Eingaben beibehalten).
00:00
EndTradeTime
Tageszeit am Freitag, nach der profitable Positionen geschlossen werden müssen.
20:00
CloseTradesAtEndTime
Aktiviert oder deaktiviert die automatische Schließroutine.
true
CandleType
Datenreihen zur Zeitverfolgung (standardmäßig 1-Minuten-Kerzen).
TimeFrameCandle(1m)
Ausführungsablauf
Beim Start der Strategie wird überprüft, ob das ausgewählte Wertpapier zur Krypto-Asset-Klasse gehört. Kryptoinstrumente werden ignoriert, um die Schutzklausel MetaTrader widerzuspiegeln.
Es wird ein Kerzenabonnement erstellt, um regelmäßige Rückrufe zu erhalten, sobald jede Kerze fertig ist.
Jede fertige Kerze löst die Zeitplanprüfungen aus. Lediglich Freitage, die nach der Annahmeschlusszeit geschlossen haben, führen zu einer weiteren Bearbeitung.
Die Strategie scannt das verbundene Portfolio, filtert die Position, die dem konfigurierten Wertpapier entspricht, und liest seinen variablen Gewinn ab.
Wenn der variable Gewinn größer als Null ist, wird eine Marktorder in die entgegengesetzte Richtung erteilt, um das Engagement vollständig zu schließen.
Doppelte Ausstiegsaufträge werden vermieden, indem aktive Aufträge überprüft werden, bevor neue Aufträge gesendet werden.
Nutzungshinweise
Verknüpfen Sie die Strategie mit einem Nicht-Krypto-Instrument zusammen mit demselben Portfolio, das die offenen Positionen besitzt, die Sie überwachen möchten.
Die Strategie eröffnet keine neuen Trades; es verwaltet nur bestehende Positionen.
Der Parameter StartTradeTime existiert für Konfigurationsparität und zukünftige Erweiterungen, wird jedoch von der aktuellen Logik nicht referenziert.
Führen Sie für Portfolios mit mehreren Symbolen eine Instanz pro Instrument aus, um den Einzelsymbolbereich des MetaTrader-Skripts zu replizieren.
Einschränkungen
Die Gewinnerkennung basiert darauf, dass das Broker-Portfolio variable PnL meldet. Wenn das Portfolio nicht in Echtzeit aktualisiert wird, kann sich der Schließbefehl verzögern.
Es werden nur Positionen für das konfigurierte Strategiesymbol geschlossen. Auf anderen Symbolen gehaltene Belichtungen bleiben davon unberührt.
Die Prüfung wird bei Candle-Close-Ereignissen durchgeführt. Wählen Sie einen angemessen kurzen Zeitrahmen, wenn Sie einen engeren Zeitplan benötigen.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Close Profit End Of Week strategy: Momentum + EMA trend following.
/// Buys when momentum positive and close above EMA, sells when momentum negative and close below EMA.
/// </summary>
public class CloseProfitEndOfWeekStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _momPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<decimal> _momentumLevel;
private decimal _prevMom;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int MomPeriod { get => _momPeriod.Value; set => _momPeriod.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public decimal MomentumLevel { get => _momentumLevel.Value; set => _momentumLevel.Value = value; }
public CloseProfitEndOfWeekStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_momPeriod = Param(nameof(MomPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Momentum Period", "Momentum period", "Indicators");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA filter period", "Indicators");
_momentumLevel = Param(nameof(MomentumLevel), 101m)
.SetDisplay("Momentum Level", "Momentum threshold", "Signals");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevMom = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevMom = 0;
_hasPrev = false;
var mom = new Momentum { Length = MomPeriod };
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(mom, ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal momValue, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
if (_hasPrev)
{
if (_prevMom <= MomentumLevel && momValue > MomentumLevel && candle.ClosePrice > emaValue && Position <= 0)
BuyMarket();
else if (_prevMom >= 200m - MomentumLevel && momValue < 200m - MomentumLevel && candle.ClosePrice < emaValue && Position >= 0)
SellMarket();
}
_prevMom = momValue;
_hasPrev = true;
}
}
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.Indicators import Momentum, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class close_profit_end_of_week_strategy(Strategy):
def __init__(self):
super(close_profit_end_of_week_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._mom_period = self.Param("MomPeriod", 20)
self._ema_period = self.Param("EmaPeriod", 50)
self._momentum_level = self.Param("MomentumLevel", 101.0)
self._prev_mom = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def MomPeriod(self):
return self._mom_period.Value
@MomPeriod.setter
def MomPeriod(self, value):
self._mom_period.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
@property
def MomentumLevel(self):
return self._momentum_level.Value
@MomentumLevel.setter
def MomentumLevel(self, value):
self._momentum_level.Value = value
def OnReseted(self):
super(close_profit_end_of_week_strategy, self).OnReseted()
self._prev_mom = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(close_profit_end_of_week_strategy, self).OnStarted2(time)
self._prev_mom = 0.0
self._has_prev = False
mom = Momentum()
mom.Length = self.MomPeriod
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(mom, ema, self._process_candle).Start()
def _process_candle(self, candle, mom_value, ema_value):
if candle.State != CandleStates.Finished:
return
mom_val = float(mom_value)
ema_val = float(ema_value)
close = float(candle.ClosePrice)
level = float(self.MomentumLevel)
if self._has_prev:
if self._prev_mom <= level and mom_val > level and close > ema_val and self.Position <= 0:
self.BuyMarket()
elif self._prev_mom >= (200.0 - level) and mom_val < (200.0 - level) and close < ema_val and self.Position >= 0:
self.SellMarket()
self._prev_mom = mom_val
self._has_prev = True
def CreateClone(self):
return close_profit_end_of_week_strategy()