世界を動かす技術を、日本語で。

フィンテックエンジニアリングハンドブック

2026年6月27日原文(w.pitula.me)

概要

Fintech Engineering Handbook は、金融システムに不可欠なソフトウェア設計パターンを解説。 金融分野に新しく参加する人や、既に従事している人、または他分野の開発者向けのリファレンス。 信頼性、正確性、トレーサビリティ を重視した原則を提示。 マネーの表現方法、通貨・為替レートの扱い、帳簿記録、監査トレイルの重要性を説明。 生きたドキュメント として、継続的な貢献・改善を歓迎。

Fintech Engineering Handbookの目的と対象読者

  • 金融システム に特化したソフトウェア設計パターンの集約
  • 新規参入者 向け:金融領域の基礎と信頼性パターンの習得
  • 既存従事者 向け:問題解決時のリファレンス、共通語彙の提供
  • 他分野の開発者 向け:金融特有の開発上の違いと理由の理解
  • 生きたドキュメント として、外部からの貢献も歓迎

基本原則

  • No invented data(データの捏造禁止)
    • 重複や恣意的な残高更新の排除
    • 冪等性、重複排除、照合 による実現
  • No lost data(データ損失禁止)
    • 全ての金銭移動の追跡・永続化
    • 高精度、少なくとも一度の配信、イベントソーシング、監査証跡、不変性 の徹底
  • No trust(信頼前提禁止)
    • 外部・内部・世界のどこも無条件で信頼しない
    • Webhook検証、データのクロスチェック、前提崩壊時の明示的失敗 による担保

マネーの表現方法

  • 金額のモデル化・保存・計算・変換方法 の選定が基礎
    • 誤ると上位レイヤー全てに影響
  • 主な表現方法
    • 浮動小数点 :精度損失リスク高、通常非推奨
    • 任意精度型(BigDecimal等) :精度管理自在、中間計算向き
    • 最小単位整数 :ISO 4217に準拠した固定精度。例:€12.34→1234
      • Crypto も同様だが、資産ごとに精度が異なり、任意幅整数が必要
    • 有理数型 :精度損失ゼロだが、速度・変換・型管理に注意
  • 保存・計算時の型の使い分け が重要
  • JSONシリアライズ時の注意 :数値型は浮動小数点扱いされるため、 文字列または最小単位整数 で送信
  • 原則 :誤った表現は 精度損失 につながり、元に戻せない

丸め処理方針

  • 丸めは不可避 だが、必ず明示的に実施
    • 分割、為替、手数料、利息などで発生
  • 丸め戦略 の選択はビジネス判断
    • 保守的(切り捨て)、統計的(偶数丸め)など
    • 法的・税務上の影響も考慮
  • 丸めの頻度最小化 :できる限り精度を保つ
  • 丸め後の合計値不一致 に注意し、必要に応じて 丸め専用アカウント 等で対応
  • 原則 :残差の追跡必須、丸めで新たな金額を生み出さない

通貨管理

  • 金額と通貨のペア管理 (構造体・クラス等で一体化)
  • 異通貨間の算術演算禁止。明示的な変換・レート管理必須
  • 許可通貨セットの制御 :外部からの任意通貨コード受付禁止
  • 通貨コードは法定通貨のみ一意
    • Crypto はネットワークやコントラクトアドレス等で識別
  • 通貨のメタデータ (記号、精度、名称等)は表示用
  • ペッグ通貨と元通貨は別物 として扱う
  • 原則 :通貨の検証・区別を徹底、異なる通貨を同一視しない

為替レート(FX Rates)の扱い

  • 為替レートは常に方向性を持つ (EUR/USD≠USD/EUR)
  • 売買で異なる価格 (ビッド/アスクスプレッド)
  • レートの時点 が重要
    • 現時点レート:保有資産評価や即時取引
    • 価値日レート:評価損益や税計算
  • レートの種類
    • 取引レート:実際の変換が行われた時のレート(原資と結果から算出)
    • 参考レート:評価や報告用、実際の取引価格ではない
  • 唯一絶対のレートは存在しない
    • 市場や計算方法で異なる
    • 中央銀行レート は参考値
  • 原則 :金額とレート情報源を必ず保持、信頼しすぎない

マネーの記録:台帳(Ledger)

  • ダブルエントリー会計 (複式簿記)を基本
    • 各取引で 出金アカウント、入金アカウント、金額 を記録
    • すべての動きがバランスし、マネーは常に移動のみ
    • 外部プロバイダー用アカウントも用意し、流出入も追跡
  • 残高は動きから算出、直接保存しない
  • アカウント種別 (資産、負債、資本、収益、費用)で会計方程式を維持
  • 1取引で複数の動き (例:純額、手数料等)
  • 記録の不変性 :訂正は新たな補正エントリで対応
  • 原則 :マネーは必ず出所・行先があり、総額は保存

時刻管理(Value/Booking/Settlement Time)

  • 取引には複数の時刻情報
    • 価値時刻:実際の発生時
    • 記帳時刻:システム記録時
    • 決済時刻:実際の資金移動時
  • 時刻のズレ (バックデート、フォワードデート)も記録
  • ビジネス報告は価値時刻や決済時刻重視
  • 原則 :全時刻を記録、単一のcreated_atに集約しない

