electrum

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

commit 51f04d4e7bdb1021c5535c47b676c3d2d084eebf
parent e7c3712181e304b8661d52391c5ca4ab3c49f575
Author: ThomasV <thomasv@electrum.org>
Date:   Wed, 21 Feb 2018 14:29:39 +0100

compute capital gains using wallet.txi and txo

Diffstat:
Mlib/wallet.py | 61+++++++++++++++++++++++++++++++++----------------------------
1 file changed, 33 insertions(+), 28 deletions(-)

diff --git a/lib/wallet.py b/lib/wallet.py @@ -503,6 +503,17 @@ class Abstract_Wallet(PrintError): delta += v return delta + def get_tx_value(self, txid): + " effect of tx on the entire domain" + delta = 0 + for addr, d in self.txi.get(txid, {}).items(): + for n, v in d: + delta -= v + for addr, d in self.txo.get(txid, {}).items(): + for n, v, cb in d: + delta += v + return delta + def get_wallet_delta(self, tx): """ effect of tx on wallet """ addresses = self.get_addresses() @@ -1694,7 +1705,7 @@ class Abstract_Wallet(PrintError): coins = self.get_utxos(domain) now = time.time() p = price_func(now) - ap = sum(self.coin_price(coin, price_func, ccy, self.txin_value(coin)) for coin in coins) + ap = sum(self.coin_price(coin['prevout_hash'], price_func, ccy, self.txin_value(coin)) for coin in coins) lp = sum([coin['value'] for coin in coins]) * p / Decimal(COIN) return lp - ap @@ -1704,42 +1715,36 @@ class Abstract_Wallet(PrintError): and the price of these coins when they entered the wallet. price_func: function that returns the fiat price given a timestamp """ - tx = self.transactions[txid] - ir, im, v, fee = self.get_wallet_delta(tx) - out_value = -v + out_value = - self.get_tx_value(txid)/Decimal(COIN) fiat_value = self.get_fiat_value(txid, ccy) - if fiat_value is None: - p = self.price_at_timestamp(txid, price_func) - liquidation_price = out_value/Decimal(COIN) * p - else: - liquidation_price = - fiat_value - - acquisition_price = out_value/Decimal(COIN) * self.average_price(tx, price_func, ccy) + liquidation_price = - fiat_value if fiat_value else out_value * self.price_at_timestamp(txid, price_func) + acquisition_price = out_value * self.average_price(txid, price_func, ccy) return acquisition_price, liquidation_price - def average_price(self, tx, price_func, ccy): - """ average price of the inputs of a transaction """ - input_value = sum(self.txin_value(txin) for txin in tx.inputs()) / Decimal(COIN) - total_price = sum(self.coin_price(txin, price_func, ccy, self.txin_value(txin)) for txin in tx.inputs()) - return total_price / input_value - - def coin_price(self, coin, price_func, ccy, txin_value): - """ fiat price of acquisition of coin """ - txid = coin['prevout_hash'] - tx = self.transactions[txid] - if all([self.is_mine(txin['address']) for txin in tx.inputs()]): - return self.average_price(tx, price_func, ccy) * txin_value/Decimal(COIN) - elif all([ not self.is_mine(txin['address']) for txin in tx.inputs()]): + def average_price(self, txid, price_func, ccy): + """ Average acquisition price of the inputs of a transaction """ + input_value = 0 + total_price = 0 + for addr, d in self.txi.get(txid, {}).items(): + for ser, v in d: + input_value += v + total_price += self.coin_price(ser.split(':')[0], price_func, ccy, v) + return total_price / (input_value/Decimal(COIN)) + + def coin_price(self, txid, price_func, ccy, txin_value): + """ + Acquisition price of a coin. + This assumes that either all inputs are mine, or no input is mine. + """ + if self.txi.get(txid, {}) != {}: + return self.average_price(txid, price_func, ccy) * txin_value/Decimal(COIN) + else: fiat_value = self.get_fiat_value(txid, ccy) if fiat_value is not None: return fiat_value else: p = self.price_at_timestamp(txid, price_func) return p * txin_value/Decimal(COIN) - else: - # could be some coinjoin transaction.. - return Decimal('NaN') - class Simple_Wallet(Abstract_Wallet): # wallet with a single keystore