Перейти к основному содержимому

Управляемые ценовые фиды теперь разрешаются через include в размещённых реестрах

Опубликовано Обновлено 9 мин чтенияMike ThriftMike Thrift
Управляемые ценовые фиды теперь разрешаются через include в размещённых реестрах
Содержание страницы

Признаемся честно: ваши активы уже идеально зафиксированы в реестре. Именно цены держат вас в цикле бесконечного переписывания.

Эта асимметрия — самая старая и самая раздражающая рутина в учёте на основе простого текста. Вы записываете покупку один раз, и она высечена в камне навсегда: 120 NWRB {41.80 USD, 2024-03-12} навсегда фиксирует количество, стоимость и дату. Ничто из происходящего после этого не меняет этих фактов. Цена же — полная противоположность: она верна ровно один день, а затем тихо становится неверной. Хуже того, она становится неверной так, что никакая проверка баланса этого не поймает, потому что реестр с устаревшими ценами всё равно сходится идеально.

Исторически способ решения этой проблемы в Beancount — получать цены скриптом и коммитить результат. Это работает, и многие это автоматизировали. Но в конечном счёте это всё тот же скрипт, за которым нужно присматривать, cron-задача, которую нужно поддерживать, и файл, который нужно постоянно сливать.

Хватит. Для реестров, размещённых на beancount.io, наш движок теперь решает эту задачу нативно. В этом посте рассказано, что именно только что вышло, чего мы намеренно не трогали и — что не менее важно — что мы ещё не построили.


Что вышло​

Размещённый реестр beancount.io теперь может содержать директиву include, указывающую на URL вместо локального имени файла:

; main.bean, in a hosted beancount.io ledger.
;
; The catalog quotes no currency for this page's language, so the example uses
; USD. Use a currency from the list under the fence.
 
option "title" "Taxable brokerage"
option "operating_currency" "USD"
 
; Only the hosted engine resolves the URL form, and upstream `include` takes a
; file glob — so the line is shown commented out here and this file still
; loads if you copy it to your own machine. Uncomment it in a hosted ledger.
; include "https://beancount.io/prices/AAPL-USD"

Обратите внимание: вам нужно войти в систему, прежде чем переходить по этому URL. Анонимные запросы перенаправляются на страницу входа. В каталоге нет котировок в валюте языка этой страницы, поэтому в примере используются доллары США — одна из валют, которые он котирует. После аутентификации откройте https://beancount.io/prices/AAPL-USD и убедитесь, что видите стандартные директивы price. Затем добавьте эту строку в ваш размещённый реестр.

Если вы читаете на другом языке, используйте вместо этого обычную валюту этого языка, и только если каталог указывает её как котировку:

  • 中文: CNY, https://beancount.io/prices/AAPL-CNY. Этот URL — не заявленная пара. Это нескорректированная цена закрытия AAPL-USD от Databento, скрещённая с USD-CNY от ЕЦБ.
  • 日本語: JPY, https://beancount.io/prices/AAPL-JPY
  • 한국어: KRW, https://beancount.io/prices/AAPL-KRW
  • Deutsch, Français, Español, Italiano, Nederlands, Català, Português, Slovenčina и Български: EUR, https://beancount.io/prices/AAPL-EUR. Болгарские книги, открытые в этом году, ведутся в евро; каталог также котирует BGN, если более старый файл всё ещё использует её.
  • فارسی, Русский и Українська: в каталоге нет IRR, RUB или UAH, поэтому нет пары для открытия. Выберите котировку, которая в нём указана.

Каталог по адресу https://beancount.io/prices/ находится за тем же логином. Сам AAPL-USD — это прямая котировка Databento, а не кросс. Другие акции первого уровня работают так же — замените тикер, сохранив валюту котировки для вашего языка. ACME-USD возвращает 404.

