機械学習で株価分析 17.C++を用いた単純な数値解析例

# はじめに
本記事では、**C++を用いた資産運用シミュレーションの単純な数値解析例**を紹介します。紹介するプログラムでは、取引回数や取引の成功率を設定することで、手数料やマーケットインパクト等の誤差要因は全く考慮しない単純な運用モデルをシミュレーションできます。

# フローチャート
### 1. パラメータの設定
以下のパラメータを任意に設定します。

* 試行回数：運用シミュレーション自体の反復回数を指定します。
* トレード回数：取引を行う累計日数を指定します。
* １日のトレード回数：1日に何度取引を行うかを指定します。
* 初期資産：運用を行う初期資産です。1を設定すれば期待値が算出されます。
* 予測の正解率：自身で構築した予測モデルの適合率を設定します。
* 正解時の上がり幅：予測が的中した場合に資産が増加する割合を設定します。
* 不正解時の下がり幅：予測が失敗した場合に資産が減少する割合を設定します。


### 2. 数値シミュレーションの試行
以下の手順で数値シミュレーションを試行します。

1. 取引予測シミュレーションのための乱数を生成
2. 乱数に基づき取引成否のフラグを設定
3. 取引成否のフラグに従い資産の増減を計算
4. 指定回数経過後の資産をアウトプット用変数に格納

ソースコードの該当箇所は以下の通りです。
```cpp
	// 数値シミュレーションの試行 -------------------------------------------------------

	for (int i = 0; i < iters; i++) {

		double value = start_value;

		for (int j = 0; j < trade_day * trade_num; j++) {

			double num = (double)rand() / RAND_MAX;
			bool flg_collect = false;
			if (num < pred_acc) { flg_collect = true; }

			if (flg_collect == true) {value = value * th_plus;}
			else {value = value * th_minus;	}

		}

		total_value[i] = value;

	}
```


### 3. シミュレーション結果の分析
シミュレーション結果として、以下のアウトプットを表示します。
* 資産の運用結果
* 運用後に資産がマイナスとなっている確率


ソースコードの該当箇所は以下の通りです。
```cpp
	// シミュレーション結果の分析 --------------------------------------------------------

	// 資産増加の期待値を算出
	double mean = 0.0;
	for (int i = 0; i < iters; i++) {
		mean += total_value[i];
	}

	mean = mean / iters;

	std::cout << " mean = " << mean << std::endl;

	// トータルでドローダウンが発生する確率を算出
	double ddp = 0.0;
	int ddp_count = 0;
	for (int i = 0; i < iters; i++) {
		if (total_value[i] < start_value) { ddp_count += 1; }
	}

	ddp = double(ddp_count) / double(iters);

	std::cout << " drowdown_per = " << ddp * 100.0 << std::endl;
```

# ソースコード全文
以下にソースコード全文を示します。

```cpp
#include <iostream>
#include <time.h>

int main() {

	// 初期設定 ------------------------------------------------------------------------

	// 乱数調整用設定
	srand(time(NULL));

	// パラメータ設定
	const int iters     = 10000;		// 試行回数
	const int trade_day =   240;		// トレード回数（240は1年間を仮定）
	const int trade_num =     1;		// １日のトレード回数
	const double start_value = 1.00;	// 初期資産
	const double pred_acc    = 0.60;	// 予測の正解率
	const double th_plus     = 1.01;	// 正解時の上がり幅
	const double th_minus    = 0.99;	// 不正解時の下がり幅

	// アウトプット用変数作成
	double total_value[iters] = { 0.0 };


	// 数値シミュレーションの試行 -------------------------------------------------------

	for (int i = 0; i < iters; i++) {

		double value = start_value;

		for (int j = 0; j < trade_day * trade_num; j++) {

			double num = (double)rand() / RAND_MAX;
			bool flg_collect = false;
			if (num < pred_acc) { flg_collect = true; }

			if (flg_collect == true) {value = value * th_plus;}
			else {value = value * th_minus;	}

		}

		total_value[i] = value;

	}


	// シミュレーション結果の分析 --------------------------------------------------------

	// 資産増加の期待値を算出
	double mean = 0.0;
	for (int i = 0; i < iters; i++) {
		mean += total_value[i];
	}

	mean = mean / iters;

	std::cout << " mean = " << mean << std::endl;

	// トータルでドローダウンが発生する確率を算出
	double ddp = 0.0;
	int ddp_count = 0;
	for (int i = 0; i < iters; i++) {
		if (total_value[i] < start_value) { ddp_count += 1; }
	}

	ddp = double(ddp_count) / double(iters);

	std::cout << " drowdown_per = " << ddp * 100.0 << std::endl;

	std::cin.get();

	return 0;

}
```
プログラムを実行し、コンソール上に期待値の平均とドローダウン率の平均が表示されれば成功です。

# 目次へのリンク

https://qiita.com/ryo2_9393/items/2b1ada62c2537c901b6b