Estrategia del Indicador de Potencia Total X
Descripción general
La estrategia recrea el comportamiento del experto MetaTrader "Exp_TotalPowerIndicatorX" usando las APIs de alto nivel de StockSharp. Se basa en una implementación personalizada del Indicador de Potencia Total que mide el dominio de toros y osos contando cuántas velas en una ventana deslizante cierran por encima o por debajo de una línea base EMA interna. Las decisiones de trading se toman cuando las líneas de fortaleza alcista y bajista se cruzan entre sí.
El indicador funciona con cualquier símbolo y marco temporal. Por defecto la estrategia se suscribe a velas de 4 horas, coincidiendo con la configuración del asesor experto original, pero el marco temporal puede ajustarse a través de un parámetro.
Lógica de trading
- Para cada vela finalizada, la estrategia alimenta el Indicador de Potencia Total con los datos de la vela. El indicador:
- Calcula una EMA con período Power Period.
- Cuenta cuántas velas dentro de Lookback Period tuvieron
High > EMA(toros) yLow < EMA(osos). - Convierte los conteos en valores de fortaleza al estilo porcentual en el rango 0–100.
- Un cruce alcista (fortaleza alcista subiendo por encima de la bajista) desencadena una entrada larga cuando el trading largo está habilitado y no hay posiciones abiertas.
- Un cruce bajista (fortaleza bajista subiendo por encima de la alcista) desencadena una entrada corta cuando el trading corto está habilitado y no hay posiciones abiertas.
- Los cruces opuestos cierran posiciones existentes cuando los interruptores de salida relevantes están habilitados.
- Un filtro de sesión de trading opcional fuerza el cierre de todas las posiciones fuera de la ventana de tiempo configurada y deshabilita nuevas entradas durante ese período.
- Los niveles opcionales de stop-loss y take-profit se expresan en múltiplos del paso de precio de la seguridad. Se recalculan después de cada entrada y salen tan pronto como el máximo o mínimo de la vela supera el nivel.
Parámetros
- Candle Type – marco temporal usado para los cálculos del indicador. Por defecto: velas de 4 horas.
- Power Period – longitud de la EMA dentro del indicador; refleja el input MQL. Por defecto: 10.
- Lookback – número de velas usadas para contar el dominio alcista y bajista. Por defecto: 45.
- Volume – tamaño de la orden enviada al exchange o simulador. Por defecto: 1.
- Enable Long Entry / Enable Short Entry – permitir o prohibir nuevas posiciones en la dirección correspondiente.
- Enable Long Exit / Enable Short Exit – cerrar posiciones en señales opuestas. Deshabilitar para mantener posiciones abiertas hasta cierre manual o stop-out.
- Use Trading Hours – habilitar el filtro de tiempo. Cuando está activo, la estrategia opera solo entre Start Hour/Minute y End Hour/Minute y cierra cualquier posición abierta fuera de ese intervalo. Se admiten ventanas nocturnas (inicio posterior al fin).
- Stop Loss Points / Take Profit Points – distancias desde el precio de entrada medidas en pasos de precio. Establecer en cero para deshabilitar el nivel. El cálculo usa
Security.PriceStep, por lo que asegúrese de que los metadatos de la seguridad estén disponibles.
Notas
- La estrategia abre una nueva posición solo cuando no hay ninguna posición activa en la seguridad, emulando el comportamiento del experto original.
- Dado que los cálculos de stop-loss y take-profit dependen del paso de precio del instrumento, ejecutar la estrategia sin esos metadatos mantiene los niveles protectores deshabilitados automáticamente.
- El valor del indicador se traza en el área del gráfico cuando la interfaz de usuario está disponible, lo que ayuda a visualizar los cruces entre la fortaleza alcista y bajista.
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()