mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-12-19 06:11:15 +00:00
Extract number-formatters from misc
This commit is contained in:
@@ -5,7 +5,7 @@ from freqtrade import constants
|
|||||||
from freqtrade.configuration import setup_utils_configuration
|
from freqtrade.configuration import setup_utils_configuration
|
||||||
from freqtrade.enums import RunMode
|
from freqtrade.enums import RunMode
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import round_coin_value
|
from freqtrade.util import round_coin_value
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -11,54 +11,12 @@ from urllib.parse import urlparse
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import rapidjson
|
import rapidjson
|
||||||
|
|
||||||
from freqtrade.constants import DECIMAL_PER_COIN_FALLBACK, DECIMALS_PER_COIN
|
|
||||||
from freqtrade.enums import SignalTagType, SignalType
|
from freqtrade.enums import SignalTagType, SignalType
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def decimals_per_coin(coin: str):
|
|
||||||
"""
|
|
||||||
Helper method getting decimal amount for this coin
|
|
||||||
example usage: f".{decimals_per_coin('USD')}f"
|
|
||||||
:param coin: Which coin are we printing the price / value for
|
|
||||||
"""
|
|
||||||
return DECIMALS_PER_COIN.get(coin, DECIMAL_PER_COIN_FALLBACK)
|
|
||||||
|
|
||||||
|
|
||||||
def round_value(value: float, decimals: int, keep_trailing_zeros=False) -> str:
|
|
||||||
"""
|
|
||||||
Round value to given decimals
|
|
||||||
:param value: Value to be rounded
|
|
||||||
:param decimals: Number of decimals to round to
|
|
||||||
:param keep_trailing_zeros: Keep trailing zeros "222.200" vs. "222.2"
|
|
||||||
:return: Rounded value as string
|
|
||||||
"""
|
|
||||||
val = f"{value:.{decimals}f}"
|
|
||||||
if not keep_trailing_zeros:
|
|
||||||
val = val.rstrip('0').rstrip('.')
|
|
||||||
return val
|
|
||||||
|
|
||||||
|
|
||||||
def round_coin_value(
|
|
||||||
value: float, coin: str, show_coin_name=True, keep_trailing_zeros=False) -> str:
|
|
||||||
"""
|
|
||||||
Get price value for this coin
|
|
||||||
:param value: Value to be printed
|
|
||||||
:param coin: Which coin are we printing the price / value for
|
|
||||||
:param show_coin_name: Return string in format: "222.22 USDT" or "222.22"
|
|
||||||
:param keep_trailing_zeros: Keep trailing zeros "222.200" vs. "222.2"
|
|
||||||
:return: Formatted / rounded value (with or without coin name)
|
|
||||||
"""
|
|
||||||
val = f"{value:.{decimals_per_coin(coin)}f}"
|
|
||||||
val = round_value(value, decimals_per_coin(coin), keep_trailing_zeros)
|
|
||||||
if show_coin_name:
|
|
||||||
val = f"{val} {coin}"
|
|
||||||
|
|
||||||
return val
|
|
||||||
|
|
||||||
|
|
||||||
def file_dump_json(filename: Path, data: Any, is_zip: bool = False, log: bool = True) -> None:
|
def file_dump_json(filename: Path, data: Any, is_zip: bool = False, log: bool = True) -> None:
|
||||||
"""
|
"""
|
||||||
Dump JSON data into a file
|
Dump JSON data into a file
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ from pandas import isna, json_normalize
|
|||||||
from freqtrade.constants import FTHYPT_FILEVERSION, Config
|
from freqtrade.constants import FTHYPT_FILEVERSION, Config
|
||||||
from freqtrade.enums import HyperoptState
|
from freqtrade.enums import HyperoptState
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import deep_merge_dicts, round_coin_value, round_dict, safe_value_fallback2
|
from freqtrade.misc import deep_merge_dicts, round_dict, safe_value_fallback2
|
||||||
from freqtrade.optimize.hyperopt_epoch_filters import hyperopt_filter_epochs
|
from freqtrade.optimize.hyperopt_epoch_filters import hyperopt_filter_epochs
|
||||||
from freqtrade.optimize.optimize_reports import generate_wins_draws_losses
|
from freqtrade.optimize.optimize_reports import generate_wins_draws_losses
|
||||||
|
from freqtrade.util import round_coin_value
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ from typing import Any, Dict, List
|
|||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT, Config
|
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT, Config
|
||||||
from freqtrade.misc import decimals_per_coin, round_coin_value
|
|
||||||
from freqtrade.optimize.optimize_reports.optimize_reports import generate_periodic_breakdown_stats
|
from freqtrade.optimize.optimize_reports.optimize_reports import generate_periodic_breakdown_stats
|
||||||
from freqtrade.types import BacktestResultType
|
from freqtrade.types import BacktestResultType
|
||||||
|
from freqtrade.util import decimals_per_coin, round_coin_value
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ from freqtrade.constants import BACKTEST_BREAKDOWNS, DATETIME_PRINT_FORMAT, IntO
|
|||||||
from freqtrade.data.metrics import (calculate_cagr, calculate_calmar, calculate_csum,
|
from freqtrade.data.metrics import (calculate_cagr, calculate_calmar, calculate_csum,
|
||||||
calculate_expectancy, calculate_market_change,
|
calculate_expectancy, calculate_market_change,
|
||||||
calculate_max_drawdown, calculate_sharpe, calculate_sortino)
|
calculate_max_drawdown, calculate_sharpe, calculate_sortino)
|
||||||
from freqtrade.misc import decimals_per_coin, round_coin_value
|
|
||||||
from freqtrade.types import BacktestResultType
|
from freqtrade.types import BacktestResultType
|
||||||
|
from freqtrade.util import decimals_per_coin, round_coin_value
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ from freqtrade.exceptions import ExchangeError, PricingError
|
|||||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs
|
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs
|
||||||
from freqtrade.exchange.types import Tickers
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.loggers import bufferHandler
|
from freqtrade.loggers import bufferHandler
|
||||||
from freqtrade.misc import decimals_per_coin
|
|
||||||
from freqtrade.persistence import KeyStoreKeys, KeyValueStore, PairLocks, Trade
|
from freqtrade.persistence import KeyStoreKeys, KeyValueStore, PairLocks, Trade
|
||||||
from freqtrade.persistence.models import PairLock
|
from freqtrade.persistence.models import PairLock
|
||||||
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
||||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||||
from freqtrade.rpc.rpc_types import RPCSendMsg
|
from freqtrade.rpc.rpc_types import RPCSendMsg
|
||||||
from freqtrade.util import dt_humanize, dt_now, dt_ts_def, format_date, shorten_date
|
from freqtrade.util import (decimals_per_coin, dt_humanize, dt_now, dt_ts_def, format_date,
|
||||||
|
shorten_date)
|
||||||
from freqtrade.wallets import PositionWallet, Wallet
|
from freqtrade.wallets import PositionWallet, Wallet
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ from freqtrade.__init__ import __version__
|
|||||||
from freqtrade.constants import DUST_PER_COIN, Config
|
from freqtrade.constants import DUST_PER_COIN, Config
|
||||||
from freqtrade.enums import MarketDirection, RPCMessageType, SignalDirection, TradingMode
|
from freqtrade.enums import MarketDirection, RPCMessageType, SignalDirection, TradingMode
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import chunks, plural, round_coin_value
|
from freqtrade.misc import chunks, plural
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc import RPC, RPCException, RPCHandler
|
from freqtrade.rpc import RPC, RPCException, RPCHandler
|
||||||
from freqtrade.rpc.rpc_types import RPCSendMsg
|
from freqtrade.rpc.rpc_types import RPCSendMsg
|
||||||
from freqtrade.util import dt_humanize
|
from freqtrade.util import dt_humanize, round_coin_value
|
||||||
|
|
||||||
|
|
||||||
MAX_MESSAGE_LENGTH = MessageLimit.MAX_TEXT_LENGTH
|
MAX_MESSAGE_LENGTH = MessageLimit.MAX_TEXT_LENGTH
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from freqtrade.util.datetime_helpers import (dt_floor_day, dt_from_ts, dt_humanize, dt_now, dt_ts,
|
from freqtrade.util.datetime_helpers import (dt_floor_day, dt_from_ts, dt_humanize, dt_now, dt_ts,
|
||||||
dt_ts_def, dt_utc, format_date, format_ms_time,
|
dt_ts_def, dt_utc, format_date, format_ms_time,
|
||||||
shorten_date)
|
shorten_date)
|
||||||
|
from freqtrade.util.formatters import decimals_per_coin, round_coin_value, round_value
|
||||||
from freqtrade.util.ft_precise import FtPrecise
|
from freqtrade.util.ft_precise import FtPrecise
|
||||||
from freqtrade.util.periodic_cache import PeriodicCache
|
from freqtrade.util.periodic_cache import PeriodicCache
|
||||||
from freqtrade.util.template_renderer import render_template, render_template_with_fallback # noqa
|
from freqtrade.util.template_renderer import render_template, render_template_with_fallback # noqa
|
||||||
@@ -19,4 +20,7 @@ __all__ = [
|
|||||||
'FtPrecise',
|
'FtPrecise',
|
||||||
'PeriodicCache',
|
'PeriodicCache',
|
||||||
'shorten_date',
|
'shorten_date',
|
||||||
|
'decimals_per_coin',
|
||||||
|
'round_value',
|
||||||
|
'round_coin_value',
|
||||||
]
|
]
|
||||||
|
|||||||
42
freqtrade/util/formatters.py
Normal file
42
freqtrade/util/formatters.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
from freqtrade.constants import DECIMAL_PER_COIN_FALLBACK, DECIMALS_PER_COIN
|
||||||
|
|
||||||
|
|
||||||
|
def decimals_per_coin(coin: str):
|
||||||
|
"""
|
||||||
|
Helper method getting decimal amount for this coin
|
||||||
|
example usage: f".{decimals_per_coin('USD')}f"
|
||||||
|
:param coin: Which coin are we printing the price / value for
|
||||||
|
"""
|
||||||
|
return DECIMALS_PER_COIN.get(coin, DECIMAL_PER_COIN_FALLBACK)
|
||||||
|
|
||||||
|
|
||||||
|
def round_value(value: float, decimals: int, keep_trailing_zeros=False) -> str:
|
||||||
|
"""
|
||||||
|
Round value to given decimals
|
||||||
|
:param value: Value to be rounded
|
||||||
|
:param decimals: Number of decimals to round to
|
||||||
|
:param keep_trailing_zeros: Keep trailing zeros "222.200" vs. "222.2"
|
||||||
|
:return: Rounded value as string
|
||||||
|
"""
|
||||||
|
val = f"{value:.{decimals}f}"
|
||||||
|
if not keep_trailing_zeros:
|
||||||
|
val = val.rstrip('0').rstrip('.')
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
def round_coin_value(
|
||||||
|
value: float, coin: str, show_coin_name=True, keep_trailing_zeros=False) -> str:
|
||||||
|
"""
|
||||||
|
Get price value for this coin
|
||||||
|
:param value: Value to be printed
|
||||||
|
:param coin: Which coin are we printing the price / value for
|
||||||
|
:param show_coin_name: Return string in format: "222.22 USDT" or "222.22"
|
||||||
|
:param keep_trailing_zeros: Keep trailing zeros "222.200" vs. "222.2"
|
||||||
|
:return: Formatted / rounded value (with or without coin name)
|
||||||
|
"""
|
||||||
|
val = f"{value:.{decimals_per_coin(coin)}f}"
|
||||||
|
val = round_value(value, decimals_per_coin(coin), keep_trailing_zeros)
|
||||||
|
if show_coin_name:
|
||||||
|
val = f"{val} {coin}"
|
||||||
|
|
||||||
|
return val
|
||||||
@@ -7,46 +7,10 @@ from unittest.mock import MagicMock
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from freqtrade.misc import (dataframe_to_json, decimals_per_coin, deep_merge_dicts, file_dump_json,
|
from freqtrade.misc import (dataframe_to_json, deep_merge_dicts, file_dump_json, file_load_json,
|
||||||
file_load_json, is_file_in_dir, json_to_dataframe, pair_to_filename,
|
is_file_in_dir, json_to_dataframe, pair_to_filename,
|
||||||
parse_db_uri_for_logging, plural, round_coin_value, round_value,
|
parse_db_uri_for_logging, plural, safe_value_fallback,
|
||||||
safe_value_fallback, safe_value_fallback2)
|
safe_value_fallback2)
|
||||||
|
|
||||||
|
|
||||||
def test_decimals_per_coin():
|
|
||||||
assert decimals_per_coin('USDT') == 3
|
|
||||||
assert decimals_per_coin('EUR') == 3
|
|
||||||
assert decimals_per_coin('BTC') == 8
|
|
||||||
assert decimals_per_coin('ETH') == 5
|
|
||||||
|
|
||||||
|
|
||||||
def test_round_coin_value():
|
|
||||||
assert round_coin_value(222.222222, 'USDT') == '222.222 USDT'
|
|
||||||
assert round_coin_value(222.2, 'USDT', keep_trailing_zeros=True) == '222.200 USDT'
|
|
||||||
assert round_coin_value(222.2, 'USDT') == '222.2 USDT'
|
|
||||||
assert round_coin_value(222.12745, 'EUR') == '222.127 EUR'
|
|
||||||
assert round_coin_value(0.1274512123, 'BTC') == '0.12745121 BTC'
|
|
||||||
assert round_coin_value(0.1274512123, 'ETH') == '0.12745 ETH'
|
|
||||||
|
|
||||||
assert round_coin_value(222.222222, 'USDT', False) == '222.222'
|
|
||||||
assert round_coin_value(222.2, 'USDT', False) == '222.2'
|
|
||||||
assert round_coin_value(222.00, 'USDT', False) == '222'
|
|
||||||
assert round_coin_value(222.12745, 'EUR', False) == '222.127'
|
|
||||||
assert round_coin_value(0.1274512123, 'BTC', False) == '0.12745121'
|
|
||||||
assert round_coin_value(0.1274512123, 'ETH', False) == '0.12745'
|
|
||||||
assert round_coin_value(222.2, 'USDT', False, True) == '222.200'
|
|
||||||
|
|
||||||
|
|
||||||
def test_round_value():
|
|
||||||
|
|
||||||
assert round_value(222.222222, 3) == '222.222'
|
|
||||||
assert round_value(222.2, 3) == '222.2'
|
|
||||||
assert round_value(222.00, 3) == '222'
|
|
||||||
assert round_value(222.12745, 3) == '222.127'
|
|
||||||
assert round_value(0.1274512123, 8) == '0.12745121'
|
|
||||||
assert round_value(0.1274512123, 5) == '0.12745'
|
|
||||||
assert round_value(222.2, 3, True) == '222.200'
|
|
||||||
assert round_value(222.2, 0, True) == '222'
|
|
||||||
|
|
||||||
|
|
||||||
def test_file_dump_json(mocker) -> None:
|
def test_file_dump_json(mocker) -> None:
|
||||||
|
|||||||
37
tests/utils/test_formatters.py
Normal file
37
tests/utils/test_formatters.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from freqtrade.util import decimals_per_coin, round_coin_value, round_value
|
||||||
|
|
||||||
|
|
||||||
|
def test_decimals_per_coin():
|
||||||
|
assert decimals_per_coin('USDT') == 3
|
||||||
|
assert decimals_per_coin('EUR') == 3
|
||||||
|
assert decimals_per_coin('BTC') == 8
|
||||||
|
assert decimals_per_coin('ETH') == 5
|
||||||
|
|
||||||
|
|
||||||
|
def test_round_coin_value():
|
||||||
|
assert round_coin_value(222.222222, 'USDT') == '222.222 USDT'
|
||||||
|
assert round_coin_value(222.2, 'USDT', keep_trailing_zeros=True) == '222.200 USDT'
|
||||||
|
assert round_coin_value(222.2, 'USDT') == '222.2 USDT'
|
||||||
|
assert round_coin_value(222.12745, 'EUR') == '222.127 EUR'
|
||||||
|
assert round_coin_value(0.1274512123, 'BTC') == '0.12745121 BTC'
|
||||||
|
assert round_coin_value(0.1274512123, 'ETH') == '0.12745 ETH'
|
||||||
|
|
||||||
|
assert round_coin_value(222.222222, 'USDT', False) == '222.222'
|
||||||
|
assert round_coin_value(222.2, 'USDT', False) == '222.2'
|
||||||
|
assert round_coin_value(222.00, 'USDT', False) == '222'
|
||||||
|
assert round_coin_value(222.12745, 'EUR', False) == '222.127'
|
||||||
|
assert round_coin_value(0.1274512123, 'BTC', False) == '0.12745121'
|
||||||
|
assert round_coin_value(0.1274512123, 'ETH', False) == '0.12745'
|
||||||
|
assert round_coin_value(222.2, 'USDT', False, True) == '222.200'
|
||||||
|
|
||||||
|
|
||||||
|
def test_round_value():
|
||||||
|
|
||||||
|
assert round_value(222.222222, 3) == '222.222'
|
||||||
|
assert round_value(222.2, 3) == '222.2'
|
||||||
|
assert round_value(222.00, 3) == '222'
|
||||||
|
assert round_value(222.12745, 3) == '222.127'
|
||||||
|
assert round_value(0.1274512123, 8) == '0.12745121'
|
||||||
|
assert round_value(0.1274512123, 5) == '0.12745'
|
||||||
|
assert round_value(222.2, 3, True) == '222.200'
|
||||||
|
assert round_value(222.2, 0, True) == '222'
|
||||||
Reference in New Issue
Block a user