【Pythonコード付き】線形回帰トレンド(単回帰)で暗号通貨を自動売買する方法

今回もビットコインの自動売買プログラムを Python で実装していきます。
これまではボリンジャーバンドやMACDなどのメジャーなテクニカル指標を使って実装してきました。
が、それだけだとPython を使うことのメリットをあまり感じられなかったという方も多かったと思います。
(別に MT 4とかでもできるやん的な)

そこで今回は、基本的な統計モデルである線形回帰モデルを使った自動売買を実装していきます。
統計や機械学習といった分野は Python の得意分野であり、驚くほど簡単にコードをかけるということをわかってもらえると思います。
この記事の目標
線形回帰トレンドから相場が上昇局面にあると判断された時に、自動でビットコインを購入するコードを書く

線形回帰分析とは?

まずはじめに線形回帰分析について簡単におさらいしておきましょう。
線形回帰モデルは大学で統計の授業を取ると、とりあえずやらされるやつですね。
上の図は、ある店のアイスクリームの販売数量とその日の気温の関係を表したものです(数字は適当に考えました)。
(軸に単位がなくてすみません。縦軸が(個)、横軸が(℃)だと思ってください)

なんとなく気温が高いほどアイスクリームが売れている傾向にありますね。
この図をずっと眺めていると、このデータの全体的な傾向を単純な直線の式で表したいという願望が生じてきますよね。
(つまり下の図のような直線を引きたいということです)
そこで、 アイスクリームの販売数量をy 気温をx としてyとxの関係を
y = ax + b
としてみましょう 。
ここでaとbの値を上手く決められれば、非常にありがたいです。
例えば
y = 1.3x – 21
という風に決まれば
気温が34℃の日は23個ぐらいアイスクリームが売れるんじゃね
と予想を立てることができますね。
このように目的変数(アイスクリーム販売個数)と説明変数(気温)に直線的な関係を仮定して分析することを線形回帰分析と呼びます。
ちなみに
目的変数yに対し説明変数xは必ずしも一つではなく複数ある場合もありえます(重回帰)。
しかし、あまり話がややこしくなるのもアレなので今回は X が一つだけ(単回帰)の場合しか考えません。
先にネタバレをしておくと、
ビットコインの価格をy
時間経過をx
とした線形回帰の式を最終的に立てていきます。
この場合に例えば

y = 3x + 40

という予測の式が立てられた場合、
時間が経つほど(つまりxが大きくなるほど)ビットコインの価格が上がるんじゃね?(つまりyが大きくなる)
と判断するということです。

単回帰の場合の線型回帰分析のやり方

ここで、実際に線形回帰分析を行う(要はaとbを求める)方法を解説しておきます。
最もメジャーな方法は、直線から予測されるyと実際のyの誤差の2乗和を最小化するようなaとbを計算することです(最小二乗法)。
具体的な計算手法は下のサイトが分かりやすかったので興味がある方はぜひ見てみると良いでしょう。
(普通の二変数関数の最小化問題を偏微分を駆使して解く流れです)

https://www.randpy.tokyo/entry/2017/06/16/153435

大学の統計の授業だと、手計算で線形回帰の式を計算させられることもあるかと思いますが、実践ではそんなことをする必要は全くありません。
特に Python を使う場合は非常に簡単に非常に簡単にかけます。

必要なコードはたったのこれだけです。
from sklearn.linear_model import LinearRegression 

linearModel = LinearRegression()
linearModel.fit(説明変数のデータ(つまりx),目的変数のデータ(つまりy))
これはscikit-learnというポピュラーなデータ分析用のライブラリを使っているからこそ、ここまで楽に書けるのですね。
手動で面倒な計算をしなくても、linearModel.fit()と書くだけで勝手に計算を行ってくれます。

回帰係数(さっきでいうa)と切片(さっきでいうb)を取得したい場合はそれぞれ以下のように書けば OK です。
#回帰係数
a = linearModel.coef_

#切片
b = linearModel.intercept_
楽チンすぎますね。
さてそれでは、この線形回帰分析を仮想通貨投資に応用していきましょう。

線型回帰の投資への応用(線形回帰トレンド)

まず、線形回帰分析を自動売買に応用するというのは何となく僕の頭に浮かんだことですが、調べてみるとテクニカル指標として昔から存在していたようです。
線型回帰トレンドというテクニカル指標がちゃんとあるんですね。

(参考)https://www.sevendata.co.jp/shihyou/technical/senkei.html

まさに、ここまで説明した線形回帰を投資に応用した例だと言えます。
今回は最初に何回かビットコイン価格を観察し、
yを仮想通貨価格、 xを時間経過として
y = ax +b
の式をつくりaが正であれば、自動で買い注文を出すという仕様にしてみようと思います。

作成するコードの動き

