[TensorFlowで株価予想] 9 - 年利6.79%

# TensorFlowで株価予想シリーズ

+ [0 - Google のサンプルコードを動かしてみる](http://qiita.com/akiraak/items/b27a5616a94cd64a8653)
+ [1 - 終値が始値よりも高くなるかで判定してみる](http://qiita.com/akiraak/items/52aebc558ee312dba2b5)
+ [2 - 日経平均225銘柄の株価予想正解率ランキング〜](http://qiita.com/akiraak/items/706f74eeba95ec32cf16)
+ [3 - 日本3506銘柄の株価予想ランキング](http://qiita.com/akiraak/items/3e1ecbb9acfd872b944a)
+ [4 - 実際に売買したら儲かるのかシミュレーションしてみる](http://qiita.com/akiraak/items/27d8e91982d3322873c3)
+ [5 - 大きく上がると予想されたときだけ買ってみるシミュレーション](http://qiita.com/akiraak/items/fe45001ad011178fae5e)
+ [6 - 学習データの項目を増やす！隠れ層のサイズも増やす！](http://qiita.com/akiraak/items/61def86cc8070d0fa4b2)
+ [7 - 株価が何%上昇すると予測したら買えばいいのか？](http://qiita.com/akiraak/items/5d08587ac460c253492d)
+ [8 - どの銘柄を買うか](http://qiita.com/akiraak/items/5e8a8c761f098a4a68fb)
+ [9 - 年利6.79%](http://qiita.com/akiraak/items/8eec7ed4ec0b383f6592)


# はじめに

これまで学習データやパラメーターなどを調整してきてなんとか黒字になる状態にもってきました。そして前回、日経平均２２５の銘柄の中から優れた成績を残せる３０銘柄を抽出しました。株価予想シリーズの最後として、この銘柄を使用した売買シミュレーションを行います。

# 売買シミュレーション方法

今までと同様に直近200日よりも過去のデータで予測器を作り、売買は直近200日のデータで行います。買いと予測したら当日の始値で購入し終値で売ります。元金は1000万円とし、手数料はGMOクリック証券のものを使います。

買いと判断する条件は大きく株価が上昇すると予想したときのみです。計算方法は以下の記事を参照してください。

[7 - 株価が何%上昇すると予測したら買えばいいのか？](http://qiita.com/akiraak/items/5d08587ac460c253492d)

銘柄にもよりますが、２００日の中でも多くても１０日、少ないと２日ほどしか買いと予想する日がでません。そこで３０銘柄全てで予測を行い、できるだけ多くの日で売買を行うようにします。

# コードの変更箇所

コードは [github](https://github.com/akiraak/tensorflow-stock-index/tree/9) に上げてあります。

まず、今回のシミュレーションとはあまり関係がないですが、学習したセッションはファイルに保存して次回から予測のみ行えるようにしました。`saver.save()`で保存。`saver.restore()`で読み出し。ものすごい簡単です。

```py:goognet.py
def save_sess_dir_path(target_brand):
    return os.path.join('sess_save', target_brand)


def save_sess_file_path(target_brand):
    return os.path.join(save_sess_dir_path(target_brand), 'sess.ckpt')


def save_sess(saver, sess, target_brand):
    dir_path = save_sess_dir_path(target_brand)
    # 既存のファイル（保存ディレクトリ）あったら削除
    if os.path.exists(dir_path):
        shutil.rmtree(dir_path)
    os.makedirs(dir_path)
    file_path = save_sess_file_path(target_brand)
    # 保存
    saved_path = saver.save(sess, file_path)


def restore_sess(saver, sess, target_brand):
    file_path = save_sess_file_path(target_brand)
    # 読み出し
    saver.restore(sess, file_path)
```

学習器の作成と、全銘柄の購入日を抽出する実行スクリプトです。

```py:calc_top.py
# -*- coding: utf-8 -*-
import os
from brands import nikkei225_excellent
from brands import (
    nikkei225_excellent5, nikkei225_excellent10,
    nikkei225_excellent20, nikkei225_excellent30
)


brands = nikkei225_excellent5
#brands = nikkei225_excellent10
#brands = nikkei225_excellent20
#brands = nikkei225_excellent30
layer1 = 512
layer2 = 512


file_path = 'up_expectation_dates.csv'
if os.path.exists(file_path):
    os.remove(file_path)

for i, (code, name, _) in enumerate(brands):
    print '{} / {}: {} {}'.format(i + 1, len(brands), code, name)
    commena = 'python goognet.py {} --layer1={} --layer2={} --load_sess=0'.format(code, layer1, layer2)
    print commena
    os.system(commena)
```

+ nikkei225_excellent5
+ nikkei225_excellent10
+ nikkei225_excellent20
+ nikkei225_excellent30

とあるのは上位３０位以外に上位５位、１０位、２０位と計算させるためです。

そして、今までと同様に銘柄ごとに学習器を作ったあとに直近２００日での予想を行います。買いと判断した日を`up_expectation_dates.csv`に保存します。

```py:goognet.py
def save_up_expectation_dates(target_brand, up_expectation_dates):
    file_path = 'up_expectation_dates.csv'
    brand_dates = []

    # 既存のファイルがあれば読み込む
    if os.path.exists(file_path):
        with open(file_path, 'r') as f:
            brand_dates = [line.split(',') for line in f.read().split('\n')]
    brand_dates.append([target_brand] + up_expectation_dates)

    # 保存
    with open(file_path, 'w') as f:
        data = '\n'.join(','.join(brand) for brand in brand_dates)
        f.write(data)
        print('Saved: {}'.format(file_path))
```

`up_expectation_dates.csv`に全銘柄の購入日が入るので、これを使って売買シミュレーションを行うのがこちらのスクリプトです。

```py:gamble.py
# -*- coding: utf-8 -*-
import os
from download import Download, YahooJp
from goognet import buy_charge


file_path = 'up_expectation_dates.csv'
brand_dates = []

if os.path.exists(file_path):
    with open(file_path, 'r') as f:
        brand_dates = [line.split(',') for line in f.read().split('\n')]

buy_dates = {}
for brand in  brand_dates:
    brand_code = brand[0]
    for date in brand[1:]:
        if not date in buy_dates:
            buy_dates[date] = brand_code

# 元金
money = 10000 * 1000
for date, brand in sorted(buy_dates.items()):
    price = YahooJp(brand).price(date)

    # 始値
    open_value = float(price[Download.COL_OPEN])
    # 終値
    close_value = float(price[Download.COL_CLOSE])
    # 購入可能な株数
    value = money / open_value
    # 購入金額
    buy_value = int(open_value * value)
    # 売却金額
    sell_value = int(close_value * value)
    # 購入
    money -= buy_value
    # 購入手数料の支払い
    money -= buy_charge(buy_value)
    # 売却
    money += sell_value
    # 売却手数料の支払い
    money -= buy_charge(sell_value)
    print date, money
print money
```

# 実行

上位何銘柄でシミュレーションを行うかをコメントアウトで切り替えて

```py:calc_top.py
brands = nikkei225_excellent5
#brands = nikkei225_excellent10
#brands = nikkei225_excellent20
#brands = nikkei225_excellent30
```

学習器の作成と購入日を`up_expectation_dates.csv`に出力させ

```shell-session
$ python calc_top.py
```

シミュレーションの実行

```shell-session
$ python gamble.py
```

# 結果

上位５銘柄、１０銘柄、２０銘柄、３０銘柄を各1０回づつ行った結果がこちらです。

## 上位５銘柄

|回数|残額|
|----|---|
|1回目|¥10,410,342|
|2回目|¥10,495,494|
|3回目|¥10,554,624|
|4回目|¥10,546,253|
|5回目|¥10,304,526|
|6回目|¥10,029,905|
|7回目|¥10,158,051|
|8回目|¥9,627,332|
|9回目|¥9,976,178|
|10回目|¥10,831,149|
|平均|¥10,293,385|

## 上位10銘柄

|回数|残額|
|----|---|
|1回目|¥10,452,770|
|2回目|¥10,881,892|
|3回目|¥10,743,861|
|4回目|¥11,051,619|
|5回目|¥10,041,100|
|6回目|¥8,972,956|
|7回目|¥12,452,135|
|8回目|¥10,855,471|
|9回目|¥10,524,320|
|10回目|¥10,818,896|
|平均|¥10,679,502|

## 上位20銘柄

|回数|残額|
|----|---|
|1回目|¥10,177,247|
|2回目|¥9,745,797|
|3回目|¥9,865,475|
|4回目|¥10,445,807|
|5回目|¥10,870,933|
|6回目|¥12,298,093|
|7回目|¥11,030,003|
|8回目|¥9,366,829|
|9回目|¥9,725,394|
|10回目|¥8,810,439|
|平均|¥10,233,602|

## 上位30銘柄

|回数|残額|
|----|---|
|1回目|¥9,270,903|
|2回目|¥7,903,217|
|3回目|¥8,200,191|
|4回目|¥8,454,232|
|5回目|¥10,598,087|
|6回目|¥11,938,333|
|7回目|¥10,117,542|
|8回目|¥8,961,300|
|9回目|¥10,874,380|
|10回目|¥9,419,724|
|平均|¥9,573,791|


20銘柄、30銘柄では赤字になる場合が多いようです。上位10銘柄を使用した時がもっとも良いのですが、それでも200日で106%の増加でしかないですね。

# おわりに

成績の良い銘柄を複数使って売買を行えば、購入の機会が増えて結果がもっとよくなると思っていたのですが、どうやらそんなに変わらないようです。年利６％であれば税金に40%持っていかれるとして年利3.6%。20年運用すると元金が２倍になるくらいです。国債よりは良いけれどもあまり美味しいとはいえないですね。

改善として学習データの変更や、判定方法の変更はできると思いますが、実際に売買を行おうとしたときの問題点を一通り検証できたので、シリーズはここで一段落とします。

そして、もっと結果の良い方法を見つけたら、こっそりと教えてください！よろしくお願い致しますｍ(_ _)ｍ