前回までのあらすじ
本記事は単独で話が完結するように心がけてはおりますが、以下の拙作記事をご一読いただくと、話の流れがより明確になります。
はじめに
今回は機械学習とは別の方法で、NIKKEI225の翌日の値幅(引値-寄り値)がプラスかマイナスかを予測してみる。
着目する点は、チャートをローソク足で見ると、陽線がしばらく継続したり、陰線が継続したりすることがけっこう頻繁に起こるということ。「3日間の連騰」とか「4日続落」とか。
- 陽線=値幅(引値-寄り値)の符号がプラス
- 陰線=値幅(引値-寄り値)の符号がマイナス
もし、今日が陽線だったとして、明日陽線となる確率と陰線になる確率が異なれば、確率の大きいほうを予想値とすれば、予想が当たる可能性が高まるという算段。
陰陽バイグラム
さっそく、NIKKEI225が、連続で陽線または陰線をつける割合を調べてみる。
NIKKEI225の株価データをcsvで落として、
Date,Open,High,Low,Close,Volume
2017-10-31,21896.38,22020.38,21840.07,22011.61,1055801728.0
2017-10-30,22047.95,22086.88,21921.24,22011.67,1397960064.0
2017-10-27,21903.27,22016.5,21815.72,22008.45,1241389952.0
2017-10-26,21698.95,21793.62,21688.56,21739.78,851784320.0
2017-10-25,21900.13,21921.36,21648.35,21707.62,1258339712.0
...
以下のコードで、陽陽、陰陽、陽陰、陰陰の割合を調べる。
import pandas as pd
import numpy as np
nikkei_225 = pd.read_csv('NIKKEI225.csv').set_index('Date').sort_index()
open_list = nikkei_225['Open'].tolist()
close_list = nikkei_225['Close'].tolist()
diff_list = np.array(close_list) - np.array(open_list)
posiposi = 0
posinega = 0
negaposi = 0
neganega = 0
for i in range(len(diff_list)-1):
if diff_list[i]>=0 and diff_list[i+1]>=0:
posiposi = posiposi + 1
elif diff_list[i]>=0 and diff_list[i+1]<0:
posinega = posinega + 1
elif diff_list[i]<0 and diff_list[i+1]>=0:
negaposi = negaposi + 1
else:
neganega = neganega + 1
print(posiposi, posinega, negaposi, neganega)
2014-10-30_2017-10-31 735件の株価で
陽陽=170件
陽陰=195件
陰陽=195件
陰陰=175件
であった。
これより、
- 今日のNikkei225が陽線なら
- 明日陽線になる確率=170/(170+195)=46.57%
- 明日陰線になる確率=195/(170+195)=53.43%
- 今日のNikkei225が陰線なら
- 明日陽線になる確率=195/(175+195)=52.70%
- 明日陰線になる確率=175/(175+195)=47.30%
という結果となった。陽陽と陰陰が多いと思っていたのだけどはずした。でも非対称なのでこれでやってみる。
売買スキーム
-
今日のNikkei225が陽線なら、明日は陽線になる確率よりも陰線になる確率が高いので、
1357NFダブルインバースを寄りで買って引けで売る -
今日のNikkei225が陰線なら、明日は明日は陰線になる確率よりも陽線になる確率が高いので、
1358日経レバ2倍を寄りで買って引けで売る
これを繰り返す。
要は、今日陽線なら明日は陰線、今日陰線なら明日は陽線と予想しているだけ。
これはシステムトレードといえるのだろうか?
損益シミュレーション(バックテスト)
2017-11-01から2020-07-28までの間、上述の売買スキームで、毎回10,000,000円づつ売買を繰り返した場合をシミュレーションしてみた。売買手数料は往復で2026円とした。
コードは以下。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
nikkei225 = pd.read_csv('NIKKEI225.csv').set_index('Date').sort_index()
n1357 = pd.read_csv('1357.csv').set_index('Date').sort_index()
n1358 = pd.read_csv('1358.csv').set_index('Date').sort_index()
nikkei225_open_list = nikkei225['Open'].tolist()
nikkei225_close_list = nikkei225['Close'].tolist()
nikkei225_diff_list = np.array(nikkei225_close_list) - np.array(nikkei225_open_list)
n1357_open_list = n1357['Open'].tolist()
n1357_close_list = n1357['Close'].tolist()
n1357_diff_list = np.array(n1357_close_list) - np.array(n1357_open_list)
n1358_open_list = n1358['Open'].tolist()
n1358_close_list = n1358['Close'].tolist()
n1358_diff_list = np.array(n1358_close_list) - np.array(n1358_open_list)
x = []
y = []
total_gain = 0
for i in range(len(nikkei225_diff_list)-1):
if nikkei225_diff_list[i]>=0: #今日のNikkei225が陽線
# 1357を1000万円分を寄りで買って引けで売る
n = int(10000000/n1357_close_list[i])
daily_gain = n1357_diff_list[i+1]*n - 2026
else: # 今日のNikkei225が陰線
# 1358を1000万円分を寄りで買って引けで売る
n = int(10000000/n1358_close_list[i])
daily_gain = n1358_diff_list[i+1]*n - 2026
total_gain += daily_gain
x.append(i)
y.append(total_gain)
# プロット
plt.plot(x, y, label="total_gain")
plt.show()
print('total_gain=', total_gain)
損益シミュレーション結果
これはいいではないか!
total_gain= 5633247
2017-11-01から2020-07-28の33か月間で、元手の10,000,000円が15,633,247円になったということだから、年率20.48%にもなる計算だ。ほんとうだろうか?皆様の追試希望です。
累積損益グラフは、小刻みに増減しつつも長期的に右肩上がりで、形は悪くない。
結果の考察
- 陰陽の確率を算出した期間は2014-10-30~2017-10-31
- その確率を使ってバックテストした期間は2017-11-01~2020-07-28
ということで、いちおう、学習期間と評価期間は分けたつもり。
たいした学習ではないので、別に学習期間と評価期間を分ける必要もないだろうということで、2014-10-30~2020-07-28の全期間の累積損益グラフをプロットしてみる。
total_gain= 969052
全期間でも累積損益はプラスだけど、前半の700日で損失を拡大させて、後半の700日で取り戻しているグラフになっている。これをどう見るか?
後半の700日は単なる偶然の産物とみるべきだろう。
まとめ
- 陰陽バイグラムに着目してNIKKEI225の翌日の値幅の符号を予測し、これをもとにシステムトレード。
- 一見よさげな結果も得たが、おそらくは単なる偶然の産物。
- これを食扶持にするのは無謀だ。
つづく(かも)