検証ラボ ── 2026-09-07
集計スクリプトは、間違っていてもエラーを出さない — 3年分のティックを測って踏んだ7つの罠
プログラムのバグには2種類あります。落ちるバグと、落ちないバグです。
集計スクリプトのバグは、ほぼ全部が後者でした。落ちません。例外も出ません。それらしい数字が返ってきます。しかも「なんとなく予想どおり」だと、そのまま信じてしまいます。
17億件のティックを集計する過程で、何度も間違った数字を出しました。そのうち何件かは記事にする直前で気づき、何件かは記事にしてから気づいて直しました。
**7件を記録しておきます。**どれも、気づいた理由のほうが本題です。
結論
- 集計のバグは**エラーではなく「それらしい数字」**として出てくる。だから実行が成功したことは何の保証にもならない
- 気づけた理由はほぼ4つに集約された:対照を置く / 粒度を変える / 端で測らない / 成功の合図を信じない
- **予想と合っている結果ほど危ない。**今回、間違いに気づいたきっかけの多くは「合いすぎている」「思ったより小さい」という違和感だった
1. 夏時間を混ぜて、倍率が4分の1になった
いちばん大きかった間違いです。
3年分をまとめて時間帯別に集計したところ、ロールオーバー時のスプレッドは平常の2.0倍でした。ところが1か月だけの標本では8.2倍出ていました。
私は最初、短い標本のほうが大げさに出ているのだろうと考えました。これが逆でした。
夏時間と冬時間ではロールオーバーの時刻が1時間ずれます。3年分を時計時刻でまとめると、1つの山が2つの時刻に塗り広げられて、両方とも低くなります。1か月の標本は片方の季節しか含まないので、山が潰れていなかっただけです。
- 気づいた理由: 短い標本と長い標本で答えが違った。どちらが正しいかを決めずに放置しなかった
- 詳しくはサンプルを増やしたら、かえって間違えた
「サンプルを増やしたのだから、こちらが正確なはずだ」という前提が間違いでした。
2. 1時間単位で測ったら、山が消えていた
上と同じ現象の、別の現れ方です。
NZドルのロールオーバーを調べたとき、1時間単位の集計では何も見えませんでした。分単位で測り直したら、1〜3分だけの山がはっきり出ました。
同じデータです。粒度を変えただけです。
さらに、同じ集計でニューヨーク17時のピークも3.6倍から9.3倍に変わりました。1時間の枠に5分の山を入れて平均すれば、当然そうなります。
- 気づいた理由: 「通説では山があるはずの時刻」に何もなかった。無いことを結論にする前に、粒度を疑った
探している現象の幅より粗く測ると、あるものが無いように見えます。
3. 「毎月第1金曜」という近似が、5回外れていた
米雇用統計のスプレッドを測るとき、発表日を「毎月第1金曜」で計算していました。よく言われる話です。
出典を書く段になって、念のため実際の日程を引きました。35回のうち5回は金曜ですらありませんでした(火曜・水曜・木曜)。
近似のままだと、取りこぼした5回が対照群に混ざります。イベント日を平常日として数えることになるので、差が小さく出ます。
実日程で測り直した結果は、ほとんど変わりませんでした。近似は結果的に妥当だったわけです。ただ、確かめるまでは分かりませんでした。
- 気づいた理由: 出典を書こうとしたから。「出典を書く」という作業自体が検算になる
詳しくは米雇用統計でスプレッドはどれだけ開くか。
4. 測る場所を変えたら、答えが3回変わった
週末をまたぐ価格の飛びを測ったときです。
- bidで測った: 72%が下方向に飛ぶ
- 仲値(bidとaskの中間)で測った: 31.5%
- 境界から4時間離して測った: 約50%
同じ現象について、3つの違う答えが出ました。
正解は3つ目です。市場の切れ目の前後では、クオートそのものが歪んでいます。スプレッドが極端に開いた状態のbidは、価格ではなく「値がついていない」という状態に近いものです。そこで測ると、歪みを現象として読んでしまいます。
- 気づいた理由: 72%という数字が綺麗すぎた。「週末は下げやすい」という結論は面白いが、その面白さが疑う理由になった
**私は2回続けて自分の結果を訂正しました。**詳しくは週明けギャップを162週分測った。
5. 「完了」と出たのに、0件だった
データ取得ソフトで13ペアをまとめてダウンロードしたとき、4秒で「完了」と表示されました。
3年分のティック13ペアが4秒で終わるはずがありません。実際、1件も取得できていませんでした。設定が別の配信元を向いていて、そこにはデータが無かったのです。
エラーは出ませんでした。「対象が0件の処理が正常に完了した」という扱いです。
- 気づいた理由: 所要時間が短すぎた。「終わりました」より「どれだけかかったか」のほうが情報量がある
この件で7時間ほど無駄にしました。手順はForexTester 6 でティックデータを取り出すに書いてあります。
6. ファイルサイズが正常でも、中身が途中で切れていた
別の日、ダウンロード中にWindows Updateがマシンを再起動しました。
再開後、ファイルサイズは正常に見えました。ところがある通貨ペアだけ、データが2024年10月28日で終わっていました。
理由は、このファイル形式があらかじめ大きめの領域を確保してから書き込むためです。だからサイズは中身の量を表しません。実際、未取得のファイルも一律で同じサイズでした。
以後、確認はサイズではなく最後のティックの日付で行うようにしました。
- 気づいた理由: 全ペアの期間を一覧にしたから。1件ずつ見ていたら気づけませんでした
7. 件数を数えるコマンドが、件数を数えていなかった
これは集計そのものではなく、確認作業のほうのミスです。
サイトマップに何件のURLが入っているかを確認しようとして、「1件」という結果が返りました。実際は36件です。
使ったコマンドが一致した行数を数えるもので、一致した回数ではなかったためです。サイトマップは1行に全URLが入っていたので、「1行」が正解でした。
- 気づいた理由: 1件はさすがにおかしい。桁がおかしい結果は、疑うのが簡単
逆に言えば、もっともらしい桁で返ってきていたら気づけませんでした。
追記:この記事を書き終えた直後に、8件目を踏んだ
正直に書きます。上の7件を書き終えたその晩に、もう1件やりました。しかも6番とまったく同じ形でした。
別の集計をしていて、月ごとの数字を並べたときに違和感がありました。3年分のはずのデータに、2018年の行が1つ混じっていたのです。
調べたところ、22銘柄のうち2銘柄だけ、ファイルの開始日が5年ぶん古いことが分かりました。他の20銘柄はすべて同じ日から始まっているのに、その2つだけ2018年4月から入っていました。約21営業日ぶん、その銘柄の全体の**2.8%**です。
**件数を見ても、ファイルサイズを見ても分かりません。**先頭のティックの日付を読むまで、まったく気づきませんでした。
気づけた理由
月ごとに割って並べたからです。
3年分をまとめて1つの数字にしていたら、2.8%の混入は中央値をほとんど動かさないので、永久に気づけませんでした。割ってみたから、そこにあるはずのない行が見えたわけです。
これは1番・2番の「粒度を変える」と同じ話です。まとめた数字は、異常を隠します。
やったこと
- 集計スクリプト11本すべてが共通の期間フィルタを通るようにした。1本ずつ書いていたから、書き忘れが起きた
- 影響範囲を1件ずつ測り直した。公開済みのものは無事で、まだ公開していないものの数値を訂正した
- 素材の落とし穴として記録に残した
何が言えるか
この記事で「4つの気づき方」を挙げましたが、私自身がその晩に守れていませんでした。「成功の合図を信じない」と書いておきながら、ファイルが揃っていることを開始日で確かめていなかったわけです。
書けば身につく、というものではないようです。**仕組みにするしかありません。**共通のフィルタを1か所に置いたのは、そのためです。
気づき方は4つに集約された
7件を並べてみると、気づけた理由はだいたい同じところに落ちます。
対照を置く
NZドルの1〜3分の山は、それ単体では1.3倍という微妙な数字です。集計のバグかもしれません。
決め手になったのは、同じ時刻の豪ドル/米ドルが完全に平坦だったことです。同じスクリプト、同じ期間、同じ処理で、片方だけに出た。だからスクリプトの問題ではありません。
対照は「比較のため」だけではなく、「自分の道具を検算するため」にも効きます。
粒度を変えて、同じ答えになるか見る
1時間で測っても分で測っても同じ結論になるなら、その結論は粒度に依存していません。変わるなら、どちらかが間違っています(あるいは両方)。
1と2は、まさにこれで見つかりました。
端で測らない
市場の切れ目、データの先頭と末尾、期間の境界。境界の近くは、現象ではなく観測の歪みが出ます。
4がその例です。境界から離して測ると、答えが変わりました。
成功の合図を信じない
「完了」も、正常なファイルサイズも、エラーが出ないことも、成功の証拠ではありません。
確認するなら、中身そのものを見る必要があります。最後のティックの日付、件数、所要時間。5と6はこれです。
それでも残る問題
正直に書いておくと、この7件は「気づけたもの」だけです。
気づいていない間違いが残っている可能性は、当然あります。しかも上に書いたとおり、予想と合っている結果ほど検算されにくいという偏りがあります。私が「予想どおりだ」と思って通した集計こそ、いちばん危ないはずです。
対策として今やっていることは2つだけです。
- **数値の出どころをすべてスクリプトに残す。**手で計算した数字を記事に書かない
- 検証の手順を先に書いてから測る(結果を見る前に、合否の基準を書いておく)。結果を見てから条件を変えると、間違いに気づく機会そのものが失われます
どちらも完全ではありません。
まとめ
- 集計のバグは落ちない。「それらしい数字」で返ってくる
- 実際に踏んだ7件は、夏時間の混合・粒度・日付の近似・測定位置・処理系の合図・ファイルサイズ・数え方
- 気づけた理由は対照を置く / 粒度を変える / 端で測らない / 成功の合図を信じないの4つに集約された
- 予想と合っている結果ほど検算されない。これはまだ解けていない
「検証した」と書くとき、その検証自体が正しいかどうかは、別に検証しなければ分かりません。今のところ、私にできているのはそこまでです。
出典
- 夏時間の混合: サンプルを増やしたら、かえって間違えた(当サイト)
- 粒度の問題: 「NZドルは1日2回ロールする」は本当か / スプレッドが開くのは1日1時間(当サイト)
- 発表日の近似: 米雇用統計でスプレッドはどれだけ開くか(当サイト)
- 測定位置: 週明けギャップを162週分測った(当サイト)
- データ取得の手順と落とし穴: ForexTester 6 でティックデータを取り出す / ForexTesterのデータはどこまで信用できるか(当サイト)
- 大量集計の実装: 17億件のティックを普通のPCで集計する(当サイト)
- 手順を先に決める: 結果を見る前に、合否の基準を書いておく(当サイト)
※本記事は情報提供を目的としたもので、特定の取引・製品を推奨するものではありません。