portfolio-tracker

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Portfolio Tracker

投资组合追踪器

Track and analyze your crypto portfolio across all exchanges.
跨所有交易所追踪并分析你的加密货币投资组合。

Overview

概述

  • Multi-Exchange Aggregation - Unified view of all holdings
  • P&L Calculation - Realized and unrealized gains
  • Asset Allocation - Distribution by coin and exchange
  • Performance Reports - Daily, weekly, monthly summaries
  • 多交易所聚合 - 统一查看所有持仓
  • 盈亏(P&L)计算 - 已实现和未实现收益
  • 资产分配 - 按币种和交易所分布
  • 业绩报告 - 每日、每周、月度汇总

Data Storage

数据存储

Portfolio data in
~/.kit/portfolio/
:
portfolio/
├── holdings.json       # Current positions
├── transactions.json   # Trade history
├── snapshots/          # Daily snapshots
│   └── 2026-02-09.json
└── reports/            # Generated reports
投资组合数据存储在
~/.kit/portfolio/
目录下:
portfolio/
├── holdings.json       # 当前持仓
├── transactions.json   # 交易历史
├── snapshots/          # 每日快照
│   └── 2026-02-09.json
└── reports/            # 生成的报告

Commands

命令

Fetch All Balances

获取所有余额

bash
python3 -c "
import ccxt
import json

exchanges_config = json.load(open('~/.kit/exchanges.json'))
total = {}

for name, config in exchanges_config.items():
    exchange = getattr(ccxt, name)(config)
    balance = exchange.fetch_balance()
    for coin, amount in balance['total'].items():
        if amount > 0:
            total[coin] = total.get(coin, 0) + amount
            print(f'{name}: {coin} = {amount}')

print('\\n=== TOTAL ===')
for coin, amount in total.items():
    print(f'{coin}: {amount}')
"
bash
python3 -c "
import ccxt
import json

exchanges_config = json.load(open('~/.kit/exchanges.json'))
total = {}

for name, config in exchanges_config.items():
    exchange = getattr(ccxt, name)(config)
    balance = exchange.fetch_balance()
    for coin, amount in balance['total'].items():
        if amount > 0:
            total[coin] = total.get(coin, 0) + amount
            print(f'{name}: {coin} = {amount}')

print('\\n=== TOTAL ===')
for coin, amount in total.items():
    print(f'{coin}: {amount}')
"

Calculate Portfolio Value

计算投资组合价值

bash
python3 -c "
import ccxt

exchange = ccxt.binance()
holdings = {'BTC': 0.5, 'ETH': 2.0, 'SOL': 10}
total_usd = 0

for coin, amount in holdings.items():
    if coin == 'USDT':
        total_usd += amount
    else:
        ticker = exchange.fetch_ticker(f'{coin}/USDT')
        value = amount * ticker['last']
        total_usd += value
        print(f'{coin}: {amount} = \${value:,.2f}')

print(f'\\nTotal: \${total_usd:,.2f}')
"
bash
python3 -c "
import ccxt

exchange = ccxt.binance()
holdings = {'BTC': 0.5, 'ETH': 2.0, 'SOL': 10}
total_usd = 0

for coin, amount in holdings.items():
    if coin == 'USDT':
        total_usd += amount
    else:
        ticker = exchange.fetch_ticker(f'{coin}/USDT')
        value = amount * ticker['last']
        total_usd += value
        print(f'{coin}: {amount} = \${value:,.2f}')

print(f'\\nTotal: \${total_usd:,.2f}')
"

Asset Allocation

资产分配

bash
python3 -c "
import ccxt

holdings = {'BTC': 0.5, 'ETH': 2.0, 'SOL': 10, 'USDT': 1000}
exchange = ccxt.binance()
values = {}
total = 0

for coin, amount in holdings.items():
    if coin == 'USDT':
        values[coin] = amount
    else:
        ticker = exchange.fetch_ticker(f'{coin}/USDT')
        values[coin] = amount * ticker['last']
    total += values[coin]

