Die Nina EA-Strategie ist ein One-Position-Trendfolger, der vom MetaTrader 4-Experten „NinaEA“ übernommen wurde. Der ursprüngliche Roboter verwendet einen benutzerdefinierten Indikator namens NINA und handelt immer dann, wenn die Differenz zwischen den bullischen und bärischen Puffern des Indikators über oder unter Null fällt. In der StockSharp-Version wird der benutzerdefinierte Indikator durch den integrierten SuperTrend-Indikator ersetzt, der auch separate bullische und bärische Puffer veröffentlicht. Eine Umkehrung der SuperTrend-Richtung dient als Nulldurchgangs-Proxy: Wenn der Trend bullisch wird, kauft die Strategie, und wenn er bärisch wird, verkauft sie.
Die Strategie behält immer höchstens eine offene Position. Ein entgegengesetztes Signal schließt sofort die bestehende Position und etabliert einen neuen Handel in die neue Richtung. Ein optionaler Stop-Loss, ausgedrückt in Preispunkten, kann aktiviert werden, um die ursprüngliche „StopLoss“-Eingabe nachzuahmen.
Handelslogik
Abonnieren Sie die konfigurierte Kerzenserie und berechnen Sie SuperTrend mit der angegebenen ATR-Periode und dem Multiplikator.
Warten Sie, bis sowohl die Strategie als auch der Indikator festgelegt sind, bevor Sie auf Signale reagieren.
Bei jeder fertigen Kerze:
Wenn ein schützender Stop-Preis erreicht wird, verlassen Sie die offene Position zum Marktwert.
Wenn der SuperTrend von bärisch zu bullisch wechselt, schließen Sie alle Short-Positionen und kaufen Sie mit dem konfigurierten Volumen.
Wenn der SuperTrend von bullisch zu bärisch wechselt, schließen Sie alle Long-Engagements und verkaufen Sie mit dem konfigurierten Volumen.
Speichern Sie die aktuelle SuperTrend-Richtung, um die nächste Umkehr zu erkennen.
Die Logik repliziert das Verhalten des MetaTrader-Experten, wobei nina = Buffer0 - Buffer1 und ein Vorzeichenwechsel sowohl Exits als auch neue Einträge bewirken.
Positions- und Risikomanagement
Es kann jeweils nur eine Position aktiv sein; Alle Trades kehren die Richtung um, anstatt mehrere Orders zu stapeln.
Aus dem Füllpreis wird ein optionaler Stop-Loss in Preispunkten berechnet. Bei einem Long-Trade wird der Stop unterhalb des Einstiegs platziert, bei einem Short-Trade wird er oberhalb des Einstiegs platziert. Wenn Sie den Parameter auf Null setzen, wird der Stopp deaktiviert.
StartProtection() wird aufgerufen, damit bei Bedarf integrierte StockSharp-Schutzmaßnahmen konfiguriert werden können.
Parameter
Parameter
Standard
Beschreibung
Volume
0.1
Bestellvolumen, das für jeden neuen Eintrag verwendet wird.
AtrPeriod
10
ATR Zeitraum, der an die SuperTrend-Berechnung übergeben wurde (bildet das Original PeriodWATR zu).
AtrMultiplier
1
ATR-Multiplikator für SuperTrend (bildet den ursprünglichen Kwatr ab).
StopLossPoints
0
Optionale Stop-Loss-Distanz in Preispunkten. Bei Zero bleibt der Stop deaktiviert, identisch mit dem MetaTrader-Code, der Market-Orders ohne Stop-Preis gesendet hat.
CandleType
TimeFrame(1 minute)
Kerzenserie, die den Indikator und die Handelslogik speist.
Konvertierungshinweise
Der MetaTrader-Experte verließ sich auf den benutzerdefinierten NINA-Indikator. Seine beiden Puffer wurden als bullische/bärische SuperTrend-Linien interpretiert, da nur ihre Differenz und ihr Vorzeichen für den Handel von Bedeutung waren. SuperTrend stellt dieselben Informationen über sein IsUpTrend-Flag bereit, was es zu einem geeigneten High-Level-Ersatz macht, der keine manuelle Pufferbehandlung erfordert.
Die Order-Closing-Logik spiegelt die OrdersTotal()-Schleife aus dem ursprünglichen Skript wider: Eine Trendumkehr schmeichelt zunächst der aktuellen Position und eröffnet dann einen Trade in die neue Richtung.
Die nicht verwendeten MetaTrader-Eingaben (highlow, cbars, from, maP, SMAspread, Slippage) werden weggelassen, da sie keinen Einfluss auf die Handelsregeln in der Originaldatei haben.
Nutzungstipps
Hängen Sie die Strategie an ein Wertpapier an und konfigurieren Sie den Kerzenzeitrahmen, der Ihrem MetaTrader-Test entspricht.
Passen Sie den ATR-Zeitraum und den Multiplikator an, um das Verhalten des ursprünglichen Indikators zu reproduzieren.
Erhöhen Sie StopLossPoints, wenn Sie ein hartes Risikolimit wünschen; andernfalls belassen Sie den Wert für rein signalbasierte Ausgänge auf Null.
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>
/// SuperTrend-based strategy from NinaEA.
/// Trades on SuperTrend direction flips - buy on up trend, sell on down trend.
/// </summary>
public class NinaEaStrategy : Strategy
{
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<decimal> _atrMultiplier;
private readonly StrategyParam<DataType> _candleType;
private bool? _previousTrendUp;
public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
public decimal AtrMultiplier { get => _atrMultiplier.Value; set => _atrMultiplier.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public NinaEaStrategy()
{
_atrPeriod = Param(nameof(AtrPeriod), 10)
.SetDisplay("ATR Period", "ATR length for SuperTrend", "Indicators");
_atrMultiplier = Param(nameof(AtrMultiplier), 1m)
.SetDisplay("ATR Multiplier", "SuperTrend multiplier", "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();
_previousTrendUp = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_previousTrendUp = null;
var superTrend = new SuperTrend
{
Length = AtrPeriod,
Multiplier = AtrMultiplier
};
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(superTrend, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue superTrendValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!superTrendValue.IsFinal)
return;
var stValue = (SuperTrendIndicatorValue)superTrendValue;
var isUpTrend = stValue.IsUpTrend;
if (_previousTrendUp is bool prevUp)
{
// Trend flipped to up - go long
if (isUpTrend && !prevUp)
{
if (Position < 0)
BuyMarket();
if (Position <= 0)
BuyMarket();
}
// Trend flipped to down - go short
else if (!isUpTrend && prevUp)
{
if (Position > 0)
SellMarket();
if (Position >= 0)
SellMarket();
}
}
_previousTrendUp = isUpTrend;
}
}
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 SuperTrend
from StockSharp.Algo.Strategies import Strategy
class nina_ea_strategy(Strategy):
"""SuperTrend-based strategy. Trades on SuperTrend direction flips.
Go long on up trend, go short on down trend."""
def __init__(self):
super(nina_ea_strategy, self).__init__()
self._atr_period = self.Param("AtrPeriod", 10) \
.SetDisplay("ATR Period", "ATR length for SuperTrend", "Indicators")
self._atr_multiplier = self.Param("AtrMultiplier", 1.0) \
.SetDisplay("ATR Multiplier", "SuperTrend multiplier", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._previous_trend_up = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def AtrPeriod(self):
return self._atr_period.Value
@property
def AtrMultiplier(self):
return self._atr_multiplier.Value
def OnReseted(self):
super(nina_ea_strategy, self).OnReseted()
self._previous_trend_up = None
def OnStarted2(self, time):
super(nina_ea_strategy, self).OnStarted2(time)
self._previous_trend_up = None
super_trend = SuperTrend()
super_trend.Length = self.AtrPeriod
super_trend.Multiplier = self.AtrMultiplier
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(super_trend, self._process_candle).Start()
def _process_candle(self, candle, super_trend_value):
if candle.State != CandleStates.Finished:
return
if not super_trend_value.IsFinal:
return
is_up_trend = super_trend_value.IsUpTrend if hasattr(super_trend_value, 'IsUpTrend') else None
if is_up_trend is None:
return
if self._previous_trend_up is not None:
prev_up = self._previous_trend_up
# Trend flipped to up - go long
if is_up_trend and not prev_up:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
# Trend flipped to down - go short
elif not is_up_trend and prev_up:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._previous_trend_up = is_up_trend
def CreateClone(self):
return nina_ea_strategy()