監査・監査証跡(Audit Trail)

  • 金融システムは監査対象
    • 会社資金とユーザー資金の分離
    • 収益の登録・説明責任
    • 外部報告情報との整合性
    • 資金へのアクセス管理
  • 完全な履歴(監査証跡) の保持が必須
    • 何が起きたか
    • いつ起きたか(複数時刻管理)
    • 誰が/何が操作したか

以降、システム設計やパターンごとに細分化した解説が必要であれば、追加でご指示ください。

Hackerたちの意見

アイデンポテンシーキーのセクションだけでも読む価値あるよ。ほとんどの開発者はこの教訓を苦労して学ぶからね。

あと、監査証跡もね。良い監査証跡があれば、会社(と君)を緊急時に救えることもあるから。デバッグやコンプライアンスデータソースの最後の手段としても役立つよ。

100%。もっと詳しく説明する価値があるね。アイデンポテンシーがどう機能するべきか、そしてそれがなぜ重要なのかを説明するのに多くの時間を費やしてきた。ほとんどのチームはその必要性を理解してるけど、最初から考えてるところはほんの少しだね。

金融業界が、今でも使われている60年代と70年代のコアバンキングシステムや金融通信プロトコルについて知っていたらよかったのに… これらの多くは、アイデンポテンシーの広まりよりも前に作られたから、アイデンポテンシーキーは色々な、できればグローバルにユニークなフィールドを組み合わせて作られることが多いんだけど、実際にはそうなってないことが多いんだよね。(たまにカーテンの裏を覗くことができるけど、例えば、同じカレンダーの日に同じ金額を同じ受取人の口座に送金できない時とか。)

お金の金額を表すために「マイナー単位の精度」戦略を考えてる人へのアドバイス:やめとけ(少なくとも、インターチェンジ/APIデータフォーマットとしては使わない方がいい)。一見賢いアイデアに見えるけど(整数計算が速くて、足し算や引き算の丸め問題がない)、異なる通貨の暗黙の桁数を持つパートナーと仕事をするようなエッジケースに遭遇したら、めちゃくちゃ痛い目に遭うよ。特に、安定コインは、表す「法定通貨」と暗黙の小数桁数が異なることが多いから、注意が必要。また、JSONベースのAPIでは金額を文字列型で表現するのも考えてみて。JSONは小数精度を指定してないから、君(と君のユーザーやベンダー)は常にパーサー/シリアライザーが浮動小数点を通じて内部的に精度を失わないように気をつけなきゃいけない。これ、すぐに厄介になるから。文字列は概念的には少し整然としてないように見えるけど、その問題を完全に回避できるよ。(これをアンチパターンだと言う人もいるけど、ユーザーや株主の肩にイデオロギーの純粋性のためにこの戦いを挑みたくはないな。)

じゃあ、代わりに何を勧める?標準の浮動小数点(「float」/「double」)、マイナー単位の千分の一(またはそれ以下)の固定小数点演算、任意精度の小数、あるいは全く別の何か?

でも、異なる通貨の暗黙の桁数を持つパートナーと仕事をするようなエッジケースに遭遇したら、めちゃくちゃ痛い目に遭うよ。 それがどうして問題になるの?彼らのAPIとやり取りするときに値を変換すればいいじゃん。

C++でHFTや低遅延をやって、ブラウザベース(つまりJavaScript)の管理フロントエンドを使った経験があるけど、みんな整数セントを使った方がいいよ。ほぼ業界標準だし、全然問題ないから。他の方法は妥協が大きすぎる。

ここでの正しい解決策は、仮数部と指数部を2つの整数として送ることだね。指数間の変換は簡単だし、必要なだけ正確にできるし、あいまいさもない。HFTの世界では、ある{スライス}に対して一貫した指数を最初に決めれば、ワイヤスペースを節約できるよ(例えば、金融商品やティックサイズ、資産クラス、取引所、フィード、サーバーなど)。でも、似たような状況では、ワイヤ上の指数を送るために追加のuint32を使う価値があることも多い。そうすれば、状況が変わっても対応できるし、「今はセントだけでいい!」という設計選択に後で縛られることもないから。(固定指数を調整したい時に、ユーザーが破壊的変更を調整しなくて済むのは感謝されるよ。)

[delayed]

これって、フィンテックだけじゃなくてソフトウェアエンジニアリング全般に当てはまると思う。例えば、リトライやアイデンポテンシー、イベントの順序について話してる部分とか。これは、正確さが求められるすべてのシステムに当てはまるよ。お金が直接関わってなくてもね。「いつでもリトライできる」って前提で作られたシステムをたくさん見てきたけど、最初にクリーンに失敗しないとリトライできないし、下流のシステムが君が思ってるのと同じレベルのアイデンポテンシーを提供してるかどうかも重要。これらはしばしばテストされないことが多い。

同意だね。ここにあることの中で、フィンテックに特に関係するのは、帳簿管理と丸めの部分だけで、あまり深くないよね。もっと過激な「アカウントごとのデータベース」みたいなことについての防衛を読みたいな。フィンテックの中で独自のトレードオフがあるやつね。それと、フィンテックのエンジニアや創業者に言いたいのは、リスクとコンプライアンスを初日から真剣に考えてほしいってこと。金融システムは信頼に基づいてるから、リスクを証明できないと信頼を失って、最終的にはビジネス全体がダメになるよ。

Hacker Newsで議論の続きを見る