見出し画像

仮想通貨bot 勉強記録㉝

~テクニカル指標の計算をTA-Libに任せる~

◆前回までのあらすじ

図1

Cloud9の使い方を紹介しました。

◆今回やること

図1

・テクニカル指標の計算をライブラリに任せる!

図2

バックテストではない実践コードは一旦置いといて、便利ライブラリの紹介をします!
このライブラリを知った時の僕↓

画像4

オイオイオイ便利すぎかオイ

こういう便利なものがポンポン出てくるのがPythonのいいところですな!

早速テクニカル指標をいとも簡単に計算してくれるライブラリ:TA-Libを使ってみましょう。

1.TA-Libをインストールする

図3

①ファイルのダウンロード

TA-Libを普通にpipでインストールしようとすると、以下のエラーが出ます。

画像6

Microsoft C++ Build Tools をインストールしろって書いてあったので試しまたけど、できませんでした。

なので、以下のURLからライブラリのファイルをダウンロードします。

TA_Lib-0.4.19-cp38-cp38-win_amd64.whl

というファイルをダウンロードしてください。
※cp39はダメ

ダウンロードしたら、ファイルをPydocに移動させます。
もしくはコンソールでcdコマンドを使い、ファイルの保存場所に移動します。

②インストール

ファイルを移動させたら、インストールします。
以下を実行してください。

pip install TA_Lib-0.4.19-cp38-cp38-win_amd64.whl

Successfully installed TA-Lib-0.4.19と表示されれば、インストール成功です!

(base) C:\Pydoc>pip install TA_Lib-0.4.19-cp38-cp38-win_amd64.whl
Processing c:\pydoc\ta_lib-0.4.19-cp38-cp38-win_amd64.whl
Installing collected packages: TA-Lib
Successfully installed TA-Lib-0.4.19

2.TA-Libを使ってみる

図3

まずは基本のSMA・EMAを、自分で作った計算式で算出してみます。
1時間足で、終値が確定した1本前のSMA(5)を確認します。

# -*- coding: utf-8 -*-
"""
Created on Wed May 12 00:39:21 2021

@author: Mamu
"""

# -*- coding: utf-8 -*-
"""
Created on Thu May  6 22:40:08 2021

@author: Mamu
"""

from datetime import datetime,timedelta,timezone
import pybybit
#--------------------設定項目--------------------
apis = [
'API',
'シークレット'
]
bybit = pybybit.API(*apis, testnet = True)

symbol           = "BTCUSD"
chart_min        = 60   # 時間軸(1 3 5 15 30 60 120 240 360 720 "D" "W" "M" )

#--------------------関数--------------------
#====================価格データ取得===================
def get_price(chart_min):
  get_start = int((datetime.now()-timedelta(minutes=chart_min*60)).timestamp()) # タイムスタンプ変換
  price = []
  #200*n本のローソク足を取得して、price[]に入れる
  for o in range(30): # ()内の回数だけデータを取得

      #pybybitでローソク足取得
      data = bybit.rest.inverse.public_kline_list(
            symbol   = symbol,
            interval = chart_min,
            from_    = get_start
            ).json()

      #priceに取得したデータを入れる
      #bybitから帰ってくるデータがstr型なので、float型に変換してから格納する
      for i in data["result"]:
          price.append({
              "open_time" :i["open_time"],
              "open"      :float(i["open"]),
              "high"      :float(i["high"]),
              "low"       :float(i["low"]),
              "close"     :float(i["close"]),
              "volume"    :float(i["volume"])
              })

      #200本x足の長さ分だけタイムスタンプを進める
      if chart_min == "D" :
          get_start += 200*60*1440

      elif chart_min == "W" :
          get_start += 200*60*10080

      else:
          get_start += 200*60*chart_min

  return price

