これから実際にBOTのアルゴリズムを作成してみましょう。
最初のステップとして「チャートの動きがチャネルブレイクアウトをした場合にシグナルを出す」というプログラムをPythonで作成してみます。
■前提知識
・Cryptowatch APIを使ってOHLCデータの取得ができている
・Pythonの基本的な記述ができる
・PythonのPandasライブラリを使ってDataFrameを使用できる
もしもこの辺りが分からないぞ。という場合は過去の記事を確認したり、おさらいしてみて下さいね。
では、本題に入っていきます。まずはシグナルについても改めて確認しましょう。
コンテンツ
シグナルとは?
株、FX、仮想通貨市場でトレードを行う時は、当然売買注文をしてポジションを取ります。※1BTCを買う。とか、売るというポジションですね。
このポジションを取る時には「何かしらの基準」が必要です。例えば、上昇トレンドの時に長期移動平均線を短期移動平均線が上抜けた。だから買いポジションを取ろう。といった具合に。
この場合、「上昇トレンド+長期移動平均線を短期移動平均線が上抜けた」という状態を、シグナルが出ている状態と言います。チャートを読み解いて自分でシグナル判断する事もあれば、システムが自動でシグナルを出してくれる事もあります。
このシグナルが有効かどうかは別として、トレードというのはチャンスの期間というのは限られています。
上記の例で言うと、短期の移動平均線が上抜けたとしても、ぼやぼやしていると、チャートの動きは変わってしまい、買いポジションを取るタイミングを失ってしまいます。
なので、今買いポジションを取るべきチャンスですよ~。というシグナルを出すと非常に便利です。方法はいくつかありますが、PCの画面にメッセージを表示する方法、メールなどで知らせる方法などなど、最低限のプログラミング(というほどでもない)の知識があれば簡単なんです。
仮想的なシグナル発信をしてみよう!
今回は、そのシグナルを仮想的に実現してみようと思います。
実際に売買をする訳ではなくて、cryptowatchを使って過去のbtc-jpyのOHLCデータを1件ずつ読み込みながら、売買すべきポイントがあれば、とりあえず簡単なメッセージを画面に出力してみます。
このメッセージ出力しているポイントが正しければ、後は自分にメールを送るなり、PCでアラートをあげるなりすれば、裁量トレードも実践できます。
※当然ですが売買も自動化できれば、全自動の仮想通貨取引BOTが完成します。ただ、いきなりここに手をつけるのは得策ではありません。場合によっては大きな損をする可能性もあるので、システムを導入する場合は、テストを繰り返しながら着実に進めましょう。
チャネルブレイクアウトのシグナルを出してみる!
今回はチャネルブレイクアウト(レンジブレイクアウト)の売買アルゴリズムを考えてみましょう。
チャネルブレイクアウトというのは、一定期間の値動きがレンジ内に収まっている場合、に値動きがレンジを上抜けたら買い(値上がりするはず)、レンジを下抜けたら売り(値下がりするはず)という考えに支えられています。
過去20日間のチャネルブレイクアウトを指標とする場合は、過去20日間の高値を上抜けたら「買い」のシグナル。逆に安値を下抜けたら「売り」のシグナルを出す様なアルゴリズムを作ればOKです。このチャネルブレイクアウトの売買アルゴリズムは実はとっても簡単です。
過去のOHLCデータでアルゴリズムを検証する準備
アルゴリズムを検証するための前提と、実際に作成する処理の流れをまずはまとめてみました。
■データの前提
・データはcryptowatchから取得する
・仮想通貨「btc-jpy」の通貨ペアを対象とする
・過去のOHLCデータで検証する
・過去20日間のレンジでチャネルブレイクアウトとする
■結果のイメージ
結果画面には日別のOHLCデータをずらずらと表示しながら、チャネルブレイクアウトの判定を行う様にします。
■処理の流れ
1)cryptowatch APIを使ってOHLCデータを取得
2)ループ開始(3/21以降を「今日」と過程して1日ずつ判定)
3)過去20日間の高値、安値を取得する
4)「本日の高値が過去20日間の高値を超える」 or「本日の安値が過去20日間の安値を下回る」場合にシグナルを出す
処理はたったのこれだけです。結構簡単そうではありませんか?チャネルブレイクアウトを使った手法はPythonのコードが販売されているほどに人気なのですが、根幹となるアルゴリズムは実はシンプルなのです。
※販売されているPythonのコードは売買取引なども自動で行っているので、コード全量としては当然もっと手のこんだものとなります。
まずは1日分だけ高値の判定
まずは1日分(3/20)分の高値の判定だけを行ってみましょう。
少し長めのプログラムを作る時は段階的に作っていくと分かりやすいです。
ここまできたら後は簡単、日付を1日ずつずらしていけばOKです。
チャネルブレイクアウトの判定を行う
次に実際のチャネルブレイクアウトを判定するプログラムを作成しましょう。
上述している「処理の流れ」を基にしてコーディングします。
■取得データ
・対象のローソク足:日足(86400秒)
・OHLCデータの開始日(判定開始日):2018/3/1
・OHLCデータの終了日(判定終了日):2018/5/31
・シグナル判定開始日:2018/3/20
・シグナル判定終了日:2018/5/31
■Pythonコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import requests from datetime import datetime from datetime import timedelta import pandas as pd #OHLCデータ取得関数 def get_data(min, before=0, after=0): #パラメータ設定する params = {"periods" : min } if before != 0: params["before"] = before if after != 0: params["after"] = after #リクエスト送信 response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc",params) data = response.json() return data #過去20日分の高値と安値を算出する関数 def judge_high_and_low(df,ref_date,period_day): for j in range(len(df)): if str(df['Time'][j]) == str(ref_date): #DataFrameの中に「基準日」を見つけた! s_idx = j - (period_day-1) #20日前の日のインデックス ※基準日を含むため-1 if s_idx >= 0 : #DataFrameの範囲内(最低限の判定) return df[s_idx:j]['high'].max(), df[s_idx:j]['low'].min()#過去20日分の高値と安値 break #終値を算出する関数 def get_close_price(df,ref_date): for j in range(len(df)): if str(df['Time'][j]) == str(ref_date): #DataFrameの中に「基準日」を見つけた! return df['close'][j] #終値を返す #main処理 min = 86400 #1日(86400秒) after = datetime(2018, 3, 1).strftime('%s') #OHLCの取得開始日 before = datetime(2018, 5, 31).strftime('%s') #OHLCの取得終了日 ref_date = datetime(2018, 3, 20) #判定開始日 period_day = 20 #チャネルブレイクのレンジ close_price_work = 0 #終値の処理用変数 #過去のOHLCデータの取得 out_data = get_data(min,before,after) Time_Data, Open_price, High_price, Low_price, Close_price = [],[],[],[],[] for ohlc in out_data["result"][str(min)]: Time_Data.append(datetime.fromtimestamp(ohlc[0])) Open_price.append(ohlc[1]) High_price.append(ohlc[2]) Low_price.append(ohlc[3]) Close_price.append(ohlc[4]) df = pd.DataFrame({'Time':Time_Data, 'open':Open_price, 'high':High_price, 'low':Low_price, 'close':Close_price}) #ループ開始 while ref_date <= datetime(2018, 5, 31): high_val,low_val = judge_high_and_low(df,ref_date,period_day) #過去20日間の高値と安値を取得 close_price_work = get_close_price(df,ref_date) #基準日の終値を取得 print(str(ref_date) + " : 過去" + str(period_day) +"日間の高値:" + str(high_val) + " 安値:" + str(low_val)) if high_val < close_price_work: print("終値が過去20日間の高値を上抜け。終値は:" + str(close_price_work)) elif low_val > close_price_work: print("終値が過去20日間の安値を下抜け。終値は:" + str(close_price_work)) ref_date = ref_date + timedelta(days=1) #次の日 |
■実行結果(抜粋)
[python]2018-03-20 00:00:00 : 過去20日間の高値:1246120 安値:777870
2018-03-21 00:00:00 : 過去20日間の高値:1246120 安値:777870
・・・
2018-03-30 00:00:00 : 過去20日間の高値:1062040 安値:777870
終値が過去20日間の安値を下抜け。終値は:750130
2018-03-31 00:00:00 : 過去20日間の高値:1062040 安値:748213
終値が過去20日間の安値を下抜け。終値は:731360
2018-04-01 00:00:00 : 過去20日間の高値:1062040 安値:706380
・・・
2018-04-16 00:00:00 : 過去20日間の高値:884400 安値:682660
終値が過去20日間の高値を上抜け。終値は:900005
2018-04-17 00:00:00 : 過去20日間の高値:904399 安値:682660
・・・
2018-04-21 00:00:00 : 過去20日間の高値:907389 安値:682660
終値が過去20日間の高値を上抜け。終値は:952839
2018-04-22 00:00:00 : 過去20日間の高値:956220 安値:700372
終値が過去20日間の高値を上抜け。終値は:960000
2018-04-23 00:00:00 : 過去20日間の高値:978300 安値:700372
2018-04-24 00:00:00 : 過去20日間の高値:989057 安値:700372
2018-04-25 00:00:00 : 過去20日間の高値:989057 安値:700372
終値が過去20日間の高値を上抜け。終値は:1065195
2018-04-26 00:00:00 : 過去20日間の高値:1065195 安値:700372
・・・
2018-05-12 00:00:00 : 過去20日間の高値:1083035 安値:920001
終値が過去20日間の安値を下抜け。終値は:913999
2018-05-13 00:00:00 : 過去20日間の高値:1083035 安値:903600
・・・
2018-05-18 00:00:00 : 過去20日間の高値:1083035 安値:895970
終値が過去20日間の安値を下抜け。終値は:894496
2018-05-19 00:00:00 : 過去20日間の高値:1083035 安値:887767
・・・
2018-05-24 00:00:00 : 過去20日間の高値:1083035 安値:881431
終値が過去20日間の安値を下抜け。終値は:830500
2018-05-25 00:00:00 : 過去20日間の高値:1083035 安値:827000
・・・
2018-05-29 00:00:00 : 過去20日間の高値:1030000 安値:800000
終値が過去20日間の安値を下抜け。終値は:780542
2018-05-30 00:00:00 : 過去20日間の高値:1021997 安値:778369
2018-05-31 00:00:00 : 過去20日間の高値:1000000 安値:773004[/python]
■解説
関数「get_data」:cryptowathAPIで過去のOHLC情報を取得しています。
関数「judge_high_and_low」:過去20日間の高値と安値を判定しています。
関数「get_close_price」」:対象日の終値を算出しています。※高値と安値の判定と一緒に算出しても良いのですが、シグナルが変わった場合でも使用できる様に単体の関数を作成しました。
main処理:上記の関数を定義した上でmain処理を開始しています。ではデータ取得時の開始&終了日付の設定を行っています。次に、OHLCデータを取得してDataFrameに値を設定しています。
最後はwhile文でループを行い、3/20以降のOHLCデータ1件ずつ(1日ずつ)を基にして、過去20日間のレンジブレイク(高値を上抜けor安値を下抜け)しているかどうかを判定しています。もしもレンジブレイクした場合は、print文でその内容を出力しています。
まとめ
まだまだ改良しなければならない部分もありますが、「OHLCデータを基にしてシグナルを出す」という処理のイメージぐらいは掴んでいただけたのではないでしょうか。
今回はチャネルブレイクアウトのシグナルを出す。という事をメインテーマにしました。シグナルには様々なものがありますので、他のシグナルだったらどの様なコードを書くべきか等を考えてみるのも面白いです。
プログラムとしてはまだまだ小さなサイズですが、様々なPythonの構文も使っていますので、色々なコードを書くとPythonのスキルも少しずつUPしますね。
このコードを基にしてさらに仮想通貨の売買BOTとして完成させていきましょう。