AO Blitz reproduziert den MT5-Expertenberater "AO_Lightning" mithilfe der High-Level-API von StockSharp. Das System überwacht die Steigung des Awesome Oscillators (AO), der aus Median-Preisen aufgebaut ist. Wenn der Oszillator sinkt, sammelt die Strategie Long-Exposure an, und wenn der Oszillator steigt, baut sie eine Short-Position auf. Positionen werden bis zu einer konfigurierbaren Obergrenze pyramidiert, während entgegengesetzte Positionen vor einem Richtungswechsel geschlossen werden.
Handelslogik
Die gewählte Kerzenserie abonnieren und den Awesome Oscillator mit Kurzperiode 5 und Langperiode 34 berechnen (die Standardwerte aus dem ursprünglichen MQL-Code).
Nur auf abgeschlossene Kerzen warten; die Strategie ignoriert Zwischenupdates, um Doppelzählungen zu vermeiden.
Bei der ersten abgeschlossenen Kerze wird der AO-Wert als Referenz gespeichert.
Wenn der aktuelle AO-Wert niedriger als der vorherige Wert ist:
Wenn eine offene Short-Position vorhanden ist, eine Market-Buy-Order senden, die darauf ausgelegt ist, den gesamten Short zu schließen und sofort eine Long-Schicht hinzuzufügen.
Wenn kein Short vorhanden ist und das Long-Exposure unter dem Limit liegt, eine zusätzliche Schicht kaufen.
Wenn der aktuelle AO-Wert höher als der vorherige Wert ist:
Wenn eine offene Long-Position vorhanden ist, eine Market-Sell-Order senden, die das Long-Exposure schließt und gleichzeitig eine Short-Schicht eröffnet.
Wenn kein Long vorhanden ist und das Short-Exposure unter dem Limit liegt, eine zusätzliche Schicht verkaufen.
AO-Werte, die dem vorherigen Wert entsprechen, lassen die Position unverändert.
Das integrierte StartProtection() wird einmalig beim Start aktiviert, damit Designer-Benutzer Stops oder andere Risikomodule anschließen können.
Die Logik spiegelt den ursprünglichen Expertenberater wider: Die AO-Steigung definiert die Handelsrichtung, entgegengesetzte Trades werden vor einem neuen Einstieg abgeflacht, und inkrementelle Orders akkumulieren sich bis zum Erreichen der Obergrenze.
Positionsmanagement
Handelsvolumen definiert die Größe jeder zusätzlichen Schicht und entspricht dem MT5-Parameter LotFixed.
Max. Positionen entspricht dem MT5-Orders-Input. Es begrenzt, wie viele Schichten auf beiden Seiten angehäuft werden können.
Pyramidisierung ist linear: Jedes gültige Signal fügt genau eine lot-große Schicht hinzu, sofern die Obergrenze nicht erreicht wurde.
Abflachung sendet kombinierte Orders (Schließen + neue Richtung), um Zwischenzustände ohne Position beim Wechsel von Short zu Long oder umgekehrt zu vermeiden.
Parameter
Name
Beschreibung
Standard
TradeVolume
Ordergröße für jede neue Schicht.
1
MaxPositions
Maximale Anzahl von Long- oder Short-Schichten, die gleichzeitig aktiv sein können.
10
AoShortPeriod
Schneller SMA-Zeitraum des Awesome Oscillators (Median-Preis-SMA).
5
AoLongPeriod
Langsamer SMA-Zeitraum des Awesome Oscillators.
34
CandleType
Von der Strategie verarbeitete Kerzendatenquelle.
5-Minuten-Zeitrahmen
Hinweise
Der ursprüngliche MT5-Experte benennt die Eingaben Period_sma_slow und Period_sma_fast, tauscht jedoch die Werte (5 und 34). Der StockSharp-Port behält das funktionale Mapping bei, indem er intuitive AoShortPeriod/AoLongPeriod-Parameter bereitstellt.
Es gibt noch keine Python-Version, entsprechend der Aufgabenanforderung.
Keine Tests enthalten; führen Sie notwendige Validierungen über Designer oder Ihr eigenes Backtesting-Framework durch, bevor Sie in die Produktion deployen.
namespace StockSharp.Samples.Strategies;
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// AO Lightning strategy.
/// Trades based on the Awesome Oscillator momentum slope direction.
/// Buys when AO is rising, sells when AO is falling.
/// </summary>
public class AoLightningStrategy : Strategy
{
private readonly StrategyParam<int> _aoShortPeriod;
private readonly StrategyParam<int> _aoLongPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevAo;
private bool _initialized;
public int AoShortPeriod
{
get => _aoShortPeriod.Value;
set => _aoShortPeriod.Value = value;
}
public int AoLongPeriod
{
get => _aoLongPeriod.Value;
set => _aoLongPeriod.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public AoLightningStrategy()
{
_aoShortPeriod = Param(nameof(AoShortPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("AO Fast", "Short SMA period for Awesome Oscillator", "Indicators");
_aoLongPeriod = Param(nameof(AoLongPeriod), 34)
.SetGreaterThanZero()
.SetDisplay("AO Slow", "Long SMA period for Awesome Oscillator", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Source candles", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevAo = 0m;
_initialized = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevAo = 0;
_initialized = false;
var ao = new AwesomeOscillator
{
ShortMa = { Length = AoShortPeriod },
LongMa = { Length = AoLongPeriod }
};
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ao, OnProcess)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ao);
DrawOwnTrades(area);
}
}
private void OnProcess(ICandleMessage candle, decimal aoValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (!_initialized)
{
_prevAo = aoValue;
_initialized = true;
return;
}
// Buy when AO is rising (bullish momentum)
if (aoValue > _prevAo && Position <= 0)
{
BuyMarket();
}
// Sell when AO is falling (bearish momentum)
else if (aoValue < _prevAo && Position >= 0)
{
SellMarket();
}
_prevAo = aoValue;
}
}
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 AwesomeOscillator
from StockSharp.Algo.Strategies import Strategy
class ao_lightning_strategy(Strategy):
def __init__(self):
super(ao_lightning_strategy, self).__init__()
self._ao_short_period = self.Param("AoShortPeriod", 5) \
.SetDisplay("AO Fast", "Short SMA period for Awesome Oscillator", "Indicators")
self._ao_long_period = self.Param("AoLongPeriod", 34) \
.SetDisplay("AO Slow", "Long SMA period for Awesome Oscillator", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Source candles", "General")
self._prev_ao = 0.0
self._initialized = False
@property
def AoShortPeriod(self):
return self._ao_short_period.Value
@property
def AoLongPeriod(self):
return self._ao_long_period.Value
@property
def CandleType(self):
return self._candle_type.Value
def OnReseted(self):
super(ao_lightning_strategy, self).OnReseted()
self._prev_ao = 0.0
self._initialized = False
def OnStarted2(self, time):
super(ao_lightning_strategy, self).OnStarted2(time)
self._prev_ao = 0.0
self._initialized = False
ao = AwesomeOscillator()
ao.ShortMa.Length = self.AoShortPeriod
ao.LongMa.Length = self.AoLongPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription \
.Bind(ao, self._on_process) \
.Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ao)
self.DrawOwnTrades(area)
def _on_process(self, candle, ao_value):
if candle.State != CandleStates.Finished:
return
av = float(ao_value)
if not self._initialized:
self._prev_ao = av
self._initialized = True
return
if av > self._prev_ao and self.Position <= 0:
self.BuyMarket()
elif av < self._prev_ao and self.Position >= 0:
self.SellMarket()
self._prev_ao = av
def CreateClone(self):
return ao_lightning_strategy()