mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-01-20 14:00:38 +00:00
Add significant digits Round_Up / round_down
This commit is contained in:
@@ -248,6 +248,39 @@ def amount_to_contract_precision(
|
||||
return amount
|
||||
|
||||
|
||||
def __price_to_precision_significant_digits(
|
||||
price: float,
|
||||
price_precision: float,
|
||||
*,
|
||||
rounding_mode: int = ROUND,
|
||||
) -> float:
|
||||
"""
|
||||
Implementation of ROUND_UP/Round_down for significant digits mode.
|
||||
"""
|
||||
from decimal import ROUND_DOWN as dec_ROUND_DOWN
|
||||
from decimal import ROUND_UP as dec_ROUND_UP
|
||||
from decimal import Decimal
|
||||
dec = Decimal(str(price))
|
||||
string = f'{dec:f}'
|
||||
precision = round(price_precision)
|
||||
|
||||
q = precision - dec.adjusted() - 1
|
||||
sigfig = Decimal('10') ** -q
|
||||
if q < 0:
|
||||
string_to_precision = string[:precision]
|
||||
# string_to_precision is '' when we have zero precision
|
||||
below = sigfig * Decimal(string_to_precision if string_to_precision else '0')
|
||||
above = below + sigfig
|
||||
res = above if rounding_mode == ROUND_UP else below
|
||||
precise = f'{res:f}'
|
||||
else:
|
||||
precise = '{:f}'.format(dec.quantize(
|
||||
sigfig,
|
||||
rounding=dec_ROUND_DOWN if rounding_mode == ROUND_DOWN else dec_ROUND_UP)
|
||||
)
|
||||
return float(precise)
|
||||
|
||||
|
||||
def price_to_precision(
|
||||
price: float,
|
||||
price_precision: Optional[float],
|
||||
@@ -289,7 +322,7 @@ def price_to_precision(
|
||||
res = price_str - missing
|
||||
return round(float(str(res)), 14)
|
||||
return price
|
||||
elif precisionMode in (SIGNIFICANT_DIGITS, DECIMAL_PLACES):
|
||||
elif precisionMode == DECIMAL_PLACES:
|
||||
|
||||
ndigits = round(price_precision)
|
||||
ticks = price * (10**ndigits)
|
||||
@@ -299,5 +332,11 @@ def price_to_precision(
|
||||
return floor(ticks) / (10**ndigits)
|
||||
|
||||
raise ValueError(f"Unknown rounding_mode {rounding_mode}")
|
||||
elif precisionMode == SIGNIFICANT_DIGITS:
|
||||
if rounding_mode in (ROUND_UP, ROUND_DOWN):
|
||||
return __price_to_precision_significant_digits(
|
||||
price, price_precision, rounding_mode=rounding_mode
|
||||
)
|
||||
|
||||
raise ValueError(f"Unknown precisionMode {precisionMode}")
|
||||
return price
|
||||
|
||||
@@ -288,6 +288,25 @@ def test_amount_to_precision(amount, precision_mode, precision, expected,):
|
||||
(2.9909, SIGNIFICANT_DIGITS, 2, 2.9, TRUNCATE),
|
||||
(0.00000777, SIGNIFICANT_DIGITS, 2, 0.0000077, TRUNCATE),
|
||||
(0.00000729, SIGNIFICANT_DIGITS, 2, 0.0000072, TRUNCATE),
|
||||
# ROUND
|
||||
(722.2, SIGNIFICANT_DIGITS, 1, 700.0, ROUND),
|
||||
(790.2, SIGNIFICANT_DIGITS, 1, 800.0, ROUND),
|
||||
(722.2, SIGNIFICANT_DIGITS, 2, 720.0, ROUND),
|
||||
(722.2, SIGNIFICANT_DIGITS, 1, 800.0, ROUND_UP),
|
||||
(722.2, SIGNIFICANT_DIGITS, 2, 730.0, ROUND_UP),
|
||||
(777.7, SIGNIFICANT_DIGITS, 2, 780.0, ROUND_UP),
|
||||
(777.7, SIGNIFICANT_DIGITS, 3, 778.0, ROUND_UP),
|
||||
(722.2, SIGNIFICANT_DIGITS, 1, 700.0, ROUND_DOWN),
|
||||
(722.2, SIGNIFICANT_DIGITS, 2, 720.0, ROUND_DOWN),
|
||||
(777.7, SIGNIFICANT_DIGITS, 2, 770.0, ROUND_DOWN),
|
||||
(777.7, SIGNIFICANT_DIGITS, 3, 777.0, ROUND_DOWN),
|
||||
|
||||
(0.000007222, SIGNIFICANT_DIGITS, 1, 0.000008, ROUND_UP),
|
||||
(0.000007222, SIGNIFICANT_DIGITS, 2, 0.0000073, ROUND_UP),
|
||||
(0.000007777, SIGNIFICANT_DIGITS, 2, 0.0000078, ROUND_UP),
|
||||
(0.000007222, SIGNIFICANT_DIGITS, 1, 0.000007, ROUND_DOWN),
|
||||
(0.000007222, SIGNIFICANT_DIGITS, 2, 0.0000072, ROUND_DOWN),
|
||||
(0.000007777, SIGNIFICANT_DIGITS, 2, 0.0000077, ROUND_DOWN),
|
||||
])
|
||||
def test_price_to_precision(price, precision_mode, precision, expected, rounding_mode):
|
||||
assert price_to_precision(
|
||||
|
||||
Reference in New Issue
Block a user