GPI開発日誌 Vol.3|ドル円Collectorを実装、実データの保存を開始

目次

はじめに

こんにちは。

GadgetStreemでは現在、ガジェット価格の上昇圧力を一つの数字で確認できる独自指数、

GPI(Gadget Pressure Index/ガジェット価格圧力指数)

を開発しています。

GPI開発日誌 Vol.1では、Docker、PostgreSQL、FastAPI、GitHub Actionsなど、GPIを継続的に開発するための基盤を構築しました。

Vol.2では、GPIへ最初に取り込む実データとしてドル円を選びました。

さらに、データ取得元としてFederal Reserve Boardが公開する

H.10 Foreign Exchange Rates

を採用し、

  • どの値を取得するのか
  • 欠損値をどう扱うのか
  • 同じデータの重複をどう防ぐのか
  • 訂正された値をどう保存するのか

といったCollectorの設計を行いました。

そして今回、設計だけだったUSD/JPY Collectorを実際に実装しました。

GadgetStreem Intelligenceのデータベースへ、初めて本物の市場データが入ります。


USD/JPY Collectorが完成

今回実装したUSD/JPY Collectorは、Federal Reserve Boardが公開しているH.10の為替データから、日本円の系列を取得するプログラムです。

H.10では、日本円の為替レートを

1米ドル当たりの日本円

として掲載しています。

二国間為替レートの履歴データは、通常、前営業週の金曜日までの値が米国東部時間の月曜日16時15分に更新されます。

例えば、

162.43

という値なら、

1米ドル=162.43円

という意味です。

H.10の最新リリースでも、為替レートは原則として「1米ドル当たりの各国通貨単位」という形式で掲載されています。


Collectorの処理フロー

USD/JPY Collectorは、次の順番で動作します。

Federal Reserve H.10
        ↓
公式データを取得
        ↓
日本円の系列を抽出
        ↓
日付・単位・値を検証
        ↓
欠損値を除外
        ↓
重複・訂正の有無を確認
        ↓
PostgreSQLへ保存

数字をそのままコピーするのではなく、

GPIで継続利用できる正しい観測データか

を確認してから保存します。


日本円の系列だけを抽出する

H.10には日本円だけでなく、

  • ユーロ
  • 英ポンド
  • カナダドル
  • スイスフラン
  • オーストラリアドル

など、複数の通貨データが含まれます。

GPI Ver.0.1で必要なのはUSD/JPYだけなので、Collectorでは日本円を表す系列だけを抽出します。

この処理を入れることで、別通貨の値を誤ってドル円として保存することを防ぎます。


XMLやデータ形式の違いを吸収

外部データは、GadgetStreem Intelligenceのデータベースと同じ形式で提供されるわけではありません。

そのためCollectorでは、

  • 提供元独自の系列ID
  • 日付形式
  • XML内の階層構造
  • 数値を示す属性
  • 欠損値の表記

などを読み取り、GSI内部の共通形式へ変換します。

例えば、外部データが次のような構造だった場合、

観測日:2026-07-17
観測値:162.43
系列:日本円

内部では、

indicator:usd_jpy
observed_at:2026-07-17
value:162.43000000
unit:JPY_PER_USD
source:Federal Reserve H.10

という共通形式で扱います。

この共通形式があることで、将来追加するDRAM、NAND、GPU、海上運賃も、同じ仕組みで保存できるようになります。


欠損値は保存しない

為替市場が休場している日や、提供元側で値を確定できない場合、観測値が存在しないことがあります。

H.10では、利用可能なデータがない場合に、数値ではない欠損表現が含まれる場合があります。

Collectorは、これを無理に

0円

として保存しません。

0円として保存してしまうと、

  • 為替が突然0円になった
  • 前日比がほぼマイナス100%
  • GPIのドル円スコアが急落

といった、あり得ない計算結果につながるからです。

そのため、

  • 欠損値
  • 空欄
  • 数値へ変換できない文字列
  • 必須情報が不足している観測値

は、DBへ保存せず安全にスキップします。


なぜ小数をFloatで保存しないのか

為替データには小数が含まれます。

