01市場は、群れである
バブルと暴落は、なぜ起きるのか。経済学の教科書は「価格は需要と供給で決まる」と教えるが、その需要と供給を生み出すのは、市場に集う無数の参加者一人ひとりの判断だ。彼らは互いを見ながら売り買いし、その総意が価格を動かし、動いた価格がまた彼らの判断を変える。
この「群れの振る舞い」を捉えるのがエージェントベースモデルだ。市場全体を方程式で表すのではなく、参加者一人ひとり(エージェント)に単純な行動ルールを与え、彼らを大量に動かして、全体として何が起きるかを観察する。鳥の群れや魚の群れと同じく、単純な個の集まりから複雑な全体が立ち現れる——その様子を、WebGPUで数千のエージェントを同時に動かして可視化する。
023種類のエージェント
市場参加者の行動を単純化し、3つのタイプに分ける。それぞれ価格への反応が異なる。
逆張りは「価格が高すぎれば売り、安すぎれば買う」。基準価格に引き戻す力だ。 トレンド追従は「上がっていれば買い、下がっていれば売る」。流れを増幅する力で、バブルと暴落の主役になる。 ノイズは理由なくランダムに売買する、市場の揺らぎだ。この3つの力の綱引きが、相場の表情を決める。
03状態をバッファに持つ — もう一つのGPGPU
反応拡散系では、状態を2次元テクスチャに持ち、各ピクセルが近傍と影響し合った。市場のエージェントは違う。一人ひとりが独立した存在で、空間的な近傍関係を持たない。この「独立した多数の個」を表すのに最適なのが、1次元のstorage bufferだ。
各エージェントの属性をvec4に詰める。タイプ(逆張り/トレンド/ノイズ)、反応の強さの係数、表示位置のばらつき、そして個体差の種。これを N 人分の配列としてGPUに置く。
04需要を計算する compute シェーダー
コンピュートシェーダーが、全エージェントの「いま売りたいか買いたいか」(需要)を並列に計算する。各エージェントは自分のタイプに応じて、現在価格と基準価格、トレンドを見て需要を決める。
ここで効くのが個体差だ。同じトレンド追従でも、全員が全く同じ反応をすると、群れは「四角い塊」のように一様に動いてしまう。各エージェントに固有の微小なノイズを加えることで、塊がほぐれ、自然な「ざわめく群れ」になる。
iとステップ数からハッシュ関数で疑似乱数を作る。同じ入力には同じ出力が返るので再現性があり、しかもエージェントごと・時刻ごとに違う値になる。fract(sin(x))系は精度が荒く偏るため、ビット演算ベースのハッシュを使う。
05頂点バッファのない粒子描画
計算した需要を、画面に描く。各エージェントを1つの粒子(点)として表示するが、ここでWebGPUらしい技法を使う。頂点バッファを一切用意しないのだ。
1つの粒子を、2枚の三角形(6頂点)からなる小さな四角形で描く。頂点シェーダーはvertex_index(何番目の頂点か)だけを受け取り、それを6で割ってエージェントID、6で割った余りで四角形のどの角かを判定する。エージェントの属性はストレージバッファから直接読む。
描画呼び出しはdraw(N * 6)——エージェント数×6頂点を指定するだけ。GPUが頂点インデックスを連番で渡し、シェーダーがその場で位置を計算する。頂点データの転送が一切不要で、計算結果(demandBuf)をそのまま描画に使える。compute が書いたバッファを、render が直接読む——これがバッファGPGPUの要だ。
06発光する点 — 群れに命を吹き込む
四角い点のままでは無機質だ。フラグメントシェーダーで、各粒子を中心が明るく外へ向かって減衰する光の点にする。頂点シェーダーが四角形の各頂点にローカル座標(-1〜1)を渡し、フラグメントが中心からの距離を計算して、円の外を切り捨て、内側を発光させる。
さらに、描画を加算ブレンドに設定する。光が重なると明るさが足し合わされ、粒子が密集する場所ほど輝く。これにより、群れの密度が光の濃淡として見えるようになる。無機質な点の集まりが、生物の群れのようにざわめく光になる。
07群れの総意が、価格になる
最後に、群れの総意から価格を決める。各エージェントの需要を合計し、買いが多ければ価格が上がり、売りが多ければ下がる。この集計は、GPUが計算したdemandBufをCPU側に読み戻して行う。
更新された価格は次のフレームのcompute(各エージェントの判断)に戻され、ループが閉じる。価格がエージェントを動かし、エージェントが価格を動かす——この相互フィードバックこそが、バブルと暴落を生む。トレンド追従が多いほどループは自己強化的になり、小さなきっかけが暴騰や暴落へ増幅される。
clampで制限し、価格を対数空間で扱い、上下限を設けることで安定させている。現実の市場にサーキットブレーカーがあるのと同じく、シミュレーションにも暴走を抑える仕掛けが要る。
08試してみる
下のデモは、ここまで解説したエージェント市場がそのまま動いている。3タイプの構成比を変えたり、ショックを与えたり、スピードを調整できる。トレンド追従を増やすとバブルと暴落が激しくなり、逆張りを増やすと市場が安定する——群集心理が相場を動かす様子を体感してほしい。
09結論 — バッファとテクスチャ、2つのGPGPU
このデモと、反応拡散系のデモは、対をなしている。どちらも「compute がデータを更新し、render がそれを描く」という同じ骨格を持つが、データの器が違う。
反応拡散はテクスチャに状態を持った。各ピクセルが近傍と相互作用する「場」のシミュレーションで、2次元格子と近傍アクセスが自然だった。市場はバッファに状態を持った。独立した多数の個が振る舞う「群れ」のシミュレーションで、1次元配列と個別計算が自然だった。流体や煙は前者、群衆や粒子や物理シミュレーションは後者——問題の構造が、器を決める。
そして両者に共通する美しさは、計算と描画が地続きなことだ。computeが書いたメモリを、renderが追加コピーなしに直接読む。CPUとGPUの間でデータを往復させる必要がない。手のひらの中のGPUで数千のエージェントが同時に思考し、その総意がリアルタイムに絵になる。群集心理という捉えどころのないものが、光る群れとして目の前で動く——計算は、見えないものを見せる道具になる。