print('Asset Allocation:')
print('=' * 40)
for coin, value in sorted(values.items(), key=lambda x: -x[1]):
    pct = (value / total) * 100
    bar = '█' * int(pct / 2)
    print(f'{coin:6} {pct:5.1f}% {bar} \${value:,.0f}')
"
bash
python3 -c "
import ccxt

holdings = {'BTC': 0.5, 'ETH': 2.0, 'SOL': 10, 'USDT': 1000}
exchange = ccxt.binance()
values = {}
total = 0

for coin, amount in holdings.items():
    if coin == 'USDT':
        values[coin] = amount
    else:
        ticker = exchange.fetch_ticker(f'{coin}/USDT')
        values[coin] = amount * ticker['last']
    total += values[coin]

print('Asset Allocation:')
print('=' * 40)
for coin, value in sorted(values.items(), key=lambda x: -x[1]):
    pct = (value / total) * 100
    bar = '█' * int(pct / 2)
    print(f'{coin:6} {pct:5.1f}% {bar} \${value:,.0f}')
"

P&L Calculation

盈亏(P&L)计算

bash
python3 -c "
bash
python3 -c "

Example: Calculate P&L from cost basis

Example: Calculate P&L from cost basis

trades = [ {'coin': 'BTC', 'amount': 0.1, 'cost_basis': 35000}, {'coin': 'BTC', 'amount': 0.2, 'cost_basis': 42000}, {'coin': 'ETH', 'amount': 1.0, 'cost_basis': 2200}, ]
import ccxt exchange = ccxt.binance()
for trade in trades: ticker = exchange.fetch_ticker(f"{trade['coin']}/USDT") current_price = ticker['last'] current_value = trade['amount'] * current_price cost = trade['amount'] * trade['cost_basis'] pnl = current_value - cost pnl_pct = (pnl / cost) * 100 emoji = '🟢' if pnl >= 0 else '🔴' print(f"{emoji} {trade['coin']}: ${pnl:+,.2f} ({pnl_pct:+.1f}%)") "
undefined
trades = [ {'coin': 'BTC', 'amount': 0.1, 'cost_basis': 35000}, {'coin': 'BTC', 'amount': 0.2, 'cost_basis': 42000}, {'coin': 'ETH', 'amount': 1.0, 'cost_basis': 2200}, ]
import ccxt exchange = ccxt.binance()
for trade in trades: ticker = exchange.fetch_ticker(f"{trade['coin']}/USDT") current_price = ticker['last'] current_value = trade['amount'] * current_price cost = trade['amount'] * trade['cost_basis'] pnl = current_value - cost pnl_pct = (pnl / cost) * 100 emoji = '🟢' if pnl >= 0 else '🔴' print(f"{emoji} {trade['coin']}: ${pnl:+,.2f} ({pnl_pct:+.1f}%)") "
undefined

Daily Snapshot

每日快照

bash
python3 -c "
import json
from datetime import datetime
import ccxt
bash
python3 -c "
import json
from datetime import datetime
import ccxt

Fetch current holdings and prices

Fetch current holdings and prices

holdings = {'BTC': 0.5, 'ETH': 2.0} exchange = ccxt.binance() snapshot = { 'timestamp': datetime.now().isoformat(), 'holdings': {}, 'total_usd': 0 }
for coin, amount in holdings.items(): ticker = exchange.fetch_ticker(f'{coin}/USDT') value = amount * ticker['last'] snapshot['holdings'][coin] = { 'amount': amount, 'price': ticker['last'], 'value_usd': value } snapshot['total_usd'] += value
filename = f"snapshot_{datetime.now().strftime('%Y-%m-%d')}.json" print(json.dumps(snapshot, indent=2))
holdings = {'BTC': 0.5, 'ETH': 2.0} exchange = ccxt.binance() snapshot = { 'timestamp': datetime.now().isoformat(), 'holdings': {}, 'total_usd': 0 }
for coin, amount in holdings.items(): ticker = exchange.fetch_ticker(f'{coin}/USDT') value = amount * ticker['last'] snapshot['holdings'][coin] = { 'amount': amount, 'price': ticker['last'], 'value_usd': value } snapshot['total_usd'] += value
filename = f"snapshot_{datetime.now().strftime('%Y-%m-%d')}.json" print(json.dumps(snapshot, indent=2))

