feat: Add "replace-exit_order" to backtesting
This commit is contained in:
@@ -396,6 +396,8 @@ class Backtesting:
|
|||||||
self.canceled_trade_entries = 0
|
self.canceled_trade_entries = 0
|
||||||
self.canceled_entry_orders = 0
|
self.canceled_entry_orders = 0
|
||||||
self.replaced_entry_orders = 0
|
self.replaced_entry_orders = 0
|
||||||
|
self.canceled_exit_orders = 0
|
||||||
|
self.replaced_exit_orders = 0
|
||||||
self.dataprovider.clear_cache()
|
self.dataprovider.clear_cache()
|
||||||
if enable_protections:
|
if enable_protections:
|
||||||
self._load_protections(self.strategy)
|
self._load_protections(self.strategy)
|
||||||
@@ -1234,8 +1236,8 @@ class Backtesting:
|
|||||||
for order in [o for o in trade.orders if o.ft_is_open]:
|
for order in [o for o in trade.orders if o.ft_is_open]:
|
||||||
if order.side == trade.entry_side:
|
if order.side == trade.entry_side:
|
||||||
self.canceled_entry_orders += 1
|
self.canceled_entry_orders += 1
|
||||||
# elif order.side == trade.exit_side:
|
elif order.side == trade.exit_side:
|
||||||
# self.canceled_exit_orders += 1
|
self.canceled_exit_orders += 1
|
||||||
# canceled orders are removed from the trade
|
# canceled orders are removed from the trade
|
||||||
del trade.orders[trade.orders.index(order)]
|
del trade.orders[trade.orders.index(order)]
|
||||||
|
|
||||||
@@ -1300,8 +1302,9 @@ class Backtesting:
|
|||||||
"""
|
"""
|
||||||
# only check on new candles for open entry orders
|
# only check on new candles for open entry orders
|
||||||
if order.side == trade.entry_side and current_time > order.order_date_utc:
|
if order.side == trade.entry_side and current_time > order.order_date_utc:
|
||||||
|
is_entry = order.side == trade.entry_side
|
||||||
requested_rate = strategy_safe_wrapper(
|
requested_rate = strategy_safe_wrapper(
|
||||||
self.strategy.adjust_entry_price, default_retval=order.ft_price
|
self.strategy.adjust_order_price, default_retval=order.ft_price
|
||||||
)(
|
)(
|
||||||
trade=trade, # type: ignore[arg-type]
|
trade=trade, # type: ignore[arg-type]
|
||||||
order=order,
|
order=order,
|
||||||
@@ -1311,6 +1314,7 @@ class Backtesting:
|
|||||||
current_order_rate=order.ft_price,
|
current_order_rate=order.ft_price,
|
||||||
entry_tag=trade.enter_tag,
|
entry_tag=trade.enter_tag,
|
||||||
side=trade.trade_direction,
|
side=trade.trade_direction,
|
||||||
|
is_entry=is_entry,
|
||||||
) # default value is current order price
|
) # default value is current order price
|
||||||
|
|
||||||
# cancel existing order whenever a new rate is requested (or None)
|
# cancel existing order whenever a new rate is requested (or None)
|
||||||
@@ -1319,10 +1323,14 @@ class Backtesting:
|
|||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
del trade.orders[trade.orders.index(order)]
|
del trade.orders[trade.orders.index(order)]
|
||||||
|
if is_entry:
|
||||||
self.canceled_entry_orders += 1
|
self.canceled_entry_orders += 1
|
||||||
|
else:
|
||||||
|
self.canceled_exit_orders += 1
|
||||||
|
|
||||||
# place new order if result was not None
|
# place new order if result was not None
|
||||||
if requested_rate:
|
if requested_rate:
|
||||||
|
if is_entry:
|
||||||
self._enter_trade(
|
self._enter_trade(
|
||||||
pair=trade.pair,
|
pair=trade.pair,
|
||||||
row=row,
|
row=row,
|
||||||
@@ -1331,10 +1339,19 @@ class Backtesting:
|
|||||||
requested_stake=(order.safe_remaining * order.ft_price / trade.leverage),
|
requested_stake=(order.safe_remaining * order.ft_price / trade.leverage),
|
||||||
direction="short" if trade.is_short else "long",
|
direction="short" if trade.is_short else "long",
|
||||||
)
|
)
|
||||||
# Delete trade if no successful entries happened (if placing the new order failed)
|
|
||||||
if not trade.has_open_orders and trade.nr_of_successful_entries == 0:
|
|
||||||
return True
|
|
||||||
self.replaced_entry_orders += 1
|
self.replaced_entry_orders += 1
|
||||||
|
else:
|
||||||
|
self._exit_trade(
|
||||||
|
trade=trade,
|
||||||
|
sell_row=row,
|
||||||
|
close_rate=requested_rate,
|
||||||
|
amount=order.safe_remaining,
|
||||||
|
exit_reason=order.ft_order_tag,
|
||||||
|
)
|
||||||
|
self.replaced_exit_orders += 1
|
||||||
|
# Delete trade if no successful entries happened (if placing the new order failed)
|
||||||
|
if not trade.has_open_orders and is_entry and trade.nr_of_successful_entries == 0:
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
# assumption: there can't be multiple open entry orders at any given time
|
# assumption: there can't be multiple open entry orders at any given time
|
||||||
return trade.nr_of_successful_entries == 0
|
return trade.nr_of_successful_entries == 0
|
||||||
|
|||||||
Reference in New Issue
Block a user