プログラミング上達したい人が書くブログ

プログラミング上達したい人が書くブログ

主に、アニメやPython、C++、競技プログラミング(初心者)について書きたいです。また、1週間に一つの記事を心掛けています。学生です。備忘録と書かれたものは他人に見せることを考えて書いてないため見にくいです。

Python使って株で楽して生きたい人生だった... 

はじめに

 楽して金を稼ぎたいと思ったけど、現実ではだめったったよという人のページです。ニートみたいな生活がしたいなあ... 

 

今回使ったライブラリ

 今回使ったライブラリは以下のようになります。

  • scikit-learn

 言わずと知れた機械学習ライブラリです。様々な機械学習に対応していて、今回は、そのなかの回帰直線とSVM(サポートベクターマシーン)を用いています。

  • numpy

 数値計算ライブラリです。これを使うことで行列の計算が容易にできます。

  • pandas

 今回は、データ収集のためにCSVファイルを使うため入れています。

  • pandas_datareader

 yahooやGoogleFinanceから企業の株価などを取得できるが、なんかできなかった

 yahooAPIが現在よろしくないらしいです。

 

今回の主な方針

 まず、説明変数には「終値」と、「後10日分の終値を用いて作った回帰直線の回帰係数」を用いています。

 理由としては、今回株をどのようにとらえるかに起因します。私は、株価の推移を波だととらえ、波であればある点の接線の傾きを求めれば、下がる瞬間が事前に分かることになると考えました。しかし、当然株価を数式として微分することはできません。そこで考えたものが回帰直線です。これを使うことで接線のようなものが取れると考えました。

 そして、目的変数には次の日の株価が上がるか下がるかを使っています。

データを取得してみる

CSVファイルでの取得は株価データサイト k-db.comでできます。

また、CSVファイルを読み込んで、その中から終値を取り出す部分のソースコードは以下のようになる。また、kabutest2_1.csvで株価のデータは保存しています。

as_matrix()でNumpyのarrayで使えるようにしています。

df = pd.read_csv("kabutest2_1.csv",encoding = 'cp932')
x1 = df["終値"].as_matrix()
 

 目的変数と説明変数を作ってみる

 まず、目的関数の一つである終値の値は、上記ですでに完了しています。そこで、残りをmake(f)という関数をつくって作成しました。その中の、回帰係数を求める部分のソースコードが以下のようになります。

 ソースコードの内容は、まず、後10日分の終値を用いて回帰直線を作るうえで、最初の10日間はデータの個数が10個以下のため、前の日の終値を含めたもので回帰直線を作っています。そして、「clf.coef_」が回帰係数を表しています。最初の「for」がこれに対応しています。また、最初の2日間は回帰直線すら作れないため3日目に作ったものを「配列a」に入れています。

 次の「for」は、10日分のデータを用いて回帰直線を作り、「配列a」に追加しています。追加するためには、np.append()で使うことができます。

    a = np.array([])
  #ここでいうfは、終値の配列、つまり上記のx1のことである。 for n in range(2,10): x = f[0:n] time = np.arange(n) time = time.reshape(-1,1) x = x.reshape(-1,1) clf = linear_model.LinearRegression() clf.fit(time,x) if n == 2: a = np.append(a,clf.coef_) a = np.append(a,clf.coef_) a = np.append(a,clf.coef_) for n in range(10,f.shape[0]): x = f[n-10:n] time = np.arange(n-10,n) time = time.reshape(-1,1) x = x.reshape(-1,1) clf = linear_model.LinearRegression() clf.fit(time,x) a = np.append(a,clf.coef_)

 

 以下のソースコードは、make関数内の目的変数を作る部分である。内容は、次の日のデータが上がったときにに目的変数の配列に1を代入、逆に下がったときに0を代入するものです。ただ、最後の日が分からなかったため、1をとりあえず入れときました。

また、最後のreturnで説明変数の一部である回帰係数を入れた配列aと目的変数であるbを戻り値としています。

    b = np.array([])
    for n in range(0,f.shape[0]-1):
        if f[n] <= f[n+1]:
            b = np.append(b,1)
        else:
            b = np.append(b,-1)
    b = np.append(b,1)

    return a,b

 

 以下のソースコードはメイン関数内のものです。これは、上部で作ったa,bをそれぞれx2,yに入れています。そして、回帰係数が次の日のほうが高かった場合は、x3に1を入れていて、下がった場合は-1を入れています。

x2,y = makex1(x1)
x3 = np.array([])
for n in range(0,x2.shape[0]-1):
    if x2[n] <= x2[n+1]:
        x3 = np.append(x3,1)
    else:
        x3 = np.append(x3,-1)
    x3 = np.append(x3,1)

これで、目的変数と説明変数の原型が完成です。今回のプログラムでは目的変数にy、説明変数にx1とx3を使います。

 

説明変数を一つの配列にまとめる

よく仕組みはわかりません。とりあえず「Python 行列の連結」で調べました。

x = np.empty((0,2), float)
for nm in range(0,x1.shape[0]):
    d = [x1[nm],x3[nm]]
    x = np.append(x,np.array([d]),axis = 0)

 

SVCを使って機械学習とそれを用いて予測を行う

  予測に使うテストデータを用意するのがめんどくさかったため作ったxとyの最後尾10個のデータを使うことにしました。よって、機械学習させるとき、ranを作ってスライスを使っています。

 predictedには予測した結果を入れています。

clf = svm.SVC(gamma = 0.01, C = 100)
ran = x.shape[0]-10
test = x[ran:ran+10]
clf.fit(x[:ran],y[:ran])

predicted = clf.predict(test)

 

結果の表示部分

表示したソースコードは以下になります。

print(y[ran:ran+10])
print(predicted)

 

実行結果

 ええ。全然違います。ちなみに上が実際のデータでしたが予測されたデータです。

[ 1.  1. -1.  1.  1.  1.  1. -1.  1.  1.]
[-1. -1. -1. -1. -1. -1.  1.  1. -1. -1.]

 

終わりに

 結局どうすればええんや...。別のデータでやったときは8割の成功率だったから結局平均すると5割に落ち着くのかなあ。なにかこれを読めばよいという書籍などがあったら教えてほしいです。