Merge branch 'develop' into pr/mkavinkumar1/6545
This commit is contained in:
@@ -187,6 +187,7 @@ class Backtesting:
|
||||
# since a "perfect" stoploss-exit is assumed anyway
|
||||
# And the regular "stoploss" function would not apply to that case
|
||||
self.strategy.order_types['stoploss_on_exchange'] = False
|
||||
|
||||
self.strategy.ft_bot_start()
|
||||
|
||||
def _load_protections(self, strategy: IStrategy):
|
||||
@@ -732,7 +733,7 @@ class Backtesting:
|
||||
current_rate=row[OPEN_IDX],
|
||||
proposed_leverage=1.0,
|
||||
max_leverage=max_leverage,
|
||||
side=direction,
|
||||
side=direction, entry_tag=entry_tag,
|
||||
) if self._can_short else 1.0
|
||||
# Cap leverage between 1.0 and max_leverage.
|
||||
leverage = min(max(leverage, 1.0), max_leverage)
|
||||
@@ -923,26 +924,30 @@ class Backtesting:
|
||||
self.protections.stop_per_pair(pair, current_time, side)
|
||||
self.protections.global_stop(current_time, side)
|
||||
|
||||
def manage_open_orders(self, trade: LocalTrade, current_time, row: Tuple) -> bool:
|
||||
def manage_open_orders(self, trade: LocalTrade, current_time: datetime, row: Tuple) -> bool:
|
||||
"""
|
||||
Check if any open order needs to be cancelled or replaced.
|
||||
Returns True if the trade should be deleted.
|
||||
"""
|
||||
for order in [o for o in trade.orders if o.ft_is_open]:
|
||||
if self.check_order_cancel(trade, order, current_time):
|
||||
oc = self.check_order_cancel(trade, order, current_time)
|
||||
if oc:
|
||||
# delete trade due to order timeout
|
||||
return True
|
||||
elif self.check_order_replace(trade, order, current_time, row):
|
||||
elif oc is None and self.check_order_replace(trade, order, current_time, row):
|
||||
# delete trade due to user request
|
||||
self.canceled_trade_entries += 1
|
||||
return True
|
||||
# default maintain trade
|
||||
return False
|
||||
|
||||
def check_order_cancel(self, trade: LocalTrade, order: Order, current_time) -> bool:
|
||||
def check_order_cancel(
|
||||
self, trade: LocalTrade, order: Order, current_time: datetime) -> Optional[bool]:
|
||||
"""
|
||||
Check if current analyzed order has to be canceled.
|
||||
Returns True if the trade should be Deleted (initial order was canceled).
|
||||
Returns True if the trade should be Deleted (initial order was canceled),
|
||||
False if it's Canceled
|
||||
None if the order is still active.
|
||||
"""
|
||||
timedout = self.strategy.ft_check_timed_out(
|
||||
trade, # type: ignore[arg-type]
|
||||
@@ -956,12 +961,15 @@ class Backtesting:
|
||||
else:
|
||||
# Close additional entry order
|
||||
del trade.orders[trade.orders.index(order)]
|
||||
trade.open_order_id = None
|
||||
return False
|
||||
if order.side == trade.exit_side:
|
||||
self.timedout_exit_orders += 1
|
||||
# Close exit order and retry exiting on next signal.
|
||||
del trade.orders[trade.orders.index(order)]
|
||||
|
||||
return False
|
||||
trade.open_order_id = None
|
||||
return False
|
||||
return None
|
||||
|
||||
def check_order_replace(self, trade: LocalTrade, order: Order, current_time,
|
||||
row: Tuple) -> bool:
|
||||
@@ -987,6 +995,7 @@ class Backtesting:
|
||||
return False
|
||||
else:
|
||||
del trade.orders[trade.orders.index(order)]
|
||||
trade.open_order_id = None
|
||||
self.canceled_entry_orders += 1
|
||||
|
||||
# place new order if result was not None
|
||||
@@ -1115,6 +1124,7 @@ class Backtesting:
|
||||
# 5. Process exit orders.
|
||||
order = trade.select_order(trade.exit_side, is_open=True)
|
||||
if order and self._get_order_filled(order.price, row):
|
||||
order.close_bt_order(current_time, trade)
|
||||
trade.open_order_id = None
|
||||
sub_trade = order.safe_amount_after_fee != trade.amount
|
||||
if sub_trade:
|
||||
|
||||
@@ -429,7 +429,7 @@ class Hyperopt:
|
||||
return new_list
|
||||
i = 0
|
||||
asked_non_tried: List[List[Any]] = []
|
||||
is_random: List[bool] = []
|
||||
is_random_non_tried: List[bool] = []
|
||||
while i < 5 and len(asked_non_tried) < n_points:
|
||||
if i < 3:
|
||||
self.opt.cache_ = {}
|
||||
@@ -438,9 +438,9 @@ class Hyperopt:
|
||||
else:
|
||||
asked = unique_list(self.opt.space.rvs(n_samples=n_points * 5))
|
||||
is_random = [True for _ in range(len(asked))]
|
||||
is_random += [rand for x, rand in zip(asked, is_random)
|
||||
if x not in self.opt.Xi
|
||||
and x not in asked_non_tried]
|
||||
is_random_non_tried += [rand for x, rand in zip(asked, is_random)
|
||||
if x not in self.opt.Xi
|
||||
and x not in asked_non_tried]
|
||||
asked_non_tried += [x for x in asked
|
||||
if x not in self.opt.Xi
|
||||
and x not in asked_non_tried]
|
||||
@@ -449,7 +449,7 @@ class Hyperopt:
|
||||
if asked_non_tried:
|
||||
return (
|
||||
asked_non_tried[:min(len(asked_non_tried), n_points)],
|
||||
is_random[:min(len(asked_non_tried), n_points)]
|
||||
is_random_non_tried[:min(len(asked_non_tried), n_points)]
|
||||
)
|
||||
else:
|
||||
return self.opt.ask(n_points=n_points), [False for _ in range(n_points)]
|
||||
|
||||
@@ -4,7 +4,6 @@ from datetime import datetime, timedelta, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Union
|
||||
|
||||
from numpy import int64
|
||||
from pandas import DataFrame, to_datetime
|
||||
from tabulate import tabulate
|
||||
|
||||
@@ -417,9 +416,6 @@ def generate_strategy_stats(pairlist: List[str],
|
||||
key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None
|
||||
worst_pair = min([pair for pair in pair_results if pair['key'] != 'TOTAL'],
|
||||
key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None
|
||||
if not results.empty:
|
||||
results['open_timestamp'] = results['open_date'].view(int64) // 1e6
|
||||
results['close_timestamp'] = results['close_date'].view(int64) // 1e6
|
||||
|
||||
backtest_days = (max_date - min_date).days or 1
|
||||
strat_stats = {
|
||||
|
||||
Reference in New Issue
Block a user