AO Relâmpago reproduz o assessor especialista MT5 "AO_Lightning" usando a API de alto nível do StockSharp. O sistema monitora a inclinação do Awesome Oscillator (AO) construído a partir de preços medianos. Quando o oscilador diminui, a estratégia acumula exposição comprada, e quando o oscilador aumenta, ela constrói uma posição vendida. As posições são piramidadas até um limite configurável enquanto posições opostas são fechadas antes de mudar de direção.
Lógica de trading
Subscrever a série de velas selecionada e calcular o Awesome Oscillator com período curto 5 e período longo 34 (os padrões retirados do código MQL original).
Aguardar apenas velas terminadas; a estratégia ignora atualizações intermediárias para evitar dupla contagem.
Na primeira vela terminada, o valor AO é armazenado como referência.
Quando o valor AO atual é menor que o valor anterior:
Se existir uma posição vendida aberta, enviar uma ordem de compra de mercado dimensionada para fechar todo o vendido e imediatamente adicionar uma camada comprada.
Se não houver vendido e a exposição comprada estiver abaixo do limite, comprar uma camada adicional.
Quando o valor AO atual é maior que o valor anterior:
Se existir uma posição comprada aberta, enviar uma ordem de venda de mercado que fecha a exposição comprada e simultaneamente abre uma camada vendida.
Se não houver comprado e a exposição vendida estiver abaixo do limite, vender uma camada adicional.
Valores AO iguais ao valor anterior deixam a posição sem alteração.
O StartProtection() integrado é habilitado uma vez na inicialização para que os usuários do Designer possam anexar stops ou outros módulos de risco, se desejado.
A lógica reflete o assessor especialista original: a inclinação do AO define a direção do trade, os trades opostos são aplainados antes de uma nova entrada, e as ordens incrementais continuam se acumulando até o limite ser atingido.
Gerenciamento de posição
Volume de trade define o tamanho de cada camada adicional e corresponde ao parâmetro MT5 LotFixed.
Máximo de posições corresponde ao input MT5 Orders. Ele restringe quantas camadas podem se acumular em qualquer lado.
Piramidação é linear: cada sinal válido adiciona exatamente uma camada do tamanho de um lote, desde que o limite não tenha sido atingido.
Aplainamento envia ordens combinadas (fechar + nova direção) para evitar estados planos intermediários ao mudar de vendido para comprado ou vice-versa.
Parâmetros
Nome
Descrição
Padrão
TradeVolume
Tamanho da ordem para cada nova camada.
1
MaxPositions
Número máximo de camadas compradas ou vendidas que podem estar ativas simultaneamente.
10
AoShortPeriod
Comprimento da SMA rápida usada pelo Awesome Oscillator (SMA de preço mediano).
5
AoLongPeriod
Comprimento da SMA lenta para o Awesome Oscillator.
34
CandleType
Fonte de dados de velas processada pela estratégia.
Período de 5 minutos
Notas
O especialista MT5 original nomeia as entradas Period_sma_slow e Period_sma_fast mas troca os valores (5 e 34). O porto StockSharp mantém o mapeamento funcional expondo parâmetros intuitivos AoShortPeriod/AoLongPeriod.
Nenhuma versão Python é fornecida ainda, conforme a solicitação da tarefa.
Nenhum teste está incluído; execute as validações necessárias via Designer ou seu próprio conjunto de backtesting antes de implantar em produção.
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()