メインコンテンツへスキップ
Beancount.io Logo
精度と許容誤差

精度と許容誤差

Beancountの精度と許容誤差システムが、特に複数通貨や端数を含む複雑な取引において、複式簿記のバランスを維持する仕組みを学びます。

数値精度の管理は複式簿記の基礎です。デジタル簿記、特に複数通貨、株価、端株を扱う場合、わずかな丸め誤差がすぐに厄介なバランスエラーにつながる可能性があります。Beancountは、精度を扱い、許容可能な誤差を設定するための洗練された直感的なシステムを提供します。このガイドでは、その仕組みを説明します。⚙️

コアとなる精度の概念

Beancountの主な目標は、すべての取引の貸借がゼロになることを保証することです。しかし、価格や原価を含む計算では、記録するのに実用的でない小数点以下の桁数が生じることがよくあります。許容誤差システムは、小さな許容可能な不均衡を可能にします。

自動許容誤差推論

デフォルトでは、Beancountは各取引に必要な許容誤差を自動的に推論します。この推論は取引ごとに個別に処理され、関係する通貨ごとに個別に計算されます。

ルールはシンプルです。許容誤差は、取引の転記に含まれる数値の最後の有効桁の半分です。

例えば、次の購入取引を考えます。

2013-04-03 * "Buy Fund"
  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 USD5.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

計算された残高はこの範囲内に収まる必要があります。2番目の例では、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 * "Purchase"
  Assets:Invest     1.245 RGAGX {43.23 USD}
  Assets:Cash      -53.82 USD

この取引では、1.245×43.23=53.821351.245 \times 43.23 = 53.82135 です。取引は 0.00135-0.00135 USD の不均衡があります。丸めオプションが有効な場合、Beancountは内部的に次のように処理します。

2013-02-23 * "Purchase"
  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. 丸め口座がある場合: デフォルトの許容誤差と丸め口座の両方がアクティブな場合、Beancountは数値を量子化し、残余を取得します。

    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桁の10進数の精度が可能になり、浮動小数点数に共通する2進表現エラーを回避できます。

  2. DisplayContextクラス: この内部クラスは、表示用のすべての数値フォーマットを処理します。通貨固有の精度設定を尊重し、列を揃えカンマを入れた出力をフォーマットできます。

  3. 精度と許容誤差: これら2つの概念を区別することが重要です。

  • 精度は、数値の_表示形式_(表示される小数点以下の桁数)に関連します。
  • 許容誤差は、検証チェック中に使用される_不均衡の許容範囲_です。

ベストプラクティス ✨

ここでは、元帳で精度を管理するための実用的な推奨事項をいくつか紹介します。

初期設定

ほとんどの新しい元帳では、これが堅牢な開始設定です。

; ほとんどの通貨(例: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. 丸め口座の残高を監視します。残高が大きい、または急速に増加している場合は、調査が必要な体系的な問題を示している可能性があります。