一般的なプログラミング言語のfloatは高速ですが、内部では2進数として近似されるため、十進数を完全に表現できない場合があります。

GadgetStreem Intelligenceでは、市場データを扱うため、USD/JPYの値を

Decimal

として処理します。

データベース側でも、

NUMERIC

型を使い、小数を正確に保存します。

GPIの計算を何度実行しても、環境によって微妙に数値が変わることを防ぐためです。


初めてPostgreSQLへ市場データを保存

Collectorによって取得・検証されたUSD/JPYは、Sprint 1で構築したPostgreSQLへ保存されます。

主に使用するテーブルは次の3つです。

data_sources

どの提供元から取得したデータなのかを管理します。

今回であれば、

Federal Reserve Board
H.10 Foreign Exchange Rates

などの情報が登録されます。

indicators

どの指標に属する観測値なのかを管理します。

今回追加されるのは、

usd_jpy

です。

observations

実際の観測値を保存します。

主な内容は、

  • 観測日
  • 公表日時
  • 取得日時
  • 数値
  • 単位
  • Revision
  • データ品質
  • 取得元
  • Methodologyバージョン

です。

つまり、単に

162.43円

だけを保存するのではありません。

いつの値なのか
どこから取得したのか
いつ取得したのか
何回目のRevisionなのか

まで一緒に記録します。


同じ処理を何度実行しても重複しない

Collectorは将来的に、自動で繰り返し実行されます。

もし実行するたびに同じ観測値を追加してしまうと、

2026-07-17 162.43
2026-07-17 162.43
2026-07-17 162.43

と、同じデータが無限に増えてしまいます。

そこでCollectorでは、

  • 同じ提供元
  • 同じ指標
  • 同じ観測日
  • 同じ値

がすでに保存されている場合、新しい行を追加しません。

実行結果は、例えば次のような区分で集計できます。

inserted
unchanged
revised
skipped
failed
  • inserted:新しく保存したデータ
  • unchanged:すでに同じ値が存在
  • revised:提供元で値が変更された
  • skipped:欠損などで保存対象外
  • failed:通信・解析・DB処理に失敗

同じコマンドを繰り返しても同じ結果になる性質を、

冪等性(べきとうせい)

と呼びます。

データ収集を自動化するうえで欠かせない仕組みです。


訂正値は上書きせずRevisionとして保存

Federal Reserveなどの公式データ提供元が、後日、過去の値を訂正する可能性もあります。

例えば、最初に保存された値が

Revision 0:162.43

だったものの、後日公式データが

162.41

へ変更されたとします。

この場合、以前の値を削除したり、無言で書き換えたりはしません。

Revision 0:162.43
Revision 1:162.41

として、両方を保存します。

現在のGPI計算では最新Revisionを使いながら、

  • 当初どの値が公表されていたのか
  • いつ訂正されたのか
  • 過去のGPIにどの程度影響したのか

を後から確認できるようにします。


元データを無制限に保存しない

GadgetStreem Intelligenceでは、データの再現性を重視しています。

しかし、外部データを取得できたからといって、そのデータファイル全体を自由に保存・再配布できるとは限りません。

そこで今回のCollectorでは、原則として元データそのものを無制限に保管せず、

  • 取得元
  • 取得日時
  • 系列ID
  • 観測値
  • SHA-256ハッシュ
  • 解析バージョン

などの来歴情報を保存します。

このハッシュ値を使えば、

取得したデータが以前と同じ内容だったか

を確認できます。

データの透明性と、提供元の利用条件の両方を考慮した設計です。


コマンドから手動実行できるようにした

開発初期では、いきなり定期実行を始めません。

まずはCLIコマンドから、開発者が手動で実行できる形にしています。

概念的には、次のようなコマンドです。

gsi collect-usd-jpy

実行すると、

  1. H.10へアクセス
  2. データを取得
  3. 日本円系列を解析
  4. 検証
  5. PostgreSQLへ保存
  6. 処理結果を表示

という一連の処理が動きます。

手動実行で安定性を確認した後、スケジューラーによる自動取得へ移行する予定です。


APIアクセス時には外部データを取りに行かない

