Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

TensorFlowで株価予想シリーズ

はじめに

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

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

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

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

7 - 株価が何%上昇すると予測したら買えばいいのか?

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

コードの変更箇所

コードは github に上げてあります。

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

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)

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

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

とあるのは上位30位以外に上位5位、10位、20位と計算させるためです。

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

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に全銘柄の購入日が入るので、これを使って売買シミュレーションを行うのがこちらのスクリプトです。

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

実行

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

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

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

$ python calc_top.py

シミュレーションの実行

$ python gamble.py

結果

上位5銘柄、10銘柄、20銘柄、30銘柄を各10回づつ行った結果がこちらです。

上位5銘柄

回数 残額
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%の増加でしかないですね。

おわりに

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

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

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

akiraak
アーケード・コンシューマゲーム/オンラインゲーム/スマホアプリ/WEBサービスなどのプログラミングをやってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away