feat(analytics): доходы, ребалансировка, налоги, бенчмарки и цели — фаза 4
Второй источник выплат: sources/tinvest/sync_events.py (GetDividends, GetBondCoupons, GetBondEvents) и sources/moex/payouts.py (ISS bondization + dividends). Приоритет между ними — pricing/payouts.resolve_payouts, решается на чтении, а не на записи: corporate_action уникален по (instrument_id, kind, source, source_id), обе версии сосуществуют, и правило можно поменять без ресинка истории. Амортизация от MOEX идёт в bond_nominal_schedule, а не в corporate_action — этим типом безраздельно владеет ledger/corporate_actions.py. analytics/income.py — metric_income_monthly (факт) и metric_income_calendar (прошлое и прогноз) с basis paid/announced/history на каждой строке, три источника числа не смешиваются. analytics/rebalance.py — сделки по portfolio_target пропорционально внутри бакета, лоты только вниз, покупки не занимают у ещё не свершившихся продаж. analytics/tax.py — оценка, не замена справки брокера: дивиденды/купоны gross, реализованный результат из lot_disposal с переоценкой каждой ноги на свою дату. analytics/benchmarks.py — TWR индекса на сетке портфеля, kind (price/total_return) не скрывается. analytics/goals.py — прогресс цели и нужный взнос по trailing XIRR. Четыре шага зарегистрированы в register_steps: benchmarks после returns (общая сетка дат), rebalance после allocation (её веса, не пересчитывает), income и tax после lots (нужен lot_disposal).
This commit is contained in:
@@ -18,17 +18,22 @@ from fintracker.api.routers import (
|
||||
accounts,
|
||||
analytics,
|
||||
auth,
|
||||
benchmarks,
|
||||
cashflow,
|
||||
categories,
|
||||
events,
|
||||
goals,
|
||||
health,
|
||||
imports,
|
||||
income,
|
||||
instruments,
|
||||
links,
|
||||
metrics,
|
||||
networth,
|
||||
rebalance,
|
||||
rules,
|
||||
sync,
|
||||
tax,
|
||||
transactions,
|
||||
)
|
||||
from fintracker.api.web import mount_web
|
||||
@@ -95,6 +100,12 @@ def create_app() -> FastAPI:
|
||||
app.include_router(instruments.router, prefix=API_PREFIX)
|
||||
app.include_router(links.router, prefix=API_PREFIX)
|
||||
app.include_router(metrics.router, prefix=API_PREFIX)
|
||||
app.include_router(goals.router, prefix=API_PREFIX)
|
||||
app.include_router(income.router, prefix=API_PREFIX)
|
||||
app.include_router(rebalance.router, prefix=API_PREFIX)
|
||||
app.include_router(tax.router, prefix=API_PREFIX)
|
||||
app.include_router(benchmarks.router, prefix=API_PREFIX)
|
||||
app.include_router(benchmarks.analytics_router, prefix=API_PREFIX)
|
||||
if settings.web_dir is not None:
|
||||
mount_web(app, settings.web_dir, API_PREFIX)
|
||||
return app
|
||||
|
||||
Reference in New Issue
Block a user