ヒストリカルデータをダウンロード可能なところは幾つかありますが、1分足で10年間以上の長期ヒストリカルデータを入手できる所では
Forexiteが有名です。
桁数は2桁/4桁ですが、主要通貨ペアは2001年以降のデータが揃っていますし、キウイ円なども2003年から入手可能です。
ただし配布形式は1日1ファイルで通貨ペア混在のため、MT4にインポートするには通貨ペア別にデータを分ける必要があり、手間が掛かっていました。
そこで今回は、ダウンロードから通貨ペア別ファイル作成までの一連の作業を、一括で行うVBスクリプトを作ってみました。
Forexiteヒストリカルデータ取得.vbs
Option Explicit
'**************************
' ダウンロード期間の指定
'**************************
Const PeriodStart = #2015/01/02# ' 2001/01/03~取得可能
Const PeriodEnd = 0 ' ゼロで前日分まで取得
' ADODB.Stream 定数
Const adTypeBinary = 1
Const adTypeText = 2
Const adSaveCreateNotExist = 1
Const adSaveCreateOverWrite = 2
' Scripting.TextStream 定数
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
' NameSpace.CopyHere 定数
Const FOF_SILENT = &H4
Const FOF_NOCONFIRMATION = &H10
'**************************
' メイン処理呼び出し
'**************************
Call Main
'----------------------------------------------------------------
' メイン処理
'----------------------------------------------------------------
Sub Main()
Dim objFs
Dim historicalDate, PeriodEndDate
Dim zipFile, txtFile
Dim exportResult
If MsgBox("処理しますか?", vbQuestion + vbYesNo) = vbNo Then Exit Sub
Set objFs = CreateObject("Scripting.FileSystemObject")
If PeriodEnd = 0 Then
PeriodEndDate = Now() - 1
Else
PeriodEndDate = PeriodEnd
End If
For historicalDate = PeriodStart To PeriodEndDate
' 土曜日以外は取得
If Weekday(historicalDate) <> 7 Then
zipFile = HistoricalDataDownloadFromForexite(historicalDate)
txtFile = ExtractHistoricalZip(zipFile)
If txtFile <> "" Then
exportResult = DivideHistoricalPrn(txtFile)
If Not exportResult Then Exit For
objFs.DeleteFile txtFile
End If
End If
Next
Set objFs = Nothing
MsgBox "処理が終わりました", vbInformation
End Sub
'----------------------------------------------------------------
' Forexiteからヒストリカルデータをダウンロードする
' 【引数】
' HistoricalDate … ダウンロードするデータの日付
' 【戻り値】
' 保存したZIPファイル名
'----------------------------------------------------------------
Function HistoricalDataDownloadFromForexite(historicalDate)
Dim objFs, objWinHttpRequest, objAdoStream
Dim downloadFolder, remoteFileName, localFileName
Dim yyyy, yy, mm, dd
HistoricalDataDownloadFromForexite = ""
If IsDate(historicalDate) Then
Set objFs = CreateObject("Scripting.FileSystemObject")
Set objWinHttpRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
Set objAdoStream = CreateObject("ADODB.Stream")
yyyy = CStr(Year(historicalDate))
yy = Right(yyyy, 2)
mm = Right("0" & Month(historicalDate), 2)
dd = Right("0" & Day(historicalDate), 2)
' ダウンロードフォルダ作成
downloadFolder = objFs.BuildPath(objFs.GetFile(WScript.ScriptFullName).ParentFolder.Path, "download")
If Not objFs.FolderExists(downloadFolder) Then objFs.CreateFolder downloadFolder
' リモートファイル名はDDMMYY.zip
remoteFileName = "https://www.forexite.com/free_forex_quotes/" & yyyy & "/" & mm & "/" & dd & mm & yy & ".zip"
' ローカルファイル名はYYYYMMDD.zipで保存
localFileName = objFs.BuildPath(downloadFolder, yyyy & mm & dd & ".zip")
If Not objFs.FileExists(localFileName) Then
' ダウンロードリクエスト
objWinHttpRequest.Open "GET", remoteFileName, False
objWinHttpRequest.Send
If objWinHttpRequest.GetResponseHeader("Content-Type") = "application/zip" Then
' ZIPファイルを保存
objAdoStream.Type = adTypeBinary
objAdoStream.Open
objAdoStream.Write objWinHttpRequest.ResponseBody
objAdoStream.SaveToFile localFileName, adSaveCreateOverWrite
objAdoStream.Close
HistoricalDataDownloadFromForexite = localFileName
End If
End If
End If
Set objAdoStream = Nothing
Set objWinHttpRequest = Nothing
Set objFs = Nothing
End Function
'----------------------------------------------------------------
' ZIPファイルを解凍する
' 【引数】
' HistoricalZipFile … ダウンロードしたヒストリカルZIPファイル
' 【戻り値】
' 解凍したtxtファイル名
'----------------------------------------------------------------
Function ExtractHistoricalZip(HistoricalZipFile)
Dim objFs, objShell, objFolder, objZipFolder
Dim workFolder, zipFile, txtFile
Set objFs = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
If objFs.FileExists(HistoricalZipFile) Then
' 作業フォルダ作成
workFolder = objFs.BuildPath(objFs.GetFile(WScript.ScriptFullName).ParentFolder.Path, "work")
If Not objFs.FolderExists(workFolder) Then objFs.CreateFolder workFolder
' ZIPファイルを解凍
Set objFolder = objShell.Namespace(workFolder)
Set objZipFolder = objShell.Namespace(HistoricalZipFile)
objFolder.CopyHere objZipFolder.Items(), FOF_SILENT Or FOF_NOCONFIRMATION
WScript.Sleep 1000
' 解凍確認
zipFile = objFs.GetBaseName(HistoricalZipFile)
If Len(zipFile) = 8 Then
txtFile = objFs.BuildPath(workFolder, Right(zipFile, 2) & Mid(zipFile, 5, 2) & Mid(zipFile, 3, 2) & ".txt")
Else
txtFile = objFs.BuildPath(workFolder, zipFile & ".txt")
End If
If objFs.FileExists(txtFile) Then ExtractHistoricalZip = txtFile
End If
Set objZipFolder = Nothing
Set objFolder = Nothing
Set objShell = Nothing
End Function
'----------------------------------------------------------------
' ヒストリカルを通貨ペア別に分けて保存する(prn形式)
' 【引数】
' HistoricalTxtFile … ダウンロードしたヒストリカルTxtファイル
' 【戻り値】
' 成功時True、失敗時False
'----------------------------------------------------------------
Function DivideHistoricalPrn(HistoricalTxtFile)
Dim objFs, objTextStream
Dim prnFolder, prnFile
Dim txtData, prnHeader, prnData, symbol
Dim txtPos, searchPos, sectionPos
Dim errFlg
Set objFs = CreateObject("Scripting.FileSystemObject")
If objFs.FileExists(HistoricalTxtFile) Then
' prnフォルダ作成 ※'PRN'はシステム予約語のためファイル名使用不可
prnFolder = objFs.BuildPath(objFs.GetFile(WScript.ScriptFullName).ParentFolder.Path, "prnData")
If Not objFs.FolderExists(prnFolder) Then objFs.CreateFolder prnFolder
' txtファイル読込
Set objTextStream = objFs.OpenTextFile(HistoricalTxtFile, ForReading)
txtData = objTextStream.ReadAll
objTextStream.Close
Set objTextStream = Nothing
If Len(txtData) > 50 Then
' ヘッダー抽出
searchPos = InStr(1, txtData, vbCrLf)
If searchPos > 0 Then
prnHeader = Left(txtData, searchPos - 1)
txtPos = searchPos + 2
Else
MsgBox "ヘッダー取得に失敗しました" & vbLf & HistoricalTxtFile, vbCritical
errFlg = True
End If
' 通貨ペア分割
Do While Len(txtData) > txtPos And Not errFlg
' 通貨ペア取得
searchPos = InStr(txtPos, txtData, ",")
If searchPos > 0 Then
symbol = Mid(txtData, txtPos, searchPos - txtPos)
' 該当通貨ペアのヒストリカルデータ最終行検索
searchPos = InStrRev(txtData, symbol)
If searchPos > 0 Then
' 通貨ペア別ヒストリカルデータ取得
sectionPos = InStr(searchPos, txtData, vbCrLf)
If sectionPos = 0 Then sectionPos = Len(txtData) + 1
prnData = Mid(txtData, txtPos, sectionPos - txtPos)
txtPos = sectionPos + 2
' prnファイル出力
prnFile = objFs.BuildPath(prnFolder, symbol & ".prn")
If Not objFs.FileExists(prnFile) Then prnData = prnHeader & vbCrLf & prnData
Set objTextStream = objFs.OpenTextFile(prnFile, ForAppending, True)
objTextStream.WriteLine prnData
objTextStream.Close
Set objTextStream = Nothing
Else
MsgBox "通貨ペア分割に失敗しました" & vbLf & HistoricalTxtFile, vbCritical
errFlg = True
End If
Else
MsgBox "通貨ペア取得に失敗しました" & vbLf & HistoricalTxtFile, vbCritical
errFlg = True
End If
Loop
Else
MsgBox "テキスト読込に失敗しました" & vbLf & HistoricalTxtFile, vbCritical
errFlg = True
End If
Else
MsgBox "テキストファイルがありません" & vbLf & HistoricalTxtFile, vbCritical
errFlg = True
End If
Set objFs = Nothing
DivideHistoricalPrn = Not errFlg
End Function
ヒストリカルデータの取得期間は最初の定数宣言で指定して下さい。
このスクリプトを実行すると、VBSを実行したフォルダに3つのフォルダが作成されます。
VBSなので処理状況は表示されませんが、downloadフォルダの中を見ていれば、状況はだいたい判ると思います。
Forexiteは2001/1/3~取得可能ですが、全期間を一度に処理すると数時間以上掛かると思います。VBSのため中断できないのでご注意下さい。
なお2回目以降は差分ダウンロード・追記方式のため、処理時間はさほど掛かりません。
MT4インポート用のテキストファイルは「prnData」にPRN形式で保存されますが、MT4が扱うPRN形式は、ほぼCSVと同じです。
PRN形式の利点は、通貨ペアの列を除去しなくてもインポート可能であり、Forexiteのテキストをそのまま流用可能な点になります。
全期間ダウンロードした場合のディスク使用容量は、ダウンロードしたZIPファイルが約1GB、prnファイルが約9.6GBになります。
MT4へのインポート方法はいつもの通りです。
ForexiteのヒストリカルデータはGMT+1なので、必要に応じて時間をシフトして下さい。
1つ注意点として、15年ものヒストリカルデータになるとファイルサイズが約300MBになりますので、連続してインポートし続けているとMT4の動作がおかしくなる事があります。
これはMT4のhstファイル作成タイミングが、インポート直後ではなくMT4を終了させた後であり、メモリ上でヒストリカルデータを保持し続ける事により、32ビットアプリのメモリ制限2GBを使い切ってしまう為と思われます。
長期間のヒストリカルデータをインポートする際は、2~4通貨ペアのインポート毎に一旦MT4を終了したほうが良いでしょう。
テーマ : FX(外国為替証拠金取引)
ジャンル : 株式・投資・マネー