Save: json.dump(snapshot, open(filename, 'w'))

Save: json.dump(snapshot, open(filename, 'w'))

"
undefined
"
undefined

Performance Report

业绩报告

bash
python3 -c "
bash
python3 -c "

Compare snapshots for performance

Compare snapshots for performance

import json from datetime import datetime, timedelta
import json from datetime import datetime, timedelta

Mock data - load from files in practice

Mock data - load from files in practice

yesterday = {'total_usd': 50000, 'holdings': {'BTC': {'value_usd': 40000}}} today = {'total_usd': 52000, 'holdings': {'BTC': {'value_usd': 42000}}}
change = today['total_usd'] - yesterday['total_usd'] change_pct = (change / yesterday['total_usd']) * 100
print('📈 DAILY PERFORMANCE REPORT') print('=' * 40) print(f"Portfolio Value: ${today['total_usd']:,.2f}") print(f"24h Change: ${change:+,.2f} ({change_pct:+.2f}%)") print() print('Top Movers:') for coin in today['holdings']: if coin in yesterday['holdings']: prev = yesterday['holdings'][coin]['value_usd'] curr = today['holdings'][coin]['value_usd'] pct = ((curr - prev) / prev) * 100 emoji = '🟢' if pct >= 0 else '🔴' print(f' {emoji} {coin}: {pct:+.2f}%') "
undefined
yesterday = {'total_usd': 50000, 'holdings': {'BTC': {'value_usd': 40000}}} today = {'total_usd': 52000, 'holdings': {'BTC': {'value_usd': 42000}}}
change = today['total_usd'] - yesterday['total_usd'] change_pct = (change / yesterday['total_usd']) * 100
print('📈 DAILY PERFORMANCE REPORT') print('=' * 40) print(f"Portfolio Value: ${today['total_usd']:,.2f}") print(f"24h Change: ${change:+,.2f} ({change_pct:+.2f}%)") print() print('Top Movers:') for coin in today['holdings']: if coin in yesterday['holdings']: prev = yesterday['holdings'][coin]['value_usd'] curr = today['holdings'][coin]['value_usd'] pct = ((curr - prev) / prev) * 100 emoji = '🟢' if pct >= 0 else '🔴' print(f' {emoji} {coin}: {pct:+.2f}%') "
undefined

Workflow

工作流程

Setting Up Tracking

设置追踪

  1. Configure exchanges in
    ~/.kit/exchanges.json
  2. Run initial balance fetch
  3. Set up daily snapshot cron job
  4. Import historical trades for accurate P&L
  1. ~/.kit/exchanges.json
    中配置交易所信息
  2. 运行初始余额获取命令
  3. 设置每日快照的定时任务(cron job)
  4. 导入历史交易记录以获取准确的盈亏数据

Metrics Tracked

追踪指标

MetricDescription
Total ValueSum of all holdings in USD
24h ChangeDaily performance
7d ChangeWeekly performance
30d ChangeMonthly performance
ATHAll-time high portfolio value
Max DrawdownLargest peak-to-trough decline
Sharpe RatioRisk-adjusted returns
指标描述
总价值所有持仓以美元计算的总和
24小时变化每日业绩表现
7天变化每周业绩表现
30天变化月度业绩表现
ATH投资组合历史最高价值
最大回撤从峰值到谷底的最大跌幅
夏普比率风险调整后的回报率

Report Types

报告类型

  • Daily Summary - Quick overview
  • Weekly Report - Detailed with charts
  • Monthly Report - Full analysis with recommendations
  • Tax Report - Realized gains for tax purposes
  • 每日摘要 - 快速概览
  • 每周报告 - 包含图表的详细报告
  • 月度报告 - 完整分析及建议
  • 税务报告 - 用于报税的已实现收益记录