モバイル&ワイヤレスブロードバンドでインターネットへ

gwaw.jp
 
Experimental / Finance × WebGPU

モンテカルロ資産シミュレーター
インフレ・取り崩し対応 × WebGPU 並列計算

一律の年利計算を超えて、リターンのランダム変動・インフレ・取り崩しを考慮した
確率論的資産シミュレーション。WebGPU compute shader で10万回を高速並列実行します。

▍ INTERACTIVE DEMO — WebGPU / WebGL2 / CPU

このページについて

従来の積立シミュレーターは「年利5%で20年運用すると確実に1,238万円」という決定論的計算です。 しかし実際の市場では毎年の収益率が大きく変動します。 モンテカルロ法では収益率を確率分布からランダムにサンプリングし、 数万回の試行から「80%の確率で900万円以上」「最悪ケースで480万円」という 確率的な結果を得ます。

3つの計算バックエンドに対応: WebGPU(compute shader)・WebGL2(GPGPU)・CPU(JavaScript)を自動判定し、 最適なものを選択します。手動切替や、試行回数を変えて処理速度を計測する スケーリングベンチマークも利用できます。
WebGPU の適用箇所: 各シミュレーションは互いに独立しているため、 10万回の試行を10万スレッドで完全並列実行できます。 GPU の得意とする「大量の単純計算の並列実行」に最適な問題です。

シミュレーター

BACKEND(クリックで手動選択 / AUTO は自動判定)
AUTO WebGPU WebGL2 CPU バックエンド判定中...

AUTO では WebGPUWebGL2CPU の順に対応状況を判定し、 利用可能な最上位のバックエンドを自動選択します。 いずれかが実行に失敗した場合も、自動的に下位のバックエンドへフォールバックします。

積立フェーズ
現在の資産額 積立開始時点の初期資産
万円
月額積立額 毎月定額で積み立てる金額
万円/月
積立期間 積立を行う年数
期待リターン μ 年率期待収益率(平均)
% / 年
リターン標準偏差 σ 収益率のばらつき(株式≒15%)
% / 年
リターン分布 正規分布 or 対数正規分布
取り崩しフェーズ
月額取り崩し額 毎月引き出す金額
万円/月
取り崩し期間 引き出しを続ける年数
インフレ率(基準) 取り崩し額の実質上昇率
% / 年
インフレ率(標準偏差) インフレのランダム変動幅
% / 年
取り崩し増加方式
シミュレーション設定
シミュレーション回数 多いほど精度が上がるが処理時間増
乱数シード 同じ値で再現性のある結果
暴落イベント確率 年率(0=なし)
% / 年
暴落時の下落幅 暴落発生時の年次下落率
% 下落
取り崩し変動幅 σ 支出のランダム変動(医療費等)
%
⚡ Scaling ベンチマーク(試行回数を変えて全バックエンド計測)

1,000 → 100,000 回まで試行回数を段階的に増やし、利用可能な全バックエンド(WebGPU / WebGL2 / CPU)の処理時間を計測します。 お使いの環境でどのバックエンドが速いかを比較できます。※ CPU は大規模試行で時間がかかります

[SYSTEM] パラメータを設定して「実行」を押してください...
SIMULATIONS
ELAPSED TIME
THROUGHPUT
BACKEND
CPU
破産確率(取り崩し期間中に資産が尽きる確率)
中央値(最終資産)
5%ile(悲観)
25%ile
75%ile
95%ile(楽観)
決定論的(一律μ)
ファンチャート(資産推移 パーセンタイル帯)
██ 5〜95%ile帯   ── 中央値(50%ile)  ── 決定論的(一律μ計算)
最終資産 分布(取り崩し終了時)
資産が尽きる年(破産年の分布)
感応度ヒートマップ(取り崩し月額 × 期待リターン → 破産確率 %)

中央の白枠が現在の設定値。青系が低リスク・赤系が高リスク。

実質価値(インフレ調整後)vs 名目資産 比較
── 名目中央値   -- 実質中央値(インフレ調整後)

実装の解説

モンテカルロ法 — 乱数生成と正規分布サンプリング

各シミュレーションで毎年の収益率を正規分布 N(μ, σ²) からサンプリングします。 ブラウザのMath.random()はメルセンヌツイスターに近い品質ですが、 WebGPU版ではGPU上でPCG(Permuted Congruential Generator)を実装します。

// Box-Muller 変換で標準正規分布 N(0,1) をサンプリング function randNormal() { const u1 = Math.random(), u2 = Math.random(); return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2); } // 年次リターンのサンプリング(正規分布モデル) function sampleReturn(mu_annual, sigma_annual) { const mu_m = mu_annual / 12; // 月次換算 const sigma_m = sigma_annual / Math.sqrt(12); return mu_m + sigma_m * randNormal(); } // 対数正規分布モデル(負のリターンに下限なし・実務的) function sampleReturnLognormal(mu, sigma) { const mu_ln = Math.log(1 + mu/12) - sigma*sigma/(24*12); const sigma_ln = Math.sqrt(Math.log(1 + (sigma/Math.sqrt(12))**2)); return Math.exp(mu_ln + sigma_ln * randNormal()) - 1; }
WebGPU compute shader — 実装(本ページで動作中)
本ページでは下記の WGSL compute shader が動作します。 各スレッドが1回のシミュレーションを担当し、workgroup_size(64) で完全並列実行します。 WebGPU 非対応環境では WebGL2、それも非対応なら CPU へ自動的にフォールバックします。
// WGSL — 本ページで動作している compute shader(抜粋) struct Params { n_months_accum : u32, n_months_draw : u32, initial_asset : f32, monthly_contrib : f32, monthly_draw : f32, mu_monthly : f32, sigma_monthly : f32, inflation_mu : f32, inflation_sigma : f32, } @compute @workgroup_size(256) fn main(@builtin(global_invocation_id) gid : vec3<u32>) { let sim_id = gid.x; // 各スレッド = 1シミュレーション var asset = params.initial_asset; var rng = pcg_init(seeds[sim_id]); // PCG 乱数初期化 // 積立フェーズ(月次ループ) for (var m = 0u; m < params.n_months_accum; m++) { let r = rand_normal(&rng, params.mu_monthly, params.sigma_monthly); asset = (asset + params.monthly_contrib) * (1.0 + r); } // 取り崩しフェーズ → results バッファに書き込み results[sim_id] = asset; }
3段階フォールバック戦略

環境に応じて最適なバックエンドを自動選択します。 各バックエンドは同一の計算ロジック(PCG乱数・Box-Muller変換)を異なる実行基盤で実装しています。

バックエンド 実行方式 特徴
① WebGPU compute shader 最速。GPGPU専用設計で大量並列に最適
② WebGL2 transform feedback 頂点シェーダーで計算し結果を頂点バッファに書き戻す。広く対応
③ CPU JavaScript 完全互換。バッチ処理でUIフリーズを防止
WebGL2 transform feedback の仕組み: 通常GPUは描画用ですが、RASTERIZER_DISCARDでラスタライズを無効化し、 頂点シェーダーの計算結果を transformFeedbackVaryings で 頂点バッファに書き戻すことで、汎用計算(GPGPU)に転用しています。 各頂点が1シミュレーションを担当します。

『モンテカルロ資産シミュレーター with WebGPU』を公開しました。