15f5812ea4354e264c62f9e1abd72c6c32c2aa50
Второй источник выплат: 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).
fin-tracker
Личная аналитика финансов и инвестиций: ZenMoney (повседневные деньги) + брокеры (T-Invest API, отчёты Сбера и ВТБ) в одной базе, с XIRR/TWR, календарём дивидендов и купонов, аллокацией и net worth. Замена Snowball Income.
backend/— Python 3.12, FastAPI, PostgreSQL, worker с расписанием синков.app/— Flutter-клиент (web, Linux, Windows, Android) поверх REST/OpenAPI.deploy/— Caddy и сертификаты;docker-compose.yml— прод на VPS.
Для агентов: AGENTS.md. Команды: just --list.
Languages
Python
46.4%
Dart
40.9%
JavaScript
11%
C++
0.7%
CMake
0.6%
Other
0.2%