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:
M | lib/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