会社員KNIGHTの趣味三昧(卓球・盆太鼓・色々!)

会社員KNIGHTの趣味三昧(卓球・盆太鼓・色々!)

PR

Calendar

Category

カテゴリ未分類

(0)

卓球

(1194)

盆太鼓・盆踊り

(407)

トイドローン

(21)

その他

(334)

■■■■■■↓以下は凍結カテゴリー↓■■■■■■

(0)

KATS(自動売買プログラム)

(87)

「VB.NETで自動売買」入門

(24)

本日の取引

(1292)

デイトレ結果(勝ち)

(365)

デイトレ結果(負け)

(591)

夜間取引結果

(15)

今週の取引

(480)

今月の取引

(103)

明日の監視銘柄

(54)

株関連

(55)

草野球

(36)

Keyword Search

▼キーワード検索

Comments

accelwin@ Re[4]:【卓球】シェイクのラケット反転について(11/23) KNIGHTさんへ ご返信ありがとうございます…
KNIGHT@ Re[1]:【卓球】シェイクのラケット反転について(11/23) accelwinさんへ ブログへのコメント、どう…
accelwin@ Re:【卓球】シェイクのラケット反転について(11/23) 61歳でカットマンに挑戦し、2カ月目に突…
KNIGHT@ Re[1]:単身赴任を終え兵庫に戻ります(06/28) Tomohiro Takahashiさんへ コメント有難う…
Tomohiro Takahashi@ Re:単身赴任を終え兵庫に戻ります(06/28) お疲れ様でした。そのうち、私も頑張って…
KNIGHT@ Re[1]:第1回 日中杯 SpinOnline(WSS団体戦)(04/14) fukufuku1789さんへ いえいえ。むしろ私が…
fukufuku1789 @ Re:第1回 日中杯 SpinOnline(WSS団体戦)(04/14) 一緒に試合に出てくださりありがとうござ…
KNIGHT@ Re[1]:第15回 朝霧オープン卓球大会(チームマッチ)(01/21) fukufuku1789さんへ お疲れ様でした。今回…
fukufuku1789 @ Re:第15回 朝霧オープン卓球大会(チームマッチ)(01/21) 惜しい試合が多かったですね。 また卓球し…
KNIGHT@ Re[3]:2023年度台東区オープン年代別後期団体戦(12/10) マニャさんへ コメントどうも有難うござい…
Nov 19, 2007
XML
今回はKATSでも使用している「 NDde 」というクラスライブラリを使って
楽天RSS(Realtime Spread Sheet)から情報を取得する方法をご紹介します。

楽天RSSはDDE(Dynamic Data Exchange)という昔ながらの技術を使用してデータ交換を行って
います。DDEはWindows2.0の頃からある枯れた技術だそうです。
.NET FrameworkはDDEをサポートしていないのですが、ネイティブなコードを書けば呼び出せます。
でもそれはかなり敷居が高いです。ですが複雑な処理をラップして.NETのクラスとしてDDEを
扱う事が出来るクラスライブラリ「NDde」が無償提供で存在しますので積極的に利用するべきだと
思います。


すぐに使用する事が出来ます。

楽天RSSを使用されている方はご存知ですが、楽天RSSはMarketSpeedを立ち上げてログインして
いないと使えない仕組みになっています。恐らく楽天証券の口座を開設していなかったり
MarketSpeedの使用料を払っていない人が楽天RSSだけ使用する事に歯止めを掛けるためだと
思っています。
NDdeは楽天RSSを経由して情報を取得するので、.NETから情報を取得するためには事前に
・楽天RSSを立ち上げる
・MarketSpeedを立ち上げ、ログインする
事が大前提になります。

では実際.NETのソースから使用する部分について解説を続けます。
ちなみに私はVB2005 Express Editionを使用していますのでVB2005EEベースでソースを書きます。


