Invest System 4.5 is a MetaTrader 5 expert advisor that has been ported to the StockSharp high-level strategy API. The strategy trades the EUR/USD pair by following the direction of the previous completed 4-hour candle. A single trade is allowed during the first minutes of the new 4-hour session and position sizing adapts to realized performance and account growth.
The code relies exclusively on the high-level API: automatic candle subscriptions are used to monitor both the 4-hour directional bias and the lower timeframe entry window, while the built-in StartProtection helper enforces static take-profit and stop-loss levels expressed in pips.
Trading Logic
Directional bias – at the close of every finished 4-hour candle the strategy stores whether the candle closed bullish or bearish. A bullish candle enables only long entries for the next session, while a bearish candle enables only shorts. If the candle closes exactly at its open, the previous direction is kept.
Entry timing – when a new 4-hour candle starts, an entry window opens. The window remains valid for a configurable number of minutes (15 by default). The strategy watches lower timeframe candles (1 minute by default) and may submit at most one market order if all filters are satisfied while the window is active.
Single position – the strategy never pyramids. If a position is already open, no new signals are processed until the next 4-hour session. Once an order is sent the entry window closes immediately to replicate the MetaTrader behavior.
Profit and loss tracking – when a position is fully closed the realized PnL is captured to drive the adaptive lot logic described below.
Position Sizing Rules
The original expert advisor uses two layers of money management:
Equity milestones: the initial account balance is stored on the very first update. When the equity exceeds 2×, 3× … 6× the initial balance the base lot size is increased proportionally. Stage 1 starts at BaseLot, stage 2 doubles it, stage 3 triples it, and so on. Secondary lot sizes (Lot2, Lot3, Lot4) are derived using the original multipliers (×2, ×7 and ×14 respectively).
Plan B escalation: a single global volume value is kept between trades.
After a losing trade with the base lot the volume is raised to the second lot (Lot3).
If another loss occurs while trading the second lot, “Plan B” activates. Plan B remaps the internal lot options so that the base lot becomes Lot2 and the aggressive lot becomes Lot4. The current volume is not changed immediately, but any subsequent loss pushes the strategy to the aggressive lot. Plan B is cancelled automatically when the account hits a new equity high.
A profitable trade always resets the current volume back to the base lot for the active stage.
These rules closely reproduce the cascading lot escalation from the MetaTrader version without manually iterating through orders or using collections.
Risk Management
StartProtection configures both the stop-loss and the take-profit in absolute price units derived from the pip size. Stops and targets are registered only once when the strategy is started, just like the original EA attaches the values to each order.
Only market orders are used. No hedge positions, scaling or partial exits are performed by the strategy itself; exits occur via the configured protective orders.
Strategy Parameters
Parameter
Description
Default
Optimization Range
StopLossPips
Stop-loss distance in pips. Use 0 to disable the stop.
240
120 – 360, step 20
TakeProfitPips
Take-profit distance in pips. Use 0 to disable the target.
40
20 – 80, step 10
EntryWindowMinutes
Length of the entry window after each new 4-hour candle opens.
15
5 – 30, step 5
SignalCandleType
Candle series used to monitor the entry window (1-minute by default).
1-minute time frame
–
TrendCandleType
Higher timeframe candle used to build the directional bias (4-hour by default).
4-hour time frame
–
BaseLot
Initial lot size for stage 1. Other lot sizes are derived automatically.
The strategy expects the attached security to provide both the 4-hour candle series and the faster timeframe series. These subscriptions are automatically created inside OnStarted.
The pip size is determined from Security.PriceStep and adjusted for fractional quoting (3 or 5 decimal places) to match MetaTrader’s treatment of pip values.
Because the original robot uses account balance thresholds, the StockSharp implementation reads Portfolio.CurrentValue on every entry candle update. When running in simulation make sure that the portfolio model updates the current equity so that the lot scaling remains consistent.
Python translation is intentionally omitted as requested.
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>
/// Invest System 4.5 strategy converted from MetaTrader.
/// Trades in the direction of the previous 4-hour candle within the first minutes of the new session.
/// </summary>
public class InvestSystem45Strategy : Strategy
{
private readonly StrategyParam<int> _stopLossPips;
private readonly StrategyParam<int> _takeProfitPips;
private readonly StrategyParam<int> _entryWindowMinutes;
private readonly StrategyParam<DataType> _signalCandleType;
private readonly StrategyParam<DataType> _trendCandleType;
private readonly StrategyParam<decimal> _baseLot;
private decimal _pipSize;
private decimal _minBalance;
private decimal _maxBalance;
private int _lotStage;
private bool _planBActive;
private decimal _stageLot1;
private decimal _stageLot2;
private decimal _stageLot3;
private decimal _stageLot4;
private decimal _lotOption1;
private decimal _lotOption2;
private decimal _currentVolume;
private bool _needsPostTradeAdjustment;
private bool _hasOpenPosition;
private decimal _pnlAtEntry;
private decimal _lastTradePnL;
private int _trendDirection;
private DateTime? _entryWindowStart;
private DateTime? _entryWindowEnd;
private bool _entryWindowActive;
private decimal _entryPrice;
private decimal _stopPrice;
private decimal _takePrice;
/// <summary>
/// Stop loss distance expressed in pips.
/// </summary>
public int StopLossPips
{
get => _stopLossPips.Value;
set => _stopLossPips.Value = value;
}
/// <summary>
/// Take profit distance expressed in pips.
/// </summary>
public int TakeProfitPips
{
get => _takeProfitPips.Value;
set => _takeProfitPips.Value = value;
}
/// <summary>
/// Minutes allowed for entries after a new trend candle opens.
/// </summary>
public int EntryWindowMinutes
{
get => _entryWindowMinutes.Value;
set => _entryWindowMinutes.Value = value;
}
/// <summary>
/// Candle type that drives entry timing.
/// </summary>
public DataType SignalCandleType
{
get => _signalCandleType.Value;
set => _signalCandleType.Value = value;
}
/// <summary>
/// Higher timeframe candle used to define trade direction.
/// </summary>
public DataType TrendCandleType
{
get => _trendCandleType.Value;
set => _trendCandleType.Value = value;
}
/// <summary>
/// Base lot size used to derive martingale steps.
/// </summary>
public decimal BaseLot
{
get => _baseLot.Value;
set => _baseLot.Value = value;
}
/// <summary>
/// Initialize <see cref="InvestSystem45Strategy"/>.
/// </summary>
public InvestSystem45Strategy()
{
_stopLossPips = Param(nameof(StopLossPips), 240)
.SetNotNegative()
.SetDisplay("Stop Loss (pips)", "Stop loss distance in pips", "Risk")
.SetOptimize(120, 360, 20);
_takeProfitPips = Param(nameof(TakeProfitPips), 40)
.SetNotNegative()
.SetDisplay("Take Profit (pips)", "Take profit distance in pips", "Risk")
.SetOptimize(20, 80, 10);
_entryWindowMinutes = Param(nameof(EntryWindowMinutes), 15)
.SetGreaterThanZero()
.SetDisplay("Entry Window", "Minutes after 4H open when entries are allowed", "Timing")
.SetOptimize(5, 30, 5);
_signalCandleType = Param(nameof(SignalCandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Signal Candles", "Candles used to time entries", "Timing");
_trendCandleType = Param(nameof(TrendCandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Trend Candles", "Higher timeframe candles for direction", "Timing");
_baseLot = Param(nameof(BaseLot), 0.1m)
.SetGreaterThanZero()
.SetDisplay("Base Lot", "Starting lot size before scaling", "Risk")
.SetOptimize(0.05m, 0.3m, 0.05m);
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
if (Security is null)
yield break;
yield return (Security, SignalCandleType);
if (!SignalCandleType.Equals(TrendCandleType))
yield return (Security, TrendCandleType);
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
ResetState();
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
ResetState();
_pipSize = CalculatePipSize();
// Recreate lot options according to current stage and plan mode.
RecalculateLotOptions();
var trendSubscription = SubscribeCandles(TrendCandleType);
trendSubscription.Bind(ProcessTrendCandle).Start();
var entrySubscription = SubscribeCandles(SignalCandleType);
entrySubscription.Bind(ProcessEntryCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, entrySubscription);
DrawOwnTrades(area);
}
}
/// <inheritdoc />
protected override void OnPositionReceived(Position position)
{
base.OnPositionReceived(position);
if (Position != 0m)
{
// Record entry state to compute realized PnL later.
if (!_hasOpenPosition)
{
_hasOpenPosition = true;
_needsPostTradeAdjustment = true;
_pnlAtEntry = PnL;
}
_entryWindowActive = false;
return;
}
if (!_hasOpenPosition)
return;
_hasOpenPosition = false;
_lastTradePnL = PnL - _pnlAtEntry;
// Mirror MetaTrader profit calculation for Plan B rules.
HandlePostTradeAdjustment();
}
private void ProcessTrendCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Store direction from the last completed 4H candle.
if (candle.ClosePrice > candle.OpenPrice)
{
_trendDirection = 1;
}
else if (candle.ClosePrice < candle.OpenPrice)
{
_trendDirection = -1;
}
_entryWindowStart = candle.CloseTime;
_entryWindowEnd = _entryWindowStart?.AddMinutes(EntryWindowMinutes);
// Open a new entry window immediately at the next candle open.
_entryWindowActive = true;
}
private void ProcessEntryCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Check SL/TP for open positions.
if (Position > 0m && _entryPrice > 0m)
{
if (_stopPrice > 0m && candle.LowPrice <= _stopPrice)
{
SellMarket(Position);
ResetTargets();
return;
}
if (_takePrice > 0m && candle.HighPrice >= _takePrice)
{
SellMarket(Position);
ResetTargets();
return;
}
}
else if (Position < 0m && _entryPrice > 0m)
{
if (_stopPrice > 0m && candle.HighPrice >= _stopPrice)
{
BuyMarket(Math.Abs(Position));
ResetTargets();
return;
}
if (_takePrice > 0m && candle.LowPrice <= _takePrice)
{
BuyMarket(Math.Abs(Position));
ResetTargets();
return;
}
}
// Update balance-dependent scaling before evaluating signals.
UpdateBalanceState();
if (!_entryWindowActive || !_entryWindowStart.HasValue || !_entryWindowEnd.HasValue)
return;
var openTime = candle.OpenTime;
if (openTime < _entryWindowStart.Value)
return;
if (openTime > _entryWindowEnd.Value)
{
_entryWindowActive = false;
return;
}
if (_trendDirection == 0)
return;
if (Position != 0m)
return;
// Lazy initialize volume when strategy is ready.
if (_currentVolume <= 0m)
_currentVolume = _lotOption1;
if (_currentVolume <= 0m)
return;
if (_trendDirection > 0)
{
BuyMarket(_currentVolume);
}
else
{
SellMarket(_currentVolume);
}
// Allow only one trade per 4H candle similar to MetaTrader logic.
_entryWindowActive = false;
}
private void HandlePostTradeAdjustment()
{
if (!_needsPostTradeAdjustment)
return;
_needsPostTradeAdjustment = false;
// Apply lot escalation rules after each closed trade.
UpdateBalanceState();
if (_lastTradePnL < 0m)
{
if (_currentVolume == _lotOption2 && !_planBActive)
{
_planBActive = true;
RecalculateLotOptions();
}
else if (_currentVolume == _lotOption1)
{
_currentVolume = _lotOption2;
}
else
{
_currentVolume = _lotOption2;
}
}
else if (_lastTradePnL > 0m)
{
_currentVolume = _lotOption1;
}
}
private void UpdateBalanceState()
{
var balance = Portfolio?.CurrentValue;
if (balance is null || balance.Value <= 0m)
return;
if (_minBalance <= 0m)
{
_minBalance = balance.Value;
_maxBalance = balance.Value;
}
if (balance.Value > _maxBalance)
{
_maxBalance = balance.Value;
if (_planBActive)
{
_planBActive = false;
RecalculateLotOptions();
}
}
var newStage = 1;
if (_minBalance > 0m)
{
// Check for equity milestones to scale base lots.
for (var stage = 6; stage >= 2; stage--)
{
if (balance.Value > _minBalance * stage)
{
newStage = stage;
break;
}
}
}
if (newStage != _lotStage)
{
_lotStage = newStage;
RecalculateLotOptions();
}
}
private decimal CalculatePipSize()
{
var step = Security?.PriceStep ?? 1m;
var decimals = Security?.Decimals ?? 0;
if (decimals == 3 || decimals == 5)
step *= 10m;
return step;
}
/// <inheritdoc />
protected override void OnOwnTradeReceived(MyTrade trade)
{
base.OnOwnTradeReceived(trade);
if (trade?.Trade == null) return;
if (Position != 0m && _entryPrice == 0m)
{
_entryPrice = trade.Trade.Price;
var slDist = StopLossPips * _pipSize;
var tpDist = TakeProfitPips * _pipSize;
if (Position > 0m)
{
_stopPrice = slDist > 0m ? _entryPrice - slDist : 0m;
_takePrice = tpDist > 0m ? _entryPrice + tpDist : 0m;
}
else
{
_stopPrice = slDist > 0m ? _entryPrice + slDist : 0m;
_takePrice = tpDist > 0m ? _entryPrice - tpDist : 0m;
}
}
if (Position == 0m)
ResetTargets();
}
private void ResetTargets()
{
_entryPrice = 0m;
_stopPrice = 0m;
_takePrice = 0m;
}
private void ResetState()
{
_pipSize = 0m;
_minBalance = 0m;
_maxBalance = 0m;
_lotStage = 1;
_planBActive = false;
_stageLot1 = 0m;
_stageLot2 = 0m;
_stageLot3 = 0m;
_stageLot4 = 0m;
_lotOption1 = 0m;
_lotOption2 = 0m;
_currentVolume = 0m;
_needsPostTradeAdjustment = false;
_hasOpenPosition = false;
_pnlAtEntry = 0m;
_lastTradePnL = 0m;
_trendDirection = 0;
_entryWindowStart = null;
_entryWindowEnd = null;
_entryWindowActive = false;
_entryPrice = 0m;
_stopPrice = 0m;
_takePrice = 0m;
}
private void RecalculateLotOptions()
{
var baseLot = BaseLot * _lotStage;
_stageLot1 = baseLot;
_stageLot2 = baseLot * 2m;
_stageLot3 = baseLot * 7m;
_stageLot4 = baseLot * 14m;
// Stage-specific lot multipliers replicate the original configuration.
if (_planBActive)
{
_lotOption1 = _stageLot2;
_lotOption2 = _stageLot4;
}
else
{
_lotOption1 = _stageLot1;
_lotOption2 = _stageLot3;
}
if (_currentVolume <= 0m)
_currentVolume = _lotOption1;
}
}
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
from StockSharp.Algo.Strategies import Strategy
class invest_system45_strategy(Strategy):
def __init__(self):
super(invest_system45_strategy, self).__init__()
self._stop_loss_pips = self.Param("StopLossPips", 240)
self._take_profit_pips = self.Param("TakeProfitPips", 40)
self._entry_window_minutes = self.Param("EntryWindowMinutes", 15)
self._signal_candle_type = self.Param("SignalCandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._trend_candle_type = self.Param("TrendCandleType", DataType.TimeFrame(TimeSpan.FromHours(4)))
self._base_lot = self.Param("BaseLot", 0.1)
self._pip_size = 0.0
self._min_balance = 0.0
self._max_balance = 0.0
self._lot_stage = 1
self._plan_b_active = False
self._stage_lot1 = 0.0
self._stage_lot2 = 0.0
self._stage_lot3 = 0.0
self._stage_lot4 = 0.0
self._lot_option1 = 0.0
self._lot_option2 = 0.0
self._current_volume = 0.0
self._needs_post_trade_adjustment = False
self._has_open_position = False
self._pnl_at_entry = 0.0
self._last_trade_pnl = 0.0
self._trend_direction = 0
self._entry_window_start = None
self._entry_window_end = None
self._entry_window_active = False
self._entry_price = 0.0
self._stop_price = 0.0
self._take_price = 0.0
@property
def StopLossPips(self):
return self._stop_loss_pips.Value
@property
def TakeProfitPips(self):
return self._take_profit_pips.Value
@property
def EntryWindowMinutes(self):
return self._entry_window_minutes.Value
@property
def SignalCandleType(self):
return self._signal_candle_type.Value
@property
def TrendCandleType(self):
return self._trend_candle_type.Value
@property
def BaseLot(self):
return self._base_lot.Value
def OnStarted2(self, time):
super(invest_system45_strategy, self).OnStarted2(time)
self._reset_state()
self._pip_size = self._calculate_pip_size()
self._recalculate_lot_options()
trend_sub = self.SubscribeCandles(self.TrendCandleType)
trend_sub.Bind(self._process_trend_candle).Start()
entry_sub = self.SubscribeCandles(self.SignalCandleType)
entry_sub.Bind(self._process_entry_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, entry_sub)
self.DrawOwnTrades(area)
def _process_trend_candle(self, candle):
if candle.State != CandleStates.Finished:
return
if float(candle.ClosePrice) > float(candle.OpenPrice):
self._trend_direction = 1
elif float(candle.ClosePrice) < float(candle.OpenPrice):
self._trend_direction = -1
self._entry_window_start = candle.CloseTime
self._entry_window_end = candle.CloseTime.AddMinutes(self.EntryWindowMinutes)
self._entry_window_active = True
def _process_entry_candle(self, candle):
if candle.State != CandleStates.Finished:
return
pos = float(self.Position)
# SL/TP management
if pos > 0 and self._entry_price > 0:
if self._stop_price > 0 and float(candle.LowPrice) <= self._stop_price:
self.SellMarket(pos)
self._on_position_closed()
return
if self._take_price > 0 and float(candle.HighPrice) >= self._take_price:
self.SellMarket(pos)
self._on_position_closed()
return
elif pos < 0 and self._entry_price > 0:
if self._stop_price > 0 and float(candle.HighPrice) >= self._stop_price:
self.BuyMarket(abs(pos))
self._on_position_closed()
return
if self._take_price > 0 and float(candle.LowPrice) <= self._take_price:
self.BuyMarket(abs(pos))
self._on_position_closed()
return
self._update_balance_state()
if not self._entry_window_active or self._entry_window_start is None or self._entry_window_end is None:
return
open_time = candle.OpenTime
if open_time < self._entry_window_start:
return
if open_time > self._entry_window_end:
self._entry_window_active = False
return
if self._trend_direction == 0:
return
if float(self.Position) != 0:
return
if self._current_volume <= 0:
self._current_volume = self._lot_option1
if self._current_volume <= 0:
return
close = float(candle.ClosePrice)
if self._trend_direction > 0:
self.BuyMarket(self._current_volume)
self._entry_price = close
sl_dist = self.StopLossPips * self._pip_size
tp_dist = self.TakeProfitPips * self._pip_size
self._stop_price = close - sl_dist if sl_dist > 0 else 0.0
self._take_price = close + tp_dist if tp_dist > 0 else 0.0
else:
self.SellMarket(self._current_volume)
self._entry_price = close
sl_dist = self.StopLossPips * self._pip_size
tp_dist = self.TakeProfitPips * self._pip_size
self._stop_price = close + sl_dist if sl_dist > 0 else 0.0
self._take_price = close - tp_dist if tp_dist > 0 else 0.0
self._has_open_position = True
self._needs_post_trade_adjustment = True
self._pnl_at_entry = float(self.PnL)
self._entry_window_active = False
def _update_balance_state(self):
portfolio = self.Portfolio
if portfolio is None:
return
balance = portfolio.CurrentValue
if balance is None or float(balance) <= 0:
return
bal = float(balance)
if self._min_balance <= 0:
self._min_balance = bal
self._max_balance = bal
if bal > self._max_balance:
self._max_balance = bal
if self._plan_b_active:
self._plan_b_active = False
self._recalculate_lot_options()
new_stage = 1
if self._min_balance > 0:
for stage in range(6, 1, -1):
if bal > self._min_balance * stage:
new_stage = stage
break
if new_stage != self._lot_stage:
self._lot_stage = new_stage
self._recalculate_lot_options()
def _calculate_pip_size(self):
sec = self.Security
if sec is None:
return 1.0
step = float(sec.PriceStep) if sec.PriceStep is not None else 1.0
decimals = int(sec.Decimals) if sec.Decimals is not None else 0
if decimals == 3 or decimals == 5:
step *= 10.0
return step
def _recalculate_lot_options(self):
base_lot = float(self.BaseLot) * self._lot_stage
self._stage_lot1 = base_lot
self._stage_lot2 = base_lot * 2.0
self._stage_lot3 = base_lot * 7.0
self._stage_lot4 = base_lot * 14.0
if self._plan_b_active:
self._lot_option1 = self._stage_lot2
self._lot_option2 = self._stage_lot4
else:
self._lot_option1 = self._stage_lot1
self._lot_option2 = self._stage_lot3
if self._current_volume <= 0:
self._current_volume = self._lot_option1
def _handle_post_trade_adjustment(self):
if not self._needs_post_trade_adjustment:
return
self._needs_post_trade_adjustment = False
self._update_balance_state()
if self._last_trade_pnl < 0:
if self._current_volume == self._lot_option2 and not self._plan_b_active:
self._plan_b_active = True
self._recalculate_lot_options()
else:
self._current_volume = self._lot_option2
elif self._last_trade_pnl > 0:
self._current_volume = self._lot_option1
def OnOwnTradeReceived(self, trade):
super(invest_system45_strategy, self).OnOwnTradeReceived(trade)
if trade is None or trade.Trade is None:
return
pos = float(self.Position)
if pos != 0 and self._entry_price == 0:
self._entry_price = float(trade.Trade.Price)
sl_dist = self.StopLossPips * self._pip_size
tp_dist = self.TakeProfitPips * self._pip_size
if pos > 0:
self._stop_price = self._entry_price - sl_dist if sl_dist > 0 else 0.0
self._take_price = self._entry_price + tp_dist if tp_dist > 0 else 0.0
else:
self._stop_price = self._entry_price + sl_dist if sl_dist > 0 else 0.0
self._take_price = self._entry_price - tp_dist if tp_dist > 0 else 0.0
if pos == 0:
self._reset_targets()
def OnPositionReceived(self, position):
super(invest_system45_strategy, self).OnPositionReceived(position)
pos = float(self.Position)
if pos != 0:
if not self._has_open_position:
self._has_open_position = True
self._needs_post_trade_adjustment = True
self._pnl_at_entry = float(self.PnL)
self._entry_window_active = False
return
if not self._has_open_position:
return
self._has_open_position = False
self._last_trade_pnl = float(self.PnL) - self._pnl_at_entry
self._handle_post_trade_adjustment()
def _on_position_closed(self):
self._reset_targets()
if self._has_open_position:
self._has_open_position = False
self._last_trade_pnl = float(self.PnL) - self._pnl_at_entry
self._handle_post_trade_adjustment()
def _reset_targets(self):
self._entry_price = 0.0
self._stop_price = 0.0
self._take_price = 0.0
def _reset_state(self):
self._pip_size = 0.0
self._min_balance = 0.0
self._max_balance = 0.0
self._lot_stage = 1
self._plan_b_active = False
self._stage_lot1 = 0.0
self._stage_lot2 = 0.0
self._stage_lot3 = 0.0
self._stage_lot4 = 0.0
self._lot_option1 = 0.0
self._lot_option2 = 0.0
self._current_volume = 0.0
self._needs_post_trade_adjustment = False
self._has_open_position = False
self._pnl_at_entry = 0.0
self._last_trade_pnl = 0.0
self._trend_direction = 0
self._entry_window_start = None
self._entry_window_end = None
self._entry_window_active = False
self._entry_price = 0.0
self._stop_price = 0.0
self._take_price = 0.0
def OnReseted(self):
super(invest_system45_strategy, self).OnReseted()
self._reset_state()
def CreateClone(self):
return invest_system45_strategy()