Daily BreakPoint Strategy
Overview
The Daily BreakPoint Strategy is a StockSharp port of the MetaTrader 5 expert advisor "Daily BreakPoint" (build 19498). The algorithm monitors the distance between the current price and the daily open. When the move from the daily open exceeds a configurable threshold and the previous candle meets strict body-size requirements, the strategy either enters in the direction of the breakout or reverses the existing exposure depending on the CloseBySignal flag.
The strategy works with two data streams at the same time:
- Intraday candles defined by the
CandleTypeparameter for signal generation. - Daily candles used to track the most recent session open price.
Trading Logic
- When a new intraday candle finishes, the strategy reads the latest daily open price and calculates the breakout levels using
BreakPointPips(converted into absolute prices via the instrument tick size). - The body size of the recently closed candle must be within the range
[LastBarSizeMinPips, LastBarSizeMaxPips]. - Bullish setup
- The candle must close above its open (
Close > Open). - The close must be at least
BreakPointPipsabove the daily open. - The breakout price (daily open + breakpoint) must lie inside the candle body.
- If
CloseBySignal = false, the strategy opens a long position. Otherwise, it closes any open long exposure and establishes a short position.
- The candle must close above its open (
- Bearish setup mirrors the bullish case: a bearish candle whose close is at least
BreakPointPipsbelow the daily open and whose body contains the breakout level triggers either a short entry (CloseBySignal = false) or a reversal into a long position (CloseBySignal = true). - Orders are sent as market orders using the configured
OrderVolume. Position size is cumulative, so multiple signals can scale the position in either direction.
Risk Management
- Stop Loss / Take Profit: Optional fixed targets defined in pips (
StopLossPips,TakeProfitPips). When set to zero the corresponding level is disabled. The strategy evaluates candle highs and lows to detect hits. - Trailing Stop: Enabled when
TrailingStopPips > 0. Once the open profit exceedsTrailingStopPips + TrailingStepPips, the stop is trailed behind the price byTrailingStopPips. The step parameter prevents frequent stop adjustments in flat markets. - All price distances are converted from pips using the instrument
PriceStep. For 3- or 5-decimal quoting the pip equals ten price steps, replicating the original expert advisor behaviour.
Parameters
| Name | Description |
|---|---|
OrderVolume |
Base volume used for every market order. |
CloseBySignal |
If true, the strategy closes existing positions and opens the opposite direction when a breakout signal appears. |
BreakPointPips |
Distance from the daily open required to confirm a breakout. |
LastBarSizeMinPips / LastBarSizeMaxPips |
Minimum and maximum body size of the trigger candle. |
TrailingStopPips |
Trailing stop distance. Set to 0 to disable trailing. |
TrailingStepPips |
Additional move required before each trailing adjustment. |
StopLossPips |
Optional fixed stop loss. 0 disables it. |
TakeProfitPips |
Optional fixed take profit. 0 disables it. |
CandleType |
Intraday candle series used for signal generation. |
Usage Notes
- The strategy automatically subscribes to both intraday and daily candles. Ensure that the data provider supports the requested time frames.
- Because the logic evaluates finished candles, orders are submitted at the close price of the signal bar.
- The pip conversion assumes Forex-style pricing. Review the defaults when applying the strategy to instruments with unconventional tick sizes.
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>
/// Daily breakout strategy that reacts to the distance from the daily open.
/// Converted from the MetaTrader Daily BreakPoint expert advisor.
/// </summary>
public class DailyBreakPointStrategy : Strategy
{
private readonly StrategyParam<decimal> _orderVolume;
private readonly StrategyParam<bool> _closeBySignal;
private readonly StrategyParam<decimal> _breakPointPips;
private readonly StrategyParam<decimal> _lastBarSizeMinPips;
private readonly StrategyParam<decimal> _lastBarSizeMaxPips;
private readonly StrategyParam<decimal> _trailingStopPips;
private readonly StrategyParam<decimal> _trailingStepPips;
private readonly StrategyParam<decimal> _stopLossPips;
private readonly StrategyParam<decimal> _takeProfitPips;
private readonly StrategyParam<DataType> _candleType;
private decimal? _currentDayOpen;
private decimal? _longStopPrice;
private decimal? _longTakePrice;
private decimal? _shortStopPrice;
private decimal? _shortTakePrice;
private decimal? _longEntryPrice;
private decimal? _shortEntryPrice;
private decimal _pipSize;
/// <summary>
/// Order volume.
/// </summary>
public decimal OrderVolume
{
get => _orderVolume.Value;
set => _orderVolume.Value = value;
}
/// <summary>
/// Reverse the position when the opposite signal appears.
/// </summary>
public bool CloseBySignal
{
get => _closeBySignal.Value;
set => _closeBySignal.Value = value;
}
/// <summary>
/// Break distance from the daily open expressed in pips.
/// </summary>
public decimal BreakPointPips
{
get => _breakPointPips.Value;
set => _breakPointPips.Value = value;
}
/// <summary>
/// Minimum size of the previous bar body in pips.
/// </summary>
public decimal LastBarSizeMinPips
{
get => _lastBarSizeMinPips.Value;
set => _lastBarSizeMinPips.Value = value;
}
/// <summary>
/// Maximum size of the previous bar body in pips.
/// </summary>
public decimal LastBarSizeMaxPips
{
get => _lastBarSizeMaxPips.Value;
set => _lastBarSizeMaxPips.Value = value;
}
/// <summary>
/// Trailing stop distance in pips.
/// </summary>
public decimal TrailingStopPips
{
get => _trailingStopPips.Value;
set => _trailingStopPips.Value = value;
}
/// <summary>
/// Trailing stop step in pips.
/// </summary>
public decimal TrailingStepPips
{
get => _trailingStepPips.Value;
set => _trailingStepPips.Value = value;
}
/// <summary>
/// Fixed stop loss in pips.
/// </summary>
public decimal StopLossPips
{
get => _stopLossPips.Value;
set => _stopLossPips.Value = value;
}
/// <summary>
/// Fixed take profit in pips.
/// </summary>
public decimal TakeProfitPips
{
get => _takeProfitPips.Value;
set => _takeProfitPips.Value = value;
}
/// <summary>
/// Intraday candle type used for signal calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="DailyBreakPointStrategy"/> class.
/// </summary>
public DailyBreakPointStrategy()
{
_orderVolume = Param(nameof(OrderVolume), 1m)
.SetGreaterThanZero()
.SetDisplay("Volume", "Default order volume", "General");
_closeBySignal = Param(nameof(CloseBySignal), true)
.SetDisplay("Close By Signal", "Reverse existing position on opposite signal", "General");
_breakPointPips = Param(nameof(BreakPointPips), 5m)
.SetGreaterThanZero()
.SetDisplay("Break Point (pips)", "Distance from the daily open", "Signals");
_lastBarSizeMinPips = Param(nameof(LastBarSizeMinPips), 1m)
.SetGreaterThanZero()
.SetDisplay("Last Bar Min (pips)", "Minimum body size of the previous bar", "Signals");
_lastBarSizeMaxPips = Param(nameof(LastBarSizeMaxPips), 5000m)
.SetGreaterThanZero()
.SetDisplay("Last Bar Max (pips)", "Maximum body size of the previous bar", "Signals");
_trailingStopPips = Param(nameof(TrailingStopPips), 2m)
.SetDisplay("Trailing Stop (pips)", "Trailing stop distance", "Risk");
_trailingStepPips = Param(nameof(TrailingStepPips), 2m)
.SetDisplay("Trailing Step (pips)", "Minimum move before trailing", "Risk");
_stopLossPips = Param(nameof(StopLossPips), 0m)
.SetDisplay("Stop Loss (pips)", "Fixed stop loss distance", "Risk");
_takeProfitPips = Param(nameof(TakeProfitPips), 30m)
.SetDisplay("Take Profit (pips)", "Fixed take profit distance", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Intraday candle series", "Data");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType), (Security, TimeSpan.FromMinutes(5).TimeFrame())];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_currentDayOpen = null;
_longStopPrice = null;
_longTakePrice = null;
_shortStopPrice = null;
_shortTakePrice = null;
_longEntryPrice = null;
_shortEntryPrice = null;
_pipSize = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
Volume = OrderVolume;
_pipSize = CalculatePipSize();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent)
);
var intradaySubscription = SubscribeCandles(CandleType);
intradaySubscription.Bind(ProcessCandle).Start();
var dailySubscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
dailySubscription.Bind(ProcessDailyCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, intradaySubscription);
DrawOwnTrades(area);
}
}
private decimal CalculatePipSize()
{
var step = Security?.PriceStep ?? 0.0001m;
if (step <= 0m)
step = 0.0001m;
var decimals = Security?.Decimals;
if (decimals == 3 || decimals == 5)
return step * 10m;
return step;
}
private decimal NormalizePrice(decimal price)
{
var step = Security?.PriceStep;
if (step is null || step.Value <= 0m)
return price;
var value = price / step.Value;
var rounded = Math.Round(value, 0, MidpointRounding.AwayFromZero);
return rounded * step.Value;
}
private void ProcessDailyCandle(ICandleMessage candle)
{
if (candle.State == CandleStates.Finished || candle.State == CandleStates.Active)
_currentDayOpen = candle.OpenPrice;
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
Volume = OrderVolume;
if (_pipSize <= 0m)
_pipSize = CalculatePipSize();
var dayOpen = _currentDayOpen;
if (dayOpen is null)
return;
var breakOffset = BreakPointPips * _pipSize;
var minBody = LastBarSizeMinPips * _pipSize;
var maxBody = LastBarSizeMaxPips * _pipSize;
var trailingStop = TrailingStopPips * _pipSize;
var trailingStep = TrailingStepPips * _pipSize;
var stopLossOffset = StopLossPips > 0m ? StopLossPips * _pipSize : 0m;
var takeProfitOffset = TakeProfitPips > 0m ? TakeProfitPips * _pipSize : 0m;
UpdateTrailing(candle, trailingStop, trailingStep);
HandleRiskExits(candle);
var bodySize = Math.Abs(candle.ClosePrice - candle.OpenPrice);
var minPrice = Math.Min(candle.OpenPrice, candle.ClosePrice);
var maxPrice = Math.Max(candle.OpenPrice, candle.ClosePrice);
var breakBuy = dayOpen.Value + breakOffset;
var breakSell = dayOpen.Value - breakOffset;
var bullishBody = candle.ClosePrice > candle.OpenPrice;
var bearishBody = candle.ClosePrice < candle.OpenPrice;
var bullishSignal = bullishBody && breakOffset > 0m &&
candle.ClosePrice - dayOpen.Value >= breakOffset &&
bodySize >= minBody &&
(maxBody <= 0m || bodySize <= maxBody);
var bearishSignal = bearishBody && breakOffset > 0m &&
dayOpen.Value - candle.ClosePrice >= breakOffset &&
bodySize >= minBody &&
(maxBody <= 0m || bodySize <= maxBody);
if (bullishSignal)
{
ExecuteBullishSignal(candle.ClosePrice, stopLossOffset, takeProfitOffset);
}
else if (bearishSignal)
{
ExecuteBearishSignal(candle.ClosePrice, stopLossOffset, takeProfitOffset);
}
}
private void UpdateTrailing(ICandleMessage candle, decimal trailingStop, decimal trailingStep)
{
if (trailingStop <= 0m)
return;
if (Position > 0 && _longEntryPrice.HasValue)
{
var profit = candle.ClosePrice - _longEntryPrice.Value;
if (profit > trailingStop + trailingStep)
{
var threshold = candle.ClosePrice - (trailingStop + trailingStep);
if (!_longStopPrice.HasValue || _longStopPrice.Value < threshold)
_longStopPrice = NormalizePrice(candle.ClosePrice - trailingStop);
}
}
else if (Position < 0 && _shortEntryPrice.HasValue)
{
var profit = _shortEntryPrice.Value - candle.ClosePrice;
if (profit > trailingStop + trailingStep)
{
var threshold = candle.ClosePrice + (trailingStop + trailingStep);
if (!_shortStopPrice.HasValue || _shortStopPrice.Value > threshold || _shortStopPrice.Value == 0m)
_shortStopPrice = NormalizePrice(candle.ClosePrice + trailingStop);
}
}
}
private void HandleRiskExits(ICandleMessage candle)
{
if (Position > 0)
{
var volume = Math.Abs(Position);
if (volume > 0m && _longStopPrice.HasValue && candle.LowPrice <= _longStopPrice.Value)
{
SellMarket();
ResetLongState();
return;
}
if (volume > 0m && _longTakePrice.HasValue && candle.HighPrice >= _longTakePrice.Value)
{
SellMarket();
ResetLongState();
}
}
else if (Position < 0)
{
var volume = Math.Abs(Position);
if (volume > 0m && _shortStopPrice.HasValue && candle.HighPrice >= _shortStopPrice.Value)
{
BuyMarket();
ResetShortState();
return;
}
if (volume > 0m && _shortTakePrice.HasValue && candle.LowPrice <= _shortTakePrice.Value)
{
BuyMarket();
ResetShortState();
}
}
else
{
ResetLongState();
ResetShortState();
}
}
private void ExecuteBullishSignal(decimal entryPrice, decimal stopLossOffset, decimal takeProfitOffset)
{
if (CloseBySignal)
{
if (Position > 0)
{
var volume = Math.Abs(Position);
SellMarket();
}
ResetLongState();
SellMarket();
_shortEntryPrice = entryPrice;
_shortStopPrice = stopLossOffset > 0m ? NormalizePrice(entryPrice + stopLossOffset) : null;
_shortTakePrice = takeProfitOffset > 0m ? NormalizePrice(entryPrice - takeProfitOffset) : null;
}
else
{
BuyMarket();
_longEntryPrice = entryPrice;
_longStopPrice = stopLossOffset > 0m ? NormalizePrice(entryPrice - stopLossOffset) : null;
_longTakePrice = takeProfitOffset > 0m ? NormalizePrice(entryPrice + takeProfitOffset) : null;
ResetShortState();
}
}
private void ExecuteBearishSignal(decimal entryPrice, decimal stopLossOffset, decimal takeProfitOffset)
{
if (CloseBySignal)
{
if (Position < 0)
{
var volume = Math.Abs(Position);
BuyMarket();
}
ResetShortState();
BuyMarket();
_longEntryPrice = entryPrice;
_longStopPrice = stopLossOffset > 0m ? NormalizePrice(entryPrice - stopLossOffset) : null;
_longTakePrice = takeProfitOffset > 0m ? NormalizePrice(entryPrice + takeProfitOffset) : null;
}
else
{
SellMarket();
_shortEntryPrice = entryPrice;
_shortStopPrice = stopLossOffset > 0m ? NormalizePrice(entryPrice + stopLossOffset) : null;
_shortTakePrice = takeProfitOffset > 0m ? NormalizePrice(entryPrice - takeProfitOffset) : null;
ResetLongState();
}
}
private void ResetLongState()
{
_longEntryPrice = null;
_longStopPrice = null;
_longTakePrice = null;
}
private void ResetShortState()
{
_shortEntryPrice = null;
_shortStopPrice = null;
_shortTakePrice = null;
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Strategies import Strategy
class daily_break_point_strategy(Strategy):
"""Daily BreakPoint: daily open breakout with body size filter and trailing stop."""
def __init__(self):
super(daily_break_point_strategy, self).__init__()
self._order_volume = self.Param("OrderVolume", 1.0) \
.SetGreaterThanZero() \
.SetDisplay("Volume", "Default order volume", "General")
self._close_by_signal = self.Param("CloseBySignal", True) \
.SetDisplay("Close By Signal", "Reverse existing position on opposite signal", "General")
self._break_point_pips = self.Param("BreakPointPips", 5.0) \
.SetGreaterThanZero() \
.SetDisplay("Break Point (pips)", "Distance from the daily open", "Signals")
self._last_bar_size_min_pips = self.Param("LastBarSizeMinPips", 1.0) \
.SetGreaterThanZero() \
.SetDisplay("Last Bar Min (pips)", "Minimum body size of the previous bar", "Signals")
self._last_bar_size_max_pips = self.Param("LastBarSizeMaxPips", 5000.0) \
.SetGreaterThanZero() \
.SetDisplay("Last Bar Max (pips)", "Maximum body size of the previous bar", "Signals")
self._trailing_stop_pips = self.Param("TrailingStopPips", 2.0) \
.SetDisplay("Trailing Stop (pips)", "Trailing stop distance", "Risk")
self._trailing_step_pips = self.Param("TrailingStepPips", 2.0) \
.SetDisplay("Trailing Step (pips)", "Minimum move before trailing", "Risk")
self._stop_loss_pips = self.Param("StopLossPips", 0.0) \
.SetDisplay("Stop Loss (pips)", "Fixed stop loss distance", "Risk")
self._take_profit_pips = self.Param("TakeProfitPips", 30.0) \
.SetDisplay("Take Profit (pips)", "Fixed take profit distance", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Intraday candle series", "Data")
self._current_day_open = None
self._long_stop_price = None
self._long_take_price = None
self._short_stop_price = None
self._short_take_price = None
self._long_entry_price = None
self._short_entry_price = None
self._pip_size = 0.0
@property
def OrderVolume(self):
return float(self._order_volume.Value)
@property
def CloseBySignal(self):
return self._close_by_signal.Value
@property
def BreakPointPips(self):
return float(self._break_point_pips.Value)
@property
def LastBarSizeMinPips(self):
return float(self._last_bar_size_min_pips.Value)
@property
def LastBarSizeMaxPips(self):
return float(self._last_bar_size_max_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 StopLossPips(self):
return float(self._stop_loss_pips.Value)
@property
def TakeProfitPips(self):
return float(self._take_profit_pips.Value)
@property
def CandleType(self):
return self._candle_type.Value
def _calc_pip_size(self):
sec = self.Security
if sec is None or sec.PriceStep is None:
return 0.0001
step = float(sec.PriceStep)
if step <= 0:
return 0.0001
decimals = None
if sec.Decimals is not None:
decimals = int(sec.Decimals)
if decimals == 3 or decimals == 5:
return step * 10.0
return step
def _normalize_price(self, price):
sec = self.Security
if sec is None or sec.PriceStep is None:
return price
step = float(sec.PriceStep)
if step <= 0:
return price
return round(price / step) * step
def OnStarted2(self, time):
super(daily_break_point_strategy, self).OnStarted2(time)
self._current_day_open = None
self._long_stop_price = None
self._long_take_price = None
self._short_stop_price = None
self._short_take_price = None
self._long_entry_price = None
self._short_entry_price = None
self._pip_size = self._calc_pip_size()
self.StartProtection(
takeProfit=Unit(2, UnitTypes.Percent),
stopLoss=Unit(1, UnitTypes.Percent)
)
intraday_subscription = self.SubscribeCandles(self.CandleType)
intraday_subscription.Bind(self.process_candle).Start()
daily_subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(5)))
daily_subscription.Bind(self.process_daily_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, intraday_subscription)
self.DrawOwnTrades(area)
def process_daily_candle(self, candle):
if candle.State == CandleStates.Finished or candle.State == CandleStates.Active:
self._current_day_open = float(candle.OpenPrice)
def process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
if self._pip_size <= 0:
self._pip_size = self._calc_pip_size()
day_open = self._current_day_open
if day_open is None:
return
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
break_offset = self.BreakPointPips * self._pip_size
min_body = self.LastBarSizeMinPips * self._pip_size
max_body = self.LastBarSizeMaxPips * self._pip_size
trailing_stop = self.TrailingStopPips * self._pip_size
trailing_step = self.TrailingStepPips * self._pip_size
stop_loss_offset = self.StopLossPips * self._pip_size if self.StopLossPips > 0 else 0.0
take_profit_offset = self.TakeProfitPips * self._pip_size if self.TakeProfitPips > 0 else 0.0
self._update_trailing(candle, trailing_stop, trailing_step)
if self._handle_risk_exits(candle):
return
body_size = abs(close - open_p)
bullish_body = close > open_p
bearish_body = close < open_p
bullish_signal = (bullish_body and break_offset > 0 and
close - day_open >= break_offset and
body_size >= min_body and
(max_body <= 0 or body_size <= max_body))
bearish_signal = (bearish_body and break_offset > 0 and
day_open - close >= break_offset and
body_size >= min_body and
(max_body <= 0 or body_size <= max_body))
if bullish_signal:
self._execute_bullish_signal(close, stop_loss_offset, take_profit_offset)
elif bearish_signal:
self._execute_bearish_signal(close, stop_loss_offset, take_profit_offset)
def _update_trailing(self, candle, trailing_stop, trailing_step):
if trailing_stop <= 0:
return
close = float(candle.ClosePrice)
if self.Position > 0 and self._long_entry_price is not None:
profit = close - self._long_entry_price
if profit > trailing_stop + trailing_step:
threshold = close - (trailing_stop + trailing_step)
if self._long_stop_price is None or self._long_stop_price < threshold:
self._long_stop_price = self._normalize_price(close - trailing_stop)
elif self.Position < 0 and self._short_entry_price is not None:
profit = self._short_entry_price - close
if profit > trailing_stop + trailing_step:
threshold = close + trailing_stop + trailing_step
if (self._short_stop_price is None or
self._short_stop_price > threshold or self._short_stop_price == 0):
self._short_stop_price = self._normalize_price(close + trailing_stop)
def _handle_risk_exits(self, candle):
h = float(candle.HighPrice)
lo = float(candle.LowPrice)
if self.Position > 0:
if self._long_stop_price is not None and lo <= self._long_stop_price:
self.SellMarket()
self._reset_long_state()
return True
if self._long_take_price is not None and h >= self._long_take_price:
self.SellMarket()
self._reset_long_state()
return True
elif self.Position < 0:
if self._short_stop_price is not None and h >= self._short_stop_price:
self.BuyMarket()
self._reset_short_state()
return True
if self._short_take_price is not None and lo <= self._short_take_price:
self.BuyMarket()
self._reset_short_state()
return True
else:
self._reset_long_state()
self._reset_short_state()
return False
def _execute_bullish_signal(self, entry_price, stop_loss_offset, take_profit_offset):
if self.CloseBySignal:
if self.Position > 0:
self.SellMarket()
self._reset_long_state()
self.SellMarket()
self._short_entry_price = entry_price
self._short_stop_price = self._normalize_price(entry_price + stop_loss_offset) if stop_loss_offset > 0 else None
self._short_take_price = self._normalize_price(entry_price - take_profit_offset) if take_profit_offset > 0 else None
else:
self.BuyMarket()
self._long_entry_price = entry_price
self._long_stop_price = self._normalize_price(entry_price - stop_loss_offset) if stop_loss_offset > 0 else None
self._long_take_price = self._normalize_price(entry_price + take_profit_offset) if take_profit_offset > 0 else None
self._reset_short_state()
def _execute_bearish_signal(self, entry_price, stop_loss_offset, take_profit_offset):
if self.CloseBySignal:
if self.Position < 0:
self.BuyMarket()
self._reset_short_state()
self.BuyMarket()
self._long_entry_price = entry_price
self._long_stop_price = self._normalize_price(entry_price - stop_loss_offset) if stop_loss_offset > 0 else None
self._long_take_price = self._normalize_price(entry_price + take_profit_offset) if take_profit_offset > 0 else None
else:
self.SellMarket()
self._short_entry_price = entry_price
self._short_stop_price = self._normalize_price(entry_price + stop_loss_offset) if stop_loss_offset > 0 else None
self._short_take_price = self._normalize_price(entry_price - take_profit_offset) if take_profit_offset > 0 else None
self._reset_long_state()
def _reset_long_state(self):
self._long_entry_price = None
self._long_stop_price = None
self._long_take_price = None
def _reset_short_state(self):
self._short_entry_price = None
self._short_stop_price = None
self._short_take_price = None
def OnReseted(self):
super(daily_break_point_strategy, self).OnReseted()
self._current_day_open = None
self._long_stop_price = None
self._long_take_price = None
self._short_stop_price = None
self._short_take_price = None
self._long_entry_price = None
self._short_entry_price = None
self._pip_size = 0.0
def CreateClone(self):
return daily_break_point_strategy()