ff4d63e8299c78d126a2f787c1a17ff4f22639b0
Случай C из плана §1.6: без него одни и те же деньги считаются дважды, а перевод на брокерский счёт выглядит расходом. match_flows — чистая функция над двумя последовательностями кандидатов, как apply() в lots.py; rebuild_flow_links её обвязка с сессией. Скоринг: та же валюта, тот же счёт, |Δ| ≤ max(1 ₽, 0,5 %), разрыв ≤ 3 РАБОЧИХ дня. Рабочих, а не календарных: деньги на брокерский счёт в субботу не приходят, и календарное окно систематически теряло бы пятничные переводы. Праздники не моделируются — лишний праздник делает матчер строже, а не наглее. Направление выбрано по данным, а не по тексту плана. План говорит «outcome на зеркальный счёт = пополнение», но зеркальный ZM-счёт это отражение брокерского кэша: деньги идут «карта → зеркало» (income на зеркале), а на брокере в тот же день deposit. На живых данных income-соглашение даёт 525 пар, обратное — 4. Для маршрута через правило broker_target, где брокера в ZenMoney нет вовсе, направление остаётся как в плане: outcome ↔ deposit. Жадность 1:1 по (дельта суммы, разрыв в днях): пара берётся, только если свободны обе стороны. Ручные линки не пересобираются — обе их стороны исключаются из пулов, иначе автоматика молча переписывала бы решение человека. Связанная транзакция получает flow_type = internal_transfer здесь, а не в classify: классификатор не может знать о линках, которых на момент его работы ещё нет.
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%