PythonでFXチャートを表示してみる WebAPI2Csv編

PythonでFXチャートを表示するのをGoogle Colabでやってみます。
https://colab.research.google.com

PythonでFXチャートを表示してみる Csv2WebAPI編
https://qiita.com/namikitakeo/items/208ebdcb61e6259dcc44

Twelve DataのWebAPI実行回数や取得レコード数には制限があります。WebAPI2Csvで5000レコード毎に1回呼び出したらCSVファイルに保存して使うようにします。

```WebAPI2Csv.py
import datetime
import pandas as pd
import mplfinance as mpf
from twelvedata import TDClient
from twelvedata.http_client import DefaultHttpClient

TWELVE_DATA_API_KEY = '****************************' # Twelve Data のAPIキー

# ヒストリカルデータを取得
def get_historical_data(symbol, interval, outputsize, start_date, end_date, timezone):
    td = TDClient(apikey = TWELVE_DATA_API_KEY)

    res = td.time_series(
              symbol = symbol,
              interval = interval,
              outputsize = outputsize,
              start_date = start_date,
              end_date = end_date,
              timezone = timezone
          ).as_json()

    df = pd.DataFrame(res).iloc[::-1].set_index('datetime').astype(float)
    df = df[df.index >= start_date]
    df.index = pd.to_datetime(df.index)

    return df

# 銘柄
symbol = 'USD/JPY'

# 時間軸
interval = '1min'

# 取得件数
outputsize = 5000

# 取得開始日
start_date = '2022-01-31'
#start_date = '2022-02-03'
#start_date = '2022-02-07'
#start_date = '2022-02-10'
#start_date = '2022-02-14'
#start_date = '2022-02-17'
#start_date = '2022-02-21'
#start_date = '2022-02-24'
#start_date = '2022-02-28'

# 取得終了日
end_date = '2022-02-03'
#end_date = '2022-02-06'
#end_date = '2022-02-10'
#end_date = '2022-02-13'
#end_date = '2022-02-17'
#end_date = '2022-02-20'
#end_date = '2022-02-24'
#end_date = '2022-02-27'
#end_date = '2022-03-03'

# タイムゾーン
timezone = 'Asia/Tokyo'

# ヒストリカルデータを取得
df = get_historical_data(symbol, interval, outputsize, start_date, end_date, timezone)

# CSVファイルに保存
df['volume']=0
df.to_csv('USDJPY_2022_02_01.csv',header=False)
#df.to_csv('USDJPY_2022_02_03.csv',header=False)
#df.to_csv('USDJPY_2022_02_07.csv',header=False)
#df.to_csv('USDJPY_2022_02_10.csv',header=False)
#df.to_csv('USDJPY_2022_02_14.csv',header=False)
#df.to_csv('USDJPY_2022_02_17.csv',header=False)
#df.to_csv('USDJPY_2022_02_21.csv',header=False)
#df.to_csv('USDJPY_2022_02_24.csv',header=False)
#df.to_csv('USDJPY_2022_02_28.csv',header=False)
```

過去データについては、アキシオリーのヒストリカルデータが使えますが、今月分については、WebAPIから取得してCSVファイルに出力しておきます。

```Csv2WebAPI.py
import json
from flask import *

app = Flask(__name__)

@app.route("/time_series")
def response_json():
   req = request.args
   symbol = req.get("symbol")
   interval = req.get("interval")
   outputsize = req.get("outputsize")
   start_date = req.get("start_date")
   s = r'{"meta":{"symbol":"'+symbol+'","interval":"'+interval+'","type":"Physical Currency"},"values":['
   year=start_date[0:4]
   month = (start_date[5:7])
   filename = symbol[0:3]+symbol[4:7]+'_'+year+'_'+month+'.txt'
   filename1 = symbol[0:3]+symbol[4:7]+'_'+year+'_'+month+'.csv'
   iyear=int(year)
   imonth=int(month)
   imonth += 1
   if (imonth>12):
       imonth -= 12
       iyear = int(year)+1
   month = ('0'+str(imonth))[len(str(imonth))-1:]
   filename2 = symbol[0:3]+symbol[4:7]+'_'+str(iyear)+'_'+month+'.csv'
   imonth += 1
   if (imonth>12):
       imonth -= 12
       iyear = int(year)+1
   month = ('0'+str(imonth))[len(str(imonth))-1:]
   filename3 = symbol[0:3]+symbol[4:7]+'_'+str(iyear)+'_'+month+'.csv'
   imonth += 1
   if (imonth>12):
       imonth -= 12
       iyear = int(year)+1
   month = ('0'+str(imonth))[len(str(imonth))-1:]
   filename4 = symbol[0:3]+symbol[4:7]+'_'+str(iyear)+'_'+month+'.csv'
   max = int(outputsize)
   if max>30:
     filenames = [filename1,filename2]
   if max>60:
     filenames = [filename1,filename2,filename3]
   if max>90:
     filenames = [filename1,filename2,filename3,filename4]
   if (max>30 and interval=="1day"):
      with open(filename,'w') as outfile:
         for fname in filenames:
            with open(fname) as infile:
               for line in infile:
                  outfile.write(line)
   else:
      filename=filename1

   start=start_date[0:10]
   output = 0
   if interval=="1h":
       max *= 60
   if interval=="1day":
       max *= 60 * 24
   first=""
   last=""
   one=""
   high=""
   low=""
   with open(filename, 'r') as f:
      for row in f:
         row=row.replace(' ',',')
         datetime=row.replace('.','-')
         hour=datetime[11:13]
         min=datetime[14:16]
         if datetime[0:10] < start:
            continue
         if output<max:
            s1=row.split(',')
            if interval=="1day":
               if (datetime[0:10]!=last):
                  last=datetime[0:10]
                  one="1"
            elif interval=="1h":
               if (hour!=last): 
                  last=hour
                  one="1"
            else:
               s+='{"datetime":"'+datetime[0:10]+' '+datetime[11:16]+':00",'
               s+='"open":"'+(s1[2])+'",'
               s+='"high":"'+(s1[3])+'",'
               s+='"low":"'+(s1[4])+'",'
               s+='"close":"'+(s1[5])+'"},'
            if one == "1":
               if (first == "1"):
                  s+='"high":"'+high+'",'
                  s+='"low":"'+low+'",'
                  s+='"close":"'+(s2[5])+'"},'
                  first = ""
               s+='{"datetime":"'+datetime[0:10]+' '+datetime[11:16]+':00",'
               s+='"open":"'+(s1[2])+'",'
               high=(s1[3])
               low=(s1[4])
               first = "1"
               one = ""
            s2=s1
            if high<(s1[3]):
               high=(s1[3])
            if low>(s1[4]):
               low=(s1[4])
         output += 1
   if (interval=="1day" or interval=="1h"):
      s+='"high":"'+high+'",'
      s+='"low":"'+low+'",'
      s+='"close":"'+(s2[5])+'"},'
   s+='],"status":"ok"}'
   s3=s.replace(',]',']')
   data = json.loads(s3)
   data['values'] = sorted(data['values'], key=lambda k: k['datetime'], reverse=True)
   return (data)

if __name__ == '__main__':
   app.run()
```