N Candles v5 Strategy
Overview
The N Candles v5 strategy searches for runs of identical candles and opens a trade in the same direction as soon as the required streak appears. The original MQL implementation by Vladimir Karputov has been translated to the StockSharp high level API. The strategy operates on closed candles only and can be executed on any timeframe, with one hour candles being the default for the StockSharp version.
Trading Logic
- When a candle closes the strategy classifies it as bullish (close above open), bearish (close below open) or neutral (close equals open).
- Consecutive bullish candles increase the bullish streak counter while resetting the bearish counter, and vice versa for bearish candles. Neutral candles reset both counters.
- If the bullish streak counter reaches the configured
CandlesCountvalue and the current net position is flat or short, the strategy sends a market buy. Short exposure is covered first and the configuredTradeVolumeis then added to establish a long position. - If the bearish streak counter reaches
CandlesCountand the position is flat or long, the strategy sells at market, first covering any long exposure before entering short. - Trades are only opened inside the optional trading session window defined by
StartHourandEndHour. Protective actions (take profit, stop loss and trailing) continue to operate outside the session to ensure positions are handled safely. - The strategy refuses to increase exposure beyond
MaxNetVolume, mirroring the volume safeguard from the MQL version.
Risk Management
- Take Profit / Stop Loss – expressed in pips and converted to absolute price distances using the security price step. Both levels are optional and can be disabled by setting the corresponding value to zero.
- Trailing Stop – activates after the price advances by
TrailingStopPipsfrom the entry price. Once active, the stop is tightened whenever price moves an additionalTrailingStepPipsin the trade direction. - Session Filter –
UseTradingHoursenables the start and end hour filter, preventing new entries outside the selected window while still letting risk management close positions. - Maximum Net Volume – the absolute position (long or short) is never
allowed to exceed
MaxNetVolume.
Parameters
| Parameter | Description | Default |
|---|---|---|
TradeVolume |
Order size used for new entries. | 1 |
CandlesCount |
Number of consecutive identical candles required for a signal. | 3 |
TakeProfitPips |
Take profit distance in pips (0 disables). | 50 |
StopLossPips |
Stop loss distance in pips (0 disables). | 50 |
TrailingStopPips |
Distance that activates the trailing stop (0 disables). | 10 |
TrailingStepPips |
Additional progress required before tightening the trailing stop. | 4 |
UseTradingHours |
Enables the trading hour filter. | true |
StartHour |
First hour (0–23) when new positions are allowed. | 11 |
EndHour |
Last hour (0–23) when new positions are allowed. | 18 |
MaxNetVolume |
Maximum absolute position size allowed. | 2 |
CandleType |
Candle data type to analyse. Default is 1 hour candles. | TimeSpan.FromHours(1) |
Usage Notes
- The strategy subscribes to candle data via the high level
SubscribeCandlesAPI and works with any instrument that provides candle series. - Because the logic relies on completed bars, it is most suitable for intraday or higher timeframes where market noise between closes is less impactful.
- Adjust the pip-based risk settings according to the instrument’s tick size.
- When deploying on instruments with significant spread differences, verify the trailing stop parameters so that the stop is not triggered by normal spread widening.
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>
/// Detects a sequence of identical candles and opens trades in the same direction.
/// Implements optional take profit, stop loss, trailing stop and trading hour filter.
/// </summary>
public class NCandlesV5Strategy : Strategy
{
private readonly StrategyParam<int> _candlesCount;
private readonly StrategyParam<decimal> _takeProfitPips;
private readonly StrategyParam<decimal> _stopLossPips;
private readonly StrategyParam<decimal> _trailingStopPips;
private readonly StrategyParam<decimal> _trailingStepPips;
private readonly StrategyParam<bool> _useTradingHours;
private readonly StrategyParam<int> _startHour;
private readonly StrategyParam<int> _endHour;
private readonly StrategyParam<decimal> _volumeParam;
private readonly StrategyParam<decimal> _maxNetVolume;
private readonly StrategyParam<DataType> _candleType;
private int _bullishCount;
private int _bearishCount;
private decimal? _longEntryPrice;
private decimal? _longTakeProfit;
private decimal? _longStopLoss;
private decimal? _longTrailingStop;
private decimal? _shortEntryPrice;
private decimal? _shortTakeProfit;
private decimal? _shortStopLoss;
private decimal? _shortTrailingStop;
/// <summary>
/// Initializes a new instance of <see cref="NCandlesV5Strategy"/>.
/// </summary>
public NCandlesV5Strategy()
{
_volumeParam = Param(nameof(TradeVolume), 1m)
.SetDisplay("Trade Volume", "Order volume for entries", "Trading")
.SetGreaterThanZero();
_candlesCount = Param(nameof(CandlesCount), 3)
.SetDisplay("Candles Count", "Number of identical candles required", "General")
.SetGreaterThanZero();
_takeProfitPips = Param(nameof(TakeProfitPips), 50m)
.SetDisplay("Take Profit (pips)", "Take profit distance in pips", "Risk");
_stopLossPips = Param(nameof(StopLossPips), 50m)
.SetDisplay("Stop Loss (pips)", "Stop loss distance in pips", "Risk");
_trailingStopPips = Param(nameof(TrailingStopPips), 10m)
.SetDisplay("Trailing Stop (pips)", "Trailing stop activation distance", "Risk");
_trailingStepPips = Param(nameof(TrailingStepPips), 4m)
.SetDisplay("Trailing Step (pips)", "Increment required to tighten trailing stop", "Risk");
_useTradingHours = Param(nameof(UseTradingHours), true)
.SetDisplay("Use Trading Hours", "Enable trading session filter", "Trading");
_startHour = Param(nameof(StartHour), 11)
.SetRange(0, 23)
.SetDisplay("Start Hour", "Hour when trading is allowed to start", "Trading");
_endHour = Param(nameof(EndHour), 18)
.SetRange(0, 23)
.SetDisplay("End Hour", "Hour when trading is allowed to stop", "Trading");
_maxNetVolume = Param(nameof(MaxNetVolume), 2m)
.SetDisplay("Max Net Volume", "Maximum absolute net position", "Risk")
.SetGreaterThanZero();
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to analyze", "General");
Volume = _volumeParam.Value;
}
/// <summary>
/// Trade volume used for new entries.
/// </summary>
public decimal TradeVolume
{
get => _volumeParam.Value;
set
{
_volumeParam.Value = value;
Volume = value;
}
}
/// <summary>
/// Number of consecutive identical candles required for a signal.
/// </summary>
public int CandlesCount
{
get => _candlesCount.Value;
set => _candlesCount.Value = value;
}
/// <summary>
/// Take profit distance in pips.
/// </summary>
public decimal TakeProfitPips
{
get => _takeProfitPips.Value;
set => _takeProfitPips.Value = value;
}
/// <summary>
/// Stop loss distance in pips.
/// </summary>
public decimal StopLossPips
{
get => _stopLossPips.Value;
set => _stopLossPips.Value = value;
}
/// <summary>
/// Trailing stop activation distance in pips.
/// </summary>
public decimal TrailingStopPips
{
get => _trailingStopPips.Value;
set => _trailingStopPips.Value = value;
}
/// <summary>
/// Trailing step distance in pips.
/// </summary>
public decimal TrailingStepPips
{
get => _trailingStepPips.Value;
set => _trailingStepPips.Value = value;
}
/// <summary>
/// Enables the trading hour filter.
/// </summary>
public bool UseTradingHours
{
get => _useTradingHours.Value;
set => _useTradingHours.Value = value;
}
/// <summary>
/// First hour of the allowed trading window.
/// </summary>
public int StartHour
{
get => _startHour.Value;
set => _startHour.Value = value;
}
/// <summary>
/// Last hour of the allowed trading window.
/// </summary>
public int EndHour
{
get => _endHour.Value;
set => _endHour.Value = value;
}
/// <summary>
/// Maximum absolute net position allowed.
/// </summary>
public decimal MaxNetVolume
{
get => _maxNetVolume.Value;
set => _maxNetVolume.Value = value;
}
/// <summary>
/// Candle type used for pattern detection.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
Volume = TradeVolume;
ResetState();
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
if (UseTradingHours && StartHour >= EndHour)
throw new InvalidOperationException("Start hour must be less than end hour when trading hours filter is enabled.");
Volume = TradeVolume;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
// Work only with completed candles to avoid premature signals.
if (candle.State != CandleStates.Finished)
return;
// Refresh trailing and exit logic before looking for new opportunities.
UpdateRiskManagement(candle);
var direction = GetDirection(candle);
// Track bullish and bearish streak length.
if (direction == 1)
{
_bullishCount++;
_bearishCount = 0;
}
else if (direction == -1)
{
_bearishCount++;
_bullishCount = 0;
}
else
{
_bullishCount = 0;
_bearishCount = 0;
}
var tradingAllowed = !UseTradingHours || (candle.OpenTime.Hour >= StartHour && candle.OpenTime.Hour <= EndHour);
// Skip entries outside the configured session window.
if (!tradingAllowed)
return;
var volume = TradeVolume;
if (volume <= 0m)
return;
var step = Security?.PriceStep ?? 1m;
// Use instrument price step to translate pip distances to absolute prices.
if (_bullishCount >= CandlesCount && Position <= 0m)
{
// Enter long after detecting the required number of bullish candles in a row.
var orderVolume = volume + Math.Max(0m, -Position);
if (orderVolume > 0m && Math.Abs(Position + orderVolume) <= MaxNetVolume)
{
BuyMarket();
SetupLongState(candle, step);
}
ResetCounters();
}
else if (_bearishCount >= CandlesCount && Position >= 0m)
{
// Enter short after detecting the required number of bearish candles in a row.
var orderVolume = volume + Math.Max(0m, Position);
if (orderVolume > 0m && Math.Abs(Position - orderVolume) <= MaxNetVolume)
{
SellMarket();
SetupShortState(candle, step);
}
ResetCounters();
}
}
private void UpdateRiskManagement(ICandleMessage candle)
{
if (Position > 0m)
{
ManageLongPosition(candle);
}
else
{
ClearLongState();
}
if (Position < 0m)
{
ManageShortPosition(candle);
}
else
{
ClearShortState();
}
}
private void ManageLongPosition(ICandleMessage candle)
{
if (_longEntryPrice is null)
// Capture entry price if it was not stored yet (for example after restart).
_longEntryPrice = candle.ClosePrice;
var step = Security?.PriceStep ?? 1m;
var close = candle.ClosePrice;
var high = candle.HighPrice;
var low = candle.LowPrice;
var trailingDistance = TrailingStopPips > 0m ? TrailingStopPips * step : 0m;
var trailingStep = TrailingStepPips > 0m ? TrailingStepPips * step : 0m;
if (TrailingStopPips > 0m && _longEntryPrice is decimal entry)
{
// Update trailing stop level according to the latest candle.
if (_longTrailingStop is null)
{
if (close - trailingDistance > entry)
_longTrailingStop = entry;
}
else
{
var newLevel = close - trailingDistance;
if (newLevel - trailingStep > _longTrailingStop)
_longTrailingStop = newLevel;
}
}
else
{
_longTrailingStop = null;
}
var exitVolume = Position > 0m ? Position : 0m;
var closed = false;
// Exit the long position when any protective target is triggered.
if (!closed && _longTakeProfit is decimal takeProfit && high >= takeProfit)
{
if (exitVolume > 0m)
SellMarket();
closed = true;
}
if (!closed && _longStopLoss is decimal stopLoss && low <= stopLoss)
{
if (exitVolume > 0m)
SellMarket();
closed = true;
}
if (!closed && _longTrailingStop is decimal trailingStop && low <= trailingStop)
{
if (exitVolume > 0m)
SellMarket();
closed = true;
}
if (closed)
ClearLongState();
}
private void ManageShortPosition(ICandleMessage candle)
{
if (_shortEntryPrice is null)
// Capture entry price if it was not stored yet (for example after restart).
_shortEntryPrice = candle.ClosePrice;
var step = Security?.PriceStep ?? 1m;
var close = candle.ClosePrice;
var high = candle.HighPrice;
var low = candle.LowPrice;
var trailingDistance = TrailingStopPips > 0m ? TrailingStopPips * step : 0m;
var trailingStep = TrailingStepPips > 0m ? TrailingStepPips * step : 0m;
if (TrailingStopPips > 0m && _shortEntryPrice is decimal entry)
{
// Update trailing stop level for the active short position.
if (_shortTrailingStop is null)
{
if (close + trailingDistance < entry)
_shortTrailingStop = entry;
}
else
{
var newLevel = close + trailingDistance;
if (newLevel + trailingStep < _shortTrailingStop)
_shortTrailingStop = newLevel;
}
}
else
{
_shortTrailingStop = null;
}
var exitVolume = Position < 0m ? -Position : 0m;
var closed = false;
// Exit the short position when any protective target is triggered.
if (!closed && _shortTakeProfit is decimal takeProfit && low <= takeProfit)
{
if (exitVolume > 0m)
BuyMarket();
closed = true;
}
if (!closed && _shortStopLoss is decimal stopLoss && high >= stopLoss)
{
if (exitVolume > 0m)
BuyMarket();
closed = true;
}
if (!closed && _shortTrailingStop is decimal trailingStop && high >= trailingStop)
{
if (exitVolume > 0m)
BuyMarket();
closed = true;
}
if (closed)
ClearShortState();
}
private static int GetDirection(ICandleMessage candle)
{
if (candle.ClosePrice > candle.OpenPrice)
return 1;
if (candle.ClosePrice < candle.OpenPrice)
return -1;
return 0;
}
private void SetupLongState(ICandleMessage candle, decimal step)
{
var entryPrice = candle.ClosePrice;
// Store reference levels for long-side risk management.
_longEntryPrice = entryPrice;
_longTakeProfit = TakeProfitPips > 0m ? entryPrice + TakeProfitPips * step : null;
_longStopLoss = StopLossPips > 0m ? entryPrice - StopLossPips * step : null;
_longTrailingStop = null;
ClearShortState();
}
private void SetupShortState(ICandleMessage candle, decimal step)
{
var entryPrice = candle.ClosePrice;
// Store reference levels for short-side risk management.
_shortEntryPrice = entryPrice;
_shortTakeProfit = TakeProfitPips > 0m ? entryPrice - TakeProfitPips * step : null;
_shortStopLoss = StopLossPips > 0m ? entryPrice + StopLossPips * step : null;
_shortTrailingStop = null;
ClearLongState();
}
private void ClearLongState()
{
_longEntryPrice = null;
_longTakeProfit = null;
_longStopLoss = null;
_longTrailingStop = null;
}
private void ClearShortState()
{
_shortEntryPrice = null;
_shortTakeProfit = null;
_shortStopLoss = null;
_shortTrailingStop = null;
}
private void ResetState()
{
ResetCounters();
ClearLongState();
ClearShortState();
}
private void ResetCounters()
{
_bullishCount = 0;
_bearishCount = 0;
}
}
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
class n_candles_v5_strategy(Strategy):
"""N Candles v5: trades after N consecutive same-direction candles with SL/TP/trailing."""
def __init__(self):
super(n_candles_v5_strategy, self).__init__()
self._volume_param = self.Param("TradeVolume", 1.0) \
.SetGreaterThanZero() \
.SetDisplay("Trade Volume", "Order volume for entries", "Trading")
self._candles_count = self.Param("CandlesCount", 3) \
.SetGreaterThanZero() \
.SetDisplay("Candles Count", "Number of identical candles required", "General")
self._take_profit_pips = self.Param("TakeProfitPips", 50.0) \
.SetDisplay("Take Profit (pips)", "Take profit distance in pips", "Risk")
self._stop_loss_pips = self.Param("StopLossPips", 50.0) \
.SetDisplay("Stop Loss (pips)", "Stop loss distance in pips", "Risk")
self._trailing_stop_pips = self.Param("TrailingStopPips", 10.0) \
.SetDisplay("Trailing Stop (pips)", "Trailing stop activation distance", "Risk")
self._trailing_step_pips = self.Param("TrailingStepPips", 4.0) \
.SetDisplay("Trailing Step (pips)", "Increment required to tighten trailing stop", "Risk")
self._use_trading_hours = self.Param("UseTradingHours", True) \
.SetDisplay("Use Trading Hours", "Enable trading session filter", "Trading")
self._start_hour = self.Param("StartHour", 11) \
.SetDisplay("Start Hour", "Hour when trading is allowed to start", "Trading")
self._end_hour = self.Param("EndHour", 18) \
.SetDisplay("End Hour", "Hour when trading is allowed to stop", "Trading")
self._max_net_volume = self.Param("MaxNetVolume", 2.0) \
.SetGreaterThanZero() \
.SetDisplay("Max Net Volume", "Maximum absolute net position", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles to analyze", "General")
self._bullish_count = 0
self._bearish_count = 0
self._long_entry_price = None
self._long_take_profit = None
self._long_stop_loss = None
self._long_trailing_stop = None
self._short_entry_price = None
self._short_take_profit = None
self._short_stop_loss = None
self._short_trailing_stop = None
@property
def TradeVolume(self):
return float(self._volume_param.Value)
@property
def CandlesCount(self):
return int(self._candles_count.Value)
@property
def TakeProfitPips(self):
return float(self._take_profit_pips.Value)
@property
def StopLossPips(self):
return float(self._stop_loss_pips.Value)
@property
def TrailingStopPips(self):
return float(self._trailing_stop_pips.Value)
@property
def TrailingStepPips(self):
return float(self._trailing_step_pips.Value)
@property
def UseTradingHours(self):
return self._use_trading_hours.Value
@property
def StartHour(self):
return int(self._start_hour.Value)
@property
def EndHour(self):
return int(self._end_hour.Value)
@property
def MaxNetVolume(self):
return float(self._max_net_volume.Value)
@property
def CandleType(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(n_candles_v5_strategy, self).OnStarted2(time)
self._bullish_count = 0
self._bearish_count = 0
self._clear_long_state()
self._clear_short_state()
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
self._update_risk_management(candle)
# Determine direction
if close > open_p:
direction = 1
elif close < open_p:
direction = -1
else:
direction = 0
if direction == 1:
self._bullish_count += 1
self._bearish_count = 0
elif direction == -1:
self._bearish_count += 1
self._bullish_count = 0
else:
self._bullish_count = 0
self._bearish_count = 0
trading_allowed = not self.UseTradingHours or (candle.OpenTime.Hour >= self.StartHour and candle.OpenTime.Hour <= self.EndHour)
if not trading_allowed:
return
volume = self.TradeVolume
if volume <= 0:
return
sec = self.Security
step = float(sec.PriceStep) if sec is not None and sec.PriceStep is not None else 1.0
if self._bullish_count >= self.CandlesCount and self.Position <= 0:
order_volume = volume + max(0.0, -self.Position)
if order_volume > 0 and abs(self.Position + order_volume) <= self.MaxNetVolume:
self.BuyMarket()
self._setup_long_state(candle, step)
self._reset_counters()
elif self._bearish_count >= self.CandlesCount and self.Position >= 0:
order_volume = volume + max(0.0, self.Position)
if order_volume > 0 and abs(self.Position - order_volume) <= self.MaxNetVolume:
self.SellMarket()
self._setup_short_state(candle, step)
self._reset_counters()
def _update_risk_management(self, candle):
if self.Position > 0:
self._manage_long_position(candle)
else:
self._clear_long_state()
if self.Position < 0:
self._manage_short_position(candle)
else:
self._clear_short_state()
def _manage_long_position(self, candle):
if self._long_entry_price is None:
self._long_entry_price = float(candle.ClosePrice)
sec = self.Security
step = float(sec.PriceStep) if sec is not None and sec.PriceStep is not None else 1.0
close = float(candle.ClosePrice)
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
trailing_distance = self.TrailingStopPips * step if self.TrailingStopPips > 0 else 0.0
trailing_step = self.TrailingStepPips * step if self.TrailingStepPips > 0 else 0.0
if self.TrailingStopPips > 0 and self._long_entry_price is not None:
entry = self._long_entry_price
if self._long_trailing_stop is None:
if close - trailing_distance > entry:
self._long_trailing_stop = entry
else:
new_level = close - trailing_distance
if new_level - trailing_step > self._long_trailing_stop:
self._long_trailing_stop = new_level
else:
self._long_trailing_stop = None
closed = False
if not closed and self._long_take_profit is not None and h >= self._long_take_profit:
if self.Position > 0:
self.SellMarket()
closed = True
if not closed and self._long_stop_loss is not None and lo <= self._long_stop_loss:
if self.Position > 0:
self.SellMarket()
closed = True
if not closed and self._long_trailing_stop is not None and lo <= self._long_trailing_stop:
if self.Position > 0:
self.SellMarket()
closed = True
if closed:
self._clear_long_state()
def _manage_short_position(self, candle):
if self._short_entry_price is None:
self._short_entry_price = float(candle.ClosePrice)
sec = self.Security
step = float(sec.PriceStep) if sec is not None and sec.PriceStep is not None else 1.0
close = float(candle.ClosePrice)
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
trailing_distance = self.TrailingStopPips * step if self.TrailingStopPips > 0 else 0.0
trailing_step = self.TrailingStepPips * step if self.TrailingStepPips > 0 else 0.0
if self.TrailingStopPips > 0 and self._short_entry_price is not None:
entry = self._short_entry_price
if self._short_trailing_stop is None:
if close + trailing_distance < entry:
self._short_trailing_stop = entry
else:
new_level = close + trailing_distance
if new_level + trailing_step < self._short_trailing_stop:
self._short_trailing_stop = new_level
else:
self._short_trailing_stop = None
closed = False
if not closed and self._short_take_profit is not None and lo <= self._short_take_profit:
if self.Position < 0:
self.BuyMarket()
closed = True
if not closed and self._short_stop_loss is not None and h >= self._short_stop_loss:
if self.Position < 0:
self.BuyMarket()
closed = True
if not closed and self._short_trailing_stop is not None and h >= self._short_trailing_stop:
if self.Position < 0:
self.BuyMarket()
closed = True
if closed:
self._clear_short_state()
def _setup_long_state(self, candle, step):
entry_price = float(candle.ClosePrice)
self._long_entry_price = entry_price
self._long_take_profit = entry_price + self.TakeProfitPips * step if self.TakeProfitPips > 0 else None
self._long_stop_loss = entry_price - self.StopLossPips * step if self.StopLossPips > 0 else None
self._long_trailing_stop = None
self._clear_short_state()
def _setup_short_state(self, candle, step):
entry_price = float(candle.ClosePrice)
self._short_entry_price = entry_price
self._short_take_profit = entry_price - self.TakeProfitPips * step if self.TakeProfitPips > 0 else None
self._short_stop_loss = entry_price + self.StopLossPips * step if self.StopLossPips > 0 else None
self._short_trailing_stop = None
self._clear_long_state()
def _clear_long_state(self):
self._long_entry_price = None
self._long_take_profit = None
self._long_stop_loss = None
self._long_trailing_stop = None
def _clear_short_state(self):
self._short_entry_price = None
self._short_take_profit = None
self._short_stop_loss = None
self._short_trailing_stop = None
def _reset_counters(self):
self._bullish_count = 0
self._bearish_count = 0
def OnReseted(self):
super(n_candles_v5_strategy, self).OnReseted()
self._bullish_count = 0
self._bearish_count = 0
self._clear_long_state()
self._clear_short_state()
def CreateClone(self):
return n_candles_v5_strategy()