Директива include в оригинальном Beancount технически ожидает имя файла, так что include с URL — это строго поведение размещённого движка. Он никогда не притворяется обычным Beancount. Вот что именно наш движок делает под капотом:

  • Он материализует фид как виртуальный файл, доступный только для чтения. URL разрешается через собственный путь разрешения include движка — попадая ровно туда, куда попал бы локальный файл, — так что каждая директива сохраняет реальное местоположение источника. Ваши исходные байты никогда не перезаписываются. Файл, который вы написали, остаётся файлом, который вы написали.
  • Строгая валидация полезной нагрузки. Полученное содержимое проверяется как только цены. Мы строго допускаем директивы price, комментарии и четыре конкретных ключа метаданных (price-source, price-kind, observed-at и provisional). Всё остальное отклоняет всё содержимое целиком. Частичного приёма нет, а значит, враждебный фид никогда не сможет протащить транзакцию в ваши книги.
  • Умное кэширование. Фиды кэшируются как неизменяемая ревизия с подвижным указателем. Циклы обновления управляются временными метками, а не истечением кэша, что гарантирует, что сбой у источника не уничтожит вашу последнюю хорошую ревизию.
  • Проверяемая свежесть. Свежесть вычисляется динамически при чтении реестра (свежая, устаревшая или недоступная) вместе с указанным фидом временем наблюдения. Цена, которую вы не можете датировать, — это цена, которую вы не можете проверить.
  • Строго только для чтения. Управляемые записи нельзя редактировать или удалять (попытка сделать это вызывает ошибку с указанием источника). Более того, они не расходуют ваш лимит директив — мы не позволяем фидам съедать бюджет вашего реестра.

Ничто из этого не меняет того, что ценовая директива фундаментально означает в Beancount. Единственная задача движка — предоставить загрузчику корректные, датированные и атрибутируемые цены.


Ваша собственная цена всегда побеждает​

Это решающий момент для всех, кто относится к своему реестру серьёзно, поэтому скажем предельно ясно:

Для одной и той же даты и одной и той же пары товаров (включая обратную), цена, написанная вами самим, всегда побеждает управляемый фид.

Не «обычно» и не «только если вы поставите include последним». Это решение о затенении принимается до построения карты цен, а значит, оно полностью независимо от того, где include находится в вашем файле. Поставьте его сверху, поставьте снизу или разбейте по трём файлам — ваша рукописная цена всегда побеждает.

Правило обратной пары легко упустить, но оно критично. Фид AAPL-USD — это цена AAPL в USD. Если вы вручную написали цену в обратную сторону — USD в AAPL, на ту же дату — ваша запись всё равно побеждает фид. То же самое верно для любой котировки, которую вы включили, будь то CNY или JPY.

Почему это правило? Потому что цена в вашем собственном файле — это осознанное решение. Это может быть точная цена закрытия, которую ваш брокер напечатал в выписке, с которой вы сверяетесь, котировка на момент времени для низколиквидного актива или конкретная цифра, которую потребовал ваш бухгалтер. Фид не знает вашего контекста. Система, которая молча переопределяет созданную человеком цифру, перестаёт быть реестром и становится мнением. Фид существует, чтобы заполнять пробелы; он не исправляет вас.


Цены меняют оценку, и ничего больше​

Это следующее заверение структурное, а не вопрос политики, и его лучше всего показать на реальных числах. Взгляните на наш пример реестра для криптовалют, включающий партии с датами, стейкинг, позиции DeFi и аирдропы:

Возьмём одну конкретную запись. Приходит аирдроп токена управления и записывается как доход по справедливой рыночной стоимости на день его поступления:

2024-03-20 * "Uniswap" "Receive UNI governance token airdrop"
  Assets:Crypto:Wallet:MetaMask:UNI       50.00 UNI {12.50 USD, 2024-03-20}
  Income:Crypto:Airdrops                -625.00 USD
 

Эти $625.00 дохода и база в $12.50 за единицу, привязанная к партии, теперь являются неизменными фактами о 2024-03-20. Любая ценовая директива в реестре — управляемая, рукописная или вовсе отсутствующая — оставляет и то, и другое нетронутым.

Цены меняют рыночную стоимость; они никогда не изменяют количества, базу затрат, денежные потоки, комиссии или реализованные прибыли. Именно поэтому ценовой фид — безопасный инструмент, на который можно опереться: самое худшее, что может сделать плохая цена, — это временно исказить, сколько позиция стоит сегодня. Она никогда не сможет испортить твёрдые числа, которые вы попадёте в налоговую декларацию.


Где неверная модель цен действительно вводит в заблуждение​

Пример реестра для акций и ETF иллюстрирует более резкую версию этого же тезиса:

Он содержит дробление акций 4 к 1, записанное правильным способом — как изменение количества, сохраняющее общую базу без затрагивания каких-либо счетов дохода:

