なぜ作ったか

相場にまつわるデータを、体感できる形にして公開する個人プロジェクト。 常設展「日経30年絵巻」は、日経平均という誰もが知る指数を、生の数値ではなく 「100万円がいくらになったか」という物語として見せることに主眼を置いている。 実験棟「実弾検証」は、逆に数値の正確さと透明性そのものを設計の中心に据えた。 性質の異なる2つの展示を、同じデータ契約の型(ビルド時に生成した JSON を 静的サイトへ流し込むだけ)で作れることを確かめたかった。

データの誠実さをどう設計したか

日経平均株価は日本経済新聞社が知的財産権を保有しており、商用利用にはライセンス契約が 原則必要という公式スタンスがある。個人・非商用の明確な例外規定は一次確認できなかった ため、リスクをゼロにはできない前提で、次の四段構えを設計した。

実験棟側は逆に「何を公開しないか」が設計の中心になる。銘柄・株数・金額・評価額は 公開スキーマにフィールドごと存在させず、さらに禁止パターンの機械検査 (check_no_leak.py)を全ビルドで実行し、既知の漏洩サンプルを 検知できることの自己テストを同梱している。

演出をどう実装したか

常設展のスクロール演出(描き進む折れ線・ズーム・狼狽売りのゴースト線)は、 外部ライブラリを使わず IntersectionObserver + requestAnimationFrame + Canvas 2D 直描画で自作した。 汎用のスクロールアニメーションライブラリを使わなかった理由は、 「描き進む一本の線」という演出そのものが本作の見せ場であり、 汎用ライブラリを挟むと、かえって制御が回り道になる。

実装中に見つかった不具合が2つある。ひとつは、章のテキストカードが不透明な 背景を持っていたため、背後で固定表示され続けるはずのチャートを完全に覆い隠して しまっていたこと。もうひとつは、IntersectionObserver の交差通知が スクロールイベントと非同期にずれるため、大きくジャンプするスクロールで章の 切り替えを取りこぼすことがあったこと。どちらも実際にブラウザで動かして初めて 気づいた類のもので、静的なコードレビューだけでは見つけにくい部分だった。

prefers-reduced-motion が指定されている場合は演出を止め、 各章に完成状態の静的チャートを表示する。JavaScript が無効な環境では、 ビルド時(サーバーサイド)に同じデータから直接 SVG の折れ線を生成し、 <noscript> で出し分けている。Canvas はクライアントで しか描けないため、「JS が動かなければグラフも消える」を避けるための対応。

技術選定の考え方

サイト生成には Astro、ホスティングには Cloudflare Pages を選んだ。 どちらも他プロジェクトで運用実績があり、新しく学ぶコストがかからない 「枯れた技術」だからという理由が大きい。新規に増える「動く部品」は 実質、自作のスクロール演出ランタイムひとつだけに絞っている。 データ生成は Python(yfinance・pandas・jsonschema)で、これも既存の 株価取得運用の延長線にある。

データ生成スクリプトは冪等性(同じ入力からは同じ出力が得られること)と atomic write(一時ファイルに書いてから置き換える)を徹底し、 生成の唯一の書き手を1スクリプトに固定した。手編集を許すと、 「今表示されている数値の根拠がどこにあるか」が追えなくなるため。

相場データ博物館トップへ