DDEを使いデータを取得する方法は大きく分けて2つあります。
1つは「○○のデータを下さい」とリクエストし、データを返してもらう方法。
もう1つは「○○のデータに変更があれば通知して下さい」とお願いし、データに変更があるたびに
イベントを発生させてもらう方法。

前者は自分から要求しない限りデータをもらえないので、例えば現在の株価などを調べるとなると

その方法でも実現可能なのですが、全く値動きしていないかも知れないデータを要求するのは
無駄ですし「定期的」のインターバルの長短によって精度とパフォーマンスのトレードオフを
考慮しなければならないので大変です。
なので前者は銘柄名や市場名、あるいは「前日終値」など不変データを取得する時に使用するのが
適切だと思います。

逆に後者はリアルタイム情報の取得に適しています。
DDEに対し「現在値(株価)の監視を開始して」と命令すると、その銘柄の株価に変更があった時に
イベントが発生します。なのでこちらが一定のタイミングで「今何円か」と聞く必要なく、
イベントハンドラに「株価が変更された時の処理」を記述するだけでよくなります。
これはVBやC#の利点だと思うので是非使いたい機能です。

前置きはこのぐらいにして実際のコードを紹介します。
NDdeにはNDde.Client.DdeClientというクラスがあり、このクラスを使って情報を取得します。
DDEにはサービス名、トピック名というものがありますが、楽天RSSに置き換えて考えると
サービス名は「RSS」、トピック名は「銘柄コード.市場コード(9898.Tなど)」です。
DdeClientのコンストラクタにはこの2つを指定しないといけません。
つまり、扱う銘柄の数だけDdeClientのインスタンスを生成する事になります。

Dim ddeClient As DdeClient = New DdeClient("RSS", "9898.T")

のような感じです(こうやって名前空間を省略して記述するには、ソースの先頭に
「Imports NDde.Client」が必要です)。


では早速、このDDEクライアントで9898.T(サハダイヤモンド)の株価を取得してみましょう。

Dim byteData as Byte() = ddeClient.Request("現在値", 1, 6000)

これでOKです。第二引数の「1」はお作法だと思ってもらって結構です。
「6000」はタイムアウトのミリ秒で、この設定だと1分間までは応答を待つ事になっています。
もっとも、この処理に1分掛かってるようじゃ明らかに異常ですが(汗)。
ただこのままだと問題があります。返って来るデータがバイト配列です。扱い辛いですよね。
データを文字列で返してくれるシグニチャ(メソッドと引数の組み合わせ)もあるのですが、
それは使わずバイト配列を返してくれるこのメソッドを使用する事をお勧めします。
株価なら良いのですが、銘柄名称などの2バイト文字を取得する時、文字列で取得すると
気持ち良く文字化けしてくれます(笑)。
何故なら楽天RSSは文字コードをShift-JISで返すようなので、.NETのUnicodeとは文字コードが
異なるからです。
化けてしまったデータはもうどうしようもないので、バイト配列でもらって自分でエンコード
してやる必要があるんです。具体的には

Encoding.Default.GetString(byteData, 0, byteData.Length - 1)

と書けます(こうやって名前空間を省略して記述するには、ソースの先頭に
「Imports System.Text」が必要です)。

また、楽天RSSから取得される数値データには余計な文字を含むものが多いです。
例えば株価を取得しているのに「150.00」など。
文字列で取得してこんなのが返って来ても不便です。
見栄えよくするため、CInt(price)で整数型に変換してやると良いでしょう。
ただ現在値など、ザラ場開始前に取得すると空文字("")を返してくるものは要注意です。
0円ではなく、まだ値がない状態です。
その時にはCIntで変換を掛けると異常終了しますので考慮が必要です。


続いて、2つ目の方法(変更を通知してもらう方法)を試してみましょう。
変更を通知してもらうメソッドはDdeClientのStartAdviseメソッドです。
Subなので戻り値はありません。

ddeClient.StartAdvise("現在値", 1, 6000)

