Die Fortrader 10-Pips-Strategie ist eine StockSharp-Portierung des MetaTrader 4-Expertenberaters 10pips.mq4 (Strategie-ID 8074). Der Roboter hält gleichzeitig eine Long- und eine Short-Position offen. Für jedes Segment werden feste Take-Profit-, Stop-Loss- und Trailing-Stop-Abstände verwendet, die in Symbolpunkten gemessen werden.
Diese Konvertierung stellt das Absicherungsverhalten innerhalb der übergeordneten Ebene API von StockSharp wieder her. Unmittelbar nach Beginn der Strategie wird eine Marktkauf- und eine Marktverkaufsorder gesendet. Immer wenn eine Schutzorder ein Bein schließt, eröffnet die Strategie sofort eine neue Order in die gleiche Richtung und hält so jederzeit zwei gegensätzliche Positionen am Leben.
Parameter
Name
Beschreibung
Take Profit Buy
Take-Profit-Distanz für die lange Strecke, in Punkten.
Stop Loss Buy
Stop-Loss-Distanz für die lange Strecke, in Punkten.
Trailing Stop Buy
Trailing-Stop-Distanz für den langen Abschnitt, in Punkten. Auf Null setzen, um das Nachziehen zu deaktivieren.
Take Profit Sell
Take-Profit-Distanz für die kurze Strecke, in Punkten.
Stop Loss Sell
Stop-Loss-Distanz für das kurze Bein, in Punkten.
Trailing Stop Sell
Trailing-Stop-Distanz für den kurzen Abschnitt, in Punkten. Auf Null setzen, um das Nachziehen zu deaktivieren.
Volume
Volumen jeder Marktorder in Lots.
Alle Entfernungen werden mit dem PriceStep des Instruments multipliziert, um Punkte in absolute Preiswerte umzurechnen. Jeder Parameter wird über StrategyParam<T> verfügbar gemacht, sodass die Strategie über die GUI angepasst oder optimiert werden kann.
Handelslogik
Startup – OnStarted abonniert Level-1-Daten, um die aktuell besten Geld- und Briefkurse zu verfolgen. Die Strategie sendet sofort einen Marktkauf- und einen Marktverkaufsauftrag.
Schutzaufträge – Nach jeder Eintragserfüllung (OnNewMyTrade) erstellt die Strategie die zugehörigen Stop-Loss- und Take-Profit-Aufträge, wenn die Abstände größer als Null sind. Bestellungen werden auf die nächste Preisstufe gerundet.
Wiedereintritt – Wenn eine Stop-Loss- oder Take-Profit-Order ausgeführt wird, wird das geschlossene Segment sofort mit einer neuen Marktorder wieder geöffnet, sodass das bidirektionale Engagement bestehen bleibt.
Trailing Stops – Level-1-Aktualisierungen lösen UpdateTrailingStops aus, der die Stop-Loss-Orders immer dann anpasst, wenn sich das aktuelle Geld/Brief über die konfigurierte Trailing-Distanz vom Einstiegspreis hinaus bewegt hat. Die Logik spiegelt die ursprüngliche EA wider: Das Trailing beginnt, sobald der Gewinn die Trailing-Distanz überschreitet, und Stops werden nur in Richtung des Gewinns verschoben.
Implementierungshinweise
Der ursprüngliche MT4-Code wartete 10 Sekunden zwischen den ersten Kauf- und Verkaufsaufträgen. Für StockSharp ist diese Verzögerung nicht erforderlich, daher werden beide Bestellungen sofort gesendet.
Da StockSharp standardmäßig Nettopositionen verwendet, kann eine echte Absicherung davon abhängen, dass der Broker/Connector gegensätzliche Positionen unterstützt. Die Strategie verfolgt jede Etappe unabhängig und stellt sie nach jedem Ausstieg wieder her.
StartProtection() wird einmal während OnStarted aufgerufen, sodass globale Risikoschutzmaßnahmen aktiv sind, sofern in den Framework-Einstellungen konfiguriert.
Nutzungstipps
Stellen Sie sicher, dass der ausgewählte Connector gleichzeitige Long- und Short-Positionen unterstützt, wenn das Absicherungsverhalten erforderlich ist.
Setzen Sie die Nachlaufdistanzen auf Null, um das Nachlaufen für den entsprechenden Abschnitt zu deaktivieren.
Optimieren Sie die Risikoparameter (Take Profit, Stop Loss, Trailing Stop) für historische Daten, damit sie zum gehandelten Symbol und Zeitrahmen passen.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Fortrader10PipsStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Fortrader10PipsStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 7).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
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 (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); }
_prevFast = fast; _prevSlow = slow;
}
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class fortrader_10_pips_strategy(Strategy):
"""
Fortrader 10 Pips: Simple EMA crossover (fast 7, slow 21).
Buys when fast crosses above slow, sells on reverse.
"""
def __init__(self):
super(fortrader_10_pips_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 7) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 21) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fortrader_10_pips_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(fortrader_10_pips_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self._fast_period.Value
slow = ExponentialMovingAverage()
slow.Length = self._slow_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self._process_candle).Start()
def _process_candle(self, candle, fast_val, slow_val):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast_val)
slow_val = float(slow_val)
if not self._has_prev:
self._prev_fast = fast_val
self._prev_slow = slow_val
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fast_val > slow_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fast_val < slow_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return fortrader_10_pips_strategy()