Bayesian BBSMA Oscillator Strategy
The strategy estimates the probability of the next candle breaking up or down using a Bayesian model built from Bollinger Bands and a simple moving average. Optional confirmation from Bill Williams' Accelerator and Alligator indicators can filter signals. When the probability of an upward break rises above the threshold, a long trade is opened. A high probability of a downward break triggers a short.
Details
- Entry Criteria:
- Long when the prime or upward probability crosses above
LowerThreshold(default 15%) and, if enabled, Bill Williams confirmation is bullish. - Short when the prime or downward probability crosses above the threshold and, if enabled, Bill Williams confirmation is bearish.
- Long when the prime or upward probability crosses above
- Long/Short: Both.
- Exit Criteria:
- Reverse signal.
- Stops: None.
- Default Values:
BbSmaPeriod= 20BbStdDevMult= 2.5AoFast= 5AoSlow= 34AcFast= 5SmaPeriod= 20BayesPeriod= 20LowerThreshold= 15UseBwConfirmation= falseJawLength= 13
- Filters:
- Category: Probabilistic trend following
- Direction: Both
- Indicators: Bollinger Bands, SMA, Awesome Oscillator, Accelerator Oscillator, Alligator
- Stops: No
- Complexity: High
- Timeframe: Any
- Seasonality: No
- Neural networks: No
- Divergence: No
- Risk level: Medium
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()