Esta estrategia reproduce el experto de MetaTrader Exp_CandlesticksBW_Tm sobre la API de alto nivel de StockSharp. Se basa en el indicador Candlesticks BW de Bill Williams, que pinta los colores de las velas combinando el Awesome Oscillator (AO) y el Accelerator Oscillator (AC). La aceleración y desaceleración del momentum se detectan mediante transiciones de color de velas, mientras que un filtro opcional de sesión de trading restringe las entradas a horas intradiarias específicas.
Cómo funciona
Se suscribe al marco temporal configurado (predeterminado H4) y alimenta cada vela finalizada a un Awesome Oscillator (5/34). La serie AO se suaviza con una media móvil simple de 5 períodos para producir el componente Accelerator.
Cada vela se clasifica en uno de seis estados de color: dos colores de momentum alcista (AO y AC subiendo), dos colores de momentum bajista (AO y AC cayendo) y dos colores neutros (dirección mixta AO/AC). La dirección del cuerpo de la vela decide entre el tono más oscuro o más claro en cada par.
Un buffer circular almacena los índices de color recientes junto con sus tiempos de apertura. El parámetro SignalBar selecciona qué barra histórica evaluar (predeterminado = vela anterior, es decir, offset 1). Una barra más atrás se usa como contexto.
Las entradas largas se habilitan cuando la barra más antigua pertenecía a una zona de momentum alcista y la barra de señal sale de esa zona. Las entradas cortas reflejan la lógica con zonas bajistas. Las señales de salida usan los mismos filtros de momentum para cerrar la dirección opuesta.
El filtro de sesión opcional (UseTimeFilter) mantiene un registro de trading entre StartHour:StartMinute y EndHour:EndMinute. Salir de la ventana liquida inmediatamente las posiciones abiertas, previniendo exposición nocturna.
Las protecciones de stop-loss y take-profit se registran a través de StartProtection, traduciendo distancias en puntos en pasos de precio del instrumento.
Reglas de trading
Abrir largo: índice de color de la barra anterior < 2 (AO y AC acelerando hacia arriba) y el índice de color de la barra de señal > 1. Las entradas largas se omiten si ya se está largo o si los largos están deshabilitados.
Abrir corto: índice de color de la barra anterior > 3 (AO y AC acelerando hacia abajo) y el índice de color de la barra de señal < 4.
Cerrar largo: se activa cuando el índice de color de la barra más antigua > 3 (aceleración bajista) y las salidas largas están habilitadas.
Cerrar corto: se activa cuando el índice de color de la barra más antigua < 2 (aceleración alcista) y las salidas cortas están habilitadas.
Cuando el filtro de tiempo está activo, las posiciones se cierran forzosamente fuera de la sesión permitida incluso sin señales de salida basadas en color.
Parámetros
Nombre
Descripción
Predeterminado
CandleType
Marco temporal usado para los cálculos AO/AC.
TimeSpan.FromHours(4).TimeFrame()
Volume
Tamaño de la orden para nuevas entradas.
1m
SignalBar
Número de velas finalizadas a omitir antes de evaluar señales (1 = vela anterior).
1
StopLossPoints
Distancia del stop protector en puntos del instrumento. Establezca 0 para deshabilitar.
1000m
TakeProfitPoints
Distancia del objetivo de beneficio en puntos del instrumento. Establezca 0 para deshabilitar.
2000m
EnableLongEntries, EnableShortEntries
Permitir abrir operaciones en la dirección respectiva.
true
EnableLongExits, EnableShortExits
Permitir cerrar operaciones en la dirección respectiva.
true
UseTimeFilter
Habilitar restricciones de sesión de trading.
true
StartHour, StartMinute, EndHour, EndMinute
Límites de sesión (inicio inclusivo, fin exclusivo para horas idénticas).
0/0/23/59
Notas
La estrategia sincroniza automáticamente las distancias de stop-loss y take-profit con el paso de precio del instrumento.
Las señales tienen marca de tiempo usando el tiempo de cierre de la barra evaluada para suprimir operaciones repetidas dentro de la misma barra.
No se proporciona versión de Python, coincidiendo con la estructura del paquete MQL fuente.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Bill Williams Candlesticks BW strategy (simplified).
/// Uses candle body direction with SMA trend filter.
/// </summary>
public class ExpCandlesticksBwTimeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smaLength;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int SmaLength
{
get => _smaLength.Value;
set => _smaLength.Value = value;
}
public ExpCandlesticksBwTimeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_smaLength = Param(nameof(SmaLength), 34)
.SetGreaterThanZero()
.SetDisplay("SMA Length", "Bill Williams median line proxy", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = SmaLength };
int bullCount = 0, bearCount = 0;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, (ICandleMessage candle, decimal smaValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var isBullish = candle.ClosePrice > candle.OpenPrice;
var isBearish = candle.ClosePrice < candle.OpenPrice;
if (isBullish)
{
bullCount++;
bearCount = 0;
}
else if (isBearish)
{
bearCount++;
bullCount = 0;
}
// 3 consecutive bullish candles above SMA
if (bullCount >= 3 && candle.ClosePrice > smaValue && Position <= 0)
{
BuyMarket();
bullCount = 0;
}
// 3 consecutive bearish candles below SMA
else if (bearCount >= 3 && candle.ClosePrice < smaValue && Position >= 0)
{
SellMarket();
bearCount = 0;
}
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class exp_candlesticks_bw_time_strategy(Strategy):
"""
Bill Williams Candlesticks BW strategy (simplified).
Uses candle body direction with SMA trend filter.
Buys after 3 consecutive bullish candles above SMA, sells after 3 bearish below SMA.
"""
def __init__(self):
super(exp_candlesticks_bw_time_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candles", "General")
self._sma_length = self.Param("SmaLength", 34) \
.SetDisplay("SMA Length", "Bill Williams median line proxy", "Indicators")
self._bull_count = 0
self._bear_count = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(exp_candlesticks_bw_time_strategy, self).OnReseted()
self._bull_count = 0
self._bear_count = 0
def OnStarted2(self, time):
super(exp_candlesticks_bw_time_strategy, self).OnStarted2(time)
self._bull_count = 0
self._bear_count = 0
sma = SimpleMovingAverage()
sma.Length = self._sma_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def _process_candle(self, candle, sma_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
sma_val = float(sma_val)
is_bullish = close > open_p
is_bearish = close < open_p
if is_bullish:
self._bull_count += 1
self._bear_count = 0
elif is_bearish:
self._bear_count += 1
self._bull_count = 0
if self._bull_count >= 3 and close > sma_val and self.Position <= 0:
self.BuyMarket()
self._bull_count = 0
elif self._bear_count >= 3 and close < sma_val and self.Position >= 0:
self.SellMarket()
self._bear_count = 0
def CreateClone(self):
return exp_candlesticks_bw_time_strategy()