Estrategia de Oscilador Bayesian BBSMA
La estrategia estima la probabilidad de que la siguiente vela rompa hacia arriba o hacia abajo usando un modelo Bayesian construido a partir de Bollinger Bands y una media móvil simple. La confirmación opcional de los indicadores Accelerator y Alligator de Bill Williams puede filtrar las señales. Cuando la probabilidad de una ruptura alcista supera el umbral, se abre una operación larga. Una alta probabilidad de ruptura bajista activa un corto.
Detalles
- Criterios de entrada:
- Largo cuando la probabilidad principal o alcista cruza por encima de
LowerThreshold(por defecto 15%) y, si está habilitado, la confirmación de Bill Williams es alcista. - Corto cuando la probabilidad principal o bajista cruza por encima del umbral y, si está habilitado, la confirmación de Bill Williams es bajista.
- Largo cuando la probabilidad principal o alcista cruza por encima de
- Largo/Corto: Ambos.
- Criterios de salida:
- Señal inversa.
- Stops: Ninguno.
- Valores predeterminados:
BbSmaPeriod= 20BbStdDevMult= 2.5AoFast= 5AoSlow= 34AcFast= 5SmaPeriod= 20BayesPeriod= 20LowerThreshold= 15UseBwConfirmation= falseJawLength= 13
- Filtros:
- Categoría: Seguimiento de tendencia probabilístico
- Dirección: Ambos
- Indicadores: Bollinger Bands, SMA, Awesome Oscillator, Accelerator Oscillator, Alligator
- Stops: No
- Complejidad: Alto
- Marco temporal: Cualquiera
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Bayesian BBSMA Oscillator strategy combines Bollinger Bands and Bayesian probabilities with optional Bill Williams confirmation.
/// </summary>
public class BayesianBbsmaOscillatorStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _bbSmaPeriod;
private readonly StrategyParam<decimal> _bbStdDevMult;
private readonly StrategyParam<int> _aoFast;
private readonly StrategyParam<int> _aoSlow;
private readonly StrategyParam<int> _acFast;
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<int> _bayesPeriod;
private readonly StrategyParam<decimal> _lowerThreshold;
private readonly StrategyParam<bool> _useBwConfirmation;
private readonly StrategyParam<int> _jawLength;
private BollingerBands _bollingerBands;
private SimpleMovingAverage _smaClose;
private SimpleMovingAverage _aoFastSma;
private SimpleMovingAverage _aoSlowSma;
private SimpleMovingAverage _acSma;
private SimpleMovingAverage _jawSma;
private SimpleMovingAverage _bbUpperUpSma;
private SimpleMovingAverage _bbUpperDownSma;
private SimpleMovingAverage _bbBasisUpSma;
private SimpleMovingAverage _bbBasisDownSma;
private SimpleMovingAverage _smaUpSma;
private SimpleMovingAverage _smaDownSma;
private decimal _prevAo;
private decimal _prevAc;
private decimal _prevSigmaProbsUp;
private decimal _prevSigmaProbsDown;
private decimal _prevProbPrime;
/// <summary>
/// Candle type for strategy calculation.
/// </summary>
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
/// <summary>
/// Bollinger SMA period.
/// </summary>
public int BbSmaPeriod { get => _bbSmaPeriod.Value; set => _bbSmaPeriod.Value = value; }
/// <summary>
/// Bollinger standard deviation multiplier.
/// </summary>
public decimal BbStdDevMult { get => _bbStdDevMult.Value; set => _bbStdDevMult.Value = value; }
/// <summary>
/// Fast period for Awesome Oscillator.
/// </summary>
public int AoFast { get => _aoFast.Value; set => _aoFast.Value = value; }
/// <summary>
/// Slow period for Awesome Oscillator.
/// </summary>
public int AoSlow { get => _aoSlow.Value; set => _aoSlow.Value = value; }
/// <summary>
/// Smoothing period for Accelerator Oscillator.
/// </summary>
public int AcFast { get => _acFast.Value; set => _acFast.Value = value; }
/// <summary>
/// Simple moving average period.
/// </summary>
public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
/// <summary>
/// Bayesian lookback period.
/// </summary>
public int BayesPeriod { get => _bayesPeriod.Value; set => _bayesPeriod.Value = value; }
/// <summary>
/// Lower probability threshold.
/// </summary>
public decimal LowerThreshold { get => _lowerThreshold.Value; set => _lowerThreshold.Value = value; }
/// <summary>
/// Require Bill Williams confirmation.
/// </summary>
public bool UseBwConfirmation { get => _useBwConfirmation.Value; set => _useBwConfirmation.Value = value; }
/// <summary>
/// Alligator jaw length.
/// </summary>
public int JawLength { get => _jawLength.Value; set => _jawLength.Value = value; }
/// <summary>
/// Constructor.
/// </summary>
public BayesianBbsmaOscillatorStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_bbSmaPeriod = Param(nameof(BbSmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("BB SMA Period", "Bollinger Bands SMA period", "Bollinger Bands")
.SetOptimize(10, 30, 5);
_bbStdDevMult = Param(nameof(BbStdDevMult), 2.5m)
.SetDisplay("BB StdDev Mult", "Bollinger Bands standard deviation multiplier", "Bollinger Bands")
.SetOptimize(1m, 4m, 0.5m);
_aoFast = Param(nameof(AoFast), 5)
.SetGreaterThanZero()
.SetDisplay("AO Fast", "Fast period for Awesome Oscillator", "Oscillators");
_aoSlow = Param(nameof(AoSlow), 34)
.SetGreaterThanZero()
.SetDisplay("AO Slow", "Slow period for Awesome Oscillator", "Oscillators");
_acFast = Param(nameof(AcFast), 5)
.SetGreaterThanZero()
.SetDisplay("AC Fast", "Smoothing period for Accelerator Oscillator", "Oscillators");
_smaPeriod = Param(nameof(SmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("SMA Period", "Simple moving average period", "General");
_bayesPeriod = Param(nameof(BayesPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Bayes Period", "Lookback period for probability calculation", "Bayesian");
_lowerThreshold = Param(nameof(LowerThreshold), 30m)
.SetDisplay("Lower Threshold", "Probability threshold (%)", "Bayesian");
_useBwConfirmation = Param(nameof(UseBwConfirmation), false)
.SetDisplay("Use BW Confirmation", "Require Bill Williams confirmation", "Filters");
_jawLength = Param(nameof(JawLength), 13)
.SetGreaterThanZero()
.SetDisplay("Jaw Length", "Alligator jaw SMA length", "Filters");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bollingerBands = default;
_smaClose = default;
_aoFastSma = default;
_aoSlowSma = default;
_acSma = default;
_jawSma = default;
_bbUpperUpSma = default;
_bbUpperDownSma = default;
_bbBasisUpSma = default;
_bbBasisDownSma = default;
_smaUpSma = default;
_smaDownSma = default;
_prevAo = default;
_prevAc = default;
_prevSigmaProbsUp = default;
_prevSigmaProbsDown = default;
_prevProbPrime = default;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_bollingerBands = new BollingerBands { Length = BbSmaPeriod, Width = BbStdDevMult };
_smaClose = new SMA { Length = SmaPeriod };
_aoFastSma = new SMA { Length = AoFast };
_aoSlowSma = new SMA { Length = AoSlow };
_acSma = new SMA { Length = AcFast };
_jawSma = new SMA { Length = JawLength };
_bbUpperUpSma = new SMA { Length = BayesPeriod };
_bbUpperDownSma = new SMA { Length = BayesPeriod };
_bbBasisUpSma = new SMA { Length = BayesPeriod };
_bbBasisDownSma = new SMA { Length = BayesPeriod };
_smaUpSma = new SMA { Length = BayesPeriod };
_smaDownSma = new SMA { Length = BayesPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(_bollingerBands, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent)
);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _bollingerBands);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue bbValue)
{
if (candle.State != CandleStates.Finished)
return;
if (bbValue is not BollingerBandsValue bb ||
bb.UpBand is not decimal bbUpper ||
bb.LowBand is not decimal bbLower ||
bb.MovingAverage is not decimal bbBasis)
return;
var t = candle.ServerTime;
var close = candle.ClosePrice;
var median = (candle.HighPrice + candle.LowPrice) / 2m;
var smaVal = _smaClose.Process(new DecimalIndicatorValue(_smaClose, close, t) { IsFinal = true });
var aoFastVal = _aoFastSma.Process(new DecimalIndicatorValue(_aoFastSma, median, t) { IsFinal = true });
var aoSlowVal = _aoSlowSma.Process(new DecimalIndicatorValue(_aoSlowSma, median, t) { IsFinal = true });
var jawVal = _jawSma.Process(new DecimalIndicatorValue(_jawSma, close, t) { IsFinal = true });
if (!aoSlowVal.IsFormed || !smaVal.IsFormed)
return;
var smaClose = smaVal.GetValue<decimal>();
var aoFast = aoFastVal.GetValue<decimal>();
var aoSlow = aoSlowVal.GetValue<decimal>();
var jaw = jawVal.GetValue<decimal>();
var ao = aoFast - aoSlow;
var aoSmaValue = _acSma.Process(new DecimalIndicatorValue(_acSma, ao, candle.ServerTime) { IsFinal = true });
if (!aoSmaValue.IsFormed)
return;
var ac = ao - aoSmaValue.GetValue<decimal>();
var acIsBlue = ac > _prevAc;
var aoIsGreen = ao > _prevAo;
var acAoIsBullish = acIsBlue && aoIsGreen;
var acAoIsBearish = !acIsBlue && !aoIsGreen;
var acAoColorIndex = acAoIsBullish ? 1 : acAoIsBearish ? -1 : 0;
var pricesAreMovingAwayUpFromAlligator = candle.ClosePrice > jaw && candle.OpenPrice > jaw;
var pricesAreMovingAwayDownFromAlligator = candle.ClosePrice < jaw && candle.OpenPrice < jaw;
var probBbUpperUp = _bbUpperUpSma.Process(new DecimalIndicatorValue(_bbUpperUpSma, candle.ClosePrice > bbUpper ? 1m : 0m, candle.ServerTime) { IsFinal = true }).GetValue<decimal>();
var probBbUpperDown = _bbUpperDownSma.Process(new DecimalIndicatorValue(_bbUpperDownSma, candle.ClosePrice < bbUpper ? 1m : 0m, candle.ServerTime) { IsFinal = true }).GetValue<decimal>();
var probBbBasisUp = _bbBasisUpSma.Process(new DecimalIndicatorValue(_bbBasisUpSma, candle.ClosePrice > bbBasis ? 1m : 0m, candle.ServerTime) { IsFinal = true }).GetValue<decimal>();
var probBbBasisDown = _bbBasisDownSma.Process(new DecimalIndicatorValue(_bbBasisDownSma, candle.ClosePrice < bbBasis ? 1m : 0m, candle.ServerTime) { IsFinal = true }).GetValue<decimal>();
var probSmaUp = _smaUpSma.Process(new DecimalIndicatorValue(_smaUpSma, candle.ClosePrice > smaClose ? 1m : 0m, candle.ServerTime) { IsFinal = true }).GetValue<decimal>();
var probSmaDown = _smaDownSma.Process(new DecimalIndicatorValue(_smaDownSma, candle.ClosePrice < smaClose ? 1m : 0m, candle.ServerTime) { IsFinal = true }).GetValue<decimal>();
if (!_bbUpperUpSma.IsFormed)
return;
var sumBbUpper = probBbUpperUp + probBbUpperDown;
var sumBbBasis = probBbBasisUp + probBbBasisDown;
var sumSma = probSmaUp + probSmaDown;
if (sumBbUpper == 0 || sumBbBasis == 0 || sumSma == 0) { _prevAo = ao; _prevAc = ac; return; }
var probUpBbUpper = probBbUpperUp / sumBbUpper;
var probUpBbBasis = probBbBasisUp / sumBbBasis;
var probUpSma = probSmaUp / sumSma;
var numDown = probUpBbUpper * probUpBbBasis * probUpSma;
var denDown = numDown + (1m - probUpBbUpper) * (1m - probUpBbBasis) * (1m - probUpSma);
var sigmaProbsDown = denDown == 0m ? 0m : numDown / denDown;
var probDownBbUpper = probBbUpperDown / sumBbUpper;
var probDownBbBasis = probBbBasisDown / sumBbBasis;
var probDownSma = probSmaDown / sumSma;
var numUp = probDownBbUpper * probDownBbBasis * probDownSma;
var denUp = numUp + (1m - probDownBbUpper) * (1m - probDownBbBasis) * (1m - probDownSma);
var sigmaProbsUp = denUp == 0m ? 0m : numUp / denUp;
var numPrime = sigmaProbsDown * sigmaProbsUp;
var denPrime = numPrime + (1m - sigmaProbsDown) * (1m - sigmaProbsUp);
var probPrime = denPrime == 0m ? 0m : numPrime / denPrime;
var threshold = LowerThreshold / 100m;
// Signal: use Bayesian probability crossovers
var upperThreshold = 1m - threshold;
var longSignal = (sigmaProbsUp > upperThreshold && _prevSigmaProbsUp <= upperThreshold) ||
(probPrime > upperThreshold && _prevProbPrime <= upperThreshold);
var shortSignal = (sigmaProbsDown > upperThreshold && _prevSigmaProbsDown <= upperThreshold) ||
(probPrime < threshold && _prevProbPrime >= threshold);
if (longSignal && Position == 0)
BuyMarket();
else if (shortSignal && Position == 0)
SellMarket();
_prevAo = ao;
_prevAc = ac;
_prevSigmaProbsUp = sigmaProbsUp;
_prevSigmaProbsDown = sigmaProbsDown;
_prevProbPrime = probPrime;
}
}
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, UnitTypes, Unit
from StockSharp.Algo.Indicators import BollingerBands, SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class bayesian_bbsma_oscillator_strategy(Strategy):
def __init__(self):
super(bayesian_bbsma_oscillator_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._bb_sma_period = self.Param("BbSmaPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("BB SMA Period", "Bollinger Bands SMA period", "Bollinger Bands")
self._bb_std_dev_mult = self.Param("BbStdDevMult", 2.5) \
.SetDisplay("BB StdDev Mult", "Bollinger Bands standard deviation multiplier", "Bollinger Bands")
self._ao_fast = self.Param("AoFast", 5) \
.SetGreaterThanZero() \
.SetDisplay("AO Fast", "Fast period for Awesome Oscillator", "Oscillators")
self._ao_slow = self.Param("AoSlow", 34) \
.SetGreaterThanZero() \
.SetDisplay("AO Slow", "Slow period for Awesome Oscillator", "Oscillators")
self._ac_fast = self.Param("AcFast", 5) \
.SetGreaterThanZero() \
.SetDisplay("AC Fast", "Smoothing period for Accelerator Oscillator", "Oscillators")
self._sma_period = self.Param("SmaPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("SMA Period", "Simple moving average period", "General")
self._bayes_period = self.Param("BayesPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Bayes Period", "Lookback period for probability calculation", "Bayesian")
self._lower_threshold = self.Param("LowerThreshold", 30.0) \
.SetDisplay("Lower Threshold", "Probability threshold (%)", "Bayesian")
self._use_bw_confirmation = self.Param("UseBwConfirmation", False) \
.SetDisplay("Use BW Confirmation", "Require Bill Williams confirmation", "Filters")
self._jaw_length = self.Param("JawLength", 13) \
.SetGreaterThanZero() \
.SetDisplay("Jaw Length", "Alligator jaw SMA length", "Filters")
self._prev_ao = 0.0
self._prev_ac = 0.0
self._prev_sigma_probs_up = 0.0
self._prev_sigma_probs_down = 0.0
self._prev_prob_prime = 0.0
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(bayesian_bbsma_oscillator_strategy, self).OnReseted()
self._prev_ao = 0.0
self._prev_ac = 0.0
self._prev_sigma_probs_up = 0.0
self._prev_sigma_probs_down = 0.0
self._prev_prob_prime = 0.0
def OnStarted2(self, time):
super(bayesian_bbsma_oscillator_strategy, self).OnStarted2(time)
self._bb = BollingerBands()
self._bb.Length = self._bb_sma_period.Value
self._bb.Width = self._bb_std_dev_mult.Value
self._sma_close = SimpleMovingAverage()
self._sma_close.Length = self._sma_period.Value
self._ao_fast_sma = SimpleMovingAverage()
self._ao_fast_sma.Length = self._ao_fast.Value
self._ao_slow_sma = SimpleMovingAverage()
self._ao_slow_sma.Length = self._ao_slow.Value
self._ac_sma = SimpleMovingAverage()
self._ac_sma.Length = self._ac_fast.Value
self._jaw_sma = SimpleMovingAverage()
self._jaw_sma.Length = self._jaw_length.Value
self._bb_upper_up_sma = SimpleMovingAverage()
self._bb_upper_up_sma.Length = self._bayes_period.Value
self._bb_upper_down_sma = SimpleMovingAverage()
self._bb_upper_down_sma.Length = self._bayes_period.Value
self._bb_basis_up_sma = SimpleMovingAverage()
self._bb_basis_up_sma.Length = self._bayes_period.Value
self._bb_basis_down_sma = SimpleMovingAverage()
self._bb_basis_down_sma.Length = self._bayes_period.Value
self._sma_up_sma = SimpleMovingAverage()
self._sma_up_sma.Length = self._bayes_period.Value
self._sma_down_sma = SimpleMovingAverage()
self._sma_down_sma.Length = self._bayes_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(self._bb, self._process_candle).Start()
self.StartProtection(
takeProfit=Unit(2, UnitTypes.Percent),
stopLoss=Unit(1, UnitTypes.Percent)
)
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, self._bb)
self.DrawOwnTrades(area)
def _process_candle(self, candle, bb_value):
if candle.State != CandleStates.Finished:
return
bb_upper = bb_value.UpBand
bb_lower = bb_value.LowBand
bb_basis = bb_value.MovingAverage
if bb_upper is None or bb_lower is None or bb_basis is None:
return
bb_upper = float(bb_upper)
bb_lower = float(bb_lower)
bb_basis = float(bb_basis)
t = candle.ServerTime
close = float(candle.ClosePrice)
median = (float(candle.HighPrice) + float(candle.LowPrice)) / 2.0
sma_val = process_float(self._sma_close, close, t, True)
ao_fast_val = process_float(self._ao_fast_sma, median, t, True)
ao_slow_val = process_float(self._ao_slow_sma, median, t, True)
jaw_val = process_float(self._jaw_sma, close, t, True)
if not ao_slow_val.IsFormed or not sma_val.IsFormed:
return
sma_close = float(sma_val)
ao_fast_v = float(ao_fast_val)
ao_slow_v = float(ao_slow_val)
jaw = float(jaw_val)
ao = ao_fast_v - ao_slow_v
ao_sma_value = process_float(self._ac_sma, ao, t, True)
if not ao_sma_value.IsFormed:
return
ac = ao - float(ao_sma_value)
ac_is_blue = ac > self._prev_ac
ao_is_green = ao > self._prev_ao
prob_bb_upper_up = float(process_float(self._bb_upper_up_sma, 1.0 if close > bb_upper else 0.0, t, True))
prob_bb_upper_down = float(process_float(self._bb_upper_down_sma, 1.0 if close < bb_upper else 0.0, t, True))
prob_bb_basis_up = float(process_float(self._bb_basis_up_sma, 1.0 if close > bb_basis else 0.0, t, True))
prob_bb_basis_down = float(process_float(self._bb_basis_down_sma, 1.0 if close < bb_basis else 0.0, t, True))
prob_sma_up = float(process_float(self._sma_up_sma, 1.0 if close > sma_close else 0.0, t, True))
prob_sma_down = float(process_float(self._sma_down_sma, 1.0 if close < sma_close else 0.0, t, True))
if not self._bb_upper_up_sma.IsFormed:
return
sum_bb_upper = prob_bb_upper_up + prob_bb_upper_down
sum_bb_basis = prob_bb_basis_up + prob_bb_basis_down
sum_sma = prob_sma_up + prob_sma_down
if sum_bb_upper == 0 or sum_bb_basis == 0 or sum_sma == 0:
self._prev_ao = ao
self._prev_ac = ac
return
p_up_bb_upper = prob_bb_upper_up / sum_bb_upper
p_up_bb_basis = prob_bb_basis_up / sum_bb_basis
p_up_sma = prob_sma_up / sum_sma
num_down = p_up_bb_upper * p_up_bb_basis * p_up_sma
den_down = num_down + (1.0 - p_up_bb_upper) * (1.0 - p_up_bb_basis) * (1.0 - p_up_sma)
sigma_probs_down = num_down / den_down if den_down != 0 else 0.0
p_down_bb_upper = prob_bb_upper_down / sum_bb_upper
p_down_bb_basis = prob_bb_basis_down / sum_bb_basis
p_down_sma = prob_sma_down / sum_sma
num_up = p_down_bb_upper * p_down_bb_basis * p_down_sma
den_up = num_up + (1.0 - p_down_bb_upper) * (1.0 - p_down_bb_basis) * (1.0 - p_down_sma)
sigma_probs_up = num_up / den_up if den_up != 0 else 0.0
num_prime = sigma_probs_down * sigma_probs_up
den_prime = num_prime + (1.0 - sigma_probs_down) * (1.0 - sigma_probs_up)
prob_prime = num_prime / den_prime if den_prime != 0 else 0.0
threshold = float(self._lower_threshold.Value) / 100.0
upper_threshold = 1.0 - threshold
long_signal = (sigma_probs_up > upper_threshold and self._prev_sigma_probs_up <= upper_threshold) or \
(prob_prime > upper_threshold and self._prev_prob_prime <= upper_threshold)
short_signal = (sigma_probs_down > upper_threshold and self._prev_sigma_probs_down <= upper_threshold) or \
(prob_prime < threshold and self._prev_prob_prime >= threshold)
if long_signal and self.Position == 0:
self.BuyMarket()
elif short_signal and self.Position == 0:
self.SellMarket()
self._prev_ao = ao
self._prev_ac = ac
self._prev_sigma_probs_up = sigma_probs_up
self._prev_sigma_probs_down = sigma_probs_down
self._prev_prob_prime = prob_prime
def CreateClone(self):
return bayesian_bbsma_oscillator_strategy()