仮想通貨の自動取引入門 ~テクニカル指標~

Yuya Sugano
20 min readAug 18, 2019

--

仮想通貨に限らず自動取引は取引時に人手を介さず、リスクをコントロールしつつコストの削減およびリターンを機械的に追求することであると考える。本稿ではAPIを通じて取得した分足や日足のデータからテクニカル指標を計算しAnaconda3/Matplotlibを使用してグラフ描画する。テクニカル指標を参考にした自動取引のプログラムは次回以降で取り扱う。

Image by TeroVesalainen from Pixabay
  • 自動取引とは(再掲)
  • OHLCの取得とデータ整形
  • グラフ表示(mpl_finance)
  • テクニカル指標の計算

自動取引とは

金融商品における自動取引とはシステムトレードの非裁量取引を、特にプログラムを用いて自動化しまた定例化することでリスクのコントロールもしくはリターンの追求を省力化した上で達成することであると考える。

システムトレードやアルゴリズム取引という語には使用する組織や文脈に応じて複数の意味があること、また意味の混ざることがあるためにここでは単純に自動取引という用語のみ使用する。[1]

アルゴリズムを使用しないものも含め、自動取引という用語の意味はより広義に捉えて頂いて問題ない。プログラムを介して、取引機会を発見し、それを自動化しているものを自動取引と呼びたいと思う。非裁量性や高頻度取引(High Frequency Trading)など様々な利点のある自動取引であるが、まず大分類としてコストの削減を目指すものとリターンの追求を実現するものの2種類がある。[2]

  • コストの削減
    ・取引コストの削減(執行系アルゴリズム、VAMPなどのベンチマーク系アルゴリズム)
    ・マーケット・メイクやバスケット取引などの定型的な業務の自動化による内部コストの削減
    ・マーケット・インパクトによるコストの削減
    ・最適な市場の選択をすることによる手数料の削減
  • リターンの追求
    ・収益機会の発見(裁定アルゴリズム、ディレクショナル・アルゴリズムなど)
    ・リベートの獲得(メイカー・テイカー手数料)
    ・スプレッド収益の発見(マーケット・メイキング・アルゴリズム)

個人投資家についてはよほど大口でない限り、リターン追求のために自動取引を導入すると考えられることから、ここでは収益機会の発見を達成する自動取引をプログラムでどのように記述していくかを考えていく。主に裁定アルゴリズム、ディレクショナルアルゴリズム、マーケット・メイキング・アルゴリズムを個人投資家は利用する。自動取引に限らないが以下のPDCAを回して行くことで(自動取引においては自動的に行うことが好ましい)、効率よく収益機会の発見および収益の発生を実現することが理想である。

1.情報の収集および整理
2.自動取引と約定の確認
3.バックテスト(ベンチマーク)

OHLCの取得とデータ整形

OHLCとは(Open/High/Low/Close)の省略表記で、ローソク足の価格データセット(始値・高値・安値・終値)である。ここに出来高(Volume)を加え、OHLCVで提供されることも多い。

OHLCのデータは引き続きbitbank.cc APIから取得し、pandasを使用してデータ整形を行うこととする。pandasのデータフレームはインデックス付きの行列のデータ形式で、描画や機械学習・ディープラーニングの処理へそのまま活用できるデファクトスタンダードのライブラリである。

bitbank.cc APIの『Candlestick』を呼び出すことでローソク足の情報を取得できることが確認できた。

bitbank.cc API Candlestick

通貨ペア、期間、日付(年数)をパラメータとして渡すことができる。時刻はUNIX時間であり、指定した日付の朝9:00からのデータが返却されることが確認できた(UTC 0:00からのデータ)。

Candlestick API parameters

以下、インタラクティブモードでの確認結果である。

