Погодьмося: ваші активи вже бездоганно зафіксовані у вашому реєстрі. Саме ціни тримають вас у циклі нескінченного повторного введення.
Ця асиметрія — найстаріша й найдратівливіша рутина в текстовому бухгалтерському обліку. Ви записуєте покупку один раз, і вона назавжди викарбувана в камені: 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 технічно очікує ім'я файлу, тож включення URL-адреси — це строго поведінка керованого рушія. Він ніколи не вдає, що є звичайним Beancount. Ось що саме наш рушій робить під капотом:
- Він матеріалізує потік як віртуальний файл, доступний лише для читання. URL-адреса розпізнається через власний шлях розпізнавання включень рушія — потрапляючи саме туди, куди потрапив би локальний файл — тож кожна директива зберігає справжнє розташування джерела. Ваші оригінальні байти ніколи не переписуються. Файл, який ви написали, залишається тим файлом, який ви написали.
- Сувора перевірка вмісту. Отриманий вміст перевіряється як лише ціна. Ми строго дозволяємо директиви
price, коментарі та чотири конкретні ключі метаданих (price-source,price-kind,observed-atіprovisional). Будь-що інше відхиляє весь вміст. Часткового прийому немає, тож шкідливий потік ніколи не зможе пронести транзакцію у ваші книги. - Розумне кешування. Потоки кешуються як незмінна ревізія з рухомим покажчиком. Цикли оновлення керуються мітками часу, а не закінченням терміну дії кешу, що гарантує, що збій на боці джерела не знищить останню справну ревізію.
- Аудитована свіжість. Свіжість обчислюється динамічно під час читання реєстру (свіжа, застаріла чи недоступна) разом із заявленим часом спостереження потоку. Ціна, яку ви не можете датувати, — це ціна, яку ви не можете аудитувати.
- Строго лише для читання. Керовані записи не можна редагувати чи видаляти (спроба зробити це викликає помилку із зазначенням джерела). Більше того, вони не зараховуються до ваших лімітів директив — ми не дозволяємо потокам з'їдати бюджет вашого реєстру.
Ніщо з цього не змінює того, що директива ціни принципово означає в Beancount. Єдина робота рушія — поставити перед завантажувачем правильні, датовані та атрибутовані ціни.
Ваша власна ціна завжди перемагає
Це вирішальний момент для кожного, хто ставиться до свого реєстру серйозно, тож скажімо цілком ясно:
Для тієї самої дати й тієї самої пари товарів (включно з її оберненою), ціна, яку ви написали самостійно, завжди перемагає над керованим потоком.
Не «зазвичай» і не «лише якщо ви розмістите своє включення останнім». Це рішення про затінення ухвалюється до побудови карти цін, що означає, що воно повністю незалежне від того, де 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читає файли з диска, тож включення URL-адреси локально не спрацює як невідповідний glob файлів. Додавання підтримки завантажувача до CLI — у нашому плані. - Немає API. Наразі ми не маємо REST, GraphQL чи MCP-поля для керованих цін.
- Немає панелі інтерфейсу. Ще немає екрана «підключити потік» і жодної позначки свіжості в інтерфейсі. (Даним про свіжість, які обчислює наш рушій, наразі ніде відображатися).
- Немає знімків, експортів чи кінцевих точок ручного оновлення.
Те, що ми випустили сьогодні, — це строго рівень рушія: розпізнавання включень, перевірка, кешування ревізій, правила пріоритету та обчислення свіжості. Це фундаментальна інфраструктура, на якій має стояти все інше, і саме тому ми створили її першою.
Куди дивитися далі
Обидва реєстри, вбудовані вище, є частиною нашої галереї прикладів — шість повністю опрацьованих шаблонів, які ви можете клонувати та запускати локально. (Обидва навмисно постачаються зі статичними, закоміченими файлами цін, що гарантує, що клон, зроблений через два роки, видасть точно такий самий звіт, як і сьогодні). Усе інше, що ми випускаємо, потрапляє безпосередньо до нашого журналу змін.
Якщо ви цілком задоволені тим, що підтримуєте актуальність цін власним завантажувачем, — продовжуйте. Це залишається найкращою відповіддю для строго локального реєстру. Власна документація Beancount щодо отримання цін та підтримуваний інструмент beanprice — найкращі місця, щоб почати.
Залиште нудну частину нудною
Ціни варто автоматизувати саме тому, що вони — єдина частина текстового реєстру, яка з часом псується. Beancount.io створений, щоб дати вам текстовий бухгалтерський облік, який залишається вашим — аудитованим, під контролем версій і ніколи не переписаним за вашою спиною. Це був базовий стандарт, якому мав відповідати керований потік, перш ніж ми погодилися його випустити.
Почніть безкоштовно й тримайте свої книги у файлах, які ви справді можете читати.





