「自動売買ロボット作成マニュアル初級編」(以下本書)ではWebクエリを用いてYahooファイナンスから価格データを取得する方法を解説しました。この方法はYahooファイナンスの価格データのWebページにおいて、価格データの位置をWebテーブル番号として指定することで、Webページから価格データのみを抜き出して取得しています。しかし、近年ではこのWebテーブル番号がランダムに変更されることがあり、一定のWebテーブル番号を指定するだけでは安定的に動作しない例が何度か確認されました。そのため、このコラムではYahooファイナンスにおけるWebテーブル番号のランダム化に自動的に対応する方法を紹介します。特に新しい知識は必要ありませんので、是非チャレンジしてみてください。
それでは早速始めてみましょう。ここでは、第8章で紹介したマクロを元に、コードを一部修正するという方法を採りたいと思います。
まずは第8章のシートから「Module1」を開きます。そして、このモジュールの一番上に、以下のコードを追加します。
Dim wtbl As Integer
このモジュール内で使用することができる変数を宣言しました。次に、「Get_Data」マクロのうち、以下の部分を修正します。
.WebTables = 19 → .WebTables = wtbl
これにより、Webクエリ実行時に指定するWebテーブルの番号を、固定の値ではなく、先ほど宣言した変数に置き換えたことになります。
それでは次に、「Calc」マクロへ移動しましょう。「Calc」マクロにおける、以下のコードを見てください。
For i = 0 To 365 * 0.65 Step 50[↓]
url = "URL;http://table.yahoo.co.jp/t?s=" & code & "&a=" & month_s & "&b=" & day_s & "&c=" & year_s & "&d=" & month_e & "&e=" & day_e & "&f=" & year_e & "&g=d&q=t&y=" & i & "&z=" & code & "&x=.csv"[↓]
If i = 0 Then[↓]
lastrow = "4"[↓]
Call Get_Data[↓]
If Range("B4") = "" Then[↓]
Exit Sub[↓]
End If[↓]
Else[↓]
上記の部分を削除しましょう。削除する範囲を誤らないように注意してください。
削除したら、新たなコードを書き込んでいきます。まずは以下の4行を記述しましょう。
For i = 0 To 365 * 0.65 Step 50[↓]
If i = 0 Then[↓]
lastrow = "4"[↓]
For wtbl = 19 To 25[↓]
コードの内容を確認していきましょう。1行目は削除したコードと同様で、これから1年分の価格データの取得の繰り返しを行おうとするFor文の開始です。次に、iが0であった場合のIf文が開始されます。For文においてiはカウンタ変数に指定されているので、このiが0ということは、すなわちFor文の最初の繰り返しの場合、という意味になります。そして、この条件式に当てはまる場合、セルの書き込み先を指定する変数、lastrowを4とします。その後、先ほど宣言した、Webテーブル番号を意味する変数wtblをカウンタ変数に、19から25までの繰り返しを開始します。
勘の良い方ならすでにお気づきかと思いますが、ここではこのようにして、wtblという変数に19から25の値を順に入れ、繰り返しWebクエリを実行することで、どの番号のときに価格データを適切に取得できるかを確認します。そして、その番号が判明した場合、価格データの取得を開始するというものなのです。19から25、というのは、これまでに確認されたWebテーブルの番号の範囲です。今後、これよりも多彩なWebテーブル番号が確認された場合、この繰り返しの範囲を変更することで対応することができます。
url = "URL;http://table.yahoo.co.jp/t?s=" & code & "&a=" & month_s & "&b=" & day_s & "&c=" & year_s & "&d=" & month_e & "&e=" & day_e & "&f=" & year_e & "&g=d&q=t&y=" & i & "&z=" & code & "&x=.csv"[↓]
Call Get_Data[↓]
ここで、urlという変数にYahooファイナンスにおけるURLを代入します。この方法は第8章で紹介した方法と変わりありません。そして「Get_Data」マクロを呼び出し、Webクエリを実行します。
このとき、先ほど削除したコードと異なる点は、Webテーブル番号が固定ではなく、For文のカウンタ変数となっているwtblという変数によって変動している点です。
If Range("B4") = "日付" Then[↓]
Exit For[↓]
Else[↓]
Range("B4:H54").ClearContents[↓]
End If[↓]
Next[↓]
Else[↓]
url = "URL;http://table.yahoo.co.jp/t?s=" & code & "&a=" & month_s & "&b=" & day_s & "&c=" & year_s & "&d=" & month_e & "&e=" & day_e & "&f=" & year_e & "&g=d&q=t&y=" & i & "&z=" & code & "&x=.csv"[↓]
Webクエリが実行されたら、次にB4セルの状態をIf文で確認します。もしB4に「日付」と代入されていた場合、それは正しいWebテーブル番号でWebクエリを実行できたという意味になります。この場合「Exit For」を用いて、Webテーブル番号を探すFor文から抜けます。そして、その後は、判明した正しいWebテーブル番号を用いてWebクエリを繰り返す、という流れになります。
もし、B4セルに「日付」と代入されていなかった場合は、正しいWebテーブル番号でWebクエリが実行されていなかったことを意味します。その場合、Else以降が実行されます。Webクエリで取得した、間違ったデータをClearContentsメソッドで削除し、このIf文を抜けます。その後、Nextの記述があるので、再びWebテーブル番号を探すFor文の繰り返しが実行されます。この処理を繰り返すことで、正しいWebテーブル番号が見つかり次第、2回目以降の価格データの取得を始めるということになります。
また、最後に再度urlを定義するコードを記述しておきます。何故なら、2回目以降の繰り返しで再びこの変数の内容を変更しながら処理を繰り返さなくてはいけないからです。
いかがでしょうか。以上で修正は完了です。この方法を行うことで、Webテーブルがランダムに変更されたとしても自動的に対応することが可能になります。また、本書の内容に即したサンプルシートには、上記の内容も含まれています。こちらのほうでもコードや動作を確認していただければと思います。
なお、余談ですが、ここでは特に新しい知識を用いることなく、便利な機能を追加することができました。これまでに習得してきた知識を用いることで、実は様々な応用が可能です。ここで紹介したのはその一例に過ぎません。「こんな機能があると便利だな」と感じたら、それを実際に作ることに挑戦されることをお勧めします。もちろん、これまでに習得した知識だけでは難しい場合もありますが、その場合は新たな知識を求めて次のステップへと進んでみましょう。きっと、より投資に役立てる知識を得られるはずです。