Перейти до основного вмісту
Beancount.io LogoBeancount.io
Точність та Допуски

Точність та Допуски

Дізнайтеся, як системи точності та допусків Beancount допомагають підтримувати баланс у подвійній бухгалтерії, особливо під час роботи зі складними транзакціями, що включають кілька валют та дробові значення.

Управління числовою точністю є наріжним каменем подвійної бухгалтерії. У цифровому бухгалтерському обліку, особливо під час роботи з кількома валютами, цінами акцій та дробовими частками, невеликі розбіжності округлення можуть швидко призвести до неприємних помилок балансування. Beancount пропонує складну, але інтуїтивно зрозумілу систему для обробки точності та встановлення прийнятних допусків. Цей посібник проведе вас через те, як це працює. ⚙️

Основні концепції точності

Головна мета Beancount — забезпечити, щоб кожна транзакція зводилася до нуля. Однак обчислення, що включають ціни або витрати, часто дають результати з більшою кількістю десяткових знаків, ніж практично записати. Система допусків дозволяє невеликі прийнятні дисбаланси.

Автоматичне визначення допуску

За замовчуванням Beancount автоматично визначає необхідний допуск для кожної транзакції. Це визначення виконується індивідуально для кожної транзакції та розраховується окремо для кожної залученої валюти.

Правило просте: допуск дорівнює половині останньої значущої цифри чисел, присутніх у проводках транзакції.

Наприклад, розглянемо цю покупку:

2013-04-03 * "Купівля фонду"
  Assets:Fund     10.22626 FUND {37.61 USD}
  Assets:Cash     -384.61 USD

Beancount визначає допуски наступним чином:

  • Для товару FUND число 10.22626 має 5 знаків після коми. Допуск дорівнює половині останньої цифри, тобто $0.00001 \div 2 = 0.000005$ FUND.
  • Для товару USD число -384.61 має 2 знаки після коми. Допуск дорівнює половині останньої цифри, тобто $0.01 \div 2 = 0.005$ USD.

Правила ваги транзакції

Перевіряючи, чи балансує транзакція, Beancount розраховує "вагу" кожної проводки. Правила для цього розрахунку:

  1. Проста сума: Якщо проводка має лише суму (наприклад, Assets:Cash -100.00 USD), її вага дорівнює цій точній сумі.
  2. Проводка з ціною: Якщо проводка має ціну за одиницю (наприклад, 10 FUND @ 38.46 USD), її вага дорівнює сума × ціна.
  3. Проводка з вартістю: Якщо проводка має загальну вартість (наприклад, 10 FUND {384.61 USD}), її вага дорівнює сумі загальної вартості.
  4. Вартість і ціна: Якщо проводка має як загальну вартість, так і ціну за одиницю (наприклад, 10 FUND {384.61 USD} @ 38.46 USD), для балансування використовується лише загальна вартість. Ціна за одиницю розглядається як коментар або нотатка.

Правила визначення точності

Система автоматичного визначення дотримується кількох конкретних правил:

  1. Формат числа
  • Цілі суми (наприклад, 10 USD) не впливають на визначення точності.
  • Максимальний допуск, який можна автоматично визначити, становить 0.05 одиниць (наприклад, з числа 10.1 USD). Якщо вам потрібен більший допуск, ви повинні вказати його вручну.
  • Вартість і ціни (наприклад, {37.61 USD}) виключаються з визначення допуску. Використовуються лише основні суми проводок.
  • Якщо проводки для однієї валюти мають різну точність (наприклад, -10.10 USD і 5.123 USD), Beancount використовує найгрубіший (найбільший) допуск. У цьому випадку він базуватиметься на -10.10 USD, даючи допуск $0.005$ USD.
  1. Обробка за замовчуванням Ви можете встановити глобальний допуск за замовчуванням або за валютою, якщо транзакція не має чисел з десятковими знаками, з яких можна його визначити.

    ; Встановлює допуск за замовчуванням для всіх валют без явних правил
    option "inferred_tolerance_default" "*:0.001"
     
    ; Встановлює конкретний допуск за замовчуванням для USD
    option "inferred_tolerance_default" "USD:0.003"
  2. Множник допуску Ви можете глобально збільшити всі визначені допуски на фіксований множник. Це корисно для послаблення перевірок у всьому файлі без зміни кожної транзакції. Множник 1.2 збільшує всі визначені допуски на 20%.

    option "inferred_tolerance_multiplier" "1.2"
  3. Визначення на основі вартості Хоча вартість зазвичай ігнорується для визначення допуску, ви можете вказати Beancount використовувати її. Це корисно, коли кінцева сума (наприклад, зняття готівки) є найточнішим числом у транзакції.

    option "infer_tolerance_from_cost" "TRUE"

Балансові підтвердження

Балансові підтвердження (balance) використовуються для перевірки того, що баланс вашого рахунку відповідає відомому значенню на певну дату. Вони також мають пов'язаний допуск.

Базовий формат

Подібно до транзакцій, допуск для підтвердження balance визначається з кількості десяткових знаків у сумі.

; Підтверджує, що баланс дорівнює 4.271 RGAGX з допуском ±0.0005
2015-05-08 balance Assets:Fund  4.271 RGAGX
 
; Підтверджує, що баланс дорівнює 4.27 RGAGX з допуском ±0.005
2015-05-08 balance Assets:Fund  4.27 RGAGX

