Riadenie numerickej presnosti je základom podvojného účtovníctva. V digitálnom účtovníctve, najmä pri práci s viacerými menami, cenami akcií a zlomkovými podielmi, môžu malé rozdiely zo zaokrúhľovania rýchlo viesť k frustrujúcim chybám pri vyrovnávaní. Beancount poskytuje sofistikovaný, ale intuitívny systém na spracovanie presnosti a nastavenie prijateľných tolerancií. Tento sprievodca vás prevedie tým, ako funguje. ⚙️
Každé číslo na tejto stránke bolo overené proti Beancount 3.2.3, vrátane hraničných hodnôt: každý príklad uvádza, ktorý zvyšok je akceptovaný a ktorý je o jednu číslicu príliš ďaleko.
Základné koncepty presnosti
Primárnym cieľom Beancount je zabezpečiť, aby každá transakcia bola vyrovnaná na nulu. Avšak výpočty zahŕňajúce ceny alebo náklady často produkujú výsledky s väčším počtom desatinných miest, než je praktické zaznamenať. Systém tolerancií umožňuje malé, prijateľné nevyrovnanosti.
Automatická inferencia tolerancií
Beancount štandardne odvodzuje požadovanú toleranciu pre každú transakciu automaticky. Táto inferencia sa vykonáva individuálne pre každú transakciu a vypočítava sa samostatne pre každú zúčastnenú menu.
Pravidlo je jedno násobenie: tolerancia pre menu je najmenšia číslica videná v sumách položiek tejto meny, vynásobená možnosťou tolerance_multiplier, ktorá je štandardne 0.5. Pri tomto štandarde je tolerancia polovica poslednej významnej číslice.
Napríklad, zvážte tento nákup:
2013-04-03 * "Buy Fund"
Assets:Fund 10.22626 FUND {37.61 USD}
Assets:Cash -384.61 USDBeancount odvodí tolerancie takto:
- Pre komoditu
FUND, číslo10.22626má 5 desatinných miest. Tolerancia je polovica poslednej číslice, takže $0.00001 \div 2 = 0.000005$FUND. - Pre menu
USD, číslo-384.61má 2 desatinné miesta. Tolerancia je polovica poslednej číslice, takže $0.01 \div 2 = 0.005$USD.
Hotovostná časť je to, proti čomu sa tolerancia meria: 10.22626 × 37.61 je 384.6096386, takže táto transakcia je 0.0003614 USD od nuly a načíta sa. Zaokrúhlite hotovostnú časť na -384.60 a rozdiel sa stane 0.0096386 USD, čo presahuje toleranciu 0.005, a Beancount hlási Transaction does not balance.
Pravidlá pre váhu transakcie
Pri kontrole, či je transakcia vyrovnaná, Beancount vypočítava "váhu" každej položky. Pravidlá pre tento výpočet sú:
- Jednoduchá suma: Ak má položka iba sumu (napr.
Assets:Cash -100.00 USD), jej váha je presne táto suma. - Položka s cenou: Ak má položka cenu za jednotku (napr.
10 FUND @ 38.46 USD), jej váha jeamount × price. - Náklad za jednotku: Jednoduché zložené zátvorky držia náklad jednej jednotky, takže
10 FUND {384.61 USD}váži10 × 384.61 = 3,846.10 USD, nie384.61 USD. - Celkový náklad: Dvojité zložené zátvorky držia náklad celej položky, takže
10 FUND {{384.61 USD}}váži384.61 USD. Beancount to prevedie na náklad za jednotku38.461 USD, keď ukladá dávku. - Náklad a cena: Ak má položka aj náklad, aj cenu za jednotku (napr.
10 FUND {384.61 USD} @ 400.00 USD), iba náklad sa použije na vyrovnanie. Cena sa zaznamenáva pre výkazníctvo, nie pre aritmetiku.
Pravidlá 3 a 4 sú tie, ktoré ľuďom zaberú popoludnie, takže tu sú vedľa seba v súbore, ktorý sa načíta:
1970-01-01 open Assets:Fund
1970-01-01 open Assets:Cash
; Per-unit cost: ten units at 384.61 each, so 3,846.10 USD leaves the
; cash account.
2013-04-03 * "Broker" "Buy at a per-unit cost"
Assets:Fund 10 FUND {384.61 USD}
Assets:Cash -3846.10 USD
; Total cost: the braces double and 384.61 USD is the entire purchase.
; The lot is stored at 38.461 USD per unit.
2013-04-04 * "Broker" "Buy at a total cost"
Assets:Fund 10 FUND {{384.61 USD}}
Assets:Cash -384.61 USDÚčet končí s 20 FUND v dvoch dávkach, s 4,230.71 USD nákladovej základne medzi nimi.
Pravidlá inferencie presnosti
Automatický inferenčný systém sa riadi niekoľkými konkrétnymi pravidlami:
- Formát čísla
- Celé sumy (napr.
10 USD) neprispievajú k inferencii presnosti. - Jedno desatinné miesto je najhrubšie, čo suma môže naznačovať:
0.1 × 0.5 = 0.05jednotiek. Nad to potrebujetetolerance_multiplieralebo predvolenú hodnotu pre menu, oboje nižšie. - Náklady a ceny (napr.
{37.61 USD}) sú vylúčené z inferencie tolerancií štandardne. Používajú sa iba primárne sumy položiek. - Ak majú položky pre rovnakú menu rôznu presnosť (napr.
-10.10 USDa5.123 USD), Beancount použije najhrubšiu (najväčšiu) toleranciu. V tomto prípade by bola založená na-10.10 USD, čo dáva toleranciu $0.005$USD.
-
Predvolené spracovanie Môžete nastaviť globálnu alebo pre menu špecifickú predvolenú toleranciu, ak transakcia nemá žiadne čísla s desatinnými miestami, z ktorých by sa dala odvodiť.
; Sets a default tolerance for all currencies without explicit rules option "inferred_tolerance_default" "*:0.001" ; Sets a specific default tolerance for USD option "inferred_tolerance_default" "USD:0.003" -
Multiplikátor tolerancie Možnosť je
tolerance_multipliera je to zlomok najmenšej číslice, ktorý sa považuje za tolerovateľný — nie percento pridané navrch. Jeho predvolená hodnota je0.5, takže nastavenie1.2neuvoľní kontroly o 20%: spôsobí, že každá odvodená tolerancia bude 2.4-krát väčšia ako predvolená.option "tolerance_multiplier" "1.2" 1970-01-01 open Assets:Cash 1970-01-01 open Expenses:Fees ; The coarsest amount has two decimals, so the tolerance is ; 1.2 x 0.01 = 0.012 USD, and this residual of exactly 0.012 passes. ; At the default 0.5 the tolerance would be 0.005 and this would fail. 2024-05-01 * "Bank" "Wire fee" Expenses:Fees 100.00 USD Assets:Cash -99.988 USDStarší názov
inferred_tolerance_multipliernastavuje rovnakú hodnotu, ale hlásiRenamed to 'tolerance_multiplier'.ako chybu načítania. -
Inferencia založená na nákladoch Zatiaľ čo náklady sú normálne ignorované pre inferenciu tolerancií, môžete Beancount inštruovať, aby ich použil. To je užitočné, keď je konečná suma (napr. výber hotovosti) najpresnejším číslom v transakcii.
option "infer_tolerance_from_cost" "TRUE"
Tu je obyčajná predvolená hodnota, bez akýchkoľvek možností, na jej presnej hranici:
1970-01-01 open Assets:Cash
1970-01-01 open Expenses:Fees
; Two decimals on the coarsest amount, so the tolerance is
; 0.5 x 0.01 = 0.005 USD. This residual is exactly 0.005 and passes;
; -99.994 would be 0.006 and would fail.
2024-05-01 * "Bank" "Wire fee"
Expenses:Fees 100.00 USD
Assets:Cash -99.995 USDKontroly zostatkov
Kontroly zostatkov (balance) sa používajú na overenie, že zostatok vášho účtu zodpovedá známej hodnote k určitému dátumu. Majú tiež súvisiacu toleranciu.
Základný formát
Tolerancia pre kontrolu balance sa odvodzuje z počtu desatinných miest v sume, ale je dvakrát veľkorysejšia ako tá použitá v transakcii: tolerance_multiplier × 2 × the smallest digit. Pri predvolenom multiplikátore je to presne jedna jednotka posledného desatinného miesta, ktoré ste napísali.
; Asserts the balance is 4.271 RGAGX with a tolerance of +/-0.001
2015-05-08 balance Assets:Fund 4.271 RGAGX
; Asserts the balance is 4.27 RGAGX with a tolerance of +/-0.01
2015-05-08 balance Assets:Fund 4.27 RGAGXPorovnanie je inkluzívne: rozdiel presne rovný tolerancii stále prejde. Pre druhý príklad, akýkoľvek zostatok od $4.26$ do $4.28$ prejde kontrolou a 4.2801 zlyhá s Balance failed for 'Assets:Fund': expected 4.27 RGAGX != accumulated 4.2801 RGAGX (0.0101 too much).
1970-01-01 open Assets:Fund
1970-01-01 open Equity:Opening-Balances
1970-01-02 * "Broker" "Opening position"
Assets:Fund 4.28 RGAGX
Equity:Opening-Balances -4.28 RGAGX
; 4.28 is 0.01 away from the asserted 4.27, which is the whole tolerance.
2015-05-08 balance Assets:Fund 4.27 RGAGXExplicitné tolerancie
Ak odvodená tolerancia nie je vhodná, môžete explicitne zadať jednu pomocou znaku tilda (~). Toto je jediná syntax explicitnej tolerancie, ktorú Beancount má, a funguje iba na direktívach balance — tilda v rámci transakčnej položky je syntaktická chyba.
1970-01-01 open Assets:Fund
1970-01-01 open Equity:Opening-Balances
1970-01-02 * "Broker" "Opening position"
Assets:Fund 4.281 RGAGX
Equity:Opening-Balances -4.281 RGAGX
; Asserts the balance is 4.271 RGAGX with a custom tolerance of
; +/-0.01 RGAGX, so anything from 4.261 to 4.281 passes.
2015-05-08 balance Assets:Fund 4.271 ~ 0.01 RGAGXPosuňte držbu na 4.2811 a rovnaká kontrola zlyhá o 0.0101.
Riadenie zaokrúhľovania
Malé zvyšky z aritmetiky nákladov a cien sú normálne. To, čo s nimi Beancount robí, je užšie, než sa zdá.
Sledovanie chýb zaokrúhľovania
Možnosť account_rounding pomenúva účet určený na absorbovanie zvyškov. Vyžaduje úplný názov účtu a ukladá sa presne tak, ako ho napíšete — nepridáva sa žiadna predpona equity, na rozdiel od možností účtov equity.
option "account_rounding" "Equity:Rounding"
1970-01-01 open Assets:Invest
1970-01-01 open Assets:Cash
1970-01-01 open Equity:Rounding
; 1.245 x 43.23 = 53.82135, so this is 0.00135 USD short of balancing.
2013-02-23 * "Broker" "Purchase"
Assets:Invest 1.245 RGAGX {43.23 USD}
Assets:Cash -53.82 USDV tejto transakcii, $1.245 \times 43.23 = 53.82135$. Transakcia je nevyrovnaná o $-0.00135$ USD, čo je v rámci odvodenej tolerancie 0.005 USD, takže sa načíta.
Na Beancount 3.2.3 sa nič neúčtuje na Equity:Rounding. Možnosť sa analyzuje a uloží, ale žiadna fáza načítača nevkladá zvyškovú položku, takže účet končí na nule a zvyšok, ktorý je mimo tolerancie, je stále chybou, nie je zachytený:
option "account_rounding" "Equity:Rounding"
1970-01-01 open Assets:Invest
1970-01-01 open Assets:Cash
1970-01-01 open Equity:Rounding
; 0.10135 USD out, far past the 0.005 tolerance. Setting
; account_rounding does not rescue it:
; Transaction does not balance: (0.10135 USD)
2013-02-23 * "Broker" "Purchase"
Assets:Invest 1.245 RGAGX {43.23 USD}
Assets:Cash -53.72 USDTakže považujte account_rounding za neaktívny na tejto verzii. Ak chcete, aby bol zvyšok zaznamenaný, nie tolerovaný, napíšte tretiu položku sami:
1970-01-01 open Assets:Invest
1970-01-01 open Assets:Cash
1970-01-01 open Equity:Rounding
2013-02-23 * "Broker" "Purchase"
Assets:Invest 1.245 RGAGX {43.23 USD}
Assets:Cash -53.82 USD
Equity:Rounding -0.00135 USDTáto verzia sa vyrovná presne na nulu a prach je viditeľný v účte, o ktorom môžete podávať správy.
Odvodená presnosť čísel
Beancount nezaokrúhľuje čísla, ktoré píšete. Neexistuje žiadna možnosť default_tolerance — neexistuje a zlyhá načítanie s Invalid option: 'default_tolerance' — a žiadne nastavenie nekvantizuje uložené sumy.
-
Ukladanie je vždy presné. Napíšte
53.82135 USDa účtovná kniha drží53.82135 USD, nech už vaše nastavenia tolerancií hovoria čokoľvek. Tolerancia rozhoduje, či je transakcia prijatá; nikdy neupravuje číslo. -
Zobrazenie je samostatné nastavenie.
display_precisionurčuje, s koľkými zlomkovými číslicami sa mena zobrazuje, a nič nemení na uloženej hodnote ani na kontrole zostatku.option "display_precision" "USD:0.01" 1970-01-01 open Assets:Cash 1970-01-01 open Income:Interest ; Rendered as 53.82 USD, stored as 53.82135 USD. 2024-06-30 * "Bank" "Interest" Assets:Cash 53.82135 USD Income:Interest -53.82135 USD -
Zaokrúhľovanie je vaša položka, ktorú treba napísať. Ak chcete zvyšok von z aritmetiky, zaokrúhlite sumu v zdroji a zaúčtujte rozdiel explicitne, ako v príklade s tromi položkami vyššie.
Detaily implementácie
Niekoľko technických bodov objasňuje, ako Beancount dosahuje túto spoľahlivosť.
-
Reprezentácia čísel: Beancount používa Python modul
decimal, nie čísla s pohyblivou rádovou čiarkou. Predvolený kontext nesie 28 významných číslic — celkových číslic, nie číslic za desatinnou čiarkou — čo sa vyhýba chybám binárnej reprezentácie bežným pri floatoch. -
Trieda DisplayContext: Táto interná trieda spracováva všetko formátovanie čísel na účely zobrazenia. Odvodzuje presnosť každej meny z čísel vo vašom súbore, pokiaľ
display_precisionju nepripne, a môže formátovať výstup so zarovnanými stĺpcami a čiarkami. -
Presnosť vs. tolerancia: Je kľúčové rozlišovať tieto dva koncepty:
- Presnosť sa vzťahuje na formát zobrazenia čísla (koľko desatinných miest sa zobrazuje).
- Tolerancia je povolená odchýlka od rovnováhy používaná počas kontrol overovania.
Najlepšie postupy ✨
Tu je niekoľko praktických odporúčaní na riadenie presnosti vo vašej účtovnej knihe.
Počiatočné nastavenie
Pre väčšinu nových účtovných kníh je toto robustná počiatočná konfigurácia:
; A floor for currencies that have no decimals to infer from
option "inferred_tolerance_default" "*:0.005"
; Leave the multiplier at its 0.5 default unless a real institution
; forces your hand; 1.2 would mean 2.4x the usual tolerance.
option "tolerance_multiplier" "0.5"Tipy na riešenie problémov
Ak narazíte na chyby vyrovnania:
- Pridajte desatinné číslice do sumy položky, aby ste vytvorili užšiu, presnejšiu lokálnu inferenciu tolerancie.
- Použite explicitné tolerancie (
~) na kontroláchbalance, ktoré zlyhávajú kvôli predvídateľným rozdielom. - Zaúčtujte zvyšok na vyhradený účet so skutočnou treťou položkou, aby ste mohli podávať správy o tom, ako často sa to stáva.
- Zvážte nastavenie predvolených hodnôt pre konkrétne meny, ak často pracujete s menami, ktoré majú rôzne konvencie (napr. JPY nemá desatinné miesta).
Migračná stratégia
Pri aplikovaní týchto konceptov na existujúcu, neprehľadnú účtovnú knihu:
- Začnite s veľkorysou globálnou toleranciou (napr.
*:0.05) a vyššímtolerance_multiplier, aby sa súbor validoval. - Postupne sprísňujte tolerancie a opravujte chyby, ktoré sa objavia.
- Pridajte explicitné číslice do súm v problematických transakciách, aby inferencia mohla robiť svoju prácu.
- Sledujte zostatok účtu zaokrúhľovania. Veľký alebo rýchlo rastúci zostatok môže signalizovať systémový problém, ktorý si vyžaduje vyšetrenie.