electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit d77e522721b98c8d455f866bc40b778c6a0fb74e
parent 7578ac6abb79347bee0a3848b2af243c9c0e0dd2
Author: ThomasV <thomasv@electrum.org>
Date:   Tue, 20 Feb 2018 21:53:12 +0100

fix #3912: Use Decimal('NaN') instead of None when exchange rate is not available.

Diffstat:
Mlib/exchange_rate.py | 35++++++++++++++++-------------------
Mlib/wallet.py | 22+++++++++-------------
2 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/lib/exchange_rate.py b/lib/exchange_rate.py @@ -109,8 +109,8 @@ class ExchangeBase(PrintError): def historical_rate(self, ccy, d_t): if d_t is None: - return None - return self.history.get(ccy, {}).get(d_t.strftime('%Y-%m-%d')) + return 'NaN' + return self.history.get(ccy, {}).get(d_t.strftime('%Y-%m-%d'), 'NaN') def get_currencies(self): rates = self.get_rates('') @@ -497,40 +497,38 @@ class FxThread(ThreadJob): def exchange_rate(self): '''Returns None, or the exchange rate as a Decimal''' rate = self.exchange.quotes.get(self.ccy) - if rate: - return Decimal(rate) + if rate is None: + return Decimal('NaN') + return Decimal(rate) def format_amount_and_units(self, btc_balance): rate = self.exchange_rate() - return '' if rate is None else "%s %s" % (self.value_str(btc_balance, rate), self.ccy) + return '' if rate.is_nan() else "%s %s" % (self.value_str(btc_balance, rate), self.ccy) def get_fiat_status_text(self, btc_balance, base_unit, decimal_point): rate = self.exchange_rate() - return _(" (No FX rate available)") if rate is None else " 1 %s~%s %s" % (base_unit, + return _(" (No FX rate available)") if rate.is_nan() else " 1 %s~%s %s" % (base_unit, self.value_str(COIN / (10**(8 - decimal_point)), rate), self.ccy) def value_str(self, satoshis, rate): - if satoshis is not None and rate is not None: - value = Decimal(satoshis) / COIN * Decimal(rate) - else: - value = None + value = Decimal('NaN') if satoshis is None else Decimal(satoshis) / COIN * Decimal(rate) return self.format_fiat(value) def format_fiat(self, value): - if value is not None: - return "%s" % (self.ccy_amount_str(value, True)) - return _("No data") + if value.is_nan(): + return _("No data") + return "%s" % (self.ccy_amount_str(value, True)) def history_rate(self, d_t): if d_t is None: - return None + return Decimal('NaN') rate = self.exchange.historical_rate(self.ccy, d_t) # Frequently there is no rate for today, until tomorrow :) # Use spot quotes in that case - if rate is None and (datetime.today().date() - d_t.date()).days <= 2: - rate = self.exchange.quotes.get(self.ccy) + if rate == 'NaN' and (datetime.today().date() - d_t.date()).days <= 2: + rate = self.exchange.quotes.get(self.ccy, 'NaN') self.history_used_spot = True - return Decimal(rate) if rate is not None else None + return Decimal(rate) def historical_value_str(self, satoshis, d_t): rate = self.history_rate(d_t) @@ -538,8 +536,7 @@ class FxThread(ThreadJob): def historical_value(self, satoshis, d_t): rate = self.history_rate(d_t) - if rate: - return Decimal(satoshis) / COIN * Decimal(rate) + return Decimal(satoshis) / COIN * Decimal(rate) def timestamp_rate(self, timestamp): from electrum.util import timestamp_to_datetime diff --git a/lib/wallet.py b/lib/wallet.py @@ -958,6 +958,7 @@ class Abstract_Wallet(PrintError): # return last balance return balance + @profiler def get_full_history(self, domain=None, from_timestamp=None, to_timestamp=None, fx=None, show_addresses=False): from .util import timestamp_to_datetime, Satoshis, Fiat out = [] @@ -1016,11 +1017,10 @@ class Abstract_Wallet(PrintError): item['fiat_default'] = fiat_default if value < 0: ap, lp = self.capital_gain(tx_hash, fx.timestamp_rate, fx.ccy) - cg = None if lp is None or ap is None else lp - ap + cg = lp - ap item['acquisition_price'] = Fiat(ap, fx.ccy) item['capital_gain'] = Fiat(cg, fx.ccy) - if cg is not None: - capital_gains += cg + capital_gains += cg else: if fiat_value is not None: fiat_income += fiat_value @@ -1686,11 +1686,9 @@ class Abstract_Wallet(PrintError): coins = self.get_utxos(domain) now = time.time() p = price_func(now) - if p is None: - return ap = sum(self.coin_price(coin, price_func, ccy, self.txin_value(coin)) for coin in coins) lp = sum([coin['value'] for coin in coins]) * p / Decimal(COIN) - return None if ap is None or lp is None else lp - ap + return lp - ap def capital_gain(self, txid, price_func, ccy): """ @@ -1704,13 +1702,11 @@ class Abstract_Wallet(PrintError): fiat_value = self.get_fiat_value(txid, ccy) if fiat_value is None: p = self.price_at_timestamp(txid, price_func) - liquidation_price = None if p is None else out_value/Decimal(COIN) * p + liquidation_price = out_value/Decimal(COIN) * p else: liquidation_price = - fiat_value - try: - acquisition_price = out_value/Decimal(COIN) * self.average_price(tx, price_func, ccy) - except: - acquisition_price = None + + acquisition_price = out_value/Decimal(COIN) * self.average_price(tx, price_func, ccy) return acquisition_price, liquidation_price def average_price(self, tx, price_func, ccy): @@ -1731,10 +1727,10 @@ class Abstract_Wallet(PrintError): return fiat_value else: p = self.price_at_timestamp(txid, price_func) - return None if p is None else p * txin_value/Decimal(COIN) + return p * txin_value/Decimal(COIN) else: # could be some coinjoin transaction.. - return None + return Decimal('NaN') class Simple_Wallet(Abstract_Wallet):