La Estrategia FT Bill Williams AO es una versión StockSharp de alto nivel del MetaTrader 4 experto FT_BillWillams_AO. el original
El robot fue publicado en FORTRADER.RU y combina los fractales Bill Williams, el indicador Alligator y el Awesome Oscillator para
identificar oportunidades de ruptura tempranas. La versión StockSharp mantiene la lógica original pero funciona con una única posición neta en lugar de
múltiples pedidos simultáneos.
El algoritmo opera con velas completadas desde un período de tiempo configurable. Cada barra:
Detecta fractales alcistas y bajistas formados a partir de un número impar de velas.
Filtra fractales comprobando si el precio del fractal está fuera de la línea de dientes Alligator.
Espera a que Awesome Oscillator (AO) forme el clásico patrón de aceleración de tres barras.
Coloca un disparador de ruptura por encima o por debajo del máximo o mínimo reciente desplazado por un número definido por el usuario de MetaTrader puntos.
Aplica la rutina de seguimiento de Bill Williams' Gragus y reglas de salida opcionales basadas en la mandíbula.
Lógica de entrada
Entradas largas
Aparece un fractal alcista y su alto precio se sitúa por encima de los dientes Alligator.
Los valores de AO tomados hace SignalShift + 2, SignalShift + 1 y SignalShift velas satisfacen A > B, B < C, y los tres son
positivo.
Un nivel de ruptura pendiente se calcula como High[SignalShift] + IndentPoints * price step.
Cuando una vela completa cruza ese nivel y AO aún aumenta (C > B), la estrategia abre o revierte a una posición larga.
Entradas cortas
Aparece un fractal bajista y su mínimo está debajo de los dientes Alligator.
Los valores de AO satisfacen A < B, B > C y los tres son negativos.
Se coloca un activador de ruptura en Low[SignalShift] - IndentPoints * price step.
Se abre una posición corta (o reversión de una posición larga) cuando la vela cae por debajo de ese disparador mientras AO sigue cayendo (C < B).
Salida y gestión de riesgos.
El stop-loss y la toma de ganancias iniciales se expresan en MetaTrader puntos y se traducen en distancia de precio real a través del instrumento.
paso de precio.
El modo CloseDropTeeth puede cerrar posiciones cuando el cierre actual o el cierre anterior cruza la mandíbula Alligator.
CloseReverseSignal determina si un fractal opuesto o la activación de la señal de ruptura opuesta debería forzar una
salir.
El interruptor UseTrailing habilita la rutina original de parada dinámica de Gragus: cuando los labios Alligator avanzan más rápido que un corto
SMA, el stop se traslada a los labios; de lo contrario, arrastra los dientes. Ambos movimientos requieren que el precio se mantenga al menos a 12 puntos de distancia.
desde la línea objetivo.
Parámetros
Nombre
Descripción
TradeVolume
Tamaño del pedido en lotes. También está escrito en Strategy.Volume.
CandleType
Tipo de datos y período de tiempo de las velas de entrada.
FractalPeriod
Número impar de velas utilizadas para confirmar fractales (por defecto 5).
IndentPoints
MetaTrader puntos agregados por encima/debajo del máximo/mínimo de la vela de ruptura.
JawPeriod, TeethPeriod, LipsPeriod
Longitud de las medias móviles suavizadas utilizadas por las líneas Alligator.
JawShift, TeethShift, LipsShift
Desplazamiento hacia adelante (en velas) aplicado a las líneas Alligator.
CloseDropTeeth
Comportamiento de la regla de cierre basada en mandíbula: deshabilitada, cruce de cierre actual o cruce de cierre anterior.
CloseReverseSignal
Condición de salida en señales opuestas: desactivada, en un nuevo fractal o una vez que la fuga opuesta esté armada.
UseTrailing
Habilita o deshabilita la rutina de parada dinámica de Gragus.
TrendSmaPeriod
Período del auxiliar SMA utilizado por la comparación final.
StopLossPoints
Distancia inicial de stop-loss en MetaTrader puntos. Establezca en cero para desactivar.
TakeProfitPoints
Distancia inicial de obtención de beneficios en MetaTrader puntos. Establezca en cero para desactivar.
SignalShift
Número de velas completamente cerradas omitidas al leer los valores de AO y los máximos/mínimos recientes.
Notas
La estrategia supone que la seguridad expone un PriceStep válido (recurre a MinPriceStep); si faltan ambos, un valor predeterminado de
Se utiliza 0.0001.
Sólo se gestiona una posición neta. Las señales de inversión cierran automáticamente la posición opuesta antes de abrir una nueva.
Para obtener mejores resultados, mantenga FractalPeriod impar; El experto original usó 5 velas.
IndentPoints, StopLossPoints y TakeProfitPoints imitan MetaTrader puntos. Ajústalos según el precio del 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()