正規分布に運用期間を追加

以前作成した正規分布のシミュレーションに、運用期間yearsを追加します。

色々と調整(抽出数を100,000回、xbins:size: maxNd/1000,)した結果が以下









データ 数値
個数
平均
分散
標準偏差σ
中央値

コードは以下

<!DOCTYPE html>
<html>
  <head>
    <!-- Load plotly.js into the DOM -->
    <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
  </head>
  <body>
    <div id="myDiv" class="box1" ><!-- Plotly chart will be drawn inside this DIV --></div>
    
    <!-- フォームの追加 --> 
 
    <form class="box2" onsubmit="redrawChart(event)">

      <div>
        <label for="currentValue">初期投資額(万円)</label>
    </br>
        <input type="number" id="currentValue" value="100" min="0" >
      </div>
    </br>
      <div>
        <label for="averageReturnRate">期待リターン(年率%):</label>
    </br>
        <input type="number" id="averageReturnRate" value="10" min="0" >
      </div>
    </br>
      <div>
        <label for="riskRate">想定リスク(標準偏差,年率%):</label>
    </br>
        <input type="number" id="riskRate" value="10" min="0">
      </div>
    </br>
      <div>
        <label for="years">運用期間(年)</label>
    </br>
        <input type="number" id="years" value="5" min="0">
      </div>
    </br>

  <!-- 再描画ボタンの追加 -->
  <div class="rebutton">
    <button onclick="redrawChart()">再描画</button>
      </div>

  </form>