Розрахований баланс повинен потрапляти в цей діапазон. Для другого прикладу будь-який баланс між 4.2654.265 і 4.2754.275 пройде перевірку.

Явні допуски

Якщо визначений допуск не підходить, ви можете вказати його явно за допомогою символу тильди (~).

; Підтверджує, що баланс дорівнює 4.271 RGAGX з власним допуском ±0.01 RGAGX
2015-05-08 balance Assets:Fund  4.271 ~ 0.01 RGAGX

Тут підтвердження буде пройдено, якщо розрахований баланс буде між 4.2614.261 та 4.2814.281 RGAGX.

Управління округленням

Для випадків, коли невеликі залишки від обчислень є очікуваними та прийнятними, Beancount надає інструменти для систематичного управління ними.

Відстеження помилок округлення

Ви можете призначити спеціальний рахунок для автоматичного збору помилок округлення. Це підтримує ваші транзакції ідеально збалансованими, збираючи крихітні залишкові суми в одне місце.

Спочатку увімкніть опцію та відкрийте рахунок:

option "account_rounding" "Equity:RoundingError"
2000-01-01 open Equity:RoundingError

Тепер Beancount автоматично додаватиме третю ногу до будь-якої транзакції, яка не балансує в межах свого допуску, розміщуючи різницю на Equity:RoundingError.

2013-02-23 * "Покупка"
  Assets:Invest     1.245 RGAGX {43.23 USD}
  Assets:Cash      -53.82 USD

У цій транзакції 1.245times43.23=53.821351.245 \\times 43.23 = 53.82135. Транзакція незбалансована на 0.00135-0.00135 USD. З увімкненою опцією округлення Beancount внутрішньо обробляє її як:

2013-02-23 * "Покупка"
  Assets:Invest         1.245 RGAGX {43.23 USD}
  Assets:Cash          -53.82 USD
  Equity:RoundingError -0.00135 USD  ; Додано автоматично

Визначена точність чисел

Beancount також може використовувати налаштування допуску для автоматичного округлення чисел ще до того, як вони будуть вставлені в структури даних книги.

  1. Допуск не вказано: Якщо допуск не визначено, числа використовуються з повною точністю. Округлення не відбувається.

  2. З допуском за замовчуванням: Якщо ви встановите допуск за замовчуванням, числа будуть квантовані до цього рівня.

    option "default_tolerance" "USD:0.001"

    З цим налаштуванням число, наприклад, 53.82135 USD, буде округлено та збережено як 53.821 USD.

  3. З рахунком округлення: Якщо активні як допуск за замовчуванням, так і рахунок округлення, Beancout квантує число та фіксує залишок.

    option "default_tolerance" "USD:0.01"
    option "account_rounding" "Equity:RoundingError"

    Число, наприклад, 53.82135 USD, буде збережено як 53.82 USD, а залишок -0.00135 USD буде розміщено на Equity:RoundingError.

Деталі реалізації

Кілька технічних моментів пояснюють, як Beancount досягає такої надійності.

  1. Представлення чисел: Beancount використовує модуль Python decimal, а не числа з плаваючою комою. Це дозволяє до 28 знаків після коми точності та уникає помилок двійкового представлення, поширених для чисел з плаваючою комою.

  2. Клас DisplayContext: Цей внутрішній клас обробляє все форматування чисел для відображення. Він враховує специфічні для валюти налаштування точності та може форматувати вихідні дані з вирівняними стовпцями та комами.

  3. Точність проти Допуску: Важливо розрізняти ці два поняття:

  • Точність стосується формату відображення числа (скільки десяткових знаків показано).
  • Допуск — це дозволений дисбаланс, який використовується під час перевірок.

Найкращі практики ✨

Ось кілька практичних рекомендацій щодо управління точністю у вашій книзі.

Початкове налаштування

Для більшості нових книг це надійна початкова конфігурація:

; Розумне значення за замовчуванням для більшості валют (наприклад, USD, EUR)
option "inferred_tolerance_default" "*:0.005"
 
; Буфер 10% на всі визначені допуски
option "inferred_tolerance_multiplier" "1.1"
 
; Рахунок для збору всіх залишків округлення
option "account_rounding" "Equity:RoundingError"
2000-01-01 open Equity:RoundingError

Поради з усунення несправностей

Якщо ви зіткнулися з помилками балансування:

  • Додайте десяткові знаки до суми проводки, щоб створити більш точне локальне визначення допуску.
  • Використовуйте явні допуски (~) для підтверджень balance, які не проходять через передбачувані розбіжності.
  • Відстежуйте помилки округлення на виділеному рахунку, щоб бачити, де і як часто вони виникають.
  • Розгляньте можливість встановлення специфічних для валюти значень за замовчуванням, якщо ви часто працюєте з валютами, що мають різні умовності (наприклад, JPY не має десяткових знаків).

Стратегія міграції

Застосовуючи ці концепції до існуючої, безладної книги:

  1. Почніть з щедрого глобального допуску (наприклад, *:0.05) та високого множника, щоб файл пройшов валідацію.
  2. Поступово звужуйте допуски та виправляйте помилки, які з'являються.
  3. Додавайте явні знаки до сум у проблемних транзакціях, щоб дозволити визначенню працювати.
  4. Слідкуйте за балансом рахунку округлення. Великий або швидко зростаючий баланс може свідчити про системну проблему, яка потребує розслідування.