AIS3-Handelsroboter-Vorlage
Überblick
Die AIS3 Trading Robot-Vorlage ist ein MetaTrader-Breakout-System, das auf zwei koordinierten Zeitrahmen basiert. Der primäre Zeitrahmen
erfasst die Struktur der vorherigen Kerze, während ein sekundärer Zeitrahmen die aktuelle Volatilität misst, um nachfolgende Aktualisierungen zu kontrollieren.
Dieser StockSharp-Port reproduziert originalgetreu die ursprüngliche Auftragsgröße, Eingabeprüfungen und abschließende Logik, ist jedoch implementiert
oben auf der übergeordneten Strategie API, sodass es in Designer, Shell oder einem beliebigen benutzerdefinierten StockSharp-Host ausgeführt werden kann.
Handelsablauf
- Marktdatenabonnements: Die Strategie abonniert zwei Kerzenserien. Die primäre Serie (Standard 15 Minuten) bietet
das vorherige Kerzenhoch, -tief, -schluss, -mittelpunkt und -bereich. Die sekundäre Serie (Standard 1 Minute) misst den verwendeten schnellen Bereich
für Trailing Stops. Ein Live-Orderbuch-Feed hält die aktuell besten Geld-/Briefkurse mit den ursprünglichen MQL
MarketInfo synchronisiert.
Anfragen.
- Breakout-Validierung:
- Ein Long-Setup wird ausgelöst, wenn der vorherige Schlusskurs über dem Mittelpunkt liegt und der aktuelle Briefkurs über den vorherigen ausbricht
hoch plus die gemessene Spanne. Der Einstiegspreis ist der aktuelle Briefkurs.
- Ein Short-Setup erfordert, dass der vorherige Schlusskurs unter dem Mittelpunkt bleibt und der Geldkurs das vorherige Tief durchbricht. Der Eintrittspreis
ist das aktuelle Gebot.
- Beide Richtungen übernehmen die Broker-Sicherheitsüberprüfungen aus der Vorlage: den Abstand zwischen der Einfahrt und dem geplanten Stopp/Ziel
muss den konfigurierten Stop-Puffer überschreiten und der Stop muss auch nach Addition auf der richtigen Seite des Einstiegspreises bleiben
verbreiten.
- Schutzanordnungen:
- Die Stop-Loss-Distanz beträgt
primaryRange × StopMultiplier und ist oberhalb (für Long-Positionen) bzw. unterhalb (für Short-Positionen) verankert
Breakout-Kerze, wie im Integrationshandbuch beschrieben.
- Die Take-Profit-Distanz beträgt
primaryRange × TakeMultiplier und wird vom Einstiegspreis in Handelsrichtung platziert.
- Handelsmanagement:
- Wenn eine Position offen ist, definiert der sekundäre Zeitrahmenbereich multipliziert mit
TrailMultiplier die Nachlaufdistanz.
- Der Trailing-Stop wird nur aktualisiert, wenn der Handel profitabel ist und das neue Niveau weiter entfernt ist als der konfigurierte Freeze- und Stop-Wert
Puffern und die Entfernung zwischen der aktuellen und der geplanten Haltestelle überschreitet
TrailStepMultiplier × spread. Dies spiegelt die wider
Die Vorlage erfordert, dass der Preis um mindestens einen Trail-Schritt steigen muss, bevor der Stop geändert wird.
- Positionen werden mit Marktaufträgen geschlossen, wenn der Geld-/Briefkurs die gespeicherten Stop-Loss- oder Take-Profit-Werte berührt.
Risikomanagement
- Kontoreserve:
AccountReserve hält einen Bruchteil des Portfolio-Eigenkapitals gesperrt. Die Strategie weigert sich, neue Positionen zu eröffnen
wenn das reservierte Kapital das beantragte Auftragsbudget unterschreiten würde. Dies entspricht dem Verhalten der Vorlage, bei dem das Risiko besteht
Die Rücklage schützt das Konto vor kaskadierenden Verlusten.
- Orderreserve:
OrderReserve steuert den Teil des verbleibenden Kapitals, der pro Trade riskiert werden darf. Die Positionsgröße
wird als riskBudget / |entry - stop| berechnet und dann an den Sicherheitsvolumenschritt angepasst. Wenn keine Portfoliokennzahlen vorhanden sind
verfügbar, wird stattdessen der Fallback-Parameter BaseVolume verwendet.
- Puffer stoppen und einfrieren:
StopBufferTicks und FreezeBufferTicks übersetzen Broker-Stoppbeschränkungen (z. B. MODE_STOPLEVEL
und MODE_FREEZELEVEL von MetaTrader) mithilfe der Wertpapierpreisstufe in Preiseinheiten umwandeln. Sie verhindern, dass die Strategie umgesetzt wird
Aufträge, die gegen Wechselkursbeschränkungen verstoßen oder den Trailing Stop zu aggressiv verschieben würden.
- Multiplikator für nachfolgende Schritte:
TrailStepMultiplier spiegelt die Konstante acd.TrailStepping aus der MQ4-Vorlage wider. Es sorgt dafür
dass nachlaufende Aktualisierungen nur dann erfolgen, wenn der neue Stopp mindestens ein Spread-Vielfaches vom vorherigen Wert entfernt ist.
Parameter
| Parameter |
Beschreibung |
AccountReserve |
Als Sicherheitsreserve gehaltener Anteil des Eigenkapitals (0–0,95). |
OrderReserve |
Anteil des handelbaren Eigenkapitals, der dem Risikobudget pro Trade zugewiesen wird (standardmäßig 0–0,5). |
PrimaryCandleType |
Arbeitszeitrahmen für die Ausbruchserkennung (standardmäßig 15-Minuten-Kerzen). |
SecondaryCandleType |
Schnellerer Zeitrahmen, der die Nachlaufdistanz steuert (standardmäßige 1-Minuten-Kerzen). |
TakeMultiplier |
Multiplikator des primären Bereichs, der zum Platzieren der Take-Profit-Order verwendet wird. |
StopMultiplier |
Multiplikator des primären Bereichs, der zur Berechnung des Schutzstopps verwendet wird. |
TrailMultiplier |
Multiplikator des sekundären Bereichs, der die Nachlaufdistanz definiert. |
BaseVolume |
Größe der Ersatzposition, wenn Portfoliokennzahlen nicht verfügbar sind. |
StopBufferTicks |
Zusätzlicher Abstand in Preisticks, der zwischen Einstiegs- und Stop-/Zielniveau bleiben muss. |
FreezeBufferTicks |
Zusätzlicher Puffer, der verhindert, dass Stoppaktualisierungen zu nahe am Einfrierniveau des Brokers liegen. |
TrailStepMultiplier |
Spread-Multiplikator, der das minimale Inkrement zwischen nachfolgenden Anpassungen definiert. |
Nutzungshinweise
- Füttern Sie die Strategie mit beiden Kerzenserien und einem Level-1- oder Orderbuch-Stream, damit die besten Geld-/Briefkurse verfügbar sind. Laufen
Wenn nur die Daten des letzten Handels berücksichtigt werden, ändern sich die Ausbruchsprüfungen, da sie auf dem Spread basieren.
- Die Standardparameterwerte replizieren das MQ4-Vorlagenbeispiel (
TakeMultiplier = 1, StopMultiplier = 2,
TrailMultiplier = 3). Passen Sie sie an die Vermögenswerte an, mit denen Sie handeln, oder experimentieren Sie mit der Ausbruchsintensität.
- Der Trailing Stop ist virtuell – Aufträge werden an der Börse nicht geändert. Wenn die Nachstellbedingung erfüllt ist, ist die Strategie einfach
gibt einen Marktausstieg aus, der die Art und Weise widerspiegelt, wie der ursprüngliche Fachberater die Stopps intern verwaltet hat.
- Kombinieren Sie die Strategie mit dem integrierten Schutzmodul von StockSharp (bereits im Konstruktor aktiviert), um den Notfall aufrechtzuerhalten
Stop-Loss-Handhabung, auch wenn die Strategie vorübergehend unterbrochen ist.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// AIS3 Trading Robot: breakout strategy with ATR-based stops and trailing.
/// Enters on breakout above/below previous candle range with EMA filter.
/// </summary>
public class Ais3TradingRobotTemplateStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _atrLength;
private readonly StrategyParam<decimal> _takeMultiplier;
private readonly StrategyParam<decimal> _stopMultiplier;
private decimal _prevHigh;
private decimal _prevLow;
private decimal _entryPrice;
private decimal _stopPrice;
public Ais3TradingRobotTemplateStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_emaLength = Param(nameof(EmaLength), 20)
.SetDisplay("EMA Length", "EMA period for trend filter.", "Indicators");
_atrLength = Param(nameof(AtrLength), 14)
.SetDisplay("ATR Length", "ATR period.", "Indicators");
_takeMultiplier = Param(nameof(TakeMultiplier), 2.0m)
.SetDisplay("Take Multiplier", "ATR multiplier for TP.", "Risk");
_stopMultiplier = Param(nameof(StopMultiplier), 1.5m)
.SetDisplay("Stop Multiplier", "ATR multiplier for SL.", "Risk");
}
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;
}
public decimal TakeMultiplier
{
get => _takeMultiplier.Value;
set => _takeMultiplier.Value = value;
}
public decimal StopMultiplier
{
get => _stopMultiplier.Value;
set => _stopMultiplier.Value = value;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0;
_prevLow = 0;
_entryPrice = 0;
_stopPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHigh = 0;
_prevLow = 0;
_entryPrice = 0;
_stopPrice = 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;
if (_prevHigh == 0 || atrVal <= 0)
{
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
return;
}
var close = candle.ClosePrice;
var takeDistance = atrVal * TakeMultiplier;
var stopDistance = atrVal * StopMultiplier;
// Manage position
if (Position > 0)
{
if (close - _entryPrice >= takeDistance)
{
SellMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else if (_stopPrice > 0 && close <= _stopPrice)
{
SellMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else
{
var trail = close - stopDistance;
if (trail > _stopPrice) _stopPrice = trail;
}
}
else if (Position < 0)
{
if (_entryPrice - close >= takeDistance)
{
BuyMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else if (_stopPrice > 0 && close >= _stopPrice)
{
BuyMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else
{
var trail = close + stopDistance;
if (trail < _stopPrice || _stopPrice == 0) _stopPrice = trail;
}
}
// Entry on breakout + EMA filter
if (Position == 0)
{
if (close > _prevHigh && close > emaVal)
{
_entryPrice = close;
_stopPrice = close - stopDistance;
BuyMarket();
}
else if (close < _prevLow && close < emaVal)
{
_entryPrice = close;
_stopPrice = close + stopDistance;
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.Indicators import ExponentialMovingAverage, AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class ais3_trading_robot_template_strategy(Strategy):
"""
AIS3 Trading Robot: breakout strategy with ATR-based stops and trailing.
Enters on breakout above/below previous candle range with EMA filter.
"""
def __init__(self):
super(ais3_trading_robot_template_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._ema_length = self.Param("EmaLength", 20) \
.SetDisplay("EMA Length", "EMA period for trend filter.", "Indicators")
self._atr_length = self.Param("AtrLength", 14) \
.SetDisplay("ATR Length", "ATR period.", "Indicators")
self._take_multiplier = self.Param("TakeMultiplier", 2.0) \
.SetDisplay("Take Multiplier", "ATR multiplier for TP.", "Risk")
self._stop_multiplier = self.Param("StopMultiplier", 1.5) \
.SetDisplay("Stop Multiplier", "ATR multiplier for SL.", "Risk")
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaLength(self):
return self._ema_length.Value
@EmaLength.setter
def EmaLength(self, value):
self._ema_length.Value = value
@property
def AtrLength(self):
return self._atr_length.Value
@AtrLength.setter
def AtrLength(self, value):
self._atr_length.Value = value
@property
def TakeMultiplier(self):
return self._take_multiplier.Value
@TakeMultiplier.setter
def TakeMultiplier(self, value):
self._take_multiplier.Value = value
@property
def StopMultiplier(self):
return self._stop_multiplier.Value
@StopMultiplier.setter
def StopMultiplier(self, value):
self._stop_multiplier.Value = value
def OnReseted(self):
super(ais3_trading_robot_template_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
def OnStarted2(self, time):
super(ais3_trading_robot_template_strategy, self).OnStarted2(time)
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
ema = ExponentialMovingAverage()
ema.Length = self.EmaLength
atr = AverageTrueRange()
atr.Length = self.AtrLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, atr, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
if self._prev_high == 0 or atr_val <= 0:
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
return
close = float(candle.ClosePrice)
take_distance = atr_val * self.TakeMultiplier
stop_distance = atr_val * self.StopMultiplier
# Manage position
if self.Position > 0:
if close - self._entry_price >= take_distance:
self.SellMarket()
self._entry_price = 0.0
self._stop_price = 0.0
elif self._stop_price > 0 and close <= self._stop_price:
self.SellMarket()
self._entry_price = 0.0
self._stop_price = 0.0
else:
trail = close - stop_distance
if trail > self._stop_price:
self._stop_price = trail
elif self.Position < 0:
if self._entry_price - close >= take_distance:
self.BuyMarket()
self._entry_price = 0.0
self._stop_price = 0.0
elif self._stop_price > 0 and close >= self._stop_price:
self.BuyMarket()
self._entry_price = 0.0
self._stop_price = 0.0
else:
trail = close + stop_distance
if trail < self._stop_price or self._stop_price == 0:
self._stop_price = trail
# Entry on breakout + EMA filter
if self.Position == 0:
if close > self._prev_high and close > ema_val:
self._entry_price = close
self._stop_price = close - stop_distance
self.BuyMarket()
elif close < self._prev_low and close < ema_val:
self._entry_price = close
self._stop_price = close + stop_distance
self.SellMarket()
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return ais3_trading_robot_template_strategy()