Chaos Trader Lite Strategy
The Chaos Trader Lite strategy replicates Bill Williams' three wise men entry techniques using StockSharp's high level API. It analyses each finished candle of the configured timeframe (1 hour by default) and places stop orders when any of the following conditions are met:
- First Wise Man – Divergent bar: detects bullish or bearish divergent candles and requires a minimum gap between price and the Alligator lips line.
- Second Wise Man – Awesome Oscillator acceleration: waits for five consecutive Awesome Oscillator readings to show accelerating momentum.
- Third Wise Man – Fractal breakout: confirms a fractal two candles back and checks that price is trading sufficiently far from the Alligator teeth line before queuing a breakout order.
Whenever a long setup appears the strategy cancels existing sell stops, closes short positions, places a new buy stop just above the previous high and records a protective stop below the candle. The opposite happens for short setups. Protective stops are monitored on each bar; if price crosses the stored level the position is exited at market.
Indicators and calculations
- Alligator lips: 5-period smoothed moving average of the median price shifted three candles forward. The strategy keeps a queue so that the value aligned with the current bar matches the MetaTrader implementation.
- Alligator teeth: 8-period smoothed moving average of the median price shifted five candles forward. The shifted value drives the third wise man filter.
- Awesome Oscillator: StockSharp's built-in indicator (5 vs 34 SMA of the median price) provides the momentum series used by the second wise man.
- Fractals: the code inspects the high/low of the candle that sits two bars behind the latest bar. A valid fractal requires that candle to be higher (or lower) than the two candles on both sides.
Trading logic
- Subscribe to the requested candle type and process only finished candles.
- Update Alligator and Awesome Oscillator indicators and store shifted values.
- Evaluate the wise men conditions:
- Divergent bar must close in the upper (for bulls) or lower (for bears) half of the candle and show a distance from the lips greater than
MagnitudePips * PriceStep. - AO acceleration requires five values:
AO[1] > AO[2] > AO[3] > AO[4]andAO[4] < AO[5]for longs, mirrored for shorts. - Fractal breakout checks that price closes above (or below) the confirmed fractal and above (or below) the Alligator teeth plus the magnitude threshold.
- Divergent bar must close in the upper (for bulls) or lower (for bears) half of the candle and show a distance from the lips greater than
- When a setup is active place a
BuyStoporSellStoporder with volumeVolumeat the candle high plus one price step (or low minus one step). Cancel the opposite stop and flatten contrary positions. - Update stored stop-loss levels: long stops trail upwards, short stops trail downwards. If a candle pierces the stored stop the strategy exits the open position at market.
Parameters
MagnitudePips(default 10) – minimal pip distance between the divergent bar and the Alligator lips.UseFirstWiseMan(default true) – enable or disable the divergent bar entry.UseSecondWiseMan(default true) – enable or disable the Awesome Oscillator acceleration entry.UseThirdWiseMan(default true) – enable or disable the fractal breakout entry.Volume(default 0.01) – order size for stop entries.CandleType(default 1 hour) – data type processed by the strategy.
Notes
- Bid/ask checks from the original MQL4 code are approximated with the candle close price in StockSharp.
- Margin and volume validation routines from MetaTrader are omitted because StockSharp handles order validation internally.
- Stop orders are cancelled when the opposite setup appears to avoid conflicting pending orders, matching the
CloseAllbehaviour from the EA.
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>
/// Chaos Trader Lite strategy implementing Bill Williams' three wise men entry concepts.
/// Uses market orders when divergent bars, Awesome Oscillator accelerations or confirmed fractals appear.
/// </summary>
public class ChaosTraderLiteStrategy : Strategy
{
private readonly StrategyParam<int> _lipsShift;
private readonly StrategyParam<int> _teethShift;
private readonly StrategyParam<int> _magnitudePips;
private readonly StrategyParam<bool> _useFirstWiseMan;
private readonly StrategyParam<bool> _useSecondWiseMan;
private readonly StrategyParam<bool> _useThirdWiseMan;
private readonly StrategyParam<DataType> _candleType;
private SimpleMovingAverage _lipsSmma = null!;
private SimpleMovingAverage _teethSmma = null!;
private AwesomeOscillator _awesomeOscillator = null!;
private readonly List<decimal> _lipsShiftQueue = new();
private readonly List<decimal> _teethShiftQueue = new();
private CandleInfo? _bar0;
private CandleInfo? _bar1;
private CandleInfo? _bar2;
private CandleInfo? _bar3;
private CandleInfo? _bar4;
private decimal? _lips0;
private decimal? _teeth0;
private decimal? _teeth1;
private decimal? _ao0;
private decimal? _ao1;
private decimal? _ao2;
private decimal? _ao3;
private decimal? _ao4;
private decimal? _ao5;
private decimal? _longStopLoss;
private decimal? _shortStopLoss;
// Pending entry prices for stop-like behavior
private decimal? _pendingBuyPrice;
private decimal? _pendingSellPrice;
private decimal? _pendingBuyStop;
private decimal? _pendingSellStop;
/// <summary>
/// Magnitude threshold in pips between price and Alligator lips.
/// </summary>
public int MagnitudePips
{
get => _magnitudePips.Value;
set => _magnitudePips.Value = value;
}
/// <summary>
/// Number of candles used to shift the Alligator lips line.
/// </summary>
public int LipsShift
{
get => _lipsShift.Value;
set => _lipsShift.Value = value;
}
/// <summary>
/// Number of candles used to shift the Alligator teeth line.
/// </summary>
public int TeethShift
{
get => _teethShift.Value;
set => _teethShift.Value = value;
}
/// <summary>
/// Enable the first wise man divergent bar setup.
/// </summary>
public bool UseFirstWiseMan
{
get => _useFirstWiseMan.Value;
set => _useFirstWiseMan.Value = value;
}
/// <summary>
/// Enable the second wise man Awesome Oscillator acceleration setup.
/// </summary>
public bool UseSecondWiseMan
{
get => _useSecondWiseMan.Value;
set => _useSecondWiseMan.Value = value;
}
/// <summary>
/// Enable the third wise man fractal breakout setup.
/// </summary>
public bool UseThirdWiseMan
{
get => _useThirdWiseMan.Value;
set => _useThirdWiseMan.Value = value;
}
/// <summary>
/// Candle type processed by the strategy.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initialize <see cref="ChaosTraderLiteStrategy"/>.
/// </summary>
public ChaosTraderLiteStrategy()
{
_magnitudePips = Param(nameof(MagnitudePips), 10)
.SetGreaterThanZero()
.SetDisplay("Magnitude", "Distance from lips in pips", "General");
_lipsShift = Param(nameof(LipsShift), 3)
.SetNotNegative()
.SetDisplay("Lips Shift", "Shift applied to Alligator lips", "Alligator");
_teethShift = Param(nameof(TeethShift), 5)
.SetNotNegative()
.SetDisplay("Teeth Shift", "Shift applied to Alligator teeth", "Alligator");
_useFirstWiseMan = Param(nameof(UseFirstWiseMan), true)
.SetDisplay("First Wise Man", "Enable divergent bar setup", "General");
_useSecondWiseMan = Param(nameof(UseSecondWiseMan), true)
.SetDisplay("Second Wise Man", "Enable Awesome Oscillator setup", "General");
_useThirdWiseMan = Param(nameof(UseThirdWiseMan), true)
.SetDisplay("Third Wise Man", "Enable fractal breakout setup", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bar0 = _bar1 = _bar2 = _bar3 = _bar4 = null;
_lipsShiftQueue.Clear();
_teethShiftQueue.Clear();
_lips0 = null;
_teeth0 = null;
_teeth1 = null;
_ao0 = null;
_ao1 = null;
_ao2 = null;
_ao3 = null;
_ao4 = null;
_ao5 = null;
_longStopLoss = null;
_shortStopLoss = null;
_pendingBuyPrice = null;
_pendingSellPrice = null;
_pendingBuyStop = null;
_pendingSellStop = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_lipsSmma = new SimpleMovingAverage { Length = 5 };
_teethSmma = new SimpleMovingAverage { Length = 8 };
_awesomeOscillator = new AwesomeOscillator { ShortMa = { Length = 5 }, LongMa = { Length = 34 } };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _lipsSmma);
DrawIndicator(area, _teethSmma);
DrawIndicator(area, _awesomeOscillator);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Check pending stop-like entries first
CheckPendingEntries(candle);
UpdateBarHistory(candle);
var median = (candle.HighPrice + candle.LowPrice) / 2m;
var candleInput = new CandleIndicatorValue(_lipsSmma, candle);
var lipsValue = _lipsSmma.Process(new DecimalIndicatorValue(_lipsSmma, median, candle.ServerTime) { IsFinal = true });
var teethValue = _teethSmma.Process(new DecimalIndicatorValue(_teethSmma, median, candle.ServerTime) { IsFinal = true });
var awesomeValue = _awesomeOscillator.Process(new CandleIndicatorValue(_awesomeOscillator, candle));
if (lipsValue.IsFinal)
{
var lips = lipsValue.ToDecimal();
_lipsShiftQueue.Add(lips);
if (_lipsShiftQueue.Count > LipsShift)
{
_lips0 = _lipsShiftQueue[0];
try { _lipsShiftQueue.RemoveAt(0); } catch { }
}
}
if (teethValue.IsFinal)
{
var teeth = teethValue.ToDecimal();
_teethShiftQueue.Add(teeth);
if (_teethShiftQueue.Count > TeethShift)
{
_teeth1 = _teeth0;
_teeth0 = _teethShiftQueue[0];
try { _teethShiftQueue.RemoveAt(0); } catch { }
}
}
if (awesomeValue.IsFinal)
{
var ao = awesomeValue.ToDecimal();
_ao5 = _ao4;
_ao4 = _ao3;
_ao3 = _ao2;
_ao2 = _ao1;
_ao1 = _ao0;
_ao0 = ao;
}
var upFractal = GetUpFractal();
var downFractal = GetDownFractal();
if (_lipsSmma.IsFormed && _teethSmma.IsFormed)
EvaluateSignals(candle, upFractal, downFractal);
UpdateProtection(candle);
}
private void CheckPendingEntries(ICandleMessage candle)
{
// Simulate buy stop: if candle high reaches or exceeds pending buy price, enter long
if (_pendingBuyPrice is decimal buyPrice && candle.HighPrice >= buyPrice)
{
if (Position <= 0)
{
if (Position < 0)
{
BuyMarket();
_shortStopLoss = null;
}
if (Volume > 0)
{
BuyMarket();
_longStopLoss = _pendingBuyStop;
}
}
_pendingBuyPrice = null;
_pendingBuyStop = null;
}
// Simulate sell stop: if candle low reaches or goes below pending sell price, enter short
if (_pendingSellPrice is decimal sellPrice && candle.LowPrice <= sellPrice)
{
if (Position >= 0)
{
if (Position > 0)
{
SellMarket();
_longStopLoss = null;
}
if (Volume > 0)
{
SellMarket();
_shortStopLoss = _pendingSellStop;
}
}
_pendingSellPrice = null;
_pendingSellStop = null;
}
}
private void EvaluateSignals(ICandleMessage candle, decimal? upFractal, decimal? downFractal)
{
if (_bar0 is not CandleInfo current || _bar1 is not CandleInfo previous)
return;
var point = Security?.PriceStep ?? 1m;
var magnitudeThreshold = MagnitudePips * point;
if (UseFirstWiseMan && _lips0 is decimal lips)
{
if (IsBullishDivergent(current, previous))
{
var distance = lips - current.High;
if (distance > magnitudeThreshold)
PlaceBuySetup(current, point);
}
if (IsBearishDivergent(current, previous))
{
var distance = current.Low - lips;
if (distance > magnitudeThreshold)
PlaceSellSetup(current, point);
}
}
if (UseSecondWiseMan && _ao1.HasValue && _ao2.HasValue && _ao3.HasValue && _ao4.HasValue && _ao5.HasValue)
{
var currentAo = _ao1.Value;
var bar2Ao = _ao2.Value;
var bar3Ao = _ao3.Value;
var bar4Ao = _ao4.Value;
var bar5Ao = _ao5.Value;
var bullishAcceleration = currentAo > bar2Ao && bar2Ao > bar3Ao && bar3Ao > bar4Ao && bar4Ao < bar5Ao;
if (bullishAcceleration)
PlaceBuySetup(current, point);
var bearishAcceleration = currentAo < bar2Ao && bar2Ao < bar3Ao && bar3Ao < bar4Ao && bar4Ao > bar5Ao;
if (bearishAcceleration)
PlaceSellSetup(current, point);
}
if (UseThirdWiseMan && _teeth0.HasValue)
{
var teeth = _teeth0.Value;
var offset = MagnitudePips * point;
if (upFractal.HasValue && candle.ClosePrice > teeth + offset)
PlaceBuySetup(current, point);
if (downFractal.HasValue && candle.ClosePrice < teeth - offset)
PlaceSellSetup(current, point);
}
}
private void UpdateProtection(ICandleMessage candle)
{
if (Position > 0 && _longStopLoss is decimal longStop)
{
if (candle.LowPrice <= longStop)
{
SellMarket();
_longStopLoss = null;
}
}
else if (Position < 0 && _shortStopLoss is decimal shortStop)
{
if (candle.HighPrice >= shortStop)
{
BuyMarket();
_shortStopLoss = null;
}
}
}
private void PlaceBuySetup(CandleInfo bar, decimal point)
{
if (Volume <= 0)
return;
var entryPrice = bar.High + point;
if (entryPrice <= 0m)
return;
var stopPrice = bar.Low - point;
// Cancel pending sell
_pendingSellPrice = null;
_pendingSellStop = null;
// Set pending buy entry (simulates buy stop order)
_pendingBuyPrice = entryPrice;
_pendingBuyStop = stopPrice;
}
private void PlaceSellSetup(CandleInfo bar, decimal point)
{
if (Volume <= 0)
return;
var entryPrice = bar.Low - point;
if (entryPrice <= 0m)
return;
var stopPrice = bar.High + point;
// Cancel pending buy
_pendingBuyPrice = null;
_pendingBuyStop = null;
// Set pending sell entry (simulates sell stop order)
_pendingSellPrice = entryPrice;
_pendingSellStop = stopPrice;
}
private static bool IsBullishDivergent(CandleInfo current, CandleInfo previous)
{
var median = (current.High + current.Low) / 2m;
return current.Low < previous.Low && current.Close > median;
}
private static bool IsBearishDivergent(CandleInfo current, CandleInfo previous)
{
var median = (current.High + current.Low) / 2m;
return current.High > previous.High && current.Close < median;
}
private decimal? GetUpFractal()
{
if (_bar0 is not CandleInfo bar0 || _bar1 is not CandleInfo bar1 || _bar2 is not CandleInfo bar2 ||
_bar3 is not CandleInfo bar3 || _bar4 is not CandleInfo bar4)
return null;
return bar2.High > bar3.High && bar2.High > bar4.High && bar2.High > bar1.High && bar2.High > bar0.High
? bar2.High
: null;
}
private decimal? GetDownFractal()
{
if (_bar0 is not CandleInfo bar0 || _bar1 is not CandleInfo bar1 || _bar2 is not CandleInfo bar2 ||
_bar3 is not CandleInfo bar3 || _bar4 is not CandleInfo bar4)
return null;
return bar2.Low < bar3.Low && bar2.Low < bar4.Low && bar2.Low < bar1.Low && bar2.Low < bar0.Low
? bar2.Low
: null;
}
private void UpdateBarHistory(ICandleMessage candle)
{
_bar4 = _bar3;
_bar3 = _bar2;
_bar2 = _bar1;
_bar1 = _bar0;
_bar0 = new CandleInfo
{
Open = candle.OpenPrice,
High = candle.HighPrice,
Low = candle.LowPrice,
Close = candle.ClosePrice
};
}
private struct CandleInfo
{
public decimal Open { get; init; }
public decimal High { get; init; }
public decimal Low { get; init; }
public decimal Close { get; init; }
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
from StockSharp.Algo.Indicators import (
SimpleMovingAverage, AwesomeOscillator, CandleIndicatorValue
)
from indicator_extensions import *
class chaos_trader_lite_strategy(Strategy):
"""Chaos Trader Lite: Bill Williams three wise men with divergent bars, AO and fractals."""
def __init__(self):
super(chaos_trader_lite_strategy, self).__init__()
self._magnitude_pips = self.Param("MagnitudePips", 10) \
.SetGreaterThanZero() \
.SetDisplay("Magnitude", "Distance from lips in pips", "General")
self._lips_shift = self.Param("LipsShift", 3) \
.SetDisplay("Lips Shift", "Shift applied to Alligator lips", "Alligator")
self._teeth_shift = self.Param("TeethShift", 5) \
.SetDisplay("Teeth Shift", "Shift applied to Alligator teeth", "Alligator")
self._use_first = self.Param("UseFirstWiseMan", True) \
.SetDisplay("First Wise Man", "Enable divergent bar setup", "General")
self._use_second = self.Param("UseSecondWiseMan", True) \
.SetDisplay("Second Wise Man", "Enable Awesome Oscillator setup", "General")
self._use_third = self.Param("UseThirdWiseMan", True) \
.SetDisplay("Third Wise Man", "Enable fractal breakout setup", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._bars = [None] * 5 # bar0..bar4, each = (o, h, lo, c)
self._lips_queue = []
self._teeth_queue = []
self._lips0 = None
self._teeth0 = None
self._teeth1 = None
self._ao_hist = [None] * 6 # ao0..ao5
self._long_sl = None
self._short_sl = None
self._pending_buy = None
self._pending_sell = None
self._pending_buy_stop = None
self._pending_sell_stop = None
@property
def MagnitudePips(self):
return int(self._magnitude_pips.Value)
@property
def LipsShift(self):
return int(self._lips_shift.Value)
@property
def TeethShift(self):
return int(self._teeth_shift.Value)
@property
def UseFirstWiseMan(self):
return self._use_first.Value
@property
def UseSecondWiseMan(self):
return self._use_second.Value
@property
def UseThirdWiseMan(self):
return self._use_third.Value
@property
def CandleType(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(chaos_trader_lite_strategy, self).OnStarted2(time)
self._bars = [None] * 5
self._lips_queue = []
self._teeth_queue = []
self._lips0 = None
self._teeth0 = None
self._teeth1 = None
self._ao_hist = [None] * 6
self._long_sl = None
self._short_sl = None
self._pending_buy = None
self._pending_sell = None
self._pending_buy_stop = None
self._pending_sell_stop = None
self._lips_sma = SimpleMovingAverage()
self._lips_sma.Length = 5
self._teeth_sma = SimpleMovingAverage()
self._teeth_sma.Length = 8
self._ao = AwesomeOscillator()
self._ao.ShortMa.Length = 5
self._ao.LongMa.Length = 34
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
o = float(candle.OpenPrice)
c = float(candle.ClosePrice)
# Check pending entries
self._check_pending(candle)
# Update bar history
self._bars[4] = self._bars[3]
self._bars[3] = self._bars[2]
self._bars[2] = self._bars[1]
self._bars[1] = self._bars[0]
self._bars[0] = (o, h, lo, c)
median = (h + lo) / 2.0
# Lips
lips_val = process_float(self._lips_sma, Decimal(median), candle.ServerTime, True)
if lips_val.IsFinal:
lv = float(lips_val.Value)
self._lips_queue.append(lv)
if len(self._lips_queue) > self.LipsShift:
self._lips0 = self._lips_queue.pop(0)
# Teeth
teeth_val = process_float(self._teeth_sma, Decimal(median), candle.ServerTime, True)
if teeth_val.IsFinal:
tv = float(teeth_val.Value)
self._teeth_queue.append(tv)
if len(self._teeth_queue) > self.TeethShift:
self._teeth1 = self._teeth0
self._teeth0 = self._teeth_queue.pop(0)
# AO
ao_val = self._ao.Process(CandleIndicatorValue(self._ao, candle))
if ao_val.IsFinal:
av = float(ao_val.Value)
self._ao_hist[5] = self._ao_hist[4]
self._ao_hist[4] = self._ao_hist[3]
self._ao_hist[3] = self._ao_hist[2]
self._ao_hist[2] = self._ao_hist[1]
self._ao_hist[1] = self._ao_hist[0]
self._ao_hist[0] = av
up_fractal = self._get_up_fractal()
down_fractal = self._get_down_fractal()
if self._lips_sma.IsFormed and self._teeth_sma.IsFormed:
self._evaluate_signals(candle, up_fractal, down_fractal)
self._update_protection(candle)
def _check_pending(self, candle):
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
if self._pending_buy is not None and h >= self._pending_buy:
if self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self._short_sl = None
self.BuyMarket()
self._long_sl = self._pending_buy_stop
self._pending_buy = None
self._pending_buy_stop = None
if self._pending_sell is not None and lo <= self._pending_sell:
if self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self._long_sl = None
self.SellMarket()
self._short_sl = self._pending_sell_stop
self._pending_sell = None
self._pending_sell_stop = None
def _evaluate_signals(self, candle, up_fractal, down_fractal):
cur = self._bars[0]
prev = self._bars[1]
if cur is None or prev is None:
return
sec = self.Security
point = float(sec.PriceStep) if sec is not None and sec.PriceStep is not None and float(sec.PriceStep) > 0 else 1.0
mag_thresh = self.MagnitudePips * point
if self.UseFirstWiseMan and self._lips0 is not None:
lips = self._lips0
if self._is_bull_div(cur, prev):
dist = lips - cur[1]
if dist > mag_thresh:
self._place_buy(cur, point)
if self._is_bear_div(cur, prev):
dist = cur[2] - lips
if dist > mag_thresh:
self._place_sell(cur, point)
if self.UseSecondWiseMan:
ao1 = self._ao_hist[1]
ao2 = self._ao_hist[2]
ao3 = self._ao_hist[3]
ao4 = self._ao_hist[4]
ao5 = self._ao_hist[5]
if ao1 is not None and ao2 is not None and ao3 is not None and ao4 is not None and ao5 is not None:
if ao1 > ao2 and ao2 > ao3 and ao3 > ao4 and ao4 < ao5:
self._place_buy(cur, point)
if ao1 < ao2 and ao2 < ao3 and ao3 < ao4 and ao4 > ao5:
self._place_sell(cur, point)
if self.UseThirdWiseMan and self._teeth0 is not None:
teeth = self._teeth0
offset = self.MagnitudePips * point
c = float(candle.ClosePrice)
if up_fractal is not None and c > teeth + offset:
self._place_buy(cur, point)
if down_fractal is not None and c < teeth - offset:
self._place_sell(cur, point)
def _is_bull_div(self, cur, prev):
median = (cur[1] + cur[2]) / 2.0
return cur[2] < prev[2] and cur[3] > median
def _is_bear_div(self, cur, prev):
median = (cur[1] + cur[2]) / 2.0
return cur[1] > prev[1] and cur[3] < median
def _place_buy(self, bar, point):
entry = bar[1] + point
if entry <= 0:
return
stop = bar[2] - point
self._pending_sell = None
self._pending_sell_stop = None
self._pending_buy = entry
self._pending_buy_stop = stop
def _place_sell(self, bar, point):
entry = bar[2] - point
if entry <= 0:
return
stop = bar[1] + point
self._pending_buy = None
self._pending_buy_stop = None
self._pending_sell = entry
self._pending_sell_stop = stop
def _update_protection(self, candle):
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
if self.Position > 0 and self._long_sl is not None:
if lo <= self._long_sl:
self.SellMarket()
self._long_sl = None
elif self.Position < 0 and self._short_sl is not None:
if h >= self._short_sl:
self.BuyMarket()
self._short_sl = None
def _get_up_fractal(self):
b = self._bars
if b[0] is None or b[1] is None or b[2] is None or b[3] is None or b[4] is None:
return None
if b[2][1] > b[3][1] and b[2][1] > b[4][1] and b[2][1] > b[1][1] and b[2][1] > b[0][1]:
return b[2][1]
return None
def _get_down_fractal(self):
b = self._bars
if b[0] is None or b[1] is None or b[2] is None or b[3] is None or b[4] is None:
return None
if b[2][2] < b[3][2] and b[2][2] < b[4][2] and b[2][2] < b[1][2] and b[2][2] < b[0][2]:
return b[2][2]
return None
def OnReseted(self):
super(chaos_trader_lite_strategy, self).OnReseted()
self._bars = [None] * 5
self._lips_queue = []
self._teeth_queue = []
self._lips0 = None
self._teeth0 = None
self._teeth1 = None
self._ao_hist = [None] * 6
self._long_sl = None
self._short_sl = None
self._pending_buy = None
self._pending_sell = None
self._pending_buy_stop = None
self._pending_sell_stop = None
def CreateClone(self):
return chaos_trader_lite_strategy()