>>> import json
>>> import requests
>>> from datetime import datetime
>>> headers = {'Content-Type': 'application/json'}
>>> api_url_base = 'https://public.bitbank.cc'
>>> pair = 'btc_jpy'
>>> period = '1min'
>>> today = "{0:%Y%m%d}".format(datetime.today())
>>> api_url = '{0}/{1}/candlestick/{2}/{3}'.format(api_url_base, pair, period, today)
>>> response = requests.get(api_url, headers=headers)
>>> ohlcv = json.loads(response.content.decode('utf-8'))['data']['candlestick'][0]['ohlcv']
>>> print(json.dumps(ohlcv, indent=4, separators=(',', ': ')))
[
[
"1101000",
"1101001",
"1101000",
"1101001",
"0.3089",
1566000000000
],
...

pip install pipenvpipenv をインストールする。

$ pip install pipenv
...
Installing collected packages: virtualenv, virtualenv-clone, setuptools, pipenv
Found existing installation: setuptools 28.8.0
Uninstalling setuptools-28.8.0:
Successfully uninstalled setuptools-28.8.0
Successfully installed pipenv-2018.11.26 setuptools-41.1.0 virtualenv-16.7.3 virtualenv-clone-0.5.3

プロジェクトのフォルダ配下で pipenv コマンドで初期化することでPipfileが作成される。

$ pipenv --python 3.6
Creating a virtualenv for this project…
...
? Successfully created virtual environment!
Virtualenv location: /home/.local/share/virtualenvs/ohlc-EV3vjiKI
Creating a Pipfile for this project…

開発環境へライブラリをインストールするには pipenv install --dev を使用する。指定した日付のOHLCデータを取得し、csvとして保存するコードをgithubへアップロードした。

https://github.com/yuyasugano/ohlc

リポジトリ内でライブラリをインストールし、 pipenv run start コマンドでアプリケーションを動かすことができる。

$ pipenv install --dev
$ pipenv run start
open high low close
2019-08-17 09:00:00 1101000 1101001 1101000 1101001
2019-08-17 09:01:01 1101002 1103059 1101002 1103031
2019-08-17 09:02:02 1101375 1101802 1101001 1101001
2019-08-17 09:03:03 1101002 1101002 1100000 1100000
2019-08-17 09:04:04 1100000 1100000 1098925 1098925

Anaconda3の公式Dockerの環境内でテストしたJupyter Notebookのファイルもリポジトリに含まれている。

ohlc.ipynb

グラフ表示(mpl_finance)

OHLCのデータ取得ができた。ローソク足の描画にはmatplotlibに存在したmpl_financeのライブラリを使用する。基本的には以下のように pipでインストールすることができる。

$ pip install mpl_financeor$ pip install git+https://github.com/matplotlib/mpl_finance.git

matplotlib 2.0.0よりmpl_financeが別ライブラリとして切り離されたため手元のmatplotlibが古いバージョンの場合は既に含まれている可能性があるので注意が必要である。[5]

グラフ描画結果を確認するために前回構築したAnaconda3の公式DockerのJupyter Notebookを使用した。mpl_financeのcandlestick_ohlcメソッドを使用していく。

ライブラリのインポート。

In [1]:
#!/usr/bin/python
import csv
import time
import json
import requests
import numpy as np
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import mpl_finance

APIに必要なコンストや変数の定義。

In [2]:
headers = {'Content-Type': 'application/json'}
api_url_base = 'https://public.bitbank.cc'
pair = 'btc_jpy'
period = '1min'
today = "{0:%Y%m%d}".format(datetime.today())

bitbank.cc APIからOHLCVのデータを取得するメソッド。

In [3]:
def api_ohlcv():
api_url = '{0}/{1}/candlestick/{2}/{3}'.format(api_url_base, pair, period, today)
response = requests.get(api_url, headers=headers)
if response.status_code == 200:
ohlcv = json.loads(response.content.decode('utf-8'))['data']['candlestick'][0]['ohlcv']
return ohlcv
else:
return None

OHLCデータとしてpandasのDataFrame形式に整形。

In [4]:
ohlcv = api_ohlcv()
open, high, low, close, volume, timestamp = [],[],[],[],[],[]
for i in ohlcv:
open.append(int(i[0]))
high.append(int(i[1]))
low.append(int(i[2]))
close.append(int(i[3]))
volume.append(float(i[4]))
time_str = str(i[5])
timestamp.append(datetime.fromtimestamp(int(time_str[:10])).strftime('%Y/%m/%d %H:%M:%M'))
date_time_index = pd.to_datetime(timestamp) # convert to DateTimeIndex type
df = pd.DataFrame({'open': open, 'high': high, 'low': low, 'close': close}, index=date_time_index) # volume is not contained
# adjustment for JST if required
df.index += pd.offsets.Hour(9) # adjustment for JST

mpl_financeへ食わせるためにNumpy ndarrayへ変換。今回のケースでは741行5列のデータが得られた。

In [5]:
df_ = df.copy()
df_.index = mdates.date2num(df_.index)
data = df_.reset_index().values # Numpy ndarray not DataFrame
print(data)
print(data.shape)

mpl_financeを使用してローソク足をグラフ描画。

In [6]:
fig = plt.figure(figsize=(15, 5))
ax = fig.add_subplot(1, 1, 1)
mpl_finance.candlestick_ohlc(ax, data, width=0.001, alpha=0.5, colorup='r', colordown='b')
ax.grid()
locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

順次実行して得られたグラフ描画が以下である。ここでは分足でグラフを作成しているが、元のローソク足データの取得期間を1hourや1dayとすることで粒度を調整できる。またそれより深い間隔についてはローソク足のデータをダウンサンプリングすることで対応する。

2019/08/17 Candlestick Minute data

pandasのDataFrameのOHLCデータをダウンサンプリングする手法はこちらの記事が参考になる。[6]

以下は取得期間を1dayとした2019年の日足データから作成したグラフである。

2019 Candlestick Day data

テクニカル指標

単純移動平均線をはじめとしたテクニカル指標は主にディレクショナルアルゴリズムの作成に活用することができる。

この項では代表的なテクニカル指標5種類の計算とMatplotlibでの描画を行い、また最後にテクニカル指標を算出できるライブラリを紹介する。

  • 単純移動平均線
  • ボリンジャーバンド
  • MACD(Moving Average Convergence Divergence)
  • RSI(Relative Strength Index)
  • 一目均衡表

※ここから2018年の日足データを使用する、これは365行のOHLCデータとなるはずである

・単純移動平均線

日足で一般的な短期25日、長期75日の移動平均線を引いたが、ゴールデンクロス・デッドクロスともに価格の上昇および下降の判断の参考となりそうにない。むしろシグナルが出てから逆の動きをしているようにさえ見える。

btc/jpy 25days moving average for 2018
Moving Average Line

・ボリンジャーバンド

25日移動平均線から計算するボリンジャーバンドを描画した。アッパーバンドおよびロワーバンドへ収まっているが、2シグマのバンドへの交差があっても値が反転しているようには見受けられない。特に3月から4月、11月後半の交差は参考とならない。

btc/jpy 25days bollinger for 2018
Bollinger

・MACD(Moving Average Convergence Divergence)

MACDの値は定石通り12日EMAと26日EMAから計算している。シグナルはMACDの9日EMAを使用する。シグナルにも指数平滑移動平均を利用した。単純移動平均があまり参考にならなかったようにここでもシグナルは参考となっているとは言い難い。

btc/jpy MACD for 2018
MACD

・RSI(Relative Strength Index)

買われすぎ・売られすぎを判断するシグナルである。9日、22日、42日の3種を描画した。修正移動平均を用いたワイルダーの提唱方法でなく、日本で一般的な単純平均値で算出した。

btc/jpy RSI for 2018
RSI

・一目均衡表

9日間の転換線と26日間の基準線を使用した標準の一目均衡表である。この指標も日足のデータにおいてはあまりフィットしていないようである。

btc/jpy Ichimoku for 2018
Ichimoku

上記のJupyter Notebookを含むpipenvプロジェクトをgithub上にアップロードした。

https://github.com/yuyasugano/technical

ローソク足はmpl_financeで作図したが、pandasのDataFrameをNumpy ndarrayへ変換する必要があるため若干の手間である。

pandasのDataFrameをそのまま使用してhighchartsで描画するライブラリが存在するため今後は一部 pandas-highcharts を導入する。

$ pip install pandas-highcharts
...
Successfully installed backcall-0.1.0 coverage-4.5.4 decorator-4.4.0 ipython-7.7.0 ipython-genutils-0.2.0 jedi-0.15.1 pandas-highcharts-0.5.2 parso-0.5.1 pexpect-4.7.0 pickleshare-0.7.5 prompt-toolkit-2.0.9 ptyprocess-0.6.0 pygments-2.4.2 traitlets-4.3.2 wcwidth-0.1.7
https://www.highcharts.com/

またテクニカル指標の算出はデファクトスタンダードとしてTa-Libというライブラリがあるが、個人的にはtoyolabさんのgithubにあるMT5IndicatorsPyも気になっている。双方の内部の実装まで追えていないため、出力される数値の整合性は検証していないが、ベンチマークを行うとおもしろいかもしれない。[7]

toyolabさんのライブラリはMetaTrader5のテクニカル指標関数をpythonへ移植したものでpandasのDataFrameのまま40種のテクニカル指標が計算可能である。[8]

pipenv のプロジェクトにTa-Libを追加する方法を記載する。 pipでTa-Libをインストールする場合には、必要なCのライブラリ類を先にインストールしておく必要がある。[9]

Ta-Lib dependencies

先のプロジェクトへパッケージを追加できた。

$ pipenv install --dev Ta-Lib
Installing Ta-Lib…
Adding Ta-Lib to Pipfile's [dev-packages]…
? Installation Succeeded
Installing dependencies from Pipfile.lock (eba2e6)…
? ???????????????????????????????? 26/26 ― 00

以上、次回以降に取引の自動化やマーケット・メイキングについて取り上げていく。

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Yuya Sugano
Yuya Sugano

Written by Yuya Sugano

Cloud Architect and Blockchain Enthusiast, techflare.blog, Vinyl DJ, Backpacker. ブロックチェーン・クラウド(AWS/Azure)関連の記事をパブリッシュ。バックパッカーとしてユーラシア大陸を陸路横断するなど旅が趣味。

No responses yet

Write a response