Fix backtest calculation problem with DCA

closes #7287
This commit is contained in:
Matthias 2022-08-24 20:36:08 +02:00
parent a6d78a8615
commit 32faad9333
2 changed files with 17 additions and 9 deletions

View File

@ -25,7 +25,7 @@ from freqtrade.enums import (BacktestState, CandleType, ExitCheckTuple, ExitType
from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
from freqtrade.exchange.exchange import (amount_to_contracts, amount_to_precision, from freqtrade.exchange.exchange import (amount_to_contracts, amount_to_precision,
contracts_to_amount) contracts_to_amount, price_to_precision)
from freqtrade.mixins import LoggingMixin from freqtrade.mixins import LoggingMixin
from freqtrade.optimize.backtest_caching import get_strategy_run_id from freqtrade.optimize.backtest_caching import get_strategy_run_id
from freqtrade.optimize.bt_progress import BTProgress from freqtrade.optimize.bt_progress import BTProgress
@ -658,7 +658,13 @@ class Backtesting:
self.order_id_counter += 1 self.order_id_counter += 1
exit_candle_time = sell_row[DATE_IDX].to_pydatetime() exit_candle_time = sell_row[DATE_IDX].to_pydatetime()
order_type = self.strategy.order_types['exit'] order_type = self.strategy.order_types['exit']
amount = amount or trade.amount # amount = amount or trade.amount
amount = contracts_to_amount(
amount_to_precision(
amount_to_contracts(amount or trade.amount, trade.contract_size),
trade.amount_precision, self.precision_mode),
trade.contract_size)
rate = price_to_precision(close_rate, trade.price_precision, self.precision_mode)
order = Order( order = Order(
id=self.order_id_counter, id=self.order_id_counter,
ft_trade_id=trade.id, ft_trade_id=trade.id,
@ -672,12 +678,12 @@ class Backtesting:
side=trade.exit_side, side=trade.exit_side,
order_type=order_type, order_type=order_type,
status="open", status="open",
price=close_rate, price=rate,
average=close_rate, average=rate,
amount=amount, amount=amount,
filled=0, filled=0,
remaining=amount, remaining=amount,
cost=amount * close_rate, cost=amount * rate,
) )
trade.orders.append(order) trade.orders.append(order)
return trade return trade
@ -823,7 +829,10 @@ class Backtesting:
if stake_amount and (not min_stake_amount or stake_amount > min_stake_amount): if stake_amount and (not min_stake_amount or stake_amount > min_stake_amount):
self.order_id_counter += 1 self.order_id_counter += 1
base_currency = self.exchange.get_pair_base_currency(pair) base_currency = self.exchange.get_pair_base_currency(pair)
precision_price = self.exchange.get_precision_price(pair)
propose_rate = price_to_precision(propose_rate, precision_price, self.precision_mode)
amount_p = (stake_amount / propose_rate) * leverage amount_p = (stake_amount / propose_rate) * leverage
contract_size = self.exchange.get_contract_size(pair) contract_size = self.exchange.get_contract_size(pair)
precision_amount = self.exchange.get_precision_amount(pair) precision_amount = self.exchange.get_precision_amount(pair)
amount = contracts_to_amount( amount = contracts_to_amount(
@ -863,7 +872,7 @@ class Backtesting:
leverage=leverage, leverage=leverage,
# interest_rate=interest_rate, # interest_rate=interest_rate,
amount_precision=precision_amount, amount_precision=precision_amount,
price_precision=self.exchange.get_precision_price(pair), price_precision=precision_price,
precision_mode=self.precision_mode, precision_mode=self.precision_mode,
contract_size=contract_size, contract_size=contract_size,
orders=[], orders=[],

View File

@ -847,7 +847,7 @@ class LocalTrade():
avg_price = FtPrecise(0.0) avg_price = FtPrecise(0.0)
close_profit = 0.0 close_profit = 0.0
close_profit_abs = 0.0 close_profit_abs = 0.0
profit = None
for o in self.orders: for o in self.orders:
if o.ft_is_open or not o.filled: if o.ft_is_open or not o.filled:
continue continue
@ -874,8 +874,6 @@ class LocalTrade():
close_profit_abs += profit close_profit_abs += profit
close_profit = self.calc_profit_ratio( close_profit = self.calc_profit_ratio(
exit_rate, amount=exit_amount, open_rate=avg_price) exit_rate, amount=exit_amount, open_rate=avg_price)
if current_amount <= ZERO:
profit = close_profit_abs
else: else:
total_stake = total_stake + self._calc_open_trade_value(tmp_amount, price) total_stake = total_stake + self._calc_open_trade_value(tmp_amount, price)
@ -900,6 +898,7 @@ class LocalTrade():
# Close profit abs / maximum owned # Close profit abs / maximum owned
# Fees are considered as they are part of close_profit_abs # Fees are considered as they are part of close_profit_abs
self.close_profit = (close_profit_abs / total_stake) * self.leverage self.close_profit = (close_profit_abs / total_stake) * self.leverage
self.close_profit_abs = close_profit_abs
def select_order_by_order_id(self, order_id: str) -> Optional[Order]: def select_order_by_order_id(self, order_id: str) -> Optional[Order]:
""" """