<div class="clear"></div>

    <!-- 全体数値の表 -->
    <div class="tables-container">
      <div>
        <table class="table-container" border="1">
          <tr>
            <th>データ</th>
            <th>数値</th>
          </tr>
          <tr>
            <td>個数</td>
            <td><span id="pieces"></span></td>
          </tr>
          <tr>
            <td>平均</td>
            <td><span id="average"></span></td>
          </tr>
          <tr>
            <td>分散</td>
            <td><span id="variance"></span></td>
          </tr>
          <tr>
            <td>標準偏差σ</td>
            <td><span id="sd"></span></td>
          </tr>
          <tr>
            <td>中央値</td>
            <td><span id="median"></span></td>
          </tr>
        </table>
      </div>
      </div>

    <script>
      
    var averageReturnRate;
    var riskRate;
    var currentValue;
    var years;  
    var nd = [];

           
 window.onload = function () {
  // フォームの初期値を設定
  document.getElementById('averageReturnRate').value="10";
  document.getElementById('riskRate').value="10";
  document.getElementById('currentValue').value="100";
  document.getElementById('years').value="10";

  // 初回描画
  redrawChart(event);
};

      
function redrawChart(event) {
  // Prevent the default form submission behavior
  event.preventDefault();
      
        // データをクリア
        nd = [];
  
  // フォームの値を取得   
  averageReturnRate = parseFloat(document.getElementById('averageReturnRate').value);
  riskRate = parseFloat(document.getElementById('riskRate').value);
  currentValue = parseFloat(document.getElementById('currentValue').value);
  years = parseFloat(document.getElementById('years').value);

  // getRandomValue()を呼び出して100,000回発生させる
  getRandomValue(averageReturnRate, riskRate, currentValue, years);      
 
 

      // データの個数を表示
      document.getElementById("pieces").textContent = nd.length;

      // データの合計を求める
      const sum = nd.reduce((a, b) => a + b, 0);

      // データの平均を求める
      const average = sum / nd.length;
      document.getElementById("average").textContent = average.toFixed(2);

   
  // データの分散を求める
      const sumSquaredDiff = nd.reduce((a, b) => a + (b - average) ** 2, 0);
      const variance = sumSquaredDiff / nd.length;
      document.getElementById("variance").textContent = variance.toFixed(2);

      // データの標準偏差を求める
      const standardDeviation = Math.sqrt(variance);
      document.getElementById("sd").textContent = standardDeviation.toFixed(2);

      // データの中央値を求める
      const sortedData = [...nd].sort((a, b) => a - b);
      const middle = Math.floor(sortedData.length / 2);
      const median =
        sortedData.length % 2 === 0
          ? (sortedData[middle - 1] + sortedData[middle]) / 2
          : sortedData[middle];
      document.getElementById("median").textContent = median.toFixed(2);
  
      // データの最大値と最小値を求める   
      maxNd = Math.max(...nd);
      minNd = Math.min(...nd);  
  
      var nd1 = [];
      var nd2 = [];
      var nd3 = [];
      var nd4 = [];
      var nd5 = [];
      var nd6 = [];
      var nd7 = [];
      var nd8 = [];
   

         function getRandomValue(averageReturnRate, riskRate, currentValue, years) {
            var x, y, z, re, s;


            for (let i = 0; i < 100000; i++) {
                re = 1; // 内側のループ前に re を初期化

                for (let j = 0; j < years; j++) {
                    x = Math.random();
                    y = Math.random();
                    z = Math.sqrt(-2 * Math.log(x)) * Math.cos(2 * Math.PI * y);
                    re *= (1 + averageReturnRate * 0.01 + riskRate * 0.01 * z);
                }

                s = currentValue * re;

                nd.push(s);
            }
            return nd; // 関数の戻り値として nd を返す
        } 

 
  // ヒストグラムの各バーに対する色を決定する関数
      function getColor(value) {
        const deviation = (value - average) / standardDeviation;
        if (deviation <= -3) {
          return "purple"; // -3標準偏差超
        } else if (deviation < -2) {
          return "orange"; // -3標準偏差以内
        } else if (deviation < -1) {
          return "cyan"; // -2標準偏差以内
        } else if (deviation < 0) {
          return "brown"; // -1標準偏差以内
        } else if (deviation < 1) {
          return "red"; // 1標準偏差以内
        } else if (deviation < 2) {
          return "green"; // 2標準偏差以内
        } else if (deviation < 3) {
          return "blue"; // 3標準偏差以内
        } else {
          return "yellow"; // 3標準偏差超
        }
      }

        // データを各範囲に分ける
      nd.forEach((value) => {
        const color = getColor(value);
        if (color === "purple") {
          nd1.push(value);
        } else if (color === "orange") {
          nd2.push(value);
        } else if (color === "cyan") {
          nd3.push(value);
        } else if (color === "brown") {
          nd4.push(value);
        } else if (color === "red") {
          nd5.push(value);
        } else if (color === "green") {
          nd6.push(value);
        } else if (color === "blue") {
          nd7.push(value);
        } else {
          nd8.push(value);
        }
      });

      var trace1 = {
        x: nd1,
        type: "histogram",
        marker: {
          color: "purple",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: minNd,
        },
        bingroup: "group1", // 各トレースを同じグループに追加
      };

      var trace2 = {
        x: nd2,
        type: "histogram",
        marker: {
          color: "orange",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: minNd,
        },
        bingroup: "group2", // 各トレースを同じグループに追加
      };

      var trace3 = {
        x: nd3,
        type: "histogram",
        marker: {
          color: "cyan",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: minNd,
        },
        bingroup: "group3", // 各トレースを同じグループに追加
      };
      var trace4 = {
        x: nd4,
        type: "histogram",
        marker: {
          color: "brown",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: -minNd,
        },
        bingroup: "group4", // 各トレースを同じグループに追加
      };
      var trace5 = {
        x: nd5,
        type: "histogram",
        marker: {
          color: "red",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: minNd,
        },
        bingroup: "group5", // 各トレースを同じグループに追加
      };
      var trace6 = {
        x: nd6,
        type: "histogram",
        marker: {
          color: "green",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: minNd,
        },
        bingroup: "group6", // 各トレースを同じグループに追加
      };
      var trace7 = {
        x: nd7,
        type: "histogram",
        marker: {
          color: "blue",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: minNd,
        },
        bingroup: "group7", // 各トレースを同じグループに追加
      };
      var trace8 = {
        x: nd8,
        type: "histogram",
        marker: {
          color: "yellow",
        },
        xbins: {
          end: maxNd,
          size: maxNd/1000,
          start: minNd,
        },
        bingroup: "group8", // 各トレースを同じグループに追加
      };

      var data = [trace1, trace2, trace3, trace4, trace5, trace6, trace7, trace8];

      var layout = {
        bargap: 0.01,
        bargroupgap: 0.01,
        title: "Sampled Results",
        xaxis: { title: "Value" },
        yaxis: { title: "Count" },
      };

         Plotly.newPlot("myDiv", data, layout); 
    }

    </script>
  </body>
</html>

コメント

タイトルとURLをコピーしました