Total Power Indikator X-Strategie
Überblick
Die Strategie recreiert das Verhalten des MetaTrader-Experten "Exp_TotalPowerIndicatorX" mit den High-Level-APIs von StockSharp. Sie basiert auf einer benutzerdefinierten Implementierung des Total Power Indikators, der die Dominanz von Bullen und Bären misst, indem er zählt, wie viele Kerzen in einem gleitenden Fenster über oder unter einer internen EMA-Basislinie schließen. Handelsentscheidungen werden getroffen, wenn sich die Stärkelinien von Bullen und Bären kreuzen.
Der Indikator funktioniert auf jedem Symbol und Zeitrahmen. Standardmäßig abonniert die Strategie 4-Stunden-Kerzen, entsprechend der ursprünglichen Expert-Advisor-Konfiguration, aber der Zeitrahmen kann über einen Parameter angepasst werden.
Handelslogik
- Für jede abgeschlossene Kerze füttert die Strategie den Total Power Indikator mit den Kerzendaten. Der Indikator:
- Berechnet eine EMA mit dem Zeitraum Power Period.
- Zählt, wie viele Kerzen innerhalb der Lookback Period
High > EMA(Bullen) undLow < EMA(Bären) hatten. - Konvertiert die Zählungen in Stärkewerte im prozentualen Stil im Bereich 0–100.
- Ein bullischer Crossover (Bullenstärke steigt über Bärenstärke) löst einen Long-Einstieg aus, wenn Long-Trading aktiviert ist und keine offenen Positionen vorhanden sind.
- Ein bearischer Crossover (Bärenstärke steigt über Bullenstärke) löst einen Short-Einstieg aus, wenn Short-Trading aktiviert ist und keine offenen Positionen vorhanden sind.
- Entgegengesetzte Crossover schließen bestehende Positionen, wenn die relevanten Exit-Schalter aktiviert sind.
- Ein optionaler Trading-Session-Filter erzwingt das Schließen aller Positionen außerhalb des konfigurierten Zeitfensters und deaktiviert neue Einstiege während dieses Zeitraums.
- Optionale Stop-Loss- und Take-Profit-Level werden als Vielfache des Sicherheits-Preisschritts ausgedrückt. Sie werden nach jedem Einstieg neu berechnet und werden ausgelöst, sobald das Hoch oder Tief der Kerze das Niveau durchbricht.
Parameter
- Candle Type – Zeitrahmen für Indikatorberechnungen. Standard: 4-Stunden-Kerzen.
- Power Period – EMA-Länge innerhalb des Indikators; spiegelt den MQL-Input wider. Standard: 10.
- Lookback – Anzahl der Kerzen zur Zählung bullischer und bearischer Dominanz. Standard: 45.
- Volume – Ordergröße, die an die Börse oder den Simulator gesendet wird. Standard: 1.
- Enable Long Entry / Enable Short Entry – neue Positionen in der entsprechenden Richtung erlauben oder verbieten.
- Enable Long Exit / Enable Short Exit – Positionen bei entgegengesetzten Signalen schließen. Deaktivieren, um Positionen offen zu halten, bis sie manuell geschlossen oder gestoppt werden.
- Use Trading Hours – Zeitfilter aktivieren. Wenn aktiv, handelt die Strategie nur zwischen Start Hour/Minute und End Hour/Minute und schließt alle offenen Positionen außerhalb dieses Intervalls. Übernacht-Fenster (Start später als Ende) werden unterstützt.
- Stop Loss Points / Take Profit Points – Abstände vom Eintrittspreis, gemessen in Preisschritten. Auf null setzen, um das Level zu deaktivieren. Die Berechnung verwendet
Security.PriceStep, daher sicherstellen, dass die Sicherheitsmetadaten verfügbar sind.
Hinweise
- Die Strategie öffnet eine neue Position nur, wenn keine bestehende Position auf der Sicherheit aktiv ist, was das Verhalten des ursprünglichen Experten emuliert.
- Da Stop-Loss- und Take-Profit-Berechnungen vom Preisschritt des Instruments abhängen, bleiben die Schutzlevel beim Ausführen der Strategie ohne diese Metadaten automatisch deaktiviert.
- Der Indikatorwert wird auf dem Diagrammbereich aufgezeichnet, wenn die Benutzeroberfläche verfügbar ist, was hilft, die Kreuzungen zwischen Bullen- und Bärenstärke zu visualisieren.
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()