Да си го кажем направо: притежанията ви вече са перфектно записани в регистъра. Именно цените ви държат в цикъл на безкрайно преписване.
Тази асиметрия е най-старата и най-досадната задача в счетоводството с чист текст. Записвате покупка веднъж и тя остава завинаги в камък: 120 NWRB {41.80 USD, 2024-03-12} заковава за постоянно количество, разход и дата. Нищо, което се случи след това, не променя тези факти. Цената обаче е точно обратното — тя е вярна точно за един ден и после тихо става грешна. Още по-лошо: грешна е по начин, който никоя проверка на баланса никога няма да улови, защото регистър с остарели цени все още се балансира перфектно.
Исторически подходът в Beancount за справяне с това беше да се изтеглят цени със скрипт и резултатът да се комитне. Работи и много хора са го автоматизирали. Но в крайна сметка това си остава скрипт, който трябва да гледате, cron задача, която поддържате, и файл, който постоянно merge-вате.
Край на това. За регистри, хоствани на beancount.io, нашият двигател вече се справя с това разрешаване нативно. Този пост описва точно какво току-що пуснахме, какво умишлено не пипнахме и — също толкова важно — какво още не сме изградили.
Какво пуснахме
Хостван регистър в beancount.io вече може да съдържа директива include, която сочи към URL вместо към локално име на файл:
; main.bean, in a hosted beancount.io ledger.
;
; This page is Bulgarian, so the quote currency is EUR. On another language of
; this site, use the currency in the list under the fence.
option "title" "Taxable brokerage"
option "operating_currency" "EUR"
; 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-EUR"Внимание: Ще трябва да влезете в профила си, преди да отворите този URL. Анонимните заявки се пренасочват към страницата за вход. Тази страница е на български, затова примерът използва евро — валутата, в която читателите тук най-често водят книгите си. След като се автентикирате, отворете https://beancount.io/prices/AAPL-EUR и потвърдете, че виждате стандартни директиви price. След това добавете този ред към хоствания си регистър.
Ако четете на друг език, използвайте обичайната валута за този език и само когато каталогът я посочва като котировка:
- English:
USD, https://beancount.io/prices/AAPL-USD - 中文:
CNY, https://beancount.io/prices/AAPL-CNY. Този URL не е посочена двойка. Това е некоригираното затваряне на Databento заAAPL-USD, кроснато с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 в upstream Beancount технически очаква име на файл, така че включването на 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 г. класифицирана като дългосрочна.
Честата капан е да запишете сплит като ценово събитие вместо това, разчитайки силно на „коригирана за сплит“ ценова серия, за да излязат сметките. Това работи само докато всяка цена, която някога погледнете, е коригирана по абсолютно същия начин. В момента, в който в регистъра ви попадне некоригирана цифра — стар потвърдителен документ, екранна снимка или канал от трета страна, който не преизчислява историческите данни — позицията изведнъж се оценява на четири пъти реалната ѝ стойност. Още по-лошо: броят акции в регистъра вече не съвпада с извлечението на брокера ви, което означава, че проверките на баланса в края на годината тихо ще се провалят.
Това е истинският аргумент в полза на разчитането на канал за цени с деклариран източник, деклариран вид и видимо време за наблюдение. Не става дума само за удобство; става дума за това да знаете точно каква математическа конвенция използват внесените ви числа.
(Кратка бележка за вградените елементи: хостваният преглед на регистъра изобразява салдата по сметките по разход и в момента не предлага контроли за оценка на страницата. Регистрите по-горе имат за цел да покажат лежащата в основата механика — партидите, сплита, продажбите. И двата са публични и можете да ги клонирате и стартирате локално.)
Какво още не е тук
Вярваме, че един changelog е по-лош от безполезен, ако дава прекалено големи обещания. Затова ето нечупената истина за това какво още не сме изградили, без прикачени срокове:
- Автентикацията е задължителна. Анонимните заявки към
https://beancount.io/prices/<ALIAS>ще ви препратят към страница за вход. - Няма локална CLI поддръжка. Локалният CLI
beaчете файлове от диска, което означава, че include на URL ще се провали локално като несъвпадащ файлов шаблон. Добавянето на поддръжка на зареждане в CLI е в плана ни. - Няма API повърхност. В момента нямаме REST, GraphQL или MCP поле за управлявани цени.
- Няма UI табло. Все още няма екран „свържи канал“ и няма етикет за свежест в UI. (Данните за свежест, които нашият двигател изчислява, в момента няма къде да бъдат показани).
- Няма snapshot-и, експорти или крайни точки за ръчно опресняване.
Това, което пуснахме днес, е строго слоят на двигателя: разрешаване на include, валидация, кеширане на ревизии, правила за приоритет и изчисляване на свежест. Това е основополагащата инфраструктура, върху която всичко останало трябва да стъпи, което е точно причината да я изградим първо.
Къде да погледнете след това
И двата регистъра, вградени по-горе, са част от нашата галерия с примери — шест напълно разработени модела, които можете да клонирате и стартирате локално. (И двата умишлено се доставят със статични, вписани във версията файлове с цени, което гарантира, че клонинг, направен две години по-късно, ще произведе точно същия отчет като днес). Всичко останало, което пускаме, се появява директно в нашия changelog.
Ако сте напълно доволни да поддържате цените актуални със собствен изтеглящ механизъм, продължете с него. Той остава най-добрият отговор за строго локален регистър. Собствената документация за изтегляне на цени на Beancount и поддържаният инструмент beanprice са най-добрите места за начало.
Пазете скучната част скучна
Цените си заслужават автоматизирането именно защото са единствената част от регистъра с чист текст, която се разваля с времето. Beancount.io е изграден да ви даде счетоводство с чист текст, което остава ваше — одитируемо, контролирано с версии и никога пренаписано зад гърба ви. Това беше базовият стандарт, който един управляван канал трябваше да покрие, преди да бяхме готови да го пуснем.
Започнете безплатно и пазете книгите си във файлове, които наистина можете да четете.





