Quantize after invert, not in outputs or formatter.
This commit is contained in:
parent
83e3ebc599
commit
81a723b285
7 changed files with 38 additions and 24 deletions
|
@ -101,6 +101,8 @@ def cmd_fetch(args):
|
||||||
|
|
||||||
if args.invert:
|
if args.invert:
|
||||||
series = series.invert()
|
series = series.invert()
|
||||||
|
if args.quantize is not None:
|
||||||
|
series = series.quantize(args.quantize)
|
||||||
if args.renamebase:
|
if args.renamebase:
|
||||||
series = series.rename_base(args.renamebase)
|
series = series.rename_base(args.renamebase)
|
||||||
if args.renamequote:
|
if args.renamequote:
|
||||||
|
@ -117,7 +119,6 @@ def cmd_fetch(args):
|
||||||
thousands=if_not_none(args.formatthousands, default.thousands),
|
thousands=if_not_none(args.formatthousands, default.thousands),
|
||||||
symbol=if_not_none(args.formatsymbol, default.symbol),
|
symbol=if_not_none(args.formatsymbol, default.symbol),
|
||||||
datesep=if_not_none(args.formatdatesep, default.datesep),
|
datesep=if_not_none(args.formatdatesep, default.datesep),
|
||||||
decimal_places=if_not_none(args.quantize, default.decimal_places),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
print(output.format(series, source, fmt=fmt), end="")
|
print(output.format(series, source, fmt=fmt), end="")
|
||||||
|
|
|
@ -9,19 +9,3 @@ class Format:
|
||||||
thousands: str = ""
|
thousands: str = ""
|
||||||
symbol: str = "rightspace"
|
symbol: str = "rightspace"
|
||||||
datesep: str = "-"
|
datesep: str = "-"
|
||||||
decimal_places: int = None
|
|
||||||
|
|
||||||
def quantize(self, num):
|
|
||||||
if self.decimal_places is None:
|
|
||||||
return num
|
|
||||||
else:
|
|
||||||
prec = getcontext().prec
|
|
||||||
digits = len(num.as_tuple().digits)
|
|
||||||
exponent = num.as_tuple().exponent
|
|
||||||
|
|
||||||
fractional_digits = -exponent
|
|
||||||
whole_digits = digits - fractional_digits
|
|
||||||
max_decimal_places = prec - whole_digits
|
|
||||||
chosen_decimal_places = min(self.decimal_places, max_decimal_places)
|
|
||||||
|
|
||||||
return num.quantize(Decimal("0." + ("0" * chosen_decimal_places)))
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Beancount(BaseOutput):
|
||||||
lines = []
|
lines = []
|
||||||
for price in series.prices:
|
for price in series.prices:
|
||||||
|
|
||||||
amount_parts = f"{fmt.quantize(price.amount):,}".split(".")
|
amount_parts = f"{price.amount:,}".split(".")
|
||||||
amount_parts[0] = amount_parts[0].replace(",", fmt.thousands)
|
amount_parts[0] = amount_parts[0].replace(",", fmt.thousands)
|
||||||
amount = ".".join(amount_parts)
|
amount = ".".join(amount_parts)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class CSV(BaseOutput):
|
||||||
lines = ["date,base,quote,amount,source,type"]
|
lines = ["date,base,quote,amount,source,type"]
|
||||||
for price in series.prices:
|
for price in series.prices:
|
||||||
date = str(price.date).replace("-", fmt.datesep)
|
date = str(price.date).replace("-", fmt.datesep)
|
||||||
amount_parts = f"{fmt.quantize(price.amount):,}".split(".")
|
amount_parts = f"{price.amount:,}".split(".")
|
||||||
amount_parts[0] = amount_parts[0].replace(",", fmt.thousands)
|
amount_parts[0] = amount_parts[0].replace(",", fmt.thousands)
|
||||||
amount = fmt.decimal.join(amount_parts)
|
amount = fmt.decimal.join(amount_parts)
|
||||||
line = ",".join(
|
line = ",".join(
|
||||||
|
|
|
@ -15,16 +15,22 @@ class GnuCashSQL(BaseOutput):
|
||||||
values_parts = []
|
values_parts = []
|
||||||
for price in series.prices:
|
for price in series.prices:
|
||||||
date = f"{price.date} {fmt.time}"
|
date = f"{price.date} {fmt.time}"
|
||||||
amount = fmt.quantize(price.amount)
|
|
||||||
m = hashlib.sha256()
|
m = hashlib.sha256()
|
||||||
m.update(
|
m.update(
|
||||||
"".join(
|
"".join(
|
||||||
[date, series.base, series.quote, src, series.type, str(amount)]
|
[
|
||||||
|
date,
|
||||||
|
series.base,
|
||||||
|
series.quote,
|
||||||
|
src,
|
||||||
|
series.type,
|
||||||
|
str(price.amount),
|
||||||
|
]
|
||||||
).encode("utf-8")
|
).encode("utf-8")
|
||||||
)
|
)
|
||||||
guid = m.hexdigest()[0:32]
|
guid = m.hexdigest()[0:32]
|
||||||
value_num = str(amount).replace(".", "")
|
value_num = str(price.amount).replace(".", "")
|
||||||
value_denom = 10 ** len(f"{amount}.".split(".")[1])
|
value_denom = 10 ** len(f"{price.amount}.".split(".")[1])
|
||||||
v = (
|
v = (
|
||||||
"("
|
"("
|
||||||
f"'{guid}', "
|
f"'{guid}', "
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Ledger(BaseOutput):
|
||||||
for price in series.prices:
|
for price in series.prices:
|
||||||
date = str(price.date).replace("-", fmt.datesep)
|
date = str(price.date).replace("-", fmt.datesep)
|
||||||
|
|
||||||
amount_parts = f"{fmt.quantize(price.amount):,}".split(".")
|
amount_parts = f"{price.amount:,}".split(".")
|
||||||
amount_parts[0] = amount_parts[0].replace(",", fmt.thousands)
|
amount_parts[0] = amount_parts[0].replace(",", fmt.thousands)
|
||||||
amount = fmt.decimal.join(amount_parts)
|
amount = fmt.decimal.join(amount_parts)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from dataclasses import dataclass, field, replace
|
from dataclasses import dataclass, field, replace
|
||||||
|
from decimal import Decimal, getcontext
|
||||||
|
|
||||||
from pricehist.price import Price
|
from pricehist.price import Price
|
||||||
|
|
||||||
|
@ -20,8 +21,30 @@ class Series:
|
||||||
prices=[Price(date=p.date, amount=(1 / p.amount)) for p in self.prices],
|
prices=[Price(date=p.date, amount=(1 / p.amount)) for p in self.prices],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def quantize(self, decimal_places):
|
||||||
|
return replace(
|
||||||
|
self,
|
||||||
|
prices=[
|
||||||
|
replace(p, amount=self._quantize(p.amount, decimal_places))
|
||||||
|
for p in self.prices
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
def rename_base(self, new_base):
|
def rename_base(self, new_base):
|
||||||
return replace(self, base=new_base)
|
return replace(self, base=new_base)
|
||||||
|
|
||||||
def rename_quote(self, new_quote):
|
def rename_quote(self, new_quote):
|
||||||
return replace(self, quote=new_quote)
|
return replace(self, quote=new_quote)
|
||||||
|
|
||||||
|
def _quantize(self, amount, decimal_places):
|
||||||
|
digits = len(amount.as_tuple().digits)
|
||||||
|
exponent = amount.as_tuple().exponent
|
||||||
|
|
||||||
|
fractional_digits = -exponent
|
||||||
|
whole_digits = digits - fractional_digits
|
||||||
|
max_decimal_places = getcontext().prec - whole_digits
|
||||||
|
|
||||||
|
chosen_decimal_places = min(decimal_places, max_decimal_places)
|
||||||
|
rounding = Decimal("0." + ("0" * chosen_decimal_places))
|
||||||
|
|
||||||
|
return amount.quantize(rounding)
|
||||||
|
|
Loading…
Add table
Reference in a new issue