A FT Bill Williams AO Strategy é uma versão de alto nível StockSharp do MetaTrader 4 especialista FT_BillWillams_AO. O original
robot foi publicado em FORTRADER.RU e combina fractais Bill Williams, o indicador Alligator e o Awesome Oscillator para
identificar oportunidades de ruptura antecipadas. A versão StockSharp mantém a lógica original, mas funciona com uma única posição líquida em vez de
vários pedidos simultâneos.
O algoritmo opera em velas concluídas a partir de um período configurável. Cada barra:
Detecta fractais de alta e baixa construídos a partir de um número ímpar de velas.
Filtra fractais verificando se o preço do fractal está fora da linha dos dentes Alligator.
Aguarda que o Awesome Oscillator (AO) forme o clássico padrão de aceleração de três barras.
Coloca um gatilho de rompimento acima/abaixo da máxima ou mínima recente, deslocado por um número definido pelo usuário de MetaTrader pontos.
Aplica a rotina de rastreamento Gragus de Bill Williams e regras de saída opcionais baseadas na mandíbula.
Lógica de entrada
Entradas longas
Um fractal de alta aparece e seu preço alto fica acima dos dentes Alligator.
Os valores AO obtidos SignalShift + 2, SignalShift + 1 e SignalShift velas atrás satisfazem A > B, B < C, e todos os três são
positivo.
Um nível de rompimento pendente é calculado como High[SignalShift] + IndentPoints * price step.
Quando uma vela completa cruza esse nível e AO ainda aumenta (C > B), a estratégia abre ou reverte para uma posição longa.
Entradas curtas
Um fractal de baixa aparece e seu mínimo está abaixo dos dentes Alligator.
Os valores AO satisfazem A < B, B > C e todos os três são negativos.
Um gatilho de breakout é colocado em Low[SignalShift] - IndentPoints * price step.
Uma posição curta (ou reversão de longa) é aberta quando a vela cai abaixo desse gatilho enquanto AO continua caindo (C < B).
Gestão de saída e risco
Stop-loss e take-profit iniciais são expressos em MetaTrader pontos e se traduzem na distância real do preço por meio do instrumento
etapa de preço.
O modo CloseDropTeeth pode fechar posições quando o fechamento atual ou o fechamento anterior cruza a mandíbula Alligator.
CloseReverseSignal determina se um fractal oposto ou a ativação do sinal de fuga oposto deve forçar um
saída.
A opção UseTrailing ativa a rotina de trailing stop original do Gragus: quando os lábios Alligator avançam mais rápido do que um curto
SMA, o stop é movido para os lábios; caso contrário, ele arrasta os dentes. Ambos os movimentos exigem que o preço fique a pelo menos 12 pontos de distância
da linha alvo.
Parâmetros
Nome
Descrição
TradeVolume
Tamanho do pedido em lotes. Também está escrito em Strategy.Volume.
CandleType
Tipo de dados e prazo das velas de entrada.
FractalPeriod
Número ímpar de velas usadas para confirmar fractais (padrão 5).
IndentPoints
MetaTrader pontos adicionados acima/abaixo da máxima/mínima da vela de rompimento.
JawPeriod, TeethPeriod, LipsPeriod
Comprimento das médias móveis suavizadas usadas pelas linhas Alligator.
JawShift, TeethShift, LipsShift
Deslocamento para frente (em velas) aplicado às linhas Alligator.
CloseDropTeeth
Comportamento da regra de fechamento baseada na mandíbula: desativado, cruzamento próximo atual ou cruzamento próximo anterior.
CloseReverseSignal
Condição de saída em sinais opostos: desativado, em novo fractal ou quando o breakout oposto estiver armado.
UseTrailing
Ativa ou desativa a rotina de trailing stop Gragus.
TrendSmaPeriod
Período do auxiliar SMA usado pela comparação final.
StopLossPoints
Distância inicial do stop-loss em MetaTrader pontos. Defina como zero para desativar.
TakeProfitPoints
Distância inicial de lucro em MetaTrader pontos. Defina como zero para desativar.
SignalShift
Número de velas totalmente fechadas ignoradas ao ler valores AO e máximos/mínimos recentes.
Notas
A estratégia assume que a segurança expõe um PriceStep válido (volta para MinPriceStep); se ambos estiverem faltando, um padrão de
0.0001 é usado.
Apenas uma posição líquida é gerenciada. Os sinais de reversão fecham automaticamente a posição oposta antes de abrir uma nova.
Para melhores resultados, mantenha FractalPeriod ímpar; o especialista original usou 5 velas.
IndentPoints, StopLossPoints e TakeProfitPoints imitam MetaTrader pontos. Ajuste-os de acordo com o preço do instrumento
escala.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Bill Williams Awesome Oscillator strategy.
/// Buys when AO crosses above zero and sells when AO crosses below zero,
/// filtered by Alligator teeth alignment.
/// </summary>
public class FtBillWilliamsAoStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _jawPeriod;
private readonly StrategyParam<int> _teethPeriod;
private readonly StrategyParam<int> _lipsPeriod;
private decimal _prevAo;
private decimal _prevTeeth;
private bool _isReady;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int JawPeriod
{
get => _jawPeriod.Value;
set => _jawPeriod.Value = value;
}
public int TeethPeriod
{
get => _teethPeriod.Value;
set => _teethPeriod.Value = value;
}
public int LipsPeriod
{
get => _lipsPeriod.Value;
set => _lipsPeriod.Value = value;
}
public FtBillWilliamsAoStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle type for strategy", "General");
_jawPeriod = Param(nameof(JawPeriod), 13)
.SetDisplay("Jaw Period", "Alligator jaw SMA period", "Alligator");
_teethPeriod = Param(nameof(TeethPeriod), 8)
.SetDisplay("Teeth Period", "Alligator teeth SMA period", "Alligator");
_lipsPeriod = Param(nameof(LipsPeriod), 5)
.SetDisplay("Lips Period", "Alligator lips SMA period", "Alligator");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevAo = 0;
_prevTeeth = 0;
_isReady = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ao = new AwesomeOscillator();
var teeth = new SMA { Length = TeethPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ao, teeth, OnProcess)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ao);
DrawIndicator(area, teeth);
DrawOwnTrades(area);
}
}
private void OnProcess(ICandleMessage candle, decimal aoVal, decimal teethVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!_isReady)
{
_prevAo = aoVal;
_prevTeeth = teethVal;
_isReady = true;
return;
}
var close = candle.ClosePrice;
// Buy signal: AO crosses above zero, price above teeth
if (_prevAo <= 0 && aoVal > 0 && close > teethVal)
{
if (Position < 0)
BuyMarket(); // close short
if (Position <= 0)
BuyMarket();
}
// Sell signal: AO crosses below zero, price below teeth
else if (_prevAo >= 0 && aoVal < 0 && close < teethVal)
{
if (Position > 0)
SellMarket(); // close long
if (Position >= 0)
SellMarket();
}
_prevAo = aoVal;
_prevTeeth = teethVal;
}
}
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, SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ft_bill_williams_ao_strategy(Strategy):
"""
FT Bill Williams AO: Awesome Oscillator zero-line cross with SMA teeth filter.
Buys when AO crosses above zero and price above teeth SMA.
Sells when AO crosses below zero and price below teeth SMA.
"""
def __init__(self):
super(ft_bill_williams_ao_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle type for strategy", "General")
self._jaw_period = self.Param("JawPeriod", 13) \
.SetDisplay("Jaw Period", "Alligator jaw SMA period", "Alligator")
self._teeth_period = self.Param("TeethPeriod", 8) \
.SetDisplay("Teeth Period", "Alligator teeth SMA period", "Alligator")
self._lips_period = self.Param("LipsPeriod", 5) \
.SetDisplay("Lips Period", "Alligator lips SMA period", "Alligator")
self._prev_ao = 0.0
self._prev_teeth = 0.0
self._is_ready = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(ft_bill_williams_ao_strategy, self).OnReseted()
self._prev_ao = 0.0
self._prev_teeth = 0.0
self._is_ready = False
def OnStarted2(self, time):
super(ft_bill_williams_ao_strategy, self).OnStarted2(time)
ao = AwesomeOscillator()
teeth = SimpleMovingAverage()
teeth.Length = self._teeth_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ao, teeth, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ao)
self.DrawIndicator(area, teeth)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ao_val, teeth_val):
if candle.State != CandleStates.Finished:
return
ao_val = float(ao_val)
teeth_val = float(teeth_val)
if not self._is_ready:
self._prev_ao = ao_val
self._prev_teeth = teeth_val
self._is_ready = True
return
close = float(candle.ClosePrice)
if self._prev_ao <= 0 and ao_val > 0 and close > teeth_val:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
elif self._prev_ao >= 0 and ao_val < 0 and close < teeth_val:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._prev_ao = ao_val
self._prev_teeth = teeth_val
def CreateClone(self):
return ft_bill_williams_ao_strategy()