Simplify usage of amount_to_contract precision
This commit is contained in:
parent
9e48e6a40b
commit
6636f17e0f
@ -9,11 +9,11 @@ from freqtrade.exchange.bitpanda import Bitpanda
|
|||||||
from freqtrade.exchange.bittrex import Bittrex
|
from freqtrade.exchange.bittrex import Bittrex
|
||||||
from freqtrade.exchange.bybit import Bybit
|
from freqtrade.exchange.bybit import Bybit
|
||||||
from freqtrade.exchange.coinbasepro import Coinbasepro
|
from freqtrade.exchange.coinbasepro import Coinbasepro
|
||||||
from freqtrade.exchange.exchange import (amount_to_contracts, amount_to_precision,
|
from freqtrade.exchange.exchange import (amount_to_contract_precision, amount_to_contracts,
|
||||||
available_exchanges, ccxt_exchanges, contracts_to_amount,
|
amount_to_precision, available_exchanges, ccxt_exchanges,
|
||||||
date_minus_candles, is_exchange_known_ccxt,
|
contracts_to_amount, date_minus_candles,
|
||||||
is_exchange_officially_supported, market_is_active,
|
is_exchange_known_ccxt, is_exchange_officially_supported,
|
||||||
price_to_precision, timeframe_to_minutes,
|
market_is_active, price_to_precision, timeframe_to_minutes,
|
||||||
timeframe_to_msecs, timeframe_to_next_date,
|
timeframe_to_msecs, timeframe_to_next_date,
|
||||||
timeframe_to_prev_date, timeframe_to_seconds,
|
timeframe_to_prev_date, timeframe_to_seconds,
|
||||||
validate_exchange, validate_exchanges)
|
validate_exchange, validate_exchanges)
|
||||||
|
@ -2943,6 +2943,29 @@ def amount_to_precision(amount: float, amount_precision: Optional[float],
|
|||||||
return amount
|
return amount
|
||||||
|
|
||||||
|
|
||||||
|
def amount_to_contract_precision(
|
||||||
|
amount, amount_precision: Optional[float], precisionMode: Optional[int],
|
||||||
|
contract_size: Optional[float]) -> float:
|
||||||
|
"""
|
||||||
|
Returns the amount to buy or sell to a precision the Exchange accepts
|
||||||
|
including calculation to and from contracts.
|
||||||
|
Re-implementation of ccxt internal methods - ensuring we can test the result is correct
|
||||||
|
based on our definitions.
|
||||||
|
:param amount: amount to truncate
|
||||||
|
:param amount_precision: amount precision to use.
|
||||||
|
should be retrieved from markets[pair]['precision']['amount']
|
||||||
|
:param precisionMode: precision mode to use. Should be used from precisionMode
|
||||||
|
one of ccxt's DECIMAL_PLACES, SIGNIFICANT_DIGITS, or TICK_SIZE
|
||||||
|
:param contract_size: contract size - taken from exchange.get_contract_size(pair)
|
||||||
|
:return: truncated amount
|
||||||
|
"""
|
||||||
|
if amount_precision is not None and precisionMode is not None:
|
||||||
|
contracts = amount_to_contracts(amount, contract_size)
|
||||||
|
amount_p = amount_to_precision(contracts, amount_precision, precisionMode)
|
||||||
|
return contracts_to_amount(amount_p, contract_size)
|
||||||
|
return amount
|
||||||
|
|
||||||
|
|
||||||
def price_to_precision(price: float, price_precision: Optional[float],
|
def price_to_precision(price: float, price_precision: Optional[float],
|
||||||
precisionMode: Optional[int]) -> float:
|
precisionMode: Optional[int]) -> float:
|
||||||
"""
|
"""
|
||||||
|
@ -23,9 +23,8 @@ from freqtrade.data.dataprovider import DataProvider
|
|||||||
from freqtrade.enums import (BacktestState, CandleType, ExitCheckTuple, ExitType, RunMode,
|
from freqtrade.enums import (BacktestState, CandleType, ExitCheckTuple, ExitType, RunMode,
|
||||||
TradingMode)
|
TradingMode)
|
||||||
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 (amount_to_contract_precision, price_to_precision,
|
||||||
from freqtrade.exchange.exchange import (amount_to_contracts, amount_to_precision,
|
timeframe_to_minutes, timeframe_to_seconds)
|
||||||
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
|
||||||
@ -659,11 +658,8 @@ class Backtesting:
|
|||||||
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 = amount_to_contract_precision(amount or trade.amount, trade.amount_precision,
|
||||||
amount_to_precision(
|
self.precision_mode, trade.contract_size)
|
||||||
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)
|
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,
|
||||||
@ -835,10 +831,7 @@ class Backtesting:
|
|||||||
|
|
||||||
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 = amount_to_contract_precision(amount_p, precision_amount, self.precision_mode,
|
||||||
amount_to_precision(
|
|
||||||
amount_to_contracts(amount_p, contract_size),
|
|
||||||
precision_amount, self.precision_mode),
|
|
||||||
contract_size)
|
contract_size)
|
||||||
# Backcalculate actual stake amount.
|
# Backcalculate actual stake amount.
|
||||||
stake_amount = amount * propose_rate / leverage
|
stake_amount = amount * propose_rate / leverage
|
||||||
|
@ -14,8 +14,7 @@ from freqtrade.constants import (DATETIME_PRINT_FORMAT, MATH_CLOSE_PREC, NON_OPE
|
|||||||
BuySell, LongShort)
|
BuySell, LongShort)
|
||||||
from freqtrade.enums import ExitType, TradingMode
|
from freqtrade.enums import ExitType, TradingMode
|
||||||
from freqtrade.exceptions import DependencyException, OperationalException
|
from freqtrade.exceptions import DependencyException, OperationalException
|
||||||
from freqtrade.exchange import amount_to_precision, price_to_precision
|
from freqtrade.exchange import amount_to_contract_precision, price_to_precision
|
||||||
from freqtrade.exchange.exchange import amount_to_contracts, contracts_to_amount
|
|
||||||
from freqtrade.leverage import interest
|
from freqtrade.leverage import interest
|
||||||
from freqtrade.persistence.base import _DECL_BASE
|
from freqtrade.persistence.base import _DECL_BASE
|
||||||
from freqtrade.util import FtPrecise
|
from freqtrade.util import FtPrecise
|
||||||
@ -625,11 +624,8 @@ class LocalTrade():
|
|||||||
else:
|
else:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f'Got different open_order_id {self.open_order_id} != {order.order_id}')
|
f'Got different open_order_id {self.open_order_id} != {order.order_id}')
|
||||||
amount_tr = contracts_to_amount(
|
amount_tr = amount_to_contract_precision(self.amount, self.amount_precision,
|
||||||
amount_to_precision(
|
self.precision_mode, self.contract_size)
|
||||||
amount_to_contracts(self.amount, self.contract_size),
|
|
||||||
self.amount_precision, self.precision_mode),
|
|
||||||
self.contract_size)
|
|
||||||
if isclose(order.safe_amount_after_fee, amount_tr, abs_tol=MATH_CLOSE_PREC):
|
if isclose(order.safe_amount_after_fee, amount_tr, abs_tol=MATH_CLOSE_PREC):
|
||||||
self.close(order.safe_price)
|
self.close(order.safe_price)
|
||||||
else:
|
else:
|
||||||
@ -882,8 +878,8 @@ class LocalTrade():
|
|||||||
self.realized_profit = close_profit_abs
|
self.realized_profit = close_profit_abs
|
||||||
self.close_profit_abs = profit
|
self.close_profit_abs = profit
|
||||||
|
|
||||||
current_amount_tr = amount_to_precision(float(current_amount),
|
current_amount_tr = amount_to_contract_precision(
|
||||||
self.amount_precision, self.precision_mode)
|
float(current_amount), self.amount_precision, self.precision_mode, self.contract_size)
|
||||||
if current_amount_tr > 0.0:
|
if current_amount_tr > 0.0:
|
||||||
# Trade is still open
|
# Trade is still open
|
||||||
# Leverage not updated, as we don't allow changing leverage through DCA at the moment.
|
# Leverage not updated, as we don't allow changing leverage through DCA at the moment.
|
||||||
|
@ -18,7 +18,8 @@ from tests.conftest import patch_exchange
|
|||||||
def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
default_conf['use_exit_signal'] = False
|
default_conf['use_exit_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch('freqtrade.optimize.backtesting.amount_to_precision', lambda x, y, z: round(x, 8))
|
mocker.patch('freqtrade.optimize.backtesting.amount_to_contract_precision',
|
||||||
|
lambda x, *args, **kwargs: round(x, 8))
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
Loading…
Reference in New Issue
Block a user