2025-07-15 * "Broker" "NWRB 4-for-1 share split — quantity change, not income"
  Assets:Brokerage:NWRB                   -120 NWRB {41.80 USD, 2024-03-12}
  Assets:Brokerage:NWRB                    480 NWRB {10.45 USD, 2024-03-12}
 

Обе стороны равны $5,016.00. Рыночная стоимость остаётся неизменной после дробления ($7,440.00 в любом случае), а дата приобретения в фигурных скобках сохраняется — именно это поддерживает классификацию продажи этих акций в 2026 году как долгосрочной.

Распространённая ловушка — записать дробление как ценовое событие, сильно полагаясь на «скорректированный на дробление» ряд цен, чтобы математика сошлась. Это работает лишь до тех пор, пока каждая цена, на которую вы когда-либо смотрите, скорректирована точно так же. В тот момент, когда в ваш реестр попадает нескорректированная цифра — старое подтверждение, скриншот или сторонний фид, который не пересчитывает исторические данные, — позиция внезапно оценивается вчетверо дороже её реальной стоимости. Хуже того, количество акций в реестре больше не совпадает с выпиской вашего брокера, а значит, ваши проверки баланса на конец года тихо провалятся.

Это и есть настоящий аргумент в пользу опоры на ценовой фид с заявленным источником, заявленным видом и видимым временем наблюдения. Речь не просто об удобстве; речь о том, чтобы точно знать, какую математическую конвенцию используют ваши импортированные числа.

(Небольшое замечание о встроенных просмотрщиках: размещённый просмотрщик реестра отображает остатки счетов по стоимости и пока не предлагает элементов управления оценкой на странице. Приведённые выше реестры призваны показать лежащую в основе механику — партии, дробление, продажи. Оба публичны, и вы можете клонировать и запустить их локально.)


Чего здесь пока нет​

Мы считаем, что список изменений хуже бесполезен, если он обещает слишком много. Поэтому вот неприкрашенная правда о том, что мы ещё не построили, без привязки к срокам:

  • Аутентификация обязательна. Анонимные запросы к https://beancount.io/prices/<ALIAS> перенаправят вас на страницу входа.
  • Нет поддержки в локальном CLI. Локальный CLI bea читает файлы с диска, а значит, include с URL локально не сработает как несопоставленный файловый шаблон. Добавление поддержки загрузчика в CLI — в нашем плане.
  • Нет API-поверхности. У нас сейчас нет ни REST, ни GraphQL, ни поля MCP для управляемых цен.
  • Нет UI-дашборда. Пока нет ни экрана «подключить фид», ни меток свежести в интерфейсе. (Данным о свежести, которые вычисляет наш движок, сейчас просто негде отображаться.)
  • Нет снимков, экспортов или эндпоинтов ручного обновления.

То, что мы выпустили сегодня, — строго уровень движка: разрешение include, валидация, кэширование ревизий, правила приоритета и вычисление свежести. Это базовая инфраструктура, на которой должно стоять всё остальное, — именно поэтому мы построили её первой.


Куда смотреть дальше​

Оба реестра, встроенных выше, — часть нашей галереи примеров: шесть полностью проработанных шаблонов, которые вы можете клонировать и запустить локально. (Оба намеренно поставляются со статичными, закоммиченными файлами цен, гарантируя, что клон, сделанный через два года, выдаст точно такой же отчёт, как сегодня.) Всё остальное, что мы выпускаем, появляется прямо в нашем списке изменений.

Если вам вполне комфортно поддерживать цены в актуальном состоянии собственным загрузчиком, оставайтесь с ним. Это по-прежнему лучший ответ для строго локального реестра. Собственная документация Beancount по получению цен и поддерживаемый инструмент beanprice — лучшие места для начала.

Пусть скучная часть остаётся скучной​

Цены стоит автоматизировать именно потому, что это единственная часть реестра на основе простого текста, которая со временем портится. Beancount.io создан, чтобы дать вам учёт на основе простого текста, который остаётся вашим — проверяемым, под контролем версий и никогда не переписываемым за вашей спиной. Это был базовый стандарт, которому должен был соответствовать управляемый фид, прежде чем мы согласились его выпустить.

Начните бесплатно и храните свои книги в файлах, которые вы действительно можете прочитать.

Источник: https://beancount.io/ru/blog/2026/09/17/managed-price-includes-hosted-ledgers

Опубликовано: 17 сентября 2026 г.

Обновлено: 19 сентября 2026 г.