ヒストリカルデータの入手
ヒストリカルデータの所在
現実世界の過去の為替レートの推移ですから、どこかにあるのは間違いありませんが、実際に利用できるようにまとまっているものは見つけにくいかもしれません。
自分で利用している証券会社等が提供しているデータがあれば(※普通は会員向けに提供されている)それを利用するのが良いですが、ここではVBAの練習もかねて以下のサイトに公開されているヒストリカルデータを利用する方法について検討してみます。
FOREXite Ltd
このサイトでは2001年から現在までのヒストリカルデータ(分足)をダウンロードすることができます(※0.01円単位のデータであることに注意)。
まずサイトを開くと、最新年の日付がずらっと並んでおり、右の「MetaStock」という列にzipファイルへのリンクが張ってあります。
普通にクリックして一つずつダウンロードしても良いのですが、見れば分かる通り1日に対して1ファイルという構成になっており、これだけ大量にあるデータを手動でダウンロードするのは非常に手間のかかる現実的ではない作業です。
そこでVBAを使ってこの作業をしてみましょう。
なお、前にも書きましたが、過剰なアクセスには十分注意してください。
サイトのHTMLを見る
先ほどのページの下の方に、2001年以降の年代別ページへのリンクがあります。
そのリンク先には同じようにヒストリカルデータがぎっしり並んでいます。
これだけのデータを無償で誰もが利用可能なように公開してくれるということは本当にありがたいことですね。
さて、このサイトからヒストリカルデータを取得するにあたり必要な情報は、ページのURLとzipファイルのURLです。
過去年分のページのURLは最新年分ページのURLである"forex_history_arhiv"の後に"_西暦"で表されているようです。
zipファイルは2012年1月2日のデータが"2012/01/020112.zip"というように"年/月/日月年"で表されています。
自動ダウンロードプログラム
それではさしあたり過去1年分のヒストリカルデータを取得するプログラムを書いてみましょう。
プログラムを使えば全てのデータを一度に取得することもできますが、やめた方が良いと思います。
以下は1年前のヒストリカルデータを新規フォルダ(エクセルがあるフォルダ内にzippedフォルダを作成)にダウンロードするサンプルコードです。
適当に書き換えれば好きなようにダウンロードできますが、安易に全年度ダウンロードをしたりしようとすると何時間もかかるかもしれず、サーバ負荷もなかなかのものだと思いますから、気をつけてください。
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'スリープ
Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias _
"URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, _
ByVal szFileName As String, _
ByVal dwReserved As Long, _
ByVal lpfnCB As Long) As Long 'URLからファイルをダウンロード
Sub GetHistricalData() 'ヒストリカルデータのダウンロード
'///概要
'1.forexite"http://www.forexite.com/free_forex_quotes/forex_history_arhiv.html"にアクセス
'2.aタグ内の"forex_history_arhiv"を含むリンクリストを作成(yearlist)
'3.年ごとにaタグ内のzipファイル名を含むリンクリスト(ziplist)を作成する
'4.ziplistを全てダウンロードする
'///
'/*変数リスト
Dim tags As Variant 'html解析用変数
Dim IE As New InternetExplorer 'IEオブジェクト作成
Dim yearlist(20) As String 'アクセスする年リスト(最大20年)
Dim cntY As Long, i As Long 'ループ用変数
Dim target As Long '取得対象(新着順の取得年数)
Dim savefolder As String
'*/
savefolder = ThisWorkbook.Path + "\zipped" '保存フォルダ
If Dir(savefolder, vbDirectory) = "" Then
MkDir savefolder '保存フォルダがなければ新規作成
End If
savefolder = savefolder + "\" '"※\マークのHTMLエスケープ用。特に意味なし。
target = 1 '取得対象指定(0=今年度分)
yearlist(0) = "http://www.forexite.com/free_forex_quotes/forex_history_arhiv.html" '最新年度
IE.Navigate2 yearlist(0) 'IEを起動してトップへ移動
While (IE.Busy = True) Or (IE.readyState < READYSTATE_COMPLETE) '表示待ち
DoEvents
Wend
cntY = 1 '年カウンタ初期化
For Each tags In IE.document.getElementsByTagName("a") 'aタグ内を検索
If InStr(tags.href, "forex_history_arhiv") Then '"forex_history_arhiv"を含むリンクを検索
yearlist(cntY) = tags.href '年リスト追加
cntY = cntY + 1 '年カウンタ加算
End If
Next
For i = target To target + 1 '1年前のみ指定
If i > target Then
Exit For
End If
If yearlist(i) = "" Then '欠番はスキップ
Exit For
Else
IE.Navigate2 yearlist(i) '年ページへ移動
While (IE.Busy = True) Or (IE.readyState < READYSTATE_COMPLETE) '表示待ち
DoEvents
Wend
For Each tags In IE.document.getElementsByTagName("a") 'aタグ内を検索
If InStr(tags.href, ".zip") Then '".zip"を含むリンクを検索
Call URLDownloadToFile(0, tags.href, savefolder + tags.nameprop, 0, 0) '実行
Sleep (10) '気持ち的な負荷軽減用
DoEvents
End If
Next
End If
Next
IE.Quit 'IEを終了
End Sub