Esta estrategia implementa el segundo patrón "sabio" del sistema de trading de Bill Williams.
Analiza el histograma del Awesome Oscillator (AO) para detectar cambios de impulso:
Compra cuando el AO está por encima de cero y forma un pico seguido de tres barras consecutivamente más bajas.
Venta cuando el AO está por debajo de cero y forma un valle seguido de tres barras consecutivamente más altas.
Cada vez que aparece una señal, la estrategia cierra la posición opuesta y abre una nueva en la
dirección de la señal. Por defecto se utilizan velas de cuatro horas, pero el marco temporal puede
cambiarse mediante un parámetro.
No se incluye lógica de stop-loss ni take-profit; las posiciones se revierten únicamente cuando aparece
un patrón opuesto. La estrategia también dibuja velas, el indicador AO y las operaciones ejecutadas en
un gráfico para análisis visual.
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 Wise Man 2 strategy using Awesome Oscillator.
/// </summary>
public class BWWiseMan2Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal _ao0;
private decimal _ao1;
private decimal _ao2;
private int _aoCount;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public BWWiseMan2Strategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_ao0 = 0;
_ao1 = 0;
_ao2 = 0;
_aoCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ao = new AwesomeOscillator();
SubscribeCandles(CandleType)
.Bind(ao, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal aoValue)
{
if (candle.State != CandleStates.Finished) return;
_ao2 = _ao1;
_ao1 = _ao0;
_ao0 = aoValue;
if (_aoCount < 3)
{
_aoCount++;
return;
}
var buySignal = (_ao2 < 0 && _ao1 < 0 && _ao0 > 0) || (_ao2 < _ao1 && _ao1 < _ao0 && _ao0 > 0);
var sellSignal = (_ao2 > 0 && _ao1 > 0 && _ao0 < 0) || (_ao2 > _ao1 && _ao1 > _ao0 && _ao0 < 0);
if (buySignal && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (sellSignal && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
}
}
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 bw_wise_man2_strategy(Strategy):
def __init__(self):
super(bw_wise_man2_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._ao0 = 0.0
self._ao1 = 0.0
self._ao2 = 0.0
self._ao_count = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(bw_wise_man2_strategy, self).OnReseted()
self._ao0 = 0.0
self._ao1 = 0.0
self._ao2 = 0.0
self._ao_count = 0
def OnStarted2(self, time):
super(bw_wise_man2_strategy, self).OnStarted2(time)
ao = AwesomeOscillator()
self.SubscribeCandles(self.candle_type) \
.Bind(ao, self.process_candle) \
.Start()
def process_candle(self, candle, ao_value):
if candle.State != CandleStates.Finished:
return
ao_value = float(ao_value)
self._ao2 = self._ao1
self._ao1 = self._ao0
self._ao0 = ao_value
if self._ao_count < 3:
self._ao_count += 1
return
buy_signal = (self._ao2 < 0 and self._ao1 < 0 and self._ao0 > 0) or \
(self._ao2 < self._ao1 and self._ao1 < self._ao0 and self._ao0 > 0)
sell_signal = (self._ao2 > 0 and self._ao1 > 0 and self._ao0 < 0) or \
(self._ao2 > self._ao1 and self._ao1 > self._ao0 and self._ao0 < 0)
if buy_signal and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif sell_signal and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return bw_wise_man2_strategy()