GadgetStreem Intelligenceでは、Webサイトへ読者がアクセスするたびにFederal Reserveへ接続する設計にはしていません。

処理は明確に分離します。

Collector
↓
事前にデータを取得
↓
PostgreSQLへ保存
↓
APIはDB内の検証済みデータを返す

この方式なら、

  • 外部データ提供元の障害
  • 通信の遅延
  • アクセス集中
  • API制限
  • XML形式の変更

が発生しても、公開ページ全体がすぐ表示不能になることを防げます。


テストで確認すること

USD/JPY Collectorでは、正常に取得できるケースだけでなく、失敗するケースもテストします。

Unit Test

  • 正しい日本円系列を抽出できる
  • 欠損値を除外できる
  • 不正な日付を拒否できる
  • 数値をDecimalへ変換できる
  • 別通貨を誤って取得しない
  • 同じデータを重複させない

Integration Test

  • PostgreSQLへ観測値を保存できる
  • 再実行時に重複しない
  • 訂正値を新Revisionとして保存できる
  • 最新Revisionを取得できる
  • トランザクション失敗時に中途半端なデータを残さない

さらにGitHub Actionsでテストを自動実行し、すべて成功しなければmainへマージできない運用を続けます。


GPI全体では、まだ30%が完成したわけではない

ドル円には暫定30%の重みを設定しています。

しかし、USD/JPY Collectorが完成したからといって、

GPIの30%が完成した

と単純には言えません。

まだ必要なものは、

  • どの期間のドル円を使うのか
  • 現在値と変化率のどちらを見るのか
  • 0~100へどう変換するのか
  • 欠損時にどうするのか
  • 他の指標とどの時点で揃えるのか

といった計算ルールです。

今回完成したのは、

信頼できるドル円データを、継続的に蓄積する入口

です。

GPIの数値へ変換する処理は、すべての構成要素が揃った後にCalculation Engineで実装します。


今回の開発で得られたこと

USD/JPY Collectorの実装によって、GadgetStreem Intelligenceは初めて、

外部の公式データ
↓
Collector
↓
検証
↓
PostgreSQL

という一連のデータパイプラインを持つことになります。

この流れは、今後追加する

  • DRAM
  • NAND
  • GPU需給
  • 海上運賃

でも共通して使用できます。

つまり今回作ったのは、単なるドル円専用プログラムではありません。

今後すべての市場データを取り込むための最初の実装モデル

でもあります。


次のVol.4で紹介すること

次回のGPI開発日誌 Vol.4では、Collectorを「一度動くプログラム」から「継続運用できるシステム」へ進化させます。

主なテーマは、

  • データ取得履歴
  • 最終成功日時
  • エラー内容
  • データ鮮度
  • 欠損の検知
  • 自動実行
  • 障害時の通知
  • 再試行ルール

です。

数字を一度取得できるだけでは、指数を毎週公開し続けることはできません。

Collectorをどう止めずに運用するのか

を取り上げる予定です。


まとめ

GPI開発日誌 Vol.2では、ドル円の取得元とCollectorの設計を決定しました。

今回のVol.3では、その設計を実装し、

Federal Reserve H.10のUSD/JPYをPostgreSQLへ保存する仕組み

を作りました。

これによりGadgetStreem Intelligenceは、

  • 公式データを取得する
  • 正しい系列を抽出する
  • 欠損を除外する
  • 数値を正確に保存する
  • 重複を防ぐ
  • 訂正履歴を残す
  • データの出どころを追跡する

という、指数開発に欠かせないデータパイプラインを持ち始めます。

まだGPIの数値そのものは完成していません。

しかし、今回からGPIは、

設計図だけのプロジェクトではなく、本物の市場データを蓄積するシステム

へ変わりました。

次は、継続的なデータ収集と品質監視の仕組みを整えます。

GadgetStreem Intelligenceが実際の指数として動き出すまで、引き続き開発過程を公開していきます。

※GPIは現在開発中の実験的な市場分析指標です。
個別製品の将来価格、値上げ、値下げ、在庫状況、購入利益を保証するものではありません。
また、投資判断を目的とした金融指標ではありません。

この記事が気に入ったら
フォローしてね!

コメント

コメントする

目次