と記述します。こうする事によって、DDEクライアントの「現在値(株価)」に変更が
あった時にclientの「Adviseイベント」が発生します。
そのイベントはVBで拾わないといけません。
でも定期的に「イベントが発生したかな?」などと調査するのではなく「イベントハンドラを
追加する」という作業を行います。

AddHandler ddeClient.Advise, AddressOf Client_Advise

と記述したとします。
すると、ddeClientインスタンスでAdviseイベントが発生すると、Client_Adviseという
メソッドが起動されるようになります(メソッド名の「Client_Advise」は任意)。

この記述を書かないと発生したイベントは拾えないので、注意が必要です。
私もハマッたのですが、

ddeClient.StartAdvise("現在値", 1, 6000)
AddHandler ddeClient.Advise, AddressOf Client_Advise


という2行を書いてやると、1行目を処理してから2行目を処理するまでの間に発生した
イベントは拾えません!つまり開始した直後のイベントが無視される可能性があるのです。
なので、イベントハンドラの登録が先だという事に注意して下さい。

AddHandler ddeClient.Advise, AddressOf Client_Advise
ddeClient.StartAdvise("現在値", 1, 6000)


ちなみに、他の項目の監視を開始して変更が発生した時でもイベントは「Advise」1つだけ
だという事に注目です。
つまり複数項目を監視させている場合にはイベントハンドラ中で「どの項目に変更が
あったのか」を判断する必要があるのです。
では、

AddHandler ddeClient.Advise, AddressOf Client_Advise
client.StartAdvise("現在値", 1, 6000)
client.StartAdvise("高値", 1, 6000)
client.StartAdvise("安値", 1, 6000)


と書いた時に、どうやって変更通知を処理するかについて説明します。

イベントハンドラメソッドは、名前は何でも良いのですが引数の型や数はイベントの規則に
従っている必要があります。
NDdeClient.Adviseイベントの引数はNDde.Client.DdeAdviseEventArgsですが、これは従うしか
無いのでお作法だと思ってこう記述します。

Private Sub Client_Advise(ByVal sender As Object, ByVal e As DdeAdviseEventArgs)
                 :
                 :
End Sub


この引数が非常に重要です。
senderの実体はDdeClientクラスのインスタンスです。DdeClientにキャストしてやれば、
Topicプロパティの値を見る事によって「どの銘柄に変更があったのか」を知る事が出来ます。

Dim client as DdeClient = DirectCast(sender, DdeClient)
Dim topic as String = client.Topic


監視する銘柄が複数で、それらに全く同じイベントハンドラを割り当てる場合は無くては
ならないものです。

次に、監視銘柄のどの項目に変更があったか知る必要があります。
それはもう1つの引数であるeを使います。
「e.Item」が項目名ですので、例えば

If e.Item.Equals("現在値") Then
  '現在値に変更があった時の処理
Else
         :


という判断が可能になります。
また変更されたデータそのものは「e.Data」で、バイト配列です。
DdeClient.Request()メソッドで返って来るバイト配列と同じように扱います。


長くなりましたが、以上がNDdeというクラスライブラリを使ってVB.NETから楽天RSS経由で
株式情報を取得する方法です。
エラーハンドリングやその他必要な情報を省略して本当に基本的な部分しか書いてませんが
参考になる方にはなるのでは、と思います。

私はもちろんこれらをベタで書いている訳ではなく、使いやすい部品としてDdeManagerという
ユーティリティクラスを作成しています。
もし「欲しい!」という方がいらっしゃれば連絡下さい。
いかなる不具合が発生しても保証しないという条件付きで、無償で提供します(笑)。
「いや、今後の開発の為に是非寄付させて欲しい」という奇特な方がいらっしゃれば
遠慮なくお申し出下さい。それも大歓迎ですよw





お気に入りの記事を「いいね!」で応援しよう

Last updated  Nov 20, 2007 12:06:50 AM
コメント(12) | コメントを書く


【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! -- / --
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x
X

© Rakuten Group, Inc.
X
Design a Mobile Website
スマートフォン版を閲覧 | PC版を閲覧
Share by: