Total Power Indicator X 策略
概览
该策略使用 StockSharp 的高级 API 重现 MetaTrader 专家顾问 “Exp_TotalPowerIndicatorX”。自定义的 Total Power 指标通过统计滚动窗口内多少根 K 线的高点高于内部 EMA、低点低于内部 EMA 来衡量多空力量,并在两条力量线发生交叉时做出交易决策。
指标适用于任意品种和周期。默认订阅 4 小时 K 线,以匹配原始 EA 的设置,不过可以通过参数自由调整时间框架。
交易逻辑
- 每当一根 K 线收盘时,将数据送入 Total Power 指标,该指标会:
- 按 Power Period 指定的周期计算 EMA。
- 在最近 Lookback Period 根 K 线中统计
High > EMA的次数(多头)以及Low < EMA的次数(空头)。 - 将计数转换为 0–100 范围的百分比型力量值。
- 当多头力量上穿空头力量时,如果允许做多且当前没有持仓,则开多。
- 当空头力量上穿多头力量时,如果允许做空且当前没有持仓,则开空。
- 如果开启了对应的平仓开关,则在出现相反交叉时平掉已有头寸。
- 可选的交易时段过滤器会在离开设定时间窗口时强制平仓,并禁止在该时间段外开仓。起始时间晚于结束时间的跨夜窗口同样支持。
- 可选的止损与止盈以价格步长的倍数表示。当 K 线的最高价或最低价触及这些水平时,会立即发出平仓指令并重新计算目标。
参数
- Candle Type:用于计算的时间框架,默认 4 小时。
- Power Period:指标内部 EMA 的长度,对应 MQL 输入参数,默认 10。
- Lookback:多空力量统计所使用的 K 线数量,默认 45。
- Volume:每次下单的数量,默认 1。
- Enable Long Entry / Enable Short Entry:允许或禁止新的多头/空头建仓。
- Enable Long Exit / Enable Short Exit:在相反信号出现时是否自动平仓。关闭后头寸会保持,直到手动或被止损止盈处理。
- Use Trading Hours:启用时段过滤,仅在 Start Hour/Minute 与 End Hour/Minute 之间进行交易,并在时段外平掉现有头寸。
- Stop Loss Points / Take Profit Points:距离开仓价的价格步长数量。设置为 0 表示禁用,需要保证
Security.PriceStep元数据可用。
说明
- 策略只有在该品种没有持仓时才会开新仓,从而与原版 EA 的行为保持一致。
- 止损与止盈依赖于品种的价格步长,如果元数据缺失则会自动禁用这些保护。
- 若界面可用,策略会在图表面板上绘制 Total Power 指标,便于观察多空力量的交叉情况。
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>
/// Strategy that replicates the Total Power Indicator expert advisor.
/// </summary>
public class TotalPowerIndicatorXStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _powerPeriod;
private readonly StrategyParam<int> _lookbackPeriod;
private readonly StrategyParam<bool> _enableLongEntry;
private readonly StrategyParam<bool> _enableShortEntry;
private readonly StrategyParam<bool> _enableLongExit;
private readonly StrategyParam<bool> _enableShortExit;
private readonly StrategyParam<bool> _useTradingHours;
private readonly StrategyParam<int> _startHour;
private readonly StrategyParam<int> _startMinute;
private readonly StrategyParam<int> _endHour;
private readonly StrategyParam<int> _endMinute;
private readonly StrategyParam<int> _stopLossPoints;
private readonly StrategyParam<int> _takeProfitPoints;
private TotalPowerIndicator _totalPower;
private decimal? _previousDifference;
private decimal? _longStopPrice;
private decimal? _longTakePrice;
private decimal? _shortStopPrice;
private decimal? _shortTakePrice;
/// <summary>
/// Candle type used for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Period for EMA inside Total Power Indicator.
/// </summary>
public int PowerPeriod
{
get => _powerPeriod.Value;
set => _powerPeriod.Value = value;
}
/// <summary>
/// Lookback period used for bull and bear strength counters.
/// </summary>
public int LookbackPeriod
{
get => _lookbackPeriod.Value;
set => _lookbackPeriod.Value = value;
}
/// <summary>
/// Enable opening long positions.
/// </summary>
public bool EnableLongEntry
{
get => _enableLongEntry.Value;
set => _enableLongEntry.Value = value;
}
/// <summary>
/// Enable opening short positions.
/// </summary>
public bool EnableShortEntry
{
get => _enableShortEntry.Value;
set => _enableShortEntry.Value = value;
}
/// <summary>
/// Enable closing long positions on opposite signals.
/// </summary>
public bool EnableLongExit
{
get => _enableLongExit.Value;
set => _enableLongExit.Value = value;
}
/// <summary>
/// Enable closing short positions on opposite signals.
/// </summary>
public bool EnableShortExit
{
get => _enableShortExit.Value;
set => _enableShortExit.Value = value;
}
/// <summary>
/// Enable time filter for trading sessions.
/// </summary>
public bool UseTradingHours
{
get => _useTradingHours.Value;
set => _useTradingHours.Value = value;
}
/// <summary>
/// Session start hour.
/// </summary>
public int StartHour
{
get => _startHour.Value;
set => _startHour.Value = value;
}
/// <summary>
/// Session start minute.
/// </summary>
public int StartMinute
{
get => _startMinute.Value;
set => _startMinute.Value = value;
}
/// <summary>
/// Session end hour.
/// </summary>
public int EndHour
{
get => _endHour.Value;
set => _endHour.Value = value;
}
/// <summary>
/// Session end minute.
/// </summary>
public int EndMinute
{
get => _endMinute.Value;
set => _endMinute.Value = value;
}
/// <summary>
/// Stop loss distance expressed in price steps.
/// </summary>
public int StopLossPoints
{
get => _stopLossPoints.Value;
set => _stopLossPoints.Value = value;
}
/// <summary>
/// Take profit distance expressed in price steps.
/// </summary>
public int TakeProfitPoints
{
get => _takeProfitPoints.Value;
set => _takeProfitPoints.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="TotalPowerIndicatorXStrategy"/>.
/// </summary>
public TotalPowerIndicatorXStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for calculations", "General");
_powerPeriod = Param(nameof(PowerPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Power Period", "EMA length used by Total Power", "Indicator")
;
_lookbackPeriod = Param(nameof(LookbackPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Lookback", "Samples counted for bull/bear strength", "Indicator")
;
_enableLongEntry = Param(nameof(EnableLongEntry), true)
.SetDisplay("Enable Long Entry", "Allow buying when bulls dominate", "Trading");
_enableShortEntry = Param(nameof(EnableShortEntry), true)
.SetDisplay("Enable Short Entry", "Allow selling when bears dominate", "Trading");
_enableLongExit = Param(nameof(EnableLongExit), true)
.SetDisplay("Enable Long Exit", "Close longs on bearish crossover", "Trading");
_enableShortExit = Param(nameof(EnableShortExit), true)
.SetDisplay("Enable Short Exit", "Close shorts on bullish crossover", "Trading");
_useTradingHours = Param(nameof(UseTradingHours), false)
.SetDisplay("Use Trading Hours", "Restrict trading to session window", "Schedule");
_startHour = Param(nameof(StartHour), 0)
.SetDisplay("Start Hour", "Session start hour", "Schedule");
_startMinute = Param(nameof(StartMinute), 0)
.SetDisplay("Start Minute", "Session start minute", "Schedule");
_endHour = Param(nameof(EndHour), 23)
.SetDisplay("End Hour", "Session end hour", "Schedule");
_endMinute = Param(nameof(EndMinute), 59)
.SetDisplay("End Minute", "Session end minute", "Schedule");
_stopLossPoints = Param(nameof(StopLossPoints), 0)
.SetDisplay("Stop Loss Points", "Stop loss distance in price steps (0=disabled)", "Risk");
_takeProfitPoints = Param(nameof(TakeProfitPoints), 0)
.SetDisplay("Take Profit Points", "Take profit distance in price steps (0=disabled)", "Risk");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_totalPower?.Reset();
_previousDifference = null;
ResetLongTargets();
ResetShortTargets();
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_totalPower = new TotalPowerIndicator
{
PowerPeriod = PowerPeriod,
LookbackPeriod = LookbackPeriod
};
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(_totalPower, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _totalPower);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue indicatorValue)
{
if (candle.State != CandleStates.Finished)
return;
if (indicatorValue is not TotalPowerIndicatorValue powerValue)
return;
if (!_totalPower.IsFormed)
{
_previousDifference = powerValue.Bulls - powerValue.Bears;
return;
}
var difference = powerValue.Bulls - powerValue.Bears;
var previous = _previousDifference ?? difference;
_previousDifference = difference;
if (HandleStops(candle))
return;
var crossUp = difference > 0m && previous <= 0m;
var crossDown = difference < 0m && previous >= 0m;
var isTradingTime = !UseTradingHours || IsWithinTradingWindow(candle.OpenTime);
if (UseTradingHours && !isTradingTime)
{
CloseAllPositions();
return;
}
if (EnableLongExit && crossDown && Position > 0m)
{
SellMarket();
ResetLongTargets();
}
if (EnableShortExit && crossUp && Position < 0m)
{
BuyMarket();
ResetShortTargets();
}
if (!isTradingTime)
return;
if (EnableLongEntry && crossUp && Position == 0m)
{
BuyMarket();
SetupLongTargets(candle.ClosePrice);
}
else if (EnableShortEntry && crossDown && Position == 0m)
{
SellMarket();
SetupShortTargets(candle.ClosePrice);
}
}
private bool HandleStops(ICandleMessage candle)
{
var step = Security?.PriceStep ?? 0m;
if (step <= 0m)
return false;
if (Position > 0m)
{
if (_longStopPrice.HasValue && candle.LowPrice <= _longStopPrice.Value)
{
SellMarket();
ResetLongTargets();
return true;
}
if (_longTakePrice.HasValue && candle.HighPrice >= _longTakePrice.Value)
{
SellMarket();
ResetLongTargets();
return true;
}
}
else if (Position < 0m)
{
if (_shortStopPrice.HasValue && candle.HighPrice >= _shortStopPrice.Value)
{
BuyMarket();
ResetShortTargets();
return true;
}
if (_shortTakePrice.HasValue && candle.LowPrice <= _shortTakePrice.Value)
{
BuyMarket();
ResetShortTargets();
return true;
}
}
return false;
}
private bool IsWithinTradingWindow(DateTimeOffset time)
{
var start = new TimeSpan(StartHour, StartMinute, 0);
var end = new TimeSpan(EndHour, EndMinute, 0);
var current = time.TimeOfDay;
if (start == end)
return true;
if (start < end)
return current >= start && current < end;
return current >= start || current < end;
}
private void CloseAllPositions()
{
if (Position > 0m)
{
SellMarket();
ResetLongTargets();
}
else if (Position < 0m)
{
BuyMarket();
ResetShortTargets();
}
}
private void SetupLongTargets(decimal entryPrice)
{
var step = Security?.PriceStep ?? 0m;
if (step <= 0m)
{
ResetLongTargets();
return;
}
_longStopPrice = StopLossPoints > 0 ? entryPrice - StopLossPoints * step : null;
_longTakePrice = TakeProfitPoints > 0 ? entryPrice + TakeProfitPoints * step : null;
ResetShortTargets();
}
private void SetupShortTargets(decimal entryPrice)
{
var step = Security?.PriceStep ?? 0m;
if (step <= 0m)
{
ResetShortTargets();
return;
}
_shortStopPrice = StopLossPoints > 0 ? entryPrice + StopLossPoints * step : null;
_shortTakePrice = TakeProfitPoints > 0 ? entryPrice - TakeProfitPoints * step : null;
ResetLongTargets();
}
private void ResetLongTargets()
{
_longStopPrice = null;
_longTakePrice = null;
}
private void ResetShortTargets()
{
_shortStopPrice = null;
_shortTakePrice = null;
}
private sealed class TotalPowerIndicator : BaseIndicator
{
private readonly List<int> _bullHistory = new();
private readonly List<int> _bearHistory = new();
private readonly ExponentialMovingAverage _ema = new();
private int _bullCount;
private int _bearCount;
private int _powerPeriod = 10;
private int _lookbackPeriod = 50;
public int PowerPeriod
{
get => _powerPeriod;
set
{
_powerPeriod = Math.Max(1, value);
_ema.Length = _powerPeriod;
}
}
public int LookbackPeriod
{
get => _lookbackPeriod;
set => _lookbackPeriod = Math.Max(1, value);
}
protected override IIndicatorValue OnProcess(IIndicatorValue input)
{
var candle = input.GetValue<ICandleMessage>();
var emaValue = _ema.Process(new DecimalIndicatorValue(_ema, candle.ClosePrice, input.Time) { IsFinal = input.IsFinal });
if (!_ema.IsFormed)
{
IsFormed = false;
return new TotalPowerIndicatorValue(this, input, 0m, 0m, 0m);
}
var ema = emaValue.ToDecimal();
var bullContribution = candle.HighPrice > ema ? 1 : 0;
var bearContribution = candle.LowPrice < ema ? 1 : 0;
UpdateCounters(_bullHistory, ref _bullCount, bullContribution);
UpdateCounters(_bearHistory, ref _bearCount, bearContribution);
if (_bullHistory.Count < LookbackPeriod || _bearHistory.Count < LookbackPeriod)
{
IsFormed = false;
return new TotalPowerIndicatorValue(this, input, 0m, 0m, 0m);
}
var bullPercent = (decimal)_bullCount * 100m / LookbackPeriod;
var bearPercent = (decimal)_bearCount * 100m / LookbackPeriod;
var bulls = Math.Clamp((bullPercent - 50m) * 2m, 0m, 100m);
var bears = Math.Clamp((bearPercent - 50m) * 2m, 0m, 100m);
var power = Math.Clamp(2m * Math.Abs(bullPercent - bearPercent), 0m, 100m);
IsFormed = true;
return new TotalPowerIndicatorValue(this, input, bulls, bears, power);
}
public override void Reset()
{
base.Reset();
_bullHistory.Clear();
_bearHistory.Clear();
_bullCount = 0;
_bearCount = 0;
_ema.Reset();
}
private void UpdateCounters(List<int> list, ref int count, int value)
{
list.Add(value);
count += value;
while (list.Count > LookbackPeriod)
{
try { count -= list[0]; list.RemoveAt(0); }
catch { break; }
}
}
}
private sealed class TotalPowerIndicatorValue : DecimalIndicatorValue
{
public TotalPowerIndicatorValue(IIndicator indicator, IIndicatorValue input, decimal bulls, decimal bears, decimal power)
: base(indicator, bulls - bears, input.Time)
{
Bulls = bulls;
Bears = bears;
Power = power;
}
public decimal Bulls { get; }
public decimal Bears { get; }
public decimal Power { get; }
}
}
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
from StockSharp.Algo.Strategies import Strategy
from StockSharp.Algo.Indicators import ExponentialMovingAverage
class total_power_indicator_x_strategy(Strategy):
"""Total Power Indicator strategy: bull/bear strength with EMA-based crossover."""
def __init__(self):
super(total_power_indicator_x_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))) \
.SetDisplay("Candle Type", "Timeframe for calculations", "General")
self._power_period = self.Param("PowerPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Power Period", "EMA length used by Total Power", "Indicator")
self._lookback_period = self.Param("LookbackPeriod", 50) \
.SetGreaterThanZero() \
.SetDisplay("Lookback", "Samples counted for bull/bear strength", "Indicator")
self._enable_long_entry = self.Param("EnableLongEntry", True) \
.SetDisplay("Enable Long Entry", "Allow buying when bulls dominate", "Trading")
self._enable_short_entry = self.Param("EnableShortEntry", True) \
.SetDisplay("Enable Short Entry", "Allow selling when bears dominate", "Trading")
self._enable_long_exit = self.Param("EnableLongExit", True) \
.SetDisplay("Enable Long Exit", "Close longs on bearish crossover", "Trading")
self._enable_short_exit = self.Param("EnableShortExit", True) \
.SetDisplay("Enable Short Exit", "Close shorts on bullish crossover", "Trading")
self._use_trading_hours = self.Param("UseTradingHours", False) \
.SetDisplay("Use Trading Hours", "Restrict trading to session window", "Schedule")
self._start_hour = self.Param("StartHour", 0) \
.SetDisplay("Start Hour", "Session start hour", "Schedule")
self._start_minute = self.Param("StartMinute", 0) \
.SetDisplay("Start Minute", "Session start minute", "Schedule")
self._end_hour = self.Param("EndHour", 23) \
.SetDisplay("End Hour", "Session end hour", "Schedule")
self._end_minute = self.Param("EndMinute", 59) \
.SetDisplay("End Minute", "Session end minute", "Schedule")
self._stop_loss_points = self.Param("StopLossPoints", 0) \
.SetDisplay("Stop Loss Points", "Stop loss distance in price steps (0=disabled)", "Risk")
self._take_profit_points = self.Param("TakeProfitPoints", 0) \
.SetDisplay("Take Profit Points", "Take profit distance in price steps (0=disabled)", "Risk")
self._prev_diff = None
self._long_stop = None
self._long_take = None
self._short_stop = None
self._short_take = None
self._bull_history = []
self._bear_history = []
self._bull_count = 0
self._bear_count = 0
self._is_formed = False
@property
def CandleType(self):
return self._candle_type.Value
@property
def PowerPeriod(self):
return self._power_period.Value
@property
def LookbackPeriod(self):
return self._lookback_period.Value
@property
def EnableLongEntry(self):
return self._enable_long_entry.Value
@property
def EnableShortEntry(self):
return self._enable_short_entry.Value
@property
def EnableLongExit(self):
return self._enable_long_exit.Value
@property
def EnableShortExit(self):
return self._enable_short_exit.Value
@property
def UseTradingHours(self):
return self._use_trading_hours.Value
@property
def StartHour(self):
return self._start_hour.Value
@property
def StartMinute(self):
return self._start_minute.Value
@property
def EndHour(self):
return self._end_hour.Value
@property
def EndMinute(self):
return self._end_minute.Value
@property
def StopLossPoints(self):
return self._stop_loss_points.Value
@property
def TakeProfitPoints(self):
return self._take_profit_points.Value
def OnStarted2(self, time):
super(total_power_indicator_x_strategy, self).OnStarted2(time)
self._ema = ExponentialMovingAverage()
self._ema.Length = max(1, self.PowerPeriod)
self._bull_history = []
self._bear_history = []
self._bull_count = 0
self._bear_count = 0
self._is_formed = False
self._prev_diff = None
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(self._ema, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, self._ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
if not self._ema.IsFormed:
return
ema_dec = float(ema_value)
bull_contrib = 1 if float(candle.HighPrice) > ema_dec else 0
bear_contrib = 1 if float(candle.LowPrice) < ema_dec else 0
self._update_counter(self._bull_history, bull_contrib, True)
self._update_counter(self._bear_history, bear_contrib, False)
lb = self.LookbackPeriod
if len(self._bull_history) < lb or len(self._bear_history) < lb:
self._is_formed = False
return
bull_pct = float(self._bull_count) * 100.0 / lb
bear_pct = float(self._bear_count) * 100.0 / lb
bulls = max(0.0, min(100.0, (bull_pct - 50.0) * 2.0))
bears = max(0.0, min(100.0, (bear_pct - 50.0) * 2.0))
difference = bulls - bears
if not self._is_formed:
self._is_formed = True
self._prev_diff = difference
return
previous = self._prev_diff if self._prev_diff is not None else difference
self._prev_diff = difference
if self._handle_stops(candle):
return
cross_up = difference > 0 and previous <= 0
cross_down = difference < 0 and previous >= 0
is_trading_time = (not self.UseTradingHours) or self._in_trading_window(candle.OpenTime)
if self.UseTradingHours and not is_trading_time:
self._close_all()
return
if self.EnableLongExit and cross_down and self.Position > 0:
self.SellMarket()
self._reset_long_targets()
if self.EnableShortExit and cross_up and self.Position < 0:
self.BuyMarket()
self._reset_short_targets()
if not is_trading_time:
return
if self.EnableLongEntry and cross_up and self.Position == 0:
self.BuyMarket()
self._setup_long(float(candle.ClosePrice))
elif self.EnableShortEntry and cross_down and self.Position == 0:
self.SellMarket()
self._setup_short(float(candle.ClosePrice))
def _update_counter(self, lst, value, is_bull):
lst.append(value)
if is_bull:
self._bull_count += value
else:
self._bear_count += value
lb = self.LookbackPeriod
while len(lst) > lb:
removed = lst.pop(0)
if is_bull:
self._bull_count -= removed
else:
self._bear_count -= removed
def _handle_stops(self, candle):
sec = self.Security
if sec is None or sec.PriceStep is None or float(sec.PriceStep) <= 0:
return False
if self.Position > 0:
if self._long_stop is not None and float(candle.LowPrice) <= self._long_stop:
self.SellMarket()
self._reset_long_targets()
return True
if self._long_take is not None and float(candle.HighPrice) >= self._long_take:
self.SellMarket()
self._reset_long_targets()
return True
elif self.Position < 0:
if self._short_stop is not None and float(candle.HighPrice) >= self._short_stop:
self.BuyMarket()
self._reset_short_targets()
return True
if self._short_take is not None and float(candle.LowPrice) <= self._short_take:
self.BuyMarket()
self._reset_short_targets()
return True
return False
def _in_trading_window(self, time):
start = TimeSpan(self.StartHour, self.StartMinute, 0)
end = TimeSpan(self.EndHour, self.EndMinute, 0)
current = time.TimeOfDay
if start == end:
return True
if start < end:
return current >= start and current < end
return current >= start or current < end
def _close_all(self):
if self.Position > 0:
self.SellMarket()
self._reset_long_targets()
elif self.Position < 0:
self.BuyMarket()
self._reset_short_targets()
def _setup_long(self, entry):
sec = self.Security
step = float(sec.PriceStep) if sec is not None and sec.PriceStep is not None and float(sec.PriceStep) > 0 else 0.0
if step <= 0:
self._reset_long_targets()
return
self._long_stop = entry - self.StopLossPoints * step if self.StopLossPoints > 0 else None
self._long_take = entry + self.TakeProfitPoints * step if self.TakeProfitPoints > 0 else None
self._reset_short_targets()
def _setup_short(self, entry):
sec = self.Security
step = float(sec.PriceStep) if sec is not None and sec.PriceStep is not None and float(sec.PriceStep) > 0 else 0.0
if step <= 0:
self._reset_short_targets()
return
self._short_stop = entry + self.StopLossPoints * step if self.StopLossPoints > 0 else None
self._short_take = entry - self.TakeProfitPoints * step if self.TakeProfitPoints > 0 else None
self._reset_long_targets()
def _reset_long_targets(self):
self._long_stop = None
self._long_take = None
def _reset_short_targets(self):
self._short_stop = None
self._short_take = None
def OnReseted(self):
super(total_power_indicator_x_strategy, self).OnReseted()
if hasattr(self, '_ema') and self._ema is not None:
self._ema.Reset()
self._prev_diff = None
self._reset_long_targets()
self._reset_short_targets()
self._bull_history = []
self._bear_history = []
self._bull_count = 0
self._bear_count = 0
self._is_formed = False
def CreateClone(self):
return total_power_indicator_x_strategy()