Stellt die Ausbruchs- und Umkehrlogik des ursprünglichen Noah10pips2006 MetaTrader 4-Expertenberaters wieder her.
Baut Preiskanäle der vorherigen Sitzung auf und platziert Stop-Orders etwa in der Mitte.
Wendet sicheres Gewinn-Trailing, optionale dynamische Positionsgrößenbestimmung und einen optionalen Umkehrhandel nach dem Schließen der ersten Position an.
Handelslogik
Berechnung der Sitzungsreichweite
Zu Beginn jedes neuen Handelstages (nach Anwendung des konfigurierten Zeitzonenversatzes) zeichnet die Strategie die Höchst- und Tiefststände der vorherigen Sitzung auf. Diese Ebenen werden zur Berechnung verwendet:
Der Mittelpunkt zwischen Hoch und Tief.
Ein „Pass“-Puffer, der 20 Pips über/unter der Spanne liegt.
Ein Einstiegskanal, der durch Subtrahieren/Addieren von 40 Pips (oder 25 % der Range, wenn die Range größer als 160 Pips ist) entsteht.
Erste ausstehende Bestellung
Wenn der Markt in das Handelsfenster eintritt, prüft die Strategie den letzten Schlusskurs:
Liegt der Schlusskurs zwischen dem Mittelpunkt und dem oberen Puffer, wird am Mittelpunkt ein Verkaufsstopp gesetzt.
Liegt der Schlusskurs zwischen dem unteren Puffer und dem Mittelpunkt, wird ein Kaufstopp am Mittelpunkt platziert.
Die Sortimentsbreite muss das konfigurierte Minimum überschreiten, bevor Bestellungen aufgegeben werden können.
Zweite ausstehende Bestellung
Bleibt nur noch eine Stop-Order aktiv, fügt das System die gegenläufige Order am entsprechenden Puffer hinzu (oberer Puffer für einen Kauf-Stopp, unterer Puffer für einen Verkaufs-Stopp). Dies spiegelt das ursprüngliche EA-Verhalten wider und bereitet die Strategie auf Ausbrüche auf beiden Seiten der Spanne vor.
Positionsmanagement
Schützende Stop-Loss- und Take-Profit-Orders werden erstellt, nachdem ein Eintrag ausgeführt wurde.
Sobald der variable Gewinn die sichere Auslöseschwelle erreicht, wird der Stop-Loss verschoben, um den konfigurierten sicheren Gewinn zu sichern.
Wenn die sichere Sperre aktiv ist, folgt ein optionaler Trailing Stop dem Preis im angegebenen Abstand.
Täglicher Shutdown
Alle ausstehenden Aufträge und offenen Positionen werden geschlossen, wenn das Handelsfenster endet oder der Annahmeschluss am Freitag erreicht ist.
Umkehrhandel
Die erste abgeschlossene Position kann eine Marktorder in die entgegengesetzte Richtung auslösen, wodurch das „Reverse After Stop“-Verhalten des ursprünglichen Codes reproduziert wird. Die Rückabwicklung wird übersprungen, wenn durch die sichere Gewinnanpassung bereits Gewinne gesichert sind.
Parameter
Parameter
Beschreibung
CandleType
Kerzenserien dienen zur Steuerung von Berechnungen und Timing. Standard: 1-Stunden-Kerzen.
TimeZoneOffset
Verschiebung (in Stunden), die vor täglichen Berechnungen auf Austauschzeitstempel angewendet wird.
StartHour, StartMinute
Öffnungszeit des Handelsfensters in der verschobenen Zeitzone.
EndHour, EndMinute
Schließzeit des Handelsfensters. Neue Einträge werden nicht nachträglich platziert.
FridayEndHour
Stunde am Freitag, wenn Positionen zwangsweise geschlossen werden.
TradeFriday
Aktiviert oder deaktiviert die Eröffnung neuer Positionen am Freitag.
StopLossPips, TakeProfitPips
Abstand (in Pips) der nach der Eingabe erstellten Schutzbefehle.
TrailingStopPips
Trailing-Stop-Distanz, die nach dem Secure-Profit-Schritt verwendet wird. Auf 0 setzen, um das Nachziehen zu deaktivieren.
SecureProfitPips
Der Gewinn wird gesperrt, wenn der sichere Auslöser aktiviert wird.
TrailSecureProfitPips
Erforderlicher Gewinnschwellenwert, bevor der Stopp auf das sichere Niveau verschoben wird.
MinimumRangePips
Mindestbreite des Eingangskanals, die für die Auftragserteilung erforderlich ist.
StartYear, StartMonth
Ignorieren Sie Marktdaten, die älter als dieses Datum sind.
MinVolume, MaxVolume
Auf das berechnete Auftragsvolumen angewendete Grenzen.
MaximumRiskPercent
Prozentsatz des Portfoliowerts, der pro Trade riskiert wird, wenn die dynamische Größenanpassung aktiviert ist.
FixedVolume
Bei true verwendet die Strategie die Eigenschaft Volume anstelle des Risikomodells.
Praktische Hinweise
Das Instrument muss gültige PriceStep- und StepPrice-Werte liefern, wenn der risikobasierte Positionsgrößenmodus verwendet wird.
Trailing- und Secure-Profit-Anpassungen basieren auf abgeschlossenen Kerzen, sodass Intrabar-Füllungen bei der nächsten abgeschlossenen Kerze verarbeitet werden.
Die Strategie storniert und ersetzt Schutzaufträge, wann immer die abschließende Logik den Stop-Preis aktualisiert.
Stellen Sie sicher, dass der Zeitzonenversatz mit der Quelle der historischen Daten übereinstimmt. Andernfalls kann die Spanne des Vortages vom ursprünglichen MT4-Experten abweichen.
Konvertierungsvorbehalte
Visuelle Zeichenobjekte aus der MT4-Version wurden weggelassen; Verwenden Sie die bereitgestellten Ebenen oder fügen Sie bei Bedarf benutzerdefinierte Diagrammanmerkungen hinzu.
Der Algorithmus geht bei der Konvertierung der festen 20/40-Pip-Puffer von vierstelligen Forex-Kursen aus; Passen Sie Parameter für verschiedene Anlageklassen an.
Reverse Trades werden zum Marktwert mit dem aktuellen Volumenmodell ausgeführt und entsprechen dem Verhalten des ursprünglichen EA nach dem Löschen entgegengesetzter ausstehender Orders.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Noah 10 Pips 2006 - session breakout strategy.
/// Tracks the previous session's high/low range.
/// Buys on breakout above the midpoint, sells on breakout below.
/// Uses Highest/Lowest indicators as channel reference.
/// </summary>
public class Noah10Pips2006Strategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private decimal _prevMid;
private decimal _prevClose;
private bool _hasPrev;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Noah10Pips2006Strategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 24)
.SetDisplay("Channel Period", "Lookback for high/low channel", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0m;
_prevLow = 0m;
_prevMid = 0m;
_prevClose = 0m;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal high, decimal low)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
var mid = (high + low) / 2m;
if (!_hasPrev)
{
_prevHigh = high;
_prevLow = low;
_prevMid = mid;
_prevClose = close;
_hasPrev = true;
return;
}
// Breakout above channel high - buy
if (_prevClose <= _prevHigh && close > high && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Breakout below channel low - sell
else if (_prevClose >= _prevLow && close < low && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
// Cross above midpoint from below - buy signal
else if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Cross below midpoint from above - sell signal
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevHigh = high;
_prevLow = low;
_prevMid = mid;
_prevClose = close;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class noah10_pips2006_strategy(Strategy):
"""Session breakout strategy. Tracks channel high/low/midpoint.
Buys on breakout above channel high or cross above midpoint.
Sells on breakout below channel low or cross below midpoint."""
def __init__(self):
super(noah10_pips2006_strategy, self).__init__()
self._channel_period = self.Param("ChannelPeriod", 24) \
.SetDisplay("Channel Period", "Lookback for high/low channel", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_high = 0.0
self._prev_low = 0.0
self._prev_mid = 0.0
self._prev_close = 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 ChannelPeriod(self):
return self._channel_period.Value
def OnReseted(self):
super(noah10_pips2006_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._prev_mid = 0.0
self._prev_close = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(noah10_pips2006_strategy, self).OnStarted2(time)
self._has_prev = False
highest = Highest()
highest.Length = self.ChannelPeriod
lowest = Lowest()
lowest.Length = self.ChannelPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._process_candle).Start()
def _process_candle(self, candle, high, low):
if candle.State != CandleStates.Finished:
return
high_val = float(high)
low_val = float(low)
close = float(candle.ClosePrice)
mid = (high_val + low_val) / 2.0
if not self._has_prev:
self._prev_high = high_val
self._prev_low = low_val
self._prev_mid = mid
self._prev_close = close
self._has_prev = True
return
# Breakout above channel high - buy
if self._prev_close <= self._prev_high and close > high_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Breakout below channel low - sell
elif self._prev_close >= self._prev_low and close < low_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
# Cross above midpoint from below - buy
elif self._prev_close <= self._prev_mid and close > mid and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Cross below midpoint from above - sell
elif self._prev_close >= self._prev_mid and close < mid and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = high_val
self._prev_low = low_val
self._prev_mid = mid
self._prev_close = close
def CreateClone(self):
return noah10_pips2006_strategy()