def fetch_(keyword, account_type, fetch_actions, fetch_balances, fetch_trades, external): "Fetch trades for configured accounts" buchfink_db = BuchfinkDB() buchfink_db.perform_assets_updates() now = ts_now() fetch_limited = fetch_actions or fetch_balances or fetch_trades if external: accounts = [account_from_string(ext, buchfink_db) for ext in external] else: accounts = buchfink_db.get_all_accounts() # TODO: This should move to BuchfinkDB.get_accounts() if keyword is not None: if keyword.startswith('/') and keyword.endswith('/'): keyword_re = re.compile(keyword[1:-1]) accounts = [acc for acc in accounts if keyword_re.search(acc.name)] else: accounts = [acc for acc in accounts if keyword in acc.name] logger.info( 'Collected %d account(s): %s', len(accounts), ', '.join([acc.name for acc in accounts]) ) for account in accounts: if account_type is not None and account_type not in account.account_type: continue name = account.name trades = [] actions = [] if account.account_type == "ethereum": if not fetch_limited or fetch_actions: logger.info('Analyzing ethereum transactions for %s', name) manager = buchfink_db.get_chain_manager(account) txs = manager.ethereum.transactions.single_address_query_transactions( account.address, start_ts=0, end_ts=now, with_limit=False, only_cache=False ) for txn in txs: tx_hash = '0x' + txn.tx_hash.hex() receipt = buchfink_db.get_ethereum_transaction_receipt(tx_hash, manager) acc_actions = classify_tx(account, tx_hash, txn, receipt) if actions: for act in actions: logger.debug('Found action: %s', act) actions.extend(acc_actions) if not fetch_limited or fetch_trades: logger.info('Fetching uniswap trades for %s', name) manager = buchfink_db.get_chain_manager(account) trades = manager.eth_modules['uniswap'].get_trades( addresses=manager.accounts.eth, from_timestamp=int(epoch_start_ts), to_timestamp=int(epoch_end_ts), only_cache=False ) elif account.account_type == "exchange": if not fetch_limited or fetch_trades: logger.info('Fetching exhange trades for %s', name) exchange = buchfink_db.get_exchange(name) api_key_is_valid, error = exchange.validate_api_key() if not api_key_is_valid: logger.critical( 'Skipping exchange %s because API key is not valid (%s)', account.name, error ) else: trades = exchange.query_online_trade_history( start_ts=epoch_start_ts, end_ts=epoch_end_ts ) else: logger.debug('No way to retrieve trades for %s, yet', name) annotations_path = "annotations/" + name + ".yaml" if not fetch_limited or fetch_actions: if os.path.exists(annotations_path): annotated = buchfink_db.get_actions_from_file(annotations_path) else: annotated = [] logger.info('Fetched %d action(s) (%d annotated) from %s', len(actions) + len(annotated), len(annotated), name) actions.extend(annotated) if actions: with open("actions/" + name + ".yaml", "w") as yaml_file: yaml.dump({ "actions": serialize_ledger_actions(actions) }, stream=yaml_file, sort_keys=True) if not fetch_limited or fetch_trades: if os.path.exists(annotations_path): annotated = buchfink_db.get_trades_from_file(annotations_path) else: annotated = [] logger.info('Fetched %d trades(s) (%d annotated) from %s', len(trades) + len(annotated), len(annotated), name) trades.extend(annotated) with open("trades/" + name + ".yaml", "w") as yaml_file: yaml.dump({ "trades": serialize_trades(trades) }, stream=yaml_file, sort_keys=True) if not fetch_limited or fetch_balances: buchfink_db.fetch_balances(account) logger.info('Fetched balances from %s', name)
def balances(keyword, minimum_balance, fetch, total, external): "Show balances across all accounts" buchfink_db = BuchfinkDB() assets_sum = {} assets_usd_sum = {} liabilities_sum = {} liabilities_usd_sum = {} if external: accounts = [account_from_string(ext, buchfink_db) for ext in external] else: accounts = buchfink_db.get_all_accounts() for account in accounts: if keyword is not None and keyword not in account.name: continue if fetch: buchfink_db.perform_assets_updates() buchfink_db.fetch_balances(account) sheet = buchfink_db.get_balances(account) for asset, balance in sheet.assets.items(): amount = balance.amount assets_sum[asset] = assets_sum.get(asset, FVal(0)) + amount assets_usd_sum[asset] = assets_usd_sum.get(asset, FVal(0)) + balance.usd_value for liability, balance in sheet.liabilities.items(): amount = balance.amount liabilities_sum[liability] = liabilities_sum.get(liability, FVal(0)) + amount liabilities_usd_sum[liability] = liabilities_usd_sum.get(liability, FVal(0)) \ + balance.usd_value currency = buchfink_db.get_main_currency() currency_in_usd = FVal(buchfink_db.inquirer.find_usd_price(currency)) table = [] assets = [obj[0] for obj in sorted(assets_usd_sum.items(), key=itemgetter(1), reverse=True)] balance_in_currency_sum = 0 small_balances_sum = 0 for asset in assets: balance = assets_sum[asset] balance_in_currency = FVal(assets_usd_sum.get(asset, 0)) / currency_in_usd if balance > ZERO: if balance_in_currency > FVal(minimum_balance): table.append([ asset.name, balance, asset.symbol, round(float(balance_in_currency), 2) ]) else: small_balances_sum += balance_in_currency balance_in_currency_sum += balance_in_currency if total: print(f'Total assets: {round(float(balance_in_currency_sum), 2)} {currency.symbol}') else: if small_balances_sum > 0: table.append(['Others', None, None, round(float(small_balances_sum), 2)]) table.append(['Total', None, None, round(float(balance_in_currency_sum), 2)]) print(tabulate(table, headers=[ 'Asset', 'Amount', 'Symbol', 'Fiat Value (%s)' % currency.symbol ])) if liabilities_sum: table = [] balance_in_currency_sum = 0 assets = [ obj[0] for obj in sorted(liabilities_usd_sum.items(), key=itemgetter(1), reverse=True) ] for asset in assets: balance = liabilities_sum[asset] balance_in_currency = liabilities_usd_sum.get(asset, FVal(0)) / currency_in_usd if balance > ZERO and balance_in_currency >= FVal(minimum_balance): balance_in_currency_sum += balance_in_currency table.append([ asset.name, balance, asset.symbol, round(float(balance_in_currency), 2) ]) table.append(['Total', None, None, round(float(balance_in_currency_sum), 2)]) if total: print( f'Total liabilities: ' f'{round(float(balance_in_currency_sum), 2)} {currency.symbol}' ) else: print() print(tabulate(table, headers=[ 'Liability', 'Amount', 'Symbol', 'Fiat Value (%s)' % currency.symbol ]))