Flat 001a ist ein Scalping-System, das für den EURUSD-Stundenchart entwickelt wurde. Es scannt die letzten drei Stundenkerzen und misst den Abstand zwischen dem höchsten Hoch und dem niedrigsten Tief. Wenn die Spanne dieses Drei-Kerzen-Fensters innerhalb einer konfigurierbaren Anzahl von Punkten bleibt, geht die Strategie davon aus, dass der Preis innerhalb der Flat gefangen bleibt. Anschließend wird versucht, kurzfristige Ausschläge in das obere oder untere Viertel des Kanals abzuschwächen, und es werden sofort Schutzanordnungen erlassen.
Der ursprüngliche MQL4-Expertenberater handelte im ersten Halbjahr nur mit EURUSD und lehnte den Handel ab, wenn das Symbol oder der Zeitrahmen falsch war. Dieser Port behält die gleichen Standardwerte bei (EURUSD, 60-Minuten-Kerzen) und reproduziert alle Einstiegs-, Stop-Loss-, Take-Profit- und Trailing-Stop-Berechnungen in StockSharp.
Indikatoren und Daten
Die Indikatoren Highest und Lowest (Periode = 3) verfolgen die Ober- und Unterseite der letzten drei abgeschlossenen Kerzen.
Ein Zeitrahmenparameter ist standardmäßig auf 60-Minuten-Kerzen eingestellt, um die H1-Anforderung des Quellcodes widerzuspiegeln.
Da keine zusätzlichen Oszillatoren oder Glättungsfilter verwendet werden, reagiert die Strategie ausschließlich auf rohe Preisextreme.
Eingabelogik
Warten Sie, bis die Abonnementkerze geschlossen ist. Es werden nur fertige Kerzen verarbeitet.
Stellen Sie sicher, dass der aktuelle Sicherheitscode mit dem konfigurierten Code übereinstimmt (Standard: EURUSD). Ist dies nicht der Fall, bleibt die Strategie im Leerlauf.
Bewerten Sie das optionale Handelsfenster. Standardmäßig sind Zutritte während der zwei Stunden ab Mitternacht der Bahnsteigzeit (Stunden 0 und 1) erlaubt. Der Filter kann deaktiviert werden.
Berechnen Sie den Drei-Kerzen-Bereich range = highest - lowest und übersetzen Sie ihn mit dem Instrument PriceStep in Punkte.
Fahren Sie nur fort, wenn die Anzahl der Punkte zwischen DiffMinPoints und DiffMaxPoints liegt.
Wenn der Schlusskurs im niedrigsten Viertel der Spanne liegt und keine Position offen ist, gehen Sie einen Long-Trade ein.
Wenn der Schlusskurs im höchsten Viertel der Spanne liegt und keine Position offen ist, gehen Sie einen Short-Trade ein.
Sobald der nicht realisierte Gewinn TrailingStopPoints * PriceStep übersteigt, wird der Stop-Loss Kerze für Kerze nachgezogen.
Long-Trades verschieben den Stop auf closePrice - TrailingDistance, wenn dieser höher als der aktuelle Stop ist.
Short-Trades verschieben den Stop auf closePrice + TrailingDistance, wenn dieser niedriger als der aktuelle Stop ist.
Alle Exits werden mit Marktaufträgen ausgeführt. Die Strategie schließt die gesamte Position, wenn entweder das Stop-Loss- oder Take-Profit-Niveau von der nachfolgenden Kerze berührt wird.
Parameter
Gruppe
Name
Beschreibung
Standard
Allgemein
CandleType
Für Berechnungen verwendeter Kerzentyp. Sollte auf einen Zeitrahmen von 60 Minuten eingestellt werden, um dem ursprünglichen System zu entsprechen.
TimeFrame(60m)
Allgemein
SecurityCode
Erwarteter Sicherheitscode. Lassen Sie das Feld leer, um mit einem beliebigen Instrument zu handeln.
EURUSD
Bereichsfilter
DiffMinPoints
Mindestspanne von drei Kerzen in Punkten, die für den Handel erforderlich sind.
18
Bereichsfilter
DiffMaxPoints
Maximal zulässiger Drei-Kerzen-Bereich in Punkten für den Handel.
28
Handelsfenster
EnableTimeFilter
Aktiviert oder deaktiviert den Stundenfilter.
true
Handelsfenster
OpenHour
Startstunde (0–23) für das Handelsfenster. Die Strategie ermöglicht auch die unmittelbare nächste Stunde.
0
Risikomanagement
TakeProfitPoints
Take-Profit-Distanz ausgedrückt in Punkten. Zum Deaktivieren auf Null setzen.
8
Risikomanagement
TrailingStopPoints
Trailing-Stop-Distanz, ausgedrückt in Punkten. Auf Null setzen, um das Nachziehen zu deaktivieren.
6
Praktische Hinweise
Die Eigenschaft StockSharp Strategy.Volume steuert die Bestellgröße. Passen Sie es an die Größe Ihres Maklervertrags an.
Stellen Sie sicher, dass das ausgewählte Instrument einen gültigen PriceStep bereitstellt. Wenn PriceStep fehlt, greift die Strategie auf 1 zurück und protokolliert eine Warnung.
Der MQL4-Expertenberater bot eine optionale Geldverwaltung durch Skalierung der Lose entsprechend dem Kontostand an. Das Beispiel von StockSharp hält die Positionsgröße konstant; Bei Bedarf können Sie Ihr eigenes Volume-Management per Skript erstellen.
Testen Sie die Strategie immer in einer Simulation, bevor Sie sie live ausführen. Die abschließende Logik geht davon aus, dass der Broker Schutzaufträge ausführt, wenn die Extremwerte der Kerze das Niveau überschreiten. In schnellen Märkten kann Slippage das realisierte Risiko erhöhen.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Flat 001a: RSI reversal with EMA filter and ATR stops.
/// </summary>
public class Flat001aStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _atrLength;
private decimal _prevRsi;
private decimal _entryPrice;
public Flat001aStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_rsiLength = Param(nameof(RsiLength), 14)
.SetDisplay("RSI Length", "RSI period.", "Indicators");
_emaLength = Param(nameof(EmaLength), 20)
.SetDisplay("EMA Length", "Trend filter.", "Indicators");
_atrLength = Param(nameof(AtrLength), 14)
.SetDisplay("ATR Length", "ATR period.", "Indicators");
}
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }
public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = 0; _entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevRsi = 0; _entryPrice = 0;
var rsi = new RelativeStrengthIndex { Length = RsiLength };
var ema = new ExponentialMovingAverage { Length = EmaLength };
var atr = new AverageTrueRange { Length = AtrLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ema, atr, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, ema); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal rsiVal, decimal emaVal, decimal atrVal)
{
if (candle.State != CandleStates.Finished) return;
if (_prevRsi == 0 || atrVal <= 0) { _prevRsi = rsiVal; return; }
var close = candle.ClosePrice;
if (Position > 0)
{
if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || rsiVal > 70) { SellMarket(); _entryPrice = 0; }
}
else if (Position < 0)
{
if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || rsiVal < 30) { BuyMarket(); _entryPrice = 0; }
}
if (Position == 0)
{
if (rsiVal > 55 && _prevRsi <= 55 && close > emaVal) { _entryPrice = close; BuyMarket(); }
else if (rsiVal < 45 && _prevRsi >= 45 && close < emaVal) { _entryPrice = close; SellMarket(); }
}
_prevRsi = rsiVal;
}
}
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 RelativeStrengthIndex, ExponentialMovingAverage, AverageTrueRange
class flat001a_strategy(Strategy):
def __init__(self):
super(flat001a_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._rsi_length = self.Param("RsiLength", 14) \
.SetDisplay("RSI Length", "RSI period.", "Indicators")
self._ema_length = self.Param("EmaLength", 20) \
.SetDisplay("EMA Length", "Trend filter.", "Indicators")
self._atr_length = self.Param("AtrLength", 14) \
.SetDisplay("ATR Length", "ATR period.", "Indicators")
self._prev_rsi = 0.0
self._entry_price = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@property
def RsiLength(self):
return self._rsi_length.Value
@property
def EmaLength(self):
return self._ema_length.Value
@property
def AtrLength(self):
return self._atr_length.Value
def OnStarted2(self, time):
super(flat001a_strategy, self).OnStarted2(time)
self._prev_rsi = 0.0
self._entry_price = 0.0
self._rsi = RelativeStrengthIndex()
self._rsi.Length = self.RsiLength
self._ema = ExponentialMovingAverage()
self._ema.Length = self.EmaLength
self._atr = AverageTrueRange()
self._atr.Length = self.AtrLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._rsi, self._ema, self._atr, self.ProcessCandle).Start()
def ProcessCandle(self, candle, rsi_val, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
rv = float(rsi_val)
ev = float(ema_val)
av = float(atr_val)
if self._prev_rsi == 0 or av <= 0:
self._prev_rsi = rv
return
close = float(candle.ClosePrice)
if self.Position > 0:
if close >= self._entry_price + av * 2.5 or close <= self._entry_price - av * 1.5 or rv > 70:
self.SellMarket()
self._entry_price = 0.0
elif self.Position < 0:
if close <= self._entry_price - av * 2.5 or close >= self._entry_price + av * 1.5 or rv < 30:
self.BuyMarket()
self._entry_price = 0.0
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_rsi = rv
return
if self.Position == 0:
if rv > 55 and self._prev_rsi <= 55 and close > ev:
self._entry_price = close
self.BuyMarket()
elif rv < 45 and self._prev_rsi >= 45 and close < ev:
self._entry_price = close
self.SellMarket()
self._prev_rsi = rv
def OnReseted(self):
super(flat001a_strategy, self).OnReseted()
self._prev_rsi = 0.0
self._entry_price = 0.0
def CreateClone(self):
return flat001a_strategy()