Initial idea backtesting order timeout

This commit is contained in:
Matthias 2022-01-16 19:39:42 +01:00
parent 6ed237a72a
commit c12e5a3b6c
1 changed files with 34 additions and 6 deletions

View File

@ -380,6 +380,10 @@ class Backtesting:
return trade
def _get_order_filled(self, rate: float, row: Tuple) -> bool:
""" Rate is within candle, therefore filled"""
return row[LOW_IDX] < rate < row[HIGH_IDX]
def _get_sell_trade_entry_for_candle(self, trade: LocalTrade,
sell_row: Tuple) -> Optional[LocalTrade]:
@ -405,6 +409,7 @@ class Backtesting:
closerate = self._get_close_rate(sell_row, trade, sell, trade_dur)
# call the custom exit price,with default value as previous closerate
current_profit = trade.calc_profit_ratio(closerate)
order_closed = True
if sell.sell_type in (SellType.SELL_SIGNAL, SellType.CUSTOM_SELL):
# Custom exit pricing only for sell-signals
closerate = strategy_safe_wrapper(self.strategy.custom_exit_price,
@ -412,8 +417,7 @@ class Backtesting:
pair=trade.pair, trade=trade,
current_time=sell_row[DATE_IDX],
proposed_rate=closerate, current_profit=current_profit)
# Use the maximum between close_rate and low as we cannot sell outside of a candle.
closerate = min(max(closerate, sell_row[LOW_IDX]), sell_row[HIGH_IDX])
order_closed = self._get_order_filled(closerate, sell_row)
# Confirm trade exit:
time_in_force = self.strategy.order_time_in_force['sell']
@ -437,6 +441,21 @@ class Backtesting:
trade.sell_reason = sell_row[EXIT_TAG_IDX]
trade.close(closerate, show_msg=False)
order = Order(
ft_is_open=order_closed,
ft_pair=trade.pair,
symbol=trade.pair,
ft_order_side="buy",
side="buy",
order_type="market",
status="closed",
price=closerate,
average=closerate,
amount=trade.amount,
filled=trade.amount,
cost=trade.amount * closerate
)
trade.orders.append(order)
return trade
return None
@ -480,9 +499,6 @@ class Backtesting:
pair=pair, current_time=current_time,
proposed_rate=row[OPEN_IDX], entry_tag=entry_tag) # default value is the open rate
# Move rate to within the candle's low/high rate
propose_rate = min(max(propose_rate, row[LOW_IDX]), row[HIGH_IDX])
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, propose_rate, -0.05) or 0
max_stake_amount = self.wallets.get_available_stake_amount()
@ -534,9 +550,10 @@ class Backtesting:
orders=[]
)
trade.adjust_stop_loss(trade.open_rate, self.strategy.stoploss, initial=True)
order_filled = self._get_order_filled(propose_rate, row)
order = Order(
ft_is_open=False,
ft_is_open=order_filled,
ft_pair=trade.pair,
symbol=trade.pair,
ft_order_side="buy",
@ -552,6 +569,8 @@ class Backtesting:
filled=amount,
cost=stake_amount + trade.fee_open
)
if not order_filled:
trade.open_order_id = 'buy'
trade.orders.append(order)
if pos_adjust:
trade.recalc_trade_from_orders()
@ -647,6 +666,15 @@ class Backtesting:
indexes[pair] = row_index
self.dataprovider._set_dataframe_max_index(row_index)
# Check order filling
for open_trade in list(open_trades[pair]):
# TODO: should open orders be stored in a separate list?
if open_trade.open_order_id:
# FIXME: check order filling
# * Get open order
# * check if filled
open_trade.open_order_id = None
# without positionstacking, we can only have one open trade per pair.
# max_open_trades must be respected
# don't open on the last row