Die Nevalyashka Breakdown Level-Strategie ist eine direkte Umsetzung des MT4-Expertenberaters Nevalyashka_BreakdownLevel. Das System erstellt eine Eröffnungsspanne zwischen zwei konfigurierbaren Zeitpunkten und handelt mit Ausbrüchen dieser Spanne. Wenn ein Ausbruch fehlschlägt und der Handel gestoppt wird, kehrt die Strategie sofort die Richtung um und verwendet einen Martingal-Multiplikator, um den Verlust auszugleichen. Profitable Trades blockieren alle weiteren Einträge für den Rest des Handelstages, was dem ursprünglichen EA-Verhalten entspricht.
Schlüsselkonzepte
Eröffnungsbereich: Das höchste Hoch und das niedrigste Tief, die zwischen RangeStart und RangeEnd gedruckt werden, definieren den Ausbruchskanal für den aktuellen Tag.
Breakout-Einträge: Eine Long-Position wird eröffnet, wenn der Schlusskurs das Hoch der Spanne überschreitet; Eine Short-Position wird eröffnet, wenn sie unter das Range-Tief fällt.
Schutzaufträge: Der Stop-Loss wird immer auf der gegenüberliegenden Seite der Spanne platziert. Der Take-Profit wird in einem Abstand positioniert, der der Range-Breite entspricht.
Breakeven-Bewegung: Wenn diese Option aktiviert ist, wird der Stop auf den Einstiegspreis verschoben, sobald sich der Handel auf halbem Weg zum Ziel bewegt.
Martingale Erholung: Nach einem Stop-Loss kehrt die Strategie die Richtung um, multipliziert das Ordervolumen mit MartingaleMultiplier und verwendet eine symmetrische Ziel-/Stoppgröße, um den vorherigen Verlust auszugleichen.
Tägliche Sperre: Jeder profitable Abschluss (Take-Profit oder manueller Ausstieg über Null) verhindert neue Geschäfte, bis sich der Handelstag ändert.
Erzwungene Flatrate: Wenn OrdersCloseTime später als RangeEnd ist, werden alle offenen Positionen zu diesem Zeitpunkt geschlossen und neue Einträge werden für den Rest des Tages blockiert.
Parameter
Name
Beschreibung
Standard
RangeStart
Startzeit (einschließlich) des Referenzbereichs.
04:00
RangeEnd
Endzeit (einschließlich) des Referenzbereichs.
09:00
OrdersCloseTime
Tageszeit für die erzwungene Schließung von Positionen. Wenn dieser Zeitpunkt nach RangeEnd liegt, werden auch danach neue Trades blockiert.
23:30
OrderVolume
Für jeden Breakout-Trade verwendetes Volumen.
0.1
MartingaleMultiplier
Der Multiplikator wird auf die nächste Order nach einem Stop-Loss angewendet, um den vorherigen Verlust auszugleichen.
2
UseBreakeven
Ermöglicht das Verschieben des Stops auf die Gewinnschwelle, sobald der Trade die Hälfte der Zieldistanz zurückgelegt hat.
true
CandleType
Kerzentyp, der zum Aufbau der Reichweite und zur Generierung von Signalen verwendet wird.
1 hour Kerzen
Handelsregeln
Range-Berechnung: Für jeden neuen Handelstag zeichnet die Strategie die Höchst- und Tiefstwerte der fertigen Kerzen zwischen RangeStart und RangeEnd (einschließlich) auf.
Eintrittsbedingungen:
Gehen Sie long, wenn der Schlusskurs der aktuellen Kerze über dem aufgezeichneten Hoch der Spanne liegt.
Gehen Sie short, wenn der Schlusskurs der aktuellen Kerze unter dem aufgezeichneten Tiefstkurs liegt.
Einträge werden übersprungen, wenn eine Martingalumkehr ansteht, am selben Tag bereits ein profitabler Handel stattgefunden hat oder die aktuelle Zeit nach OrdersCloseTime liegt (wenn OrdersCloseTime > RangeEnd).
Risikomanagement:
Stop-Loss ist auf der gegenüberliegenden Seite der Eröffnungsspanne verankert.
Der Take-Profit wird auf den Einstiegspreis plus/minus der Eröffnungsspannenbreite festgelegt.
Wenn UseBreakeven aktiviert ist, bewegt sich der Stop auf den Einstiegspreis, nachdem die Hälfte der Zieldistanz zurückgelegt wurde.
Martingale Umkehrung:
Wenn der Stop-Loss erreicht wird, wird die Position geschlossen, das Volumen mit MartingaleMultiplier multipliziert und eine sofortige Marktorder in die entgegengesetzte Richtung gesendet.
Der neue Stop und das neue Ziel werden beide in einem Abstand platziert, der dem Verlust pro Lot dividiert durch den Multiplikator entspricht, was der Wiederherstellungslogik des ursprünglichen EA entspricht.
Tägliche Handelssperre:
Wenn ein Trade mit einem nicht negativen Gewinn endet oder das Ziel erreicht wird, sind keine neuen Trades zulässig, bis sich das Handelsdatum ändert.
Zwangsausgang:
Wenn OrdersCloseTime nach dem Bereichsfenster liegt und die aktuelle Zeit diesen Wert erreicht, werden alle offenen Positionen abgeflacht und der Tag gesperrt.
Notizen
Die Strategie verwendet das übergeordnete StockSharp API (Strategy.SubscribeCandles().Bind(...)), um nahe an den Rahmenkonventionen zu bleiben.
Alle zustandsbehafteten Berechnungen (Bereichsgrenzen, ausstehende Martingalbefehle, Breakeven-Zustand) werden in der Strategieklasse gespeichert, um historische Suchvorgänge zu vermeiden.
Bei der Konvertierung bleibt das ursprüngliche Verhalten von EA erhalten, bei dem Handelstage nach Kalenderdatum gezählt und Martingalschritte unmittelbar nach einem Stopp verwaltet werden.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Nevalyashka BreakdownLevel: Previous candle breakout with EMA filter and ATR stops.
/// </summary>
public class NevalyashkaBreakdownLevelStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _atrLength;
private decimal _prevHigh;
private decimal _prevLow;
private decimal _entryPrice;
public NevalyashkaBreakdownLevelStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(8).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_emaLength = Param(nameof(EmaLength), 30)
.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 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();
_prevHigh = 0; _prevLow = 0; _entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHigh = 0; _prevLow = 0; _entryPrice = 0;
var ema = new ExponentialMovingAverage { Length = EmaLength };
var atr = new AverageTrueRange { Length = AtrLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, atr, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, ema); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal atrVal)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (_prevHigh == 0 || atrVal <= 0) { _prevHigh = candle.HighPrice; _prevLow = candle.LowPrice; return; }
if (Position > 0)
{
if (close <= _entryPrice - atrVal * 1.5m || close >= _entryPrice + atrVal * 2.5m) { SellMarket(); _entryPrice = 0; }
}
else if (Position < 0)
{
if (close >= _entryPrice + atrVal * 1.5m || close <= _entryPrice - atrVal * 2.5m) { BuyMarket(); _entryPrice = 0; }
}
if (Position == 0)
{
if (close > _prevHigh && close > emaVal) { _entryPrice = close; BuyMarket(); }
else if (close < _prevLow && close < emaVal) { _entryPrice = close; SellMarket(); }
}
_prevHigh = candle.HighPrice; _prevLow = candle.LowPrice;
}
}
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 ExponentialMovingAverage, AverageTrueRange
class nevalyashka_breakdown_level_strategy(Strategy):
def __init__(self):
super(nevalyashka_breakdown_level_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(8))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._ema_length = self.Param("EmaLength", 30) \
.SetDisplay("EMA Length", "Trend filter.", "Indicators")
self._atr_length = self.Param("AtrLength", 14) \
.SetDisplay("ATR Length", "ATR period.", "Indicators")
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@property
def EmaLength(self):
return self._ema_length.Value
@property
def AtrLength(self):
return self._atr_length.Value
def OnStarted2(self, time):
super(nevalyashka_breakdown_level_strategy, self).OnStarted2(time)
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
self._ema = ExponentialMovingAverage()
self._ema.Length = self.EmaLength
self._atr = AverageTrueRange()
self._atr.Length = self.AtrLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._ema, self._atr, self.ProcessCandle).Start()
def ProcessCandle(self, candle, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
ev = float(ema_val)
av = float(atr_val)
close = float(candle.ClosePrice)
if self._prev_high == 0 or av <= 0:
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
return
if self.Position > 0:
if close <= self._entry_price - av * 1.5 or close >= self._entry_price + av * 2.5:
self.SellMarket()
self._entry_price = 0.0
elif self.Position < 0:
if close >= self._entry_price + av * 1.5 or close <= self._entry_price - av * 2.5:
self.BuyMarket()
self._entry_price = 0.0
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
return
if self.Position == 0:
if close > self._prev_high and close > ev:
self._entry_price = close
self.BuyMarket()
elif close < self._prev_low and close < ev:
self._entry_price = close
self.SellMarket()
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
def OnReseted(self):
super(nevalyashka_breakdown_level_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
def CreateClone(self):
return nevalyashka_breakdown_level_strategy()