Contents
FXをシステムトレードしたい
FXのシステムトレードは、現在のところOANDA fxTrade APIの利用を考えています。
OANDAのREST APIを利用すると、1通貨単位から取引でき、様々な注文をAPI経由で行うことができます。
手数料(スプレッド)も安いようなので、この証券会社の利用を考えています。
システムトレードに不可欠なヒストリカルデータ
システムトレードを行うにあたっては、ヒストリカルデータの入手は必須となります。
OANDAのREST APIでも過去データを扱うことは可能です。
(APIの説明ページには過去に戻れる期間が「完全」となっています。)
このAPIを利用したいのですが、これにはOANDAへの口座開設が必要です。
さらにAPIを利用するためには、「OANDA Japanに口座をお持ちのお客様で、口座残高が25万円以上ある方」という条件があります。
OANDAに25万円を入金して開発に着手しても、そこからがスタートになるので
開発が終わってさらにバックテストも終わった後となると、
実際に運用がスタートするのはかなり先のことになります。
その間、何もしない資金(25万円)をOANDAに預けっぱなしにしておくのはもったいないので、
他からヒストリカルデータを入手することを考えます。
FXのヒストリカルデータを探す
OANDA以外にもヒストリカルデータを提供している証券会社はいくつかあります。
しかし、私が現在口座を持っている証券会社ではどこも提供していません・・・。
口座作るだけならタダなので、データ取得用に口座を作ってもよいのですが、
トレードしない証券会社にムダに口座を開きたくありません。
みずほ銀行が提供しているデータがありましたが、日足データでした。
日足データを元に自動取引プログラムを開発しても、
買い・売りのシグナルが出るのは、多くても1週間に1回程度でしょう。
長期トレンドを短期トレンドが上抜けしてとかだと
月に1回とかかもしれません。
そうなると、会社を終えて帰宅した後に、
チャートをチェックして注文を出すスタイルと変わりません。
自分が寝ている間にも積極的にトレードしてくれなければ
わざわざ自動取引プログラムを開発する意味がありません。
日足データだけだと、システムトレードをする目的を叶えられないので
もっと細かいデータが必要です。
できれば5分足とか1分足とか。
FOREXITEからデータ入手できそう
で、探してみたらありました。
1分足を提供しているサイトが。
FOREXITEというサイトです。
ロシアのサイトのようで、ロシア語がチンプンカンプンのサイトです。
(ヘッダーのイギリス国旗をクリックしましょう。英語表記になってわかるようになります。)
FOREXITEでは2001年からの1分足データをダウンロードできますが、ひとつ問題があります。
それは、1日分のデータが1ファイル(zip)にまとめられているということです。
これだと、1年分だと365回ファイルをダウンロードしなくてはいけません。
(厳密にはデータがあるのは365日よりも少ないので、ファイル数はもう少し少なくなりますが)
16年分のデータをダウンロードできますが、とてもではありませんが
一つ一つダウンロードしていられません。
ヒストリカルデータ取得スクリプトを作った
そこでPythonで自動ダウンロードするスクリプトを作りました。
今回作成したスクリプトは、FOREXITEから各ファイルをダウンロードし、
特定のフォルダ内に解凍するという動作を行うものです。
スクリプトのソースコード
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# -*- coding: utf-8 -*- """ Created on Wed Jan 4 18:14:53 2017 @author: """ import os import shutil import time import datetime import requests import zipfile baseurl = 'https://www.forexite.com/free_forex_quotes/' target_directory = './historicaldata/' def check_dir(): if os.path.exists(target_directory) == False: os.mkdir(target_directory) def get_filelist(): START_DATE = datetime.datetime(2001, 1, 3) today = datetime.datetime.today() date_list = [] get_date = START_DATE while get_date < today: year = "{0:04d}".format(get_date.year) year2 = year[2:] month = "{0:02d}".format(get_date.month) day = "{0:02d}".format(get_date.day) filepath = year + "/" + month + "/" + day + month + year2 + ".zip" date = year + month + day datedata = {'date':date, 'filepath':filepath} date_list.append(datedata) get_date += datetime.timedelta(days=1) return date_list def download_file(url): filename = url.split('/')[-1] res = requests.get(url, stream=True) content_type = res.headers['content-type'] if res.status_code == 200 and content_type == 'application/zip': with open(filename, 'wb') as f: for chunk in res.iter_content(chunk_size=1024): if chunk: f.write(chunk) f.flush() return filename # ファイルが開けなかった場合は False を返す return False def move_file(filename): if os.path.exists(filename) == True: shutil.move(filename, target_directory + filename) return target_directory + filename else: return None def zip_extract(filename, date): with zipfile.ZipFile(filename, 'r') as f: filelist = f.namelist() zfile = zipfile.ZipFile(filename) zfile.extractall(target_directory) for info in filelist: os.rename(target_directory + info, target_directory + date + '.txt') if __name__ == '__main__': check_dir() filelist = get_filelist() for filedata in filelist: filepath = filedata['filepath'] filename = download_file(baseurl + filepath) if filename != False: time.sleep(1) filepath = move_file(filename) if filepath != None: zip_extract(filepath, filedata['date']) |
データ取得スクリプトの簡単な説明
ダウンロードするzipファイルの名前は対象の日付になっているので、
2001年1月3日から現在の日付まで日付を動かしながら
各zipファイルをダウンロードしていきます。
ダウンロードしたファイルを特定のフォルダに移動して解凍、
分かりやすいファイル名に変更するところまで実装しています。
営業日の関係で、ファイルが存在しない日があります。
その日は当然ファイルがないので処理を飛ばしたいので、
以下のif文を入れて、status_codeが200の場合のみ
処理を継続するようにしました。
1 |
if res.status_code == 200: |
ここで問題だったのは、ファイルが存在しない場合でも
status_code = 200が返ってきたことです。
このURLをブラウザで開くと堂々と「404」と表示されますが、
status_codeは200がセットされています。
そこで、このif文にヘッダーのcontent-typeを見るように条件を追加しました。
content-typeがzipの場合だけダウンロードするようにしました。
今後の課題
このスクリプトを実行することで、各日付ファイルのダウンロードと解凍を行うことができますが、
1ファイル内に各通貨ペアごとの情報がまとめて入っています。
このままだと使えないので、データベースに登録してやりたいところですが、
どのデータベースがよいのか(MySQLか、SQLiteかなど)や
どういった形式が使いやすいのかなど検討して
データ加工+データベースへの登録を行いたいと思います。
ここは次回の記事で紹介します。