TDS Global Strategy
The strategy replicates the original MetaTrader "TDSGlobal" expert based on Alexander Elder's Triple Screen concept. It evaluates daily candles and combines the slope of MACD (12, 23, 9) with a 24-period Williams %R filter. The system seeks to buy when the trend is turning up while %R shows oversold conditions, and to sell when the trend turns down and %R signals overbought.
Whenever a valid setup is detected, the strategy places stop orders beyond the previous session's high or low. Entries are pushed away from the current market by a configurable buffer to avoid entering too close to the price, mirroring the original "16 point" offset logic. Once in a position the strategy manages a protective stop, optional take profit and a trailing stop in price steps.
Trading Logic
- Data: Works on daily candles by default (configurable).
- Trend filter: Compares two most recent MACD main-line values. Rising MACD implies long bias, falling MACD implies short bias.
- Oscillator filter: Uses the previous Williams %R value. Below
WilliamsBuyLevel(default -75) allows long setups, aboveWilliamsSellLevel(default -25) allows short setups. - Entry:
- Long: place a buy-stop above the prior high plus one price step. The entry is lifted to at least
EntryBufferStepsprice steps above the last close to keep a minimum distance from the market. - Short: place a sell-stop below the prior low minus one price step. The order is lowered to at most the last close minus
EntryBufferStepssteps.
- Long: place a buy-stop above the prior high plus one price step. The entry is lifted to at least
- Risk management:
- Initial stop is anchored to the opposite extreme of the previous candle (high for shorts, low for longs).
- Take profit distance equals
TakeProfitStepsprice steps. The default value (999) keeps the behaviour close to the MQL version that used a very wide target. - Trailing stop is enabled when
TrailingStopSteps> 0. It follows the close by that many steps and only tightens in the direction of the trade.
- Order handling:
- Existing stop orders are cancelled and refreshed whenever the entry price or protective levels need to be updated.
- Opposite trend signals remove pending orders that no longer align with the MACD direction.
- When a position opens the stored pending levels are reused to initialise the live stop/take prices.
- Optional staggering: The original EA staggered order placement across FX pairs to avoid simultaneous pending orders.
Setting
UseSymbolStaggertotrueenforces the same minute windows for EURUSD, GBPUSD, USDCHF and USDJPY.
Parameters
MacdFastLength,MacdSlowLength,MacdSignalLength– MACD periods used for the trend slope check.WilliamsLength– lookback for Williams %R.WilliamsBuyLevel,WilliamsSellLevel– oversold/overbought thresholds (negative values, closer to -100/-0 respectively).EntryBufferSteps– minimum offset from the current market when placing stop entries (number of price steps).TakeProfitSteps– target distance in price steps (set a small number to activate a hard target).TrailingStopSteps– trailing stop distance in steps; set to zero to disable trailing.UseSymbolStagger– enables the symbol-specific minute windows.CandleType– timeframe for candles (daily by default).
Notes
- Use the strategy volume to control the lot size; it defaults to 1 if no volume is specified.
- Pending orders and trailing exits operate on completed candles, so fills between candle closes are approximated by the stored entry price.
- The take profit default is large to match the original EA behaviour; adjust it when you need a finite target.
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>
/// Triple screen style daily breakout strategy using MACD slope and Williams %R.
/// Places stop orders beyond the prior day's extremes and manages trailing exits.
/// </summary>
public class TdsGlobalStrategy : Strategy
{
private readonly StrategyParam<int> _macdFastLength;
private readonly StrategyParam<int> _macdSlowLength;
private readonly StrategyParam<int> _macdSignalLength;
private readonly StrategyParam<int> _williamsLength;
private readonly StrategyParam<decimal> _williamsBuyLevel;
private readonly StrategyParam<decimal> _williamsSellLevel;
private readonly StrategyParam<int> _entryBufferSteps;
private readonly StrategyParam<decimal> _takeProfitSteps;
private readonly StrategyParam<decimal> _trailingStopSteps;
private readonly StrategyParam<bool> _useSymbolStagger;
private readonly StrategyParam<DataType> _candleType;
private decimal _priceStep;
private decimal? _macdPrev1;
private decimal? _macdPrev2;
private decimal? _williamsPrev1;
private decimal? _prevHigh;
private decimal? _prevLow;
private decimal? _prevClose;
private bool _hasPendingOrder;
private Sides? _pendingSide;
private decimal? _pendingEntryPrice;
private decimal? _pendingStopPrice;
private decimal? _pendingTakePrice;
private decimal? _entryPrice;
private decimal? _stopPrice;
private decimal? _takePrice;
private DateTimeOffset? _lastEntryTime;
/// <summary>
/// Fast EMA period used by MACD.
/// </summary>
public int MacdFastLength
{
get => _macdFastLength.Value;
set => _macdFastLength.Value = value;
}
/// <summary>
/// Slow EMA period used by MACD.
/// </summary>
public int MacdSlowLength
{
get => _macdSlowLength.Value;
set => _macdSlowLength.Value = value;
}
/// <summary>
/// Signal period for MACD.
/// </summary>
public int MacdSignalLength
{
get => _macdSignalLength.Value;
set => _macdSignalLength.Value = value;
}
/// <summary>
/// Williams %R lookback length.
/// </summary>
public int WilliamsLength
{
get => _williamsLength.Value;
set => _williamsLength.Value = value;
}
/// <summary>
/// Oversold threshold for Williams %R.
/// </summary>
public decimal WilliamsBuyLevel
{
get => _williamsBuyLevel.Value;
set => _williamsBuyLevel.Value = value;
}
/// <summary>
/// Overbought threshold for Williams %R.
/// </summary>
public decimal WilliamsSellLevel
{
get => _williamsSellLevel.Value;
set => _williamsSellLevel.Value = value;
}
/// <summary>
/// Minimum distance from market price when placing stop entries (in steps).
/// </summary>
public int EntryBufferSteps
{
get => _entryBufferSteps.Value;
set => _entryBufferSteps.Value = value;
}
/// <summary>
/// Take profit distance expressed in price steps.
/// </summary>
public decimal TakeProfitSteps
{
get => _takeProfitSteps.Value;
set => _takeProfitSteps.Value = value;
}
/// <summary>
/// Trailing stop distance expressed in price steps.
/// </summary>
public decimal TrailingStopSteps
{
get => _trailingStopSteps.Value;
set => _trailingStopSteps.Value = value;
}
/// <summary>
/// Enable symbol specific minute windows for order placement.
/// </summary>
public bool UseSymbolStagger
{
get => _useSymbolStagger.Value;
set => _useSymbolStagger.Value = value;
}
/// <summary>
/// Candle type used for calculations (defaults to daily candles).
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="TdsGlobalStrategy"/> class.
/// </summary>
public TdsGlobalStrategy()
{
_macdFastLength = Param(nameof(MacdFastLength), 12)
.SetGreaterThanZero()
.SetDisplay("MACD Fast", "Fast EMA length", "MACD");
_macdSlowLength = Param(nameof(MacdSlowLength), 23)
.SetGreaterThanZero()
.SetDisplay("MACD Slow", "Slow EMA length", "MACD");
_macdSignalLength = Param(nameof(MacdSignalLength), 9)
.SetGreaterThanZero()
.SetDisplay("MACD Signal", "Signal line length", "MACD");
_williamsLength = Param(nameof(WilliamsLength), 24)
.SetGreaterThanZero()
.SetDisplay("Williams Length", "%R lookback", "Filters");
_williamsBuyLevel = Param(nameof(WilliamsBuyLevel), 30m)
.SetDisplay("Williams Buy", "Oversold threshold", "Filters");
_williamsSellLevel = Param(nameof(WilliamsSellLevel), 70m)
.SetDisplay("Williams Sell", "Overbought threshold", "Filters");
_entryBufferSteps = Param(nameof(EntryBufferSteps), 16)
.SetGreaterThanZero()
.SetDisplay("Entry Buffer", "Minimum distance from market in steps", "Risk");
_takeProfitSteps = Param(nameof(TakeProfitSteps), 999m)
.SetDisplay("Take Profit Steps", "Target distance in price steps", "Risk");
_trailingStopSteps = Param(nameof(TrailingStopSteps), 10m)
.SetDisplay("Trailing Stop Steps", "Trailing stop distance in steps", "Risk");
_useSymbolStagger = Param(nameof(UseSymbolStagger), false)
.SetDisplay("Use Time Windows", "Apply symbol specific minute windows", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_priceStep = 0m;
_macdPrev1 = null;
_macdPrev2 = null;
_williamsPrev1 = null;
_prevHigh = null;
_prevLow = null;
_prevClose = null;
ResetPendingOrder();
ResetPositionState();
_lastEntryTime = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_priceStep = Security?.PriceStep ?? 1m;
if (_priceStep <= 0)
_priceStep = 1m;
var macd = new MACD
{
ShortMa = { Length = MacdFastLength },
LongMa = { Length = MacdSlowLength },
};
var williams = new RelativeStrengthIndex { Length = WilliamsLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(macd, williams, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal macdLine, decimal williams)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormed)
{
UpdateHistory(macdLine, williams, candle);
return;
}
ManageOpenPosition(candle);
if (Math.Abs(Position) > 0)
{
UpdateHistory(macdLine, williams, candle);
return;
}
if (_macdPrev1 is null || _macdPrev2 is null || _williamsPrev1 is null ||
_prevHigh is null || _prevLow is null || _prevClose is null)
{
UpdateHistory(macdLine, williams, candle);
return;
}
if (UseSymbolStagger && !IsWithinAllowedWindow(candle.CloseTime))
{
UpdateHistory(macdLine, williams, candle);
return;
}
var direction = _macdPrev1 > _macdPrev2 ? 1 : _macdPrev1 < _macdPrev2 ? -1 : 0;
var oversold = _williamsPrev1 <= WilliamsBuyLevel;
var overbought = _williamsPrev1 >= WilliamsSellLevel;
var volume = Volume;
if (volume <= 0)
volume = 1m;
var cooldownPassed = _lastEntryTime is null || candle.CloseTime - _lastEntryTime >= TimeSpan.FromHours(24);
if (direction > 0 && oversold && cooldownPassed)
{
PlaceBuyStop(volume, candle.CloseTime);
}
else if (direction < 0 && overbought && cooldownPassed)
{
PlaceSellStop(volume, candle.CloseTime);
}
else if (_hasPendingOrder)
{
if ((_pendingSide == Sides.Buy && direction < 0) ||
(_pendingSide == Sides.Sell && direction > 0))
{
ResetPendingOrder();
}
}
UpdateHistory(macdLine, williams, candle);
}
private void ManageOpenPosition(ICandleMessage candle)
{
var position = Position;
if (position > 0)
{
if (_entryPrice is null)
{
_entryPrice = _pendingEntryPrice ?? candle.ClosePrice;
_stopPrice = _pendingStopPrice;
_takePrice = _pendingTakePrice;
ResetPendingOrder();
}
if (TrailingStopSteps > 0)
{
var trailing = candle.ClosePrice - TrailingStopSteps * _priceStep;
if (_stopPrice is null || trailing > _stopPrice)
_stopPrice = trailing;
}
if (_stopPrice is not null && candle.LowPrice <= _stopPrice)
{
if (Position > 0) SellMarket(Math.Abs(Position)); else if (Position < 0) BuyMarket(Math.Abs(Position));
ResetPositionState();
ResetPendingOrder();
return;
}
if (_takePrice is not null && candle.HighPrice >= _takePrice)
{
if (Position > 0) SellMarket(Math.Abs(Position)); else if (Position < 0) BuyMarket(Math.Abs(Position));
ResetPositionState();
ResetPendingOrder();
}
}
else if (position < 0)
{
if (_entryPrice is null)
{
_entryPrice = _pendingEntryPrice ?? candle.ClosePrice;
_stopPrice = _pendingStopPrice;
_takePrice = _pendingTakePrice;
ResetPendingOrder();
}
if (TrailingStopSteps > 0)
{
var trailing = candle.ClosePrice + TrailingStopSteps * _priceStep;
if (_stopPrice is null || trailing < _stopPrice)
_stopPrice = trailing;
}
if (_stopPrice is not null && candle.HighPrice >= _stopPrice)
{
if (Position > 0) SellMarket(Math.Abs(Position)); else if (Position < 0) BuyMarket(Math.Abs(Position));
ResetPositionState();
ResetPendingOrder();
return;
}
if (_takePrice is not null && candle.LowPrice <= _takePrice)
{
if (Position > 0) SellMarket(Math.Abs(Position)); else if (Position < 0) BuyMarket(Math.Abs(Position));
ResetPositionState();
ResetPendingOrder();
}
}
else
{
ResetPositionState();
}
}
private void PlaceBuyStop(decimal volume, DateTimeOffset time)
{
if (_prevHigh is null || _prevLow is null || _prevClose is null)
return;
var entryPrice = Math.Max(_prevHigh.Value + _priceStep, _prevClose.Value + EntryBufferSteps * _priceStep);
var stopPrice = _prevLow.Value - _priceStep;
var takePrice = TakeProfitSteps > 0 ? entryPrice + TakeProfitSteps * _priceStep : (decimal?)null;
if (_hasPendingOrder && _pendingSide == Sides.Buy &&
_pendingEntryPrice == entryPrice &&
_pendingStopPrice == stopPrice &&
_pendingTakePrice == takePrice)
{
return;
}
BuyMarket(volume);
_lastEntryTime = time;
_pendingSide = Sides.Buy;
_pendingEntryPrice = entryPrice;
_pendingStopPrice = stopPrice;
_pendingTakePrice = takePrice;
_hasPendingOrder = true;
}
private void PlaceSellStop(decimal volume, DateTimeOffset time)
{
if (_prevHigh is null || _prevLow is null || _prevClose is null)
return;
var entryPrice = Math.Min(_prevLow.Value - _priceStep, _prevClose.Value - EntryBufferSteps * _priceStep);
var stopPrice = _prevHigh.Value + _priceStep;
var takePrice = TakeProfitSteps > 0 ? entryPrice - TakeProfitSteps * _priceStep : (decimal?)null;
if (_hasPendingOrder && _pendingSide == Sides.Sell &&
_pendingEntryPrice == entryPrice &&
_pendingStopPrice == stopPrice &&
_pendingTakePrice == takePrice)
{
return;
}
SellMarket(volume);
_lastEntryTime = time;
_pendingSide = Sides.Sell;
_pendingEntryPrice = entryPrice;
_pendingStopPrice = stopPrice;
_pendingTakePrice = takePrice;
_hasPendingOrder = true;
}
private void ResetPendingOrder()
{
_hasPendingOrder = false;
_pendingSide = null;
_pendingEntryPrice = null;
_pendingStopPrice = null;
_pendingTakePrice = null;
}
private void ResetPositionState()
{
_entryPrice = null;
_stopPrice = null;
_takePrice = null;
}
private void UpdateHistory(decimal macdLine, decimal williams, ICandleMessage candle)
{
if (_macdPrev1 is not null)
_macdPrev2 = _macdPrev1;
_macdPrev1 = macdLine;
_williamsPrev1 = williams;
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
_prevClose = candle.ClosePrice;
}
private bool IsWithinAllowedWindow(DateTimeOffset time)
{
if (!UseSymbolStagger)
return true;
var minute = time.Minute;
var code = Security?.Code?.ToUpperInvariant();
switch (code)
{
case "USDCHF":
return (minute >= 0 && minute <= 1) || (minute >= 8 && minute <= 9) ||
(minute >= 16 && minute <= 17) || (minute >= 24 && minute <= 25) ||
(minute >= 32 && minute <= 33) || (minute >= 40 && minute <= 41) ||
(minute >= 48 && minute <= 49);
case "GBPUSD":
return (minute >= 2 && minute <= 3) || (minute >= 10 && minute <= 11) ||
(minute >= 18 && minute <= 19) || (minute >= 26 && minute <= 27) ||
(minute >= 34 && minute <= 35) || (minute >= 42 && minute <= 43) ||
(minute >= 50 && minute <= 51);
case "USDJPY":
return (minute >= 4 && minute <= 5) || (minute >= 12 && minute <= 13) ||
(minute >= 20 && minute <= 21) || (minute >= 28 && minute <= 29) ||
(minute >= 36 && minute <= 37) || (minute >= 44 && minute <= 45) ||
(minute >= 52 && minute <= 53);
case "EURUSD":
return (minute >= 6 && minute <= 7) || (minute >= 14 && minute <= 15) ||
(minute >= 22 && minute <= 23) || (minute >= 30 && minute <= 31) ||
(minute >= 38 && minute <= 39) || (minute >= 46 && minute <= 47) ||
(minute >= 54 && minute <= 59);
default:
return true;
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import MovingAverageConvergenceDivergence, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class tds_global_strategy(Strategy):
def __init__(self):
super(tds_global_strategy, self).__init__()
self._macd_fast_length = self.Param("MacdFastLength", 12)
self._macd_slow_length = self.Param("MacdSlowLength", 23)
self._macd_signal_length = self.Param("MacdSignalLength", 9)
self._williams_length = self.Param("WilliamsLength", 24)
self._williams_buy_level = self.Param("WilliamsBuyLevel", 30.0)
self._williams_sell_level = self.Param("WilliamsSellLevel", 70.0)
self._entry_buffer_steps = self.Param("EntryBufferSteps", 16)
self._take_profit_steps = self.Param("TakeProfitSteps", 999.0)
self._trailing_stop_steps = self.Param("TrailingStopSteps", 10.0)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1)))
self._price_step = 1.0
self._macd_prev1 = None
self._macd_prev2 = None
self._williams_prev1 = None
self._prev_high = None
self._prev_low = None
self._prev_close = None
self._entry_price = None
self._stop_price = None
self._take_price = None
@property
def MacdFastLength(self):
return self._macd_fast_length.Value
@MacdFastLength.setter
def MacdFastLength(self, value):
self._macd_fast_length.Value = value
@property
def MacdSlowLength(self):
return self._macd_slow_length.Value
@MacdSlowLength.setter
def MacdSlowLength(self, value):
self._macd_slow_length.Value = value
@property
def MacdSignalLength(self):
return self._macd_signal_length.Value
@MacdSignalLength.setter
def MacdSignalLength(self, value):
self._macd_signal_length.Value = value
@property
def WilliamsLength(self):
return self._williams_length.Value
@WilliamsLength.setter
def WilliamsLength(self, value):
self._williams_length.Value = value
@property
def WilliamsBuyLevel(self):
return self._williams_buy_level.Value
@WilliamsBuyLevel.setter
def WilliamsBuyLevel(self, value):
self._williams_buy_level.Value = value
@property
def WilliamsSellLevel(self):
return self._williams_sell_level.Value
@WilliamsSellLevel.setter
def WilliamsSellLevel(self, value):
self._williams_sell_level.Value = value
@property
def EntryBufferSteps(self):
return self._entry_buffer_steps.Value
@EntryBufferSteps.setter
def EntryBufferSteps(self, value):
self._entry_buffer_steps.Value = value
@property
def TakeProfitSteps(self):
return self._take_profit_steps.Value
@TakeProfitSteps.setter
def TakeProfitSteps(self, value):
self._take_profit_steps.Value = value
@property
def TrailingStopSteps(self):
return self._trailing_stop_steps.Value
@TrailingStopSteps.setter
def TrailingStopSteps(self, value):
self._trailing_stop_steps.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(tds_global_strategy, self).OnStarted2(time)
self._price_step = float(self.Security.PriceStep) if self.Security is not None and self.Security.PriceStep is not None else 1.0
if self._price_step <= 0.0:
self._price_step = 1.0
self._macd_prev1 = None
self._macd_prev2 = None
self._williams_prev1 = None
self._prev_high = None
self._prev_low = None
self._prev_close = None
self._entry_price = None
self._stop_price = None
self._take_price = None
macd = MovingAverageConvergenceDivergence()
macd.ShortMa.Length = self.MacdFastLength
macd.LongMa.Length = self.MacdSlowLength
williams = RelativeStrengthIndex()
williams.Length = self.WilliamsLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(macd, williams, self.ProcessCandle).Start()
self.StartProtection(
Unit(2000.0, UnitTypes.Absolute),
Unit(1000.0, UnitTypes.Absolute))
def ProcessCandle(self, candle, macd_line, williams):
if candle.State != CandleStates.Finished:
return
macd_val = float(macd_line)
williams_val = float(williams)
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
self._manage_open_position(candle)
if abs(self.Position) > 0:
self._update_history(macd_val, williams_val, candle)
return
if self._macd_prev1 is None or self._macd_prev2 is None or \
self._williams_prev1 is None or self._prev_high is None or \
self._prev_low is None or self._prev_close is None:
self._update_history(macd_val, williams_val, candle)
return
direction = 1 if self._macd_prev1 > self._macd_prev2 else (-1 if self._macd_prev1 < self._macd_prev2 else 0)
oversold = self._williams_prev1 <= float(self.WilliamsBuyLevel)
overbought = self._williams_prev1 >= float(self.WilliamsSellLevel)
if direction > 0 and oversold:
self.BuyMarket()
entry = close
tp_steps = float(self.TakeProfitSteps)
self._entry_price = entry
self._stop_price = self._prev_low - self._price_step
self._take_price = entry + tp_steps * self._price_step if tp_steps > 0.0 else None
elif direction < 0 and overbought:
self.SellMarket()
entry = close
tp_steps = float(self.TakeProfitSteps)
self._entry_price = entry
self._stop_price = self._prev_high + self._price_step
self._take_price = entry - tp_steps * self._price_step if tp_steps > 0.0 else None
self._update_history(macd_val, williams_val, candle)
def _manage_open_position(self, candle):
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
if self.Position > 0:
if self._entry_price is None:
self._entry_price = close
trail_steps = float(self.TrailingStopSteps)
if trail_steps > 0.0:
trailing = close - trail_steps * self._price_step
if self._stop_price is None or trailing > self._stop_price:
self._stop_price = trailing
if self._stop_price is not None and low <= self._stop_price:
self.SellMarket()
self._reset_position()
return
if self._take_price is not None and high >= self._take_price:
self.SellMarket()
self._reset_position()
elif self.Position < 0:
if self._entry_price is None:
self._entry_price = close
trail_steps = float(self.TrailingStopSteps)
if trail_steps > 0.0:
trailing = close + trail_steps * self._price_step
if self._stop_price is None or trailing < self._stop_price:
self._stop_price = trailing
if self._stop_price is not None and high >= self._stop_price:
self.BuyMarket()
self._reset_position()
return
if self._take_price is not None and low <= self._take_price:
self.BuyMarket()
self._reset_position()
else:
self._reset_position()
def _update_history(self, macd_val, williams_val, candle):
if self._macd_prev1 is not None:
self._macd_prev2 = self._macd_prev1
self._macd_prev1 = macd_val
self._williams_prev1 = williams_val
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
self._prev_close = float(candle.ClosePrice)
def _reset_position(self):
self._entry_price = None
self._stop_price = None
self._take_price = None
def OnReseted(self):
super(tds_global_strategy, self).OnReseted()
self._price_step = 1.0
self._macd_prev1 = None
self._macd_prev2 = None
self._williams_prev1 = None
self._prev_high = None
self._prev_low = None
self._prev_close = None
self._reset_position()
def CreateClone(self):
return tds_global_strategy()