老後資金シミュレーター(Retirement Simulator)
個人の老後資金計画をシミュレーションし、現役時代から年金受給期間までの資産推移を可視化する。
- アーキテクチャ: スタンドアロンWebアプリケーション
- 動作環境: クライアントサイド(ブラウザ)
- 通信: オフライン動作(ネットワーク通信なし)
| 機能ID | 機能名 | 概要 |
|---|---|---|
| F001 | 手取り計算機能 | 年収から社会保険料・税金を差し引いた月手取り額を計算 |
| F002 | ライフサイクルシミュレーション | 現役期間~年金受給期間の資産推移をシミュレーション |
| F003 | 投資計算機能 | 投資積立と複利運用をシミュレーション |
| F004 | ランダムイベント生成 | 突発的な支出イベントをランダムに発生 |
| F005 | 投資補填機能 | 現金不足時に投資資産から自動補填(税金20%考慮) |
| F006 | 結果表示機能 | シミュレーション結果を月次で詳細表示 |
| F007 | パラメータ設定機能 | ユーザーによる各種設定値の入力 |
| F008 | 給与変更機能 | 転職・昇進による年収変更設定(複数設定可能) |
関数名: calculateNetMonthly(salaryAnnual)
入力:
salaryAnnual(number): 年収(円)
処理ロジック:
- 社会保険料計算:
年収 × 14% - 課税所得計算:
年収 - 社会保険料 - 基礎控除(480,000円) - 所得税計算(累進課税):
const brackets = [ { up:1,950,000, rate:0.05 }, { up:3,300,000, rate:0.10 }, { up:6,950,000, rate:0.20 }, { up:9,000,000, rate:0.23 }, { up:18,000,000, rate:0.33 }, { up:40,000,000, rate:0.40 }, { up:Infinity, rate:0.45 } ];
- 住民税計算:
課税所得 × 10% - 手取り年収:
年収 - 社会保険料 - 所得税 - 住民税 - 月手取り:
手取り年収 ÷ 12
出力:
number: 月手取り額(円)
関数名: simulateRetirement(opts)
入力パラメータ:
interface SimulationOptions {
startAge: number; // シミュレーション開始年齢
retirementAge: number; // 退職年齢
pensionStartAge: number; // 年金開始年齢
gapIncome: number; // 退職後収入(月額)
salary: number; // 年収
monthlyPension: number; // 年金月額
initialCash: number; // 開始時現金
initialInv: number; // 開始時投資残高
expenseCurrent: number; // 現役時生活費(月額)
expenseGap: number; // 退職後生活費(月額)
expenseRetired: number; // 老後生活費(月額)
investRate: number; // 投資率(0-1)
annualInterest: number; // 年利回り(0-1)
eventProb: number; // イベント発生率(0-1)
eventTypes: EventType[]; // イベント種別配列
}
interface EventType {
name: string; // イベント名
cost: number; // 費用
}処理フロー:
- 100歳まで年齢をループ
- 各年齢で1-12月をループ
- 年初(1月)に投資残高に利息適用
- 年齢に応じた収入判定:
age < retirementAge: 給与収入(年齢に応じた年収で計算、投資積立含む)retirementAge ≤ age < pensionStartAge: 退職後収入age ≥ pensionStartAge: 年金収入
- 年齢に応じた生活費差引
- ランダムイベント処理
- 現金不足時の投資補填処理
- 月次結果を配列に追加
出力:
string[]: 月次シミュレーション結果の文字列配列
概要: 転職・昇進による年収変更を複数設定可能
データ構造:
interface SalaryChange {
age: number; // 変更年齢
salary: number; // 変更後年収
}機能:
- 年齢指定による年収変更
- 複数設定(転職→昇進の組み合わせ可能)
- 動的な項目追加・削除
- トグル表示(設定エリアの表示/非表示)
- 年齢降順ソート(新しい設定が優先)
処理ロジック:
function getCurrentSalary(age) {
let currentSalary = baseSalary;
for (const change of salaryChanges.sort((a,b) => b.age - a.age)) {
if (age >= change.age) {
currentSalary = change.salary;
break;
}
}
return currentSalary;
}<body>
<h1>老後資金シミュレーター</h1>
<div id="controls"> <!-- 入力コントロール -->
<div id="output"> <!-- 結果表示エリア -->
</body>| フィールドID | ラベル | 型 | 初期値 | 最小値 | 最大値 | 単位 |
|---|---|---|---|---|---|---|
| startAge | シミュレーション開始年齢 | number | 30 | 0 | - | 歳 |
| retirementAge | 退職年齢 | number | 65 | 0 | - | 歳 |
| pensionStartAge | 年金開始年齢 | number | 65 | 0 | - | 歳 |
| gapIncome | 退職後収入(月額) | number | 0 | 0 | - | 円 |
| salary | 給与(年収) | number | 3,000,000 | 0 | - | 円 |
| toggleSalaryChanges | 給与変更設定表示/非表示 | button | - | - | - | - |
| salaryChangeAge | 給与変更年齢 | number | - | 0 | 100 | 歳 |
| salaryChangeSalary | 給与変更後年収 | number | - | 0 | - | 円 |
| monthlyPension | 年金月額 | number | 145,000 | 0 | - | 円 |
| initialCash | 開始時貯金 | number | 1,000,000 | 0 | - | 円 |
| initialInv | 開始時投資残高 | number | 0 | 0 | - | 円 |
| expenseCurrent | 現役時生活費(月額) | number | 155,600 | 0 | - | 円 |
| expenseGap | 退職~年金開始期間の生活費(月額) | number | 228,000 | 0 | - | 円 |
| expenseRetired | 老後生活費(月額) | number | 228,000 | 0 | - | 円 |
| investRate | 投資率(%) | number | 20 | 0 | 100 | % |
| interest | 利回り(年%) | number | 4 | 0 | - | % |
| eventProb | イベント発生率(月%) | number | 1 | 0 | - | % |
表示形式: 等幅フォント、スクロール可能エリア 最大高さ: 400px 背景色: #f9f9f9 ボーダー: 1px solid #ddd
出力例:
-- 30歳1月 --
給与: ¥188,125 (投資: ¥37,625)
生活費: ¥155,600
現金: ¥1,032,525 投資: ¥37,625 総資産: ¥1,070,150
-- 35歳1月 -- (転職の例)
給与: ¥251,250 (投資: ¥50,250) [年収: ¥4,000,000]
生活費: ¥155,600
現金: ¥1,247,525 投資: ¥725,125 総資産: ¥1,972,650
-- 65歳3月 -- (投資補填の例)
年金: ¥145,000
生活費: ¥228,000
🔄 投資から補填: ¥83,000 (税金: ¥16,600)
現金: ¥0 投資: ¥900,400 総資産: ¥900,400
const eventTypes = [
{name:'入院',cost:200000},
{name:'歯科治療',cost:50000},
{name:'薬の購入',cost:20000},
{name:'家電故障',cost:100000},
{name:'車検',cost:80000},
{name:'冠婚葬祭',cost:120000},
{name:'健康診断',cost:30000},
{name:'引越し',cost:200000}
];グローバル変数: なし(関数型プログラミング) データの永続化: なし(セッション毎にリセット) 入力値の取得: DOM要素から動的取得
適用タイミング: 毎年1月1日
計算式: 新残高 = 前年残高 × (1 + 年利回り)
小数処理: Math.round() で四捨五入
if(cash < 0 && investBal > 0){
const need = -cash; // 必要額
const draw = Math.min(investBal, need); // 実際の取り崩し額
const tax = draw * 0.2; // 20%の税金
investBal -= (draw + tax); // 投資残高減少(補填額 + 税金)
cash += draw; // 現金増加(補填額のみ)
}税金考慮の詳細:
- 税率: 20%(譲渡所得税等を想定)
- 税金対象: 投資から取り崩した金額
- 投資残高への影響: 補填額 + 税金を減算
- 現金への影響: 補填額のみを加算(税金分は現金化されない)
判定: Math.random() < eventProb
イベント選択: eventTypes[Math.floor(Math.random()*eventTypes.length)]
実行頻度: 毎月判定
- 時間計算量: O(年数 × 12) = O(70 × 12) = O(840) ≈ O(1)
- 空間計算量: O(年数 × 12 × 平均行数) ≈ O(5000行)
- 計算処理: 100ms以下
- 画面描画: 200ms以下
実装方針: HTML5のバリデーション属性を活用
<input type="number" min="0" step="0.1">不正値の扱い:
parseFloat()でNaNの場合は0にフォールバック- 負の値は自然に処理(マイナス資産として表示)
対応ブラウザ:
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
必要JavaScript機能:
- ES6 Arrow Functions
- Template Literals
- Destructuring Assignment
- Array.filter/find/forEach
- ローカル実行: サーバーとの通信なし
- データ永続化なし: ブラウザを閉じると全データ消去
- 外部依存なし: CDNや外部ライブラリ不使用
- 数値のみ: type="number"で文字列入力を制限
- XSS対策: textContentを使用(innerHTML使用なし)
テスト対象関数:
calculateNetMonthly()simulateRetirement()
テストケース分類:
- 正常系: 一般的な入力値での動作確認
- 境界値: 0、最大値での動作確認
- 異常系: 負の値、無効な値での動作確認
- 給与変更系: 転職・昇進による年収変更の動作確認
テストシナリオ:
- 30年間のライフサイクル全体テスト
- 各期間(現役・退職後・年金受給)の遷移テスト
- 投資機能と補填機能の連携テスト
- 給与変更機能とライフサイクルの連携テスト
- 複数回の転職・昇進パターンテスト
独自実装:
class TestSuite {
test(name, testFn) { /* テスト登録 */ }
run() { /* 全テスト実行 */ }
displayResults() { /* 結果表示 */ }
}アサーション関数:
assertEquals(actual, expected, message)assertApproxEquals(actual, expected, tolerance, message)assertTrue(condition, message)assertContains(text, substring, message)
- 配布方法: HTMLファイルの直接配布
- インストール: 不要
- 更新方法: ファイル差し替え
- ログ出力: console.assertによる開発者向けログのみ
- エラー監視: ブラウザの開発者ツールで確認
- データバックアップ: 不要(永続化データなし)
- 設定バックアップ: ユーザーが手動でメモ
- JavaScript無効環境では動作不可
- 計算精度は浮動小数点数の限界内
- 税制・年金制度の将来変更は未考慮
- インフレ・デフレ影響は未考慮
- 投資売却時の税金は一律20%で簡略化(実際の税制は複雑)
- 特定口座(源泉徴収あり)、NISA等の税制優遇制度は未考慮
- モダンブラウザ環境
- JavaScript有効
- 800×600以上の画面解像度
- インフレ率考慮機能
- 複数シナリオ比較機能
- グラフ表示機能
- 設定保存・読込機能
- PDF出力機能
- 給与変更の理由記録機能(転職・昇進・減給の区別)
- 賞与・臨時収入の設定機能
- TypeScript化
- モジュール分割
- Web Workers活用
- PWA対応
文書バージョン: 1.2
最終更新日: 2024年12月
作成者: システム開発チーム
v1.1 変更点: 投資補填時の税金(20%)考慮を追加
v1.2 変更点: 給与変更機能(転職・昇進対応)を追加