TDS Global 策略
该策略复刻了 MetaTrader 平台上的 “TDSGlobal” 专家顾问,遵循 Alexander Elder 的三重筛选理念。默认使用日线 K 线,结合 MACD (12, 23, 9) 主线斜率与 24 周期的 Williams %R 指标。MACD 上升且 %R 低于阈值时寻找做多机会, MACD 下降且 %R 高于阈值时寻找做空机会。
一旦出现信号,系统会在上一根 K 线的高点或低点之外挂入止损单,并强制与当前价格保持 EntryBufferSteps
个最小价位的距离,复现原始 EA 中的 “16 点” 逻辑。开仓后会跟踪保护性止损、可选的止盈以及按价位步长
移动的跟踪止损。
交易规则
- 数据:默认使用日线,可通过
CandleType参数调整。 - 趋势过滤:比较最近两个 MACD 主线值。主线抬高视为多头趋势,主线下行视为空头趋势。
- 震荡过滤:使用上一根 K 线的 Williams %R。低于
WilliamsBuyLevel(默认 -75)允许做多,高于WilliamsSellLevel(默认 -25)允许做空。 - 入场:
- 多头:在上一根高点上方一格挂入买入止损,若距离不够,则将价格提升至前收盘价上方
EntryBufferSteps个价位。 - 空头:在上一根低点下方一格挂入卖出止损,若距离不够,则将价格降低至前收盘价下方
EntryBufferSteps个价位。
- 多头:在上一根高点上方一格挂入买入止损,若距离不够,则将价格提升至前收盘价上方
- 风险控制:
- 初始止损放在上一根 K 线的相反端点(多头用前低,空头用前高)。
- 止盈距离为
TakeProfitSteps个价位,默认值 999 保持与原策略类似的宽阔目标。 TrailingStopSteps大于 0 时启用跟踪止损,只沿有利方向收紧。
- 订单管理:
- 当入场价或保护价位发生变化时,会取消并重新挂出对应的止损单。
- 当 MACD 趋势反向时,撤销与当前方向不符的待挂单。
- 开仓后复用之前计算好的价格初始化实时止损/止盈。
- 可选分时:
UseSymbolStagger选项可以启用原 EA 针对 EURUSD、GBPUSD、USDCHF、USDJPY 的分钟错峰, 避免在同一时刻提交多个挂单。
参数说明
MacdFastLength、MacdSlowLength、MacdSignalLength:MACD 指标周期。WilliamsLength:Williams %R 的回溯长度。WilliamsBuyLevel、WilliamsSellLevel:多空信号阈值(负值)。EntryBufferSteps:挂单与市场之间的最小价位距离。TakeProfitSteps:止盈距离,设为较小值即可启用固定止盈。TrailingStopSteps:跟踪止损的距离,设为 0 表示关闭。UseSymbolStagger:是否启用品种错峰窗口。CandleType:计算所用的 K 线类型。
额外说明
- 交易量由策略的
Volume属性控制,如果未设置则默认使用 1。 - 由于在收盘时处理挂单与风控,盘中成交会以存储的入场价进行近似。
- 默认的止盈距离非常大,保持与原始脚本一致;如需实际目标,请调整
TakeProfitSteps。
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()