def print_price( data ):
 print( "時間: " + datetime.fromtimestamp(data["open_time"]).strftime('%Y/%m/%d %H:%M') + " 始値: " + str(data["open"])+ " 高値: " + str(data["high"]) + " 安値: " + str(data["low"]) + " 終値: " + str(data["close"]) )

#====================〇単純移動平均を計算====================
def calculate_SMA( value,before=None ):
  if before is not None:
      MA = sum(i["close"] for i in kline[-1*value + before: before]) / value
  else:
      MA = sum(i["close"] for i in kline[-1*value:]) / value
  return MA

#====================指数移動平均を計算====================
def calculate_EMA( value,before=None ):

   # 指定期間だけ前の移動平均を計算
   if before is not None:
       MA = (sum(i["close"] for i in kline[-2*value + before : -1*value + before]) / value)
       EMA = (kline[-1*value + before]["close"] * 2 / (value+1)) + (MA * (value-1) / (value+1))
       for i in range(value-1):
           EMA = (kline[-1*value+before+1 + i]["close"] * 2 /(value+1)) + (EMA * (value-1) / (value+1))

   # 最新の移動平均を計算
   else:
       MA = sum(i["close"] for i in kline[-2*value: -1*value]) / value
       EMA = (kline[-1*value]["close"] * 2 / (value+1)) + (MA * (value-1) / (value+1))
       for i in range(value-1):
           EMA = (kline[-1*value+1 + i]["close"] * 2 /(value+1)) + (EMA * (value-1) / (value+1))
   return EMA

#--------------------メイン処理--------------------

kline = get_price( chart_min )
last_data = kline[-2]

print_price( last_data )
my_SMA = calculate_SMA( 5,before = -1)
my_EMA = calculate_EMA( 5,before = -1)

print("my_SMA{0}:{1}".format(5,round(my_SMA,1)))
print("my_EMA{0}:{1}".format(5,round(my_EMA,1)))

実行結果

時間: 2021/05/12 00:00 始値: 55824.0 高値: 56199.0 安値: 55649.0 終値: 56125.0
my_SMA5:55685.0
my_EMA5:55834.7

my_SMA5:55685.0
my_EMA5:55834.7 ですね。

次に、TA-Libで算出してみます。
使い方は後で説明します。とりあえず算出。

# -*- coding: utf-8 -*-
"""
Created on Thu May  6 22:40:08 2021

@author: Mamu
"""

from datetime import datetime,timedelta,timezone
import pybybit
import pandas as pd
import talib as ta
import numpy as np
#--------------------設定項目--------------------
apis = [
'API',
'シークレット'
]
bybit = pybybit.API(*apis, testnet = True)

symbol           = "BTCUSD"
chart_min        = 60   # 時間軸(1 3 5 15 30 60 120 240 360 720 "D" "W" "M" )

#--------------------関数--------------------
#====================価格データ取得===================
def get_price(chart_min):
   get_start = int((datetime.now()-timedelta(minutes=chart_min*60)).timestamp()) # タイムスタンプ変換
   price = []
   #200*n本のローソク足を取得して、price[]に入れる
   for o in range(30): # ()内の回数だけデータを取得

       #pybybitでローソク足取得
       data = bybit.rest.inverse.public_kline_list(
             symbol   = symbol,
             interval = chart_min,
             from_    = get_start
             ).json()

       #priceに取得したデータを入れる
       #bybitから帰ってくるデータがstr型なので、float型に変換してから格納する
       for i in data["result"]:
           price.append({
               "open_time" :i["open_time"],
               "open"      :float(i["open"]),
               "high"      :float(i["high"]),
               "low"       :float(i["low"]),
               "close"     :float(i["close"]),
               "volume"    :float(i["volume"])
               })

       #200本x足の長さ分だけタイムスタンプを進める
       if chart_min == "D" :
           get_start += 200*60*1440

       elif chart_min == "W" :
           get_start += 200*60*10080

       else:
           get_start += 200*60*chart_min

   return price