改めてこれから作成するコードの動作を日本語で説明しておきます。
今回のコードの動作
①初めは相場のデータがないので、まず何もせずBTC価格をしばらく観測
②観測したデータに対して線型回帰分析を行い(=線型回帰トレンドのラインを作成し)相場が強いのか弱いのか判断する
③相場が上昇局面にあると判断したら、買い注文を入れる
では早速プログラムの作成に取りかかりましょう。

プログラムの下準備

まずはプログラムを動かすための下準備です。
今回はコインチェックで動かします。
やることはいつもの通り、口座開設APIキーの発行必要ライブラリのインストールの3つです。
これらがまだの人は下の記事の手順に従って2種類の API キーを発行しておいてください。

【コピペOK】仮想通貨をPythonで自動売買する方法を初心者向けに解説

2020年12月7日
まだ入っていない人は上記記事で紹介しているライブラリもpipでインストールしておく必要があります。
それに加えて今回はscikit-learnを使うのでこちらもインストールしておきます。
pip3 install scikit-learn
取得したデータの形などを見たい人はmatplotlibで可視化すると良いでしょう。
こちらはあってもなくても良いです。
pip3 install matplotlib

コード本体

以下がコードの本体です。
import pandas as pd
from sklearn.linear_model import LinearRegression
# import matplotlib.pyplot as plt
from coincheck import market,order,account
import time


access_key=input("APIのアクセスキーを入力してください")
secret_key=input("APIのシークレットキーを入力してください")

#何秒ごとに価格データを確認するか
interval_sec=7

#今回は回帰係数(回帰直線の傾き)が0以上で買い判断とする
target_tangent = 0

#初めの何回か(デフォルトでは25回)は取引をせずに価格データをただ集める
def price_data_collecting(how_many_samples=25):
    print("まずは今から"+str(how_many_samples*interval_sec)+"秒間、価格データを収集します。")
    price_list=[]
    for i in range(how_many_samples):
        price_list.append(m1.ticker()["last"])
        time.sleep(interval_sec)

    print("収集が完了しました。")
    return price_list

#coincheckのAPIラッパーインスタンス
m1=market.Market()
o1 = order.Order(secret_key=secret_key,access_key=access_key)


price_data = price_data_collecting()
x = [i for i in range(len(price_data))]

#先程取得したデータをpandasのデータフレームに格納しておく(今後の発展性のため)
#今回の目的を達成するだけなら、リストのまま処理しても良かった
df= pd.DataFrame()
df["x"]=x
df["y"]=price_data

#線形回帰を行う
linearModel = LinearRegression()
linearModel.fit(df[["x"]],df[["y"]])

#回帰係数
coef = linearModel.coef_
#切片
intercept = linearModel.intercept_
#決定係数
score = linearModel.score(df[["x"]],df[["y"]])

if intercept > target_tangent:
    print("買い注文を実行します。")
    print(o1.buy_btc_jpy(rate=str(df["y"].iloc[-1]),amount=0.005))
else:
    print("トレンドが発生していると判断できなかったので、購入注文を行いません。")

print("回帰係数、切片、決定係数の値はそれぞれ以下です。")
print(coef,intercept,score)

#データの散布図を表示する
# plt.scatter(df["x"],df["y"])
# plt.show()
今後の拡張性を考えて、はじめに観測したデータはpandasのデータフレームの中に格納しておく仕様にしてみました。

これで他のデータ分析手法と組み合わせるときもやりやすいのではないかと思います(あまり変わらないという説もある)。
forループでコードをまわし、何回も線形回帰トレンドを使って売買を繰り返したい人は、forループ毎にデータの数が増えていかないように注意する必要があるでしょう。

今回はこんな感じで終わりにします。
バグ報告や質問ご要望などは適宜受け付けております。
(返信できない場合もあります。ご了承ください。)

【コピペOK】深層学習AIを使った仮想通貨の自動売買を初心者向けに解説

2021年2月21日

【初心者向け】BTCの自動利確アルゴリズムをPythonで実装する方法

2021年2月12日

【Python3】MACDによるビットコインの自動売買botの作り方【GMOコイン編】

2021年2月2日

【保存版】仮想通貨の取引所APIを徹底比較。自動売買に最適な口座はココ!

2020年12月26日
スポンサーリンク

SNSシェアお願いします!

3 件のコメント

  • こんばんは。
    いつも参考にさせていただいております。
    以下文章に関して質問です。
    「forループでコードをまわし、何回も線形回帰トレンドを使って売買を繰り返したい人は、forループ毎にデータの数が増えていかないように注意する必要があるでしょう。」
    何十時間も稼働させる際にデータ数が増えないようにするためにはどのようにすればよろしいでしょうか?
    よろしくお願い申し上げます。

  • コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

    CAPTCHA