def print_price( data ):
  print( "時間: " + datetime.fromtimestamp(data["open_time"]).strftime('%Y/%m/%d %H:%M') + " 始値: " + str(data["open"])+ " 高値: " + str(data["high"]) + " 安値: " + str(data["low"]) + " 終値: " + str(data["close"]) )


def cleate_table(price):
   df = pd.DataFrame(price)

   # 世界協定時から日本標準時を算出
   tz_jst = timezone(timedelta(hours=+9), name='JST')

   # dfのopen_timeを日本時間にして表示(UTCのままでいい場合は不要)
   df['open_time'] = (df['open_time'].apply(lambda x : datetime.fromtimestamp(x, tz_jst).strftime('%Y/%m/%d %H:%M')))

   # print(df)

   return df

#--------------------メイン処理--------------------

kline = get_price( chart_min )
last_data = kline[-2]
df = cleate_table(kline)

talib_SMA = ta.SMA(np.array(df['close']), timeperiod = 5)
talib_EMA = ta.EMA(np.array(df['close']), timeperiod = 5)

print_price( last_data )
print("talib_SMA{0}:{1}".format( 5 ,round(talib_SMA[-2],1)))
print("talib_EMA{0}:{1}".format( 5 ,round(talib_EMA[-2],1)))

実行結果

時間: 2021/05/12 00:00 始値: 55824.0 高値: 56199.0 安値: 55649.0 終値: 56125.0
talib_SMA5:55685.0
talib_EMA5:55829.9

talib_SMA5:55685.0
talib_EMA5:55829.9 です。

SMAは同じですが、EMAは誤差があります。
Bybitのチャートで確認してみましょう。

画像8

TA-Libの完全勝利やないか。。。!

RSIもたった1行追加するだけで算出できます。

RSI = ta.RSI(np.array(df['close']), timeperiod = 14)
時間: 2021/05/12 00:00 始値: 55824.0 高値: 56199.0 安値: 55649.0 終値: 56125.0
talib_SMA5:55685.0
talib_EMA5:55829.9
talib_RSI14:49.7

RSIはちょっとずれてますね、、、なんでだろう?後で調べよう。

まぁこんな感じで、テクニカル指標をサクッと計算してくれるのです!

3.TA-Libの使い方

図3

get_function_groups()で使える機能を確認できます。

import talib as ta
from pprint import pprint

pprint(ta.get_function_groups())

使える機能がグループごとに表示されます。

{'Cycle Indicators': ['HT_DCPERIOD',
                     'HT_DCPHASE',
                     'HT_PHASOR',
                     'HT_SINE',
                     'HT_TRENDMODE'],
'Math Operators': ['ADD',
                   'DIV',
                   'MAX',
                   'MAXINDEX',
                   'MIN',
                   'MININDEX',
                   'MINMAX',
                   'MINMAXINDEX',
                   'MULT',
                   'SUB',
                   'SUM'],
'Math Transform': ['ACOS',
                   'ASIN',
                   'ATAN',
                   'CEIL',
                   'COS',
                   'COSH',
                   'EXP',
                   'FLOOR',
                   'LN',
                   'LOG10',
                   'SIN',
                   'SINH',
                   'SQRT',
                   'TAN',
                   'TANH'],
'Momentum Indicators': ['ADX',
                        'ADXR',
                        'APO',
                        'AROON',
                        'AROONOSC',
                        'BOP',
                        'CCI',
                        'CMO',
                        'DX',
                        'MACD',
                        'MACDEXT',
                        'MACDFIX',
                        'MFI',
                        'MINUS_DI',
                        'MINUS_DM',
                        'MOM',
                        'PLUS_DI',
                        'PLUS_DM',
                        'PPO',
                        'ROC',
                        'ROCP',
                        'ROCR',
                        'ROCR100',
                        'RSI',
                        'STOCH',
                        'STOCHF',
                        'STOCHRSI',
                        'TRIX',
                        'ULTOSC',
                        'WILLR'],
'Overlap Studies': ['BBANDS',
                    'DEMA',
                    'EMA',
                    'HT_TRENDLINE',
                    'KAMA',
                    'MA',
                    'MAMA',
                    'MAVP',
                    'MIDPOINT',
                    'MIDPRICE',
                    'SAR',
                    'SAREXT',
                    'SMA',
                    'T3',
                    'TEMA',
                    'TRIMA',
                    'WMA'],
'Pattern Recognition': ['CDL2CROWS',
                        'CDL3BLACKCROWS',
                        'CDL3INSIDE',
                        'CDL3LINESTRIKE',
                        'CDL3OUTSIDE',
                        'CDL3STARSINSOUTH',
                        'CDL3WHITESOLDIERS',
                        'CDLABANDONEDBABY',
                        'CDLADVANCEBLOCK',
                        'CDLBELTHOLD',
                        'CDLBREAKAWAY',
                        'CDLCLOSINGMARUBOZU',
                        'CDLCONCEALBABYSWALL',
                        'CDLCOUNTERATTACK',
                        'CDLDARKCLOUDCOVER',
                        'CDLDOJI',
                        'CDLDOJISTAR',
                        'CDLDRAGONFLYDOJI',
                        'CDLENGULFING',
                        'CDLEVENINGDOJISTAR',
                        'CDLEVENINGSTAR',
                        'CDLGAPSIDESIDEWHITE',
                        'CDLGRAVESTONEDOJI',
                        'CDLHAMMER',
                        'CDLHANGINGMAN',
                        'CDLHARAMI',
                        'CDLHARAMICROSS',
                        'CDLHIGHWAVE',
                        'CDLHIKKAKE',
                        'CDLHIKKAKEMOD',
                        'CDLHOMINGPIGEON',
                        'CDLIDENTICAL3CROWS',
                        'CDLINNECK',
                        'CDLINVERTEDHAMMER',
                        'CDLKICKING',
                        'CDLKICKINGBYLENGTH',
                        'CDLLADDERBOTTOM',
                        'CDLLONGLEGGEDDOJI',
                        'CDLLONGLINE',
                        'CDLMARUBOZU',
                        'CDLMATCHINGLOW',
                        'CDLMATHOLD',
                        'CDLMORNINGDOJISTAR',
                        'CDLMORNINGSTAR',
                        'CDLONNECK',
                        'CDLPIERCING',
                        'CDLRICKSHAWMAN',
                        'CDLRISEFALL3METHODS',
                        'CDLSEPARATINGLINES',
                        'CDLSHOOTINGSTAR',
                        'CDLSHORTLINE',
                        'CDLSPINNINGTOP',
                        'CDLSTALLEDPATTERN',
                        'CDLSTICKSANDWICH',
                        'CDLTAKURI',
                        'CDLTASUKIGAP',
                        'CDLTHRUSTING',
                        'CDLTRISTAR',
                        'CDLUNIQUE3RIVER',
                        'CDLUPSIDEGAP2CROWS',
                        'CDLXSIDEGAP3METHODS'],
'Price Transform': ['AVGPRICE', 'MEDPRICE', 'TYPPRICE', 'WCLPRICE'],
'Statistic Functions': ['BETA',
                        'CORREL',
                        'LINEARREG',
                        'LINEARREG_ANGLE',
                        'LINEARREG_INTERCEPT',
                        'LINEARREG_SLOPE',
                        'STDDEV',
                        'TSF',
                        'VAR'],
'Volatility Indicators': ['ATR', 'NATR', 'TRANGE'],
'Volume Indicators': ['AD', 'ADOSC', 'OBV']}

Volatility Indicators の項目にATRもありますね!

それぞれの関数の使い方は、↓のページに書いてあります。

色々な指標を計算してみるといいと思います。
スイングbot等でテクニカル指標を使いたい時に役立ちそうなライブラリの紹介でした!

今回はここまで

いいなと思ったら応援しよう!