カテゴリ未分類 0
■■■■■■↓以下は凍結カテゴリー↓■■■■■■ 0
全24件 (24件中 1-24件目)
1
前回から間を置かずに<その3>を投稿する事は私自身も予定していませんでした。ログイン処理が出来たら、皆さんが知りたいのは恐らく注文処理と一覧取得処理だと思います。注文処理は、クリック証券のWebサービスのように容易にはいきません。SBI証券バックアップサイトは発注を行う時に2画面に渡って行います。つまり、HTTPリクエストを2度送信して初めて発注出来ます。また、その間処理がシーケンシャルに行われているか判断するために隠しパラメータを使用しているので、悩んでいる方もいらっしゃるかと思います。保有銘柄一覧や注文一覧など、一覧情報の取得に悩まれている方もいらっしゃるでしょう。こちらは、HTMLソースから繰り返し情報を効率良く取得するにはどうするかというのがポイントになってくると思います。それら2つのメイン処理は次回以降に回すとして、その予備知識として先に「正規表現」というものを扱いHTMLソースから効率良くデータを取得する方法をご紹介します。作成する処理はクリック証券編と同様、購買余力の取得です。クリック証券編<その6>に書いているように「余力確認」ボタンを作成し、コードの実装を行う準備をして下さい。どんなURLを送信しないといけないかは、実際のSBI証券バックアップサイトで確認します。Webブラウザを使ってログインすると、トップページに「買付余力」というリンクがあります。トップページのHTMLソースを見て「買付余力」と書いているリンク(Aタグ)に書いてあるURLを確認しても構いません。でもソースを見慣れていない人はややこしいですしURLも相対パスで書いているので分かりにくいです。そこで、簡単な方法があります。実際に「買付余力」リンクをクリックし、買付余力画面を表示して下さい。その時WebブラウザのURLに表示されているのがそれです。 ※もしWebブラウザでURLの表示をしていない場合はブラウザのオプションから表示して下さいちなみに買付余力の確認には何のリクエストパラメータも要りません。よって、ログイン処理の時と同様にソースを書くと、このようになります。Dim res As WebResponse = HttpPost("https://k.sbisec.co.jp/~~/purchaseMarginList.do", "")Dim html As String = ""Using sr As New IO.StreamReader(res.GetResponseStream, Encoding.GetEncoding(932)) html = sr.ReadToEnd()End Usingこれで、変数「html」には応答HTMLソースが返って来ています。問題はここからです。そのHTMLソースから、どうやって買付余力を取得するかです。例えば私の買付余力画面はこのようになっています(お恥ずかしい)。人間が見れば「47,508円だな」と分かりますが、プログラムからこの金額を取得するには果たしてどうしましょうか。Webサービスの応答のように「ここに金額が入っていますよ」と示すタグもありません。せいぜい、単に表を構成するTABLEタグぐらいでしょう。入力項目(テキストボックス等)ではなくただの表示項目なので、特にそこをデータとして識別するものは何もありません。しかも、金額は複数箇所にあります(^^; 取得したいのは一番上にある金額です。こんな時、テキスト文字列を解析するのに非常に役立つのが「正規表現」です。私が解説するよりも、もっと良いリソースがネット上に沢山ありますので、ご存じない方は是非このキーワードで検索して頂ければ幸いです。奥が深いです。.NET Frameworkで正規表現を扱うには「System.Text.RegularExpressions.Regex」というクラスを使用します。このクラスには、文字列から自分の指定した文字列パターンに合致するものを検索する「Match()」というメソッドがあり、それを使用します。申し訳ないですが、まずはソースをご紹介します。Dim m As Match = Regex.Match(html, "<td\salign=""right"">\s*(?<yoryoku>\S*)円")このように「Regex」というクラスをコーディングするには、ソース上部にImports System.Text.RegularExpressionsが必要です。あるいは「System.Text.RegularExpressions.Regex」とフルで書いて下さい。上のソースのポイントはダブルクォーテーションで囲まれた部分です。少しだけ解説すると、文字列中の「""」は、一番外側のダブルクォーテーションとは違い、文字列中の「"という文字」という風に扱うものです。2つ続けて記述します。「\s」は半角スペースを意味します。「*」は、0回以上繰り返すという意味です。「?<yoryoku>」は、その位置にある文字を「yoryoku」という変数として定義しています。つまり、上の文字列は、HTMLソースの中から、一番最初に見付かった「<td align="right"> xxxxxx円」という文字列パターンを探します。「xxxxxx」の部分の長さは言及していません。また、その左のスペースの長さも。スペースが終わって何か違う文字列が入っている部分(「円」が出現する手前)である「xxxxxx」の部分を変数「yoryoku」という名前で定義します。この結果の変数「m」を使って余力を取得します。m.Groups("yoryoku").Valueが求めている値です。メッセージボックスで出力するために以下のように書きます。「Groups」なんて書いてますので、もし指定したパターンに合致する場所が複数箇所存在する場合は「yoryoku」は複数あります。今回もそうですね。ですが、上の1行だけだと、最初に見つかったものしか取得していません。複数回の取得方法は一覧情報を取得する回に解説させて頂きます。MessageBox.Show("購買余力は" & m.Groups("yoryoku").Value & "円です。")いかがでしょうか?これで、HTMLソースから何とかデータを取得する事が出来そうですよね。最終的にソースはこうなりました。正規表現についてあまり理解されていない方は、次回までに学習される事をお勧めします。Webスクレイピングのために有効な知識ですので損は無いと思います。
Nov 21, 2010
コメント(2)
前回から開始したSBI証券バックアップサイトからの発注シリーズ。今日からいよいよ処理の作成を始めます。まずはログイン処理です。この記事の前準備として、SBI証券に口座開設しておく事と、過去記事で利用していた「SampleApplication」を作っておく必要があります。記事に沿って開発を行ってみようという方は「VB.NETで楽天RSSからリアルタイム情報を取得する」から始まり「クリック証券のWebサービスで発注する」を<その4>まで進め、HTTPリクエストを送信する「HttpPost()メソッド」を作成するところまで完了しておく必要があります。 ※前回「<その3>まで進めておく」と書きましたが<その4>の間違いですでは早速書いてきます。ログインボタンをクリックした時の処理を実装するわけですが、クリック証券の時のように「このURLで、このリクエストパラメータを送信して下さい」などという仕様は公開されていません。自力で送信するしかありません。ではどうするのか。WebブラウザからSBI証券バックアップサイトを使ってログインするかのように振舞います。ではSBI証券バックアップサイトのHTMLソースを確認するためにブラウザで開いてみましょう。ログイン画面が開きましたか?お使いのブラウザによってメニューが違いますが、例えばFirefoxであればメニューバーの「表示」から「ページのソース」をクリックするか、ページ上で右クリックして「ページのソースを表示」を選択するとHTMLソースが表示されます。「HTMLソースが全く読めません」という方は、恐らく今後私の記事を読み進める事は困難だと思いますので、勉強されるか断念されるしかないと思います(^^;ソースの中から把握したいのは、ログインボタンをクリックした時にどんなURLとリクエストパラメータを送信しているか。まずログインボタンが属しているFORMタグの属性から、送信URLを確認します。「https://k.sbisec.co.jp/~~/loginUserCheck.do(少し伏せ字にしてます)」です。ログインする時はこのURLにパラメータを送信するようです。次に、リクエストパラメータとしてどんな値を送信する必要があるか。Javascriptなどでパラメータを追加しているサイトもありますが、単純なサイトであればFORMタグに囲まれている中に存在するINPUTタグやHIDDENタグを探せば良いです。ログインの場合ですと単純なのですぐに分かります。ユーザーIDを表す「username」とパスワードを表す「password」です。簡単ですよね?(笑)それでは、クリック証券編と同様、HttpPost()メソッドを使ってリクエストを送信します。Dim res As WebResponse = _HttpPost("https://k.sbisec.co.jp/~~/loginUserCheck.do", "username=xxxxxx&password=xxxxxx")1行が長いので2行に分けましたが、プログラム上で1行のソースを分割する場合、上のように「 _」を付ける必要があります。実際には折り返さなくても構いません。お好みで結構です。もうこの1行だけでログイン処理は終了です。ですが問題はここからなのです。クリック証券のWebサービスだと「応答はこのようなXMLで返ります。ステータスは・・・」などと仕様が公開されているのですが、単にWebサイトを操作しているだけなのでそんなものはありません。返って来るのはログインボタンをクリックした後に返って来る画面のHTMLソース。それだけです。そこにどんな情報が含まれているかは実際にそのページのソースを見るしかありません。という事で、確認のために、実際にSBI証券バックアップサイトにブラウザからログインして下さい。私が今ログインすると、このような画面が表示されました。この画面から「ログインが成功した」と判断します。判断基準は自分で考えるしかありません(^^;一番順当な考え方だと私が思うのは、画面の右上と右下に「ログアウト」のリンクが出てますよね?ログアウトするリンクが出ているという事はログインしている状態だと判断出来ます。HTMLソースの中に「ログアウト」という文字列を発見したらログインしていると判断する事にします。まずは先ほどの応答クラス「WebResponse」の変数resから応答HTMLを文字列で取得します。Dim html As String = ""Using sr As New IO.StreamReader(res.GetResponseStream, Encoding.GetEncoding(932)) html = sr.ReadToEnd()End Using説明は割愛させて頂きます。エンコーディングを「932」で行っているのは、Webサイトの文字コードがShift_JISだからです。確かクリック証券の時はUnicodeだったのでこの記述は無かったですかね。次に、安易ではありますが「HTML文字列中に"ログアウト"が含まれていたらログインが成功した」とみなすためのコードを追加します。If html.Contains("ログアウト") Then MessageBox.Show("SBI証券バックアップサイトにログインしました。")Else MessageBox.Show("SBI証券バックアップサイトにログイン出来ませんでした。")End Ifログイン出来なかった時の原因ですが、ユーザーIDかパスワードが間違っているのか、入力されていないのか、どのような理由かは・・・知りません(苦笑)。その時に応じて画面にエラーメッセージが出ていると思うので、その文字列を解析して独自で判断ロジックを入れて頂くという事です。仕様は公開されていないのですから。。。さて、ログイン処理のプログラムはこのようになりました。今回は非常に簡単でしたが、複雑な応答HTMLから欲しい情報を取得するのは、ログイン結果のような簡単な手順ではありません。また、リクエストパラメータの値なども複雑化しますので、特に発注処理などは手こずってしまう事もあると思います。次回はクリック証券の時と同様「購買余力の確認」を行う予定です。もしご不明な点や、ご意見・ご指摘等があれば遠慮なくコメント下さい。宜しくお願いします。
Nov 20, 2010
コメント(0)
私が過去に連載していた「VB.NETで自動売買」入門というものがあります。私が試行錯誤して自動売買プログラムを開発した経験が少しでも皆さんの参考になればと思い、公開させて頂いたものです。株価などのリアルタイム情報の取得については、楽天証券のMarketSpeedとRealtimeSpreadSheetを使い、発注については、クリック証券のWebサービスAPIを使用したプログラムでした。しかし、2009年2月にクリック証券がWebサービスの公開を中止してしまい、発注部分についての記事がほとんど使い物にならなくなってしまいました。私個人としましては、自動売買プログラムKATSの修正を行い、何とか運用再開を行ったのですが、クリック証券に替わる新たな方法についての入門編を書くというモチベーションはありませんでした。ですがこの度ブログにリクエストがあり「期待されている方がいらっしゃるなら書いてみよう」という事で「SBI証券バックアップサイトで発注する」編の連載を開始する事にしました。連載と言っても不定期になりますし、大した内容が無いのですぐに終わるとは思いますが、少しでも皆さんの参考になれば幸いです。今回は初回という事で、SBI証券バックアップサイトを使って発注する事に決めた理由を書きたいと思います。クリック証券の時は、公開されたAPIに基づき、安定した無駄の無い発注処理を行う事が出来ました。しかし、WebサービスのAPIが無い今、残された手段の中で私が有力だと思うのが「Webスクレイピング」でした。Webスクレイピングとは、APIを公開していない通常のWebサイトの情報から自分が必要な情報を取得する技術で、Web2.0の要素の一つと言われているマッシュアップで有効となるテクニックです。しかし、一般のWebサイトから地道な作業で情報を取得する作業ですので、APIを使用する方法に比べてデメリットが沢山あります。その中でも痛いのは下の2つです。(1)仕様が公開されていないWebサイトのデザインは予告無く変更される場合があるので、開発したプログラムが突然動かなくなる事があります。これは大きなデメリットです。サイトの作りによりますが、ちょっとしたデザイン変更で全く動かなくなるケースもあると思いますし、エラーなど発生しなければ暫く気付かないという事もあり得ます。(2)レスポンスが悪いAPIだと必要な情報のみをデータで取得出来るので非常に軽快ですが、Webスクレイピングの場合はWebサイトのソース(HTML)を受信するので、本来取得したいデータ以外にWebサイトをデザインしているような不要なデータを沢山受信しています。また、その中から必要なデータを抽出する処理も必要なため、どうしてもレスポンスは遅くなってしまいがちです。デメリットを少しでも少なくするためには、Webサイトの作りがなるべく簡素で、動作も複雑でないもの。例えばJavaScriptを駆使していたりフレームを使ったようなサイトは向いていません。また、画像をガンガン使った様な凝ったサイトも然りです。また、その条件を満たした上で重要なのはやはり手数料です。プログラムで発注するのであまり至れり尽くせりのサービスやGUIは必要なく、出来るだけ手数料が安い証券会社を選ぶべきです。という事で皆さんにご意見を伺ったり自分で調べたりしながら至った結論はSBI証券でした。手数料が安く、決め手となったのは「バックアップサイト」でした。SBI証券の通常のWebサイトは普通にビジーなサイトで操作するのは大変なのですが、障害時などの臨時サイトとして、最低限の情報だけでやり取りをするバックアップサイトなるものが存在します。見るとシンプルなWebサイトなのでやり取りする情報が少なく、構造も分かりやすくて良い感じです。また、あまり頻繁にデザイン変更するようなサイトにも見えないので「これだ!」という感じで決定しました。もしこの記事を読んで自動売買プログラムの開発を行われる方は、是非SBI証券の口座を開設してみて下さい。ちなみに、この連載は過去の記事で利用した「SampleApplication」を使って行います。記事に沿って開発を行ってみようという方は「VB.NETで楽天RSSからリアルタイム情報を取得する」から始まり「クリック証券のWebサービスで発注する」を<その3>まで進めたところから続きを始めるつもりですので宜しくお願いします。
Nov 13, 2010
コメント(0)
過去の連載記事全てをリンク一覧にしました。ご活用下さい。・VB.NETで楽天RSSからリアルタイム情報を取得する<その1>・VB.NETで楽天RSSからリアルタイム情報を取得する<その2>・VB.NETで楽天RSSからリアルタイム情報を取得する<その3>・VB.NETで楽天RSSからリアルタイム情報を取得する<その4>・VB.NETで楽天RSSからリアルタイム情報を取得する<その5>・VB.NETで楽天RSSからリアルタイム情報を取得する<その6>・VB.NETで楽天RSSからリアルタイム情報を取得する<その7>・VB.NETで楽天RSSからリアルタイム情報を取得する<その8>・VB.NETで楽天RSSからリアルタイム情報を取得する<その9>・VB.NETで楽天RSSからリアルタイム情報を取得する<その10>・VB.NETで楽天RSSからリアルタイム情報を取得する<「バイト配列を文字列に変換する方法」の訂正>・クリック証券のWebサービスで発注する<その1>・クリック証券のWebサービスで発注する<その2>・クリック証券のWebサービスで発注する<その3>・クリック証券のWebサービスで発注する<その4>・クリック証券のWebサービスで発注する<その5>・クリック証券のWebサービスで発注する<その6>・クリック証券のWebサービスで発注する<その7>・クリック証券のWebサービスで発注する<その8>
Jan 12, 2009
コメント(2)
今回は保有銘柄一覧取得の続きです。前回が途中で終わっているので、今回はなるべく早く投稿した方が良いと思い3連休中にアップする事にしていました。<その7>を読んでない方は先にお読み下さい。これから実装するソースコードは、Webサービスの応答XMLを元に作成したDataSetからHoyuKabuGridというDataGridViewにデータを格納する事でした。「保有株一覧取得」ボタンをクリックする度にデータを格納していたら件数がどんどん増えていきます。もしかしたら前回ボタンを押した時から今回押す時までに保有銘柄を売っていたら逆にデータが減る可能性もあります。なので、ボタンがクリックされたらまずDataGridViewのデータをクリアする事から始めないといけません。こう書きます。'最初にDataGridViewをクリアするHoyuKabuGrid.Rows.Clear()「Rows」というプロパティは、DataGridViewの全行の集まり(コレクション)を表します。それに対するClear()メソッドは、全ての行を削除します。次はいよいよDataSetからの項目移送です。設定する項目は証券コード、取得単価、保有数量でした。取得単価と保有数量はhoyukabuTategyokuItemテーブルに。一方証券コードはmeigaraテーブルに入っています。どちらも保有する銘柄の数だけデータが存在し、両テーブルの件数が違うという事は絶対にありません。なので、どちらかのテーブルの件数を基準にして、何行目を指しているかを合わせて項目移送して行けば良いです。基準とするテーブルはどちらのテーブルでも構いません。今回は証券コードが入っているmeigaraテーブルを元にループする事にします。全行をループする時には「For~Each」という構文で書くとシンプルなのですが、ループ内で「今何行目を処理しているか」を取得するには通常のFor文を使って回す方が良いのでそちらを使います。このように書きます。'保有銘柄の数だけループするFor i As Integer = 0 To ds.Tables("meigara").Rows.Count - 1Next1行目の最後まで打ってEnterを押すと「Next」は勝手にコーディングされるので活用して下さい。それ以外のコードも、入力途中で候補が出ます。CTRL+スペースでも出せますので、入力速度アップと間違い防止のため、是非補完機能(インテリセンス)を使われる事をお勧めします。この文は、iという変数を0から「meigaraテーブルの行数-1」まで回すという意味です。なぜ-1かというと、.NETの配列の添え字は0から始まるからです。例えばデータが5行だと「0行目から4行目」という風に表されます。なので、n行の時0からn-1までループするためにこう書いています。このループの中で、3つの項目を移送していきます。HoyuKabuGridに直接移送しても良いのですが、1行が長くなると何をしているか後で読みにくくなるので、一旦各DataTableの該当行(DataRow)を取得してから項目移送する事にします。For文の中に2行追加します。Dim row1 As DataRow = ds.Tables("meigara").Rows(i)Dim row2 As DataRow = ds.Tables("hoyukabuTategyokuItem").Rows(i)「row1」や「row2」は変数名なので何でも構いません。DataSet「ds」の「Tables」プロパティはDataTableを表し「Rows」プロパティはそのテーブルの全行を表すんでした。そのi番目というカッコを付ける事によってある1行を表す事になります。型はDataRowです。両テーブルとも同じ添え字を使っているので、同じ保有銘柄を指しています。あとはrow1とrow2の3項目をHoyuKabuGridに移送すれば終わりです。HoyuKabuGridは空なので、ループを回す毎に行を追加しなければなりません。行を追加するためにはDataGridViewの「Rows」プロパティにあるAdd()メソッドを使うのですが、その方法はいくつものバリエーションがあります。「シグニチャ(シグネチャ)」というのですが、ご存じない方は無視して下さい。今回は、全く引数の無いAdd()メソッドを使用し、空の新規行を追加した上でその行の項目にデータを移送するという方法を取ります。まずはHoyuKabuGridへの行の追加です。HoyuKabuGrid.Rows.Add()そして3項目の移送はこうなります。HoyuKabuGrid.Rows(i).Cells("shokenCode").Value = row1.Item("shokenCode")HoyuKabuGrid.Rows(i).Cells("tanka").Value = row2.Item("tanka")HoyuKabuGrid.Rows(i).Cells("suryo").Value = row2.Item("suryo")例えば1行目は、HoyuKabuGridのi行目(今追加した行)の「shokenCode」というセルの値に、row1の列「shokenCode」を移送するという意味です。残り2つの項目は移送元のDataRowが違うのでrow2になっている事にご注意下さい。これで保有株一覧を画面に表示する事が出来ます!でも、せっかくですから最後に結果メッセージをダイアログ表示します。これは何度もやってますので皆さん大丈夫ですね?MessageBox.Show(ds.Tables("hoyukabuTategyokuListResponse").Rows(0).Item("message"))では早速実行し、ログイン後に「保有株一覧取得」をクリックしてみて下さい。どうですか?保有株の一覧がDataGridViewに表示されましたか?HoyuKabuList_Click()メソッドは最終的に以下のようになりました。これで私が予定していた「クリック証券のWebサービスで発注する」編は終わりました。今は次の予定もありません。「楽天RSSでリアルタイム情報を取得する」とのペアにより、自動売買プログラムを作る為にどんな事をするのか全く分からなかった方のとっかかりにはなったのでは無いかと自負しています。ところがご紹介した内容は本当に基礎の基礎です。これらの内容を元にご自分でプログラムの勉強をして、本当に自動売買プログラムが開発出来るスキルを身に付けて欲しいと思います。ところで、恐らくこのブログをご覧の方の中には、実現方法が分からなかったり解決出来ないバグが出るなど、色々な事で悩まれている方がいらっしゃるのでは無いかと推測します。私が答えられる事であれば、時間の許す限り回答していきたいと思いますので、遠慮なくブログ上にコメント頂けたらと思います。また「こんな内容で入門編を連載して欲しい」などの要望もお待ちしております。私の気力があれば連載させて頂くかも知れません(笑)。宜しくお願いします。
Jan 12, 2009
コメント(0)
クリック証券Webサービスについての記事は今回を最終回にするつもりでしたが、今回は準備も含めて長くなりますので、2回に分けて書きたいと思います。すみません。前回の記事にgatさんからコメント頂いた事から、一覧形式でのデータをどう扱うかについて悩まれている方がいらっしゃる事が分かりました。今回の内容が理解出来れば、恐らく他の全ての発注について応用可能だと思います。保有株一覧の取得です。では早速始めます。序盤の説明はログインボタンや余力確認ボタンと同様なので割愛させて頂きます。Form3にボタンを追加後、Textプロパティを「保有株一覧取得」、Nameプロパティを「HoyuKabuList」と変更した後でボタンをダブルクリックし、ソースコードを生成しました。保有株一覧は余力情報のようにダイアログ表示するだけでは済まないのですがまず最初のステップとして、Webサービスの呼び出しの結果XMLがDataSetに格納するとどのような状態になるのか確認するために以下のソースコードを記述します。'保有株一覧の取得Dim res As WebResponse = HttpPost(baseUrl & "/ws/kabu/hoyukabuTategyokuList.do", "lst=1")'株式余力情報の取得結果をDataSetに取り込むDim ds As New DataSetUsing resStream As Stream = res.GetResponseStream() ds.ReadXml(resStream)End UsingConsole.WriteLine(ds.GetXml)「クリック証券 Webサービス仕様書【株式取引編】- 第2.1.0版 -」の39ページに記載されている通り、送信パラメータが1つ存在します。一覧指定「lst」です。必要に応じて1、2、3のいずれかを指定して下さい。今回は「保有株のみ」の1を設定しています。記述出来たら一度実行してみて下さい。保有株一覧取得の前に、ちゃんとログインして下さいね(笑)。ボタンを押すと「出力」ウィンドウに文字列が表示されます。以下は私の保有株2つの例です。<hoyukabuTategyokuListResponse> <responseStatus>OK</responseStatus> <message>保有株、信用建玉一覧の取得が完了しました。</message> <hoyukabuTategyokuList> <hoyukabuTategyokuItem> <shubetsu>1</shubetsu> <chumonKano>1</chumonKano> <baibai /> <shijo /> <koza>2</koza> <shinyo>0</shinyo> <suryo>300</suryo> <chumonSuryo>0</chumonSuryo> <tatebi /> <hensaiKijitsu /> <tanka>14</tanka> <shiharaiShokeihi /> <uketoriRisoku /> <tategyokuKey /> <meigara shokenCode="1844" /> </hoyukabuTategyokuItem> <hoyukabuTategyokuItem> <shubetsu>1</shubetsu> <chumonKano>1</chumonKano> <baibai /> <shijo /> <koza>2</koza> <shinyo>0</shinyo> <suryo>9</suryo> <chumonSuryo>0</chumonSuryo> <tatebi /> <hensaiKijitsu /> <tanka>81</tanka> <shiharaiShokeihi /> <uketoriRisoku /> <tategyokuKey /> <meigara shokenCode="2316" /> </hoyukabuTategyokuItem> </hoyukabuTategyokuList></hoyukabuTategyokuListResponse>これはWebサービスの結果XMLを表示したものではなく、「結果XML→DataSet→XML」と変換したものです。DataSetの中でどんなDataTableとして保持されているかを確認する事が出来ます。仕様書に書いている「応答メッセージの例」とは順番が異なっている事にお気付きでしょうか。このデータはDataSetの中でどういう風に保持されているのでしょうか。まず「hoyukabuTategyokuListResponse」という名前のDataTableが存在します。列はresponseStatus」と「message」の2つで、中には1レコードが登録されています。データは「OK」「保有株、信用建玉一覧の取得が完了しました。」です。2テーブル目は「hoyukabuTategyokuItem」です。但し、中身はありません。3テーブル目は「hoyukabuTategyokuItem」で「shubetsu」「chumonKano」など沢山の列が定義されていて、2銘柄分となる2レコードが登録されています。最後4テーブル目に「meigara」というテーブルがあり「shokenCode」という列のみ存在します。データは2レコードです。こんな具合に登録されているので、中身を確認する事無くDataSetからデータを取得しようとした時に混乱してしまいます。でも内容が分かったのでもう安心ですよね?2つ目のテーブルは何も入っていないので無視します。1つ目のテーブルは結果ステータスとメッセージですので、画面に一覧を表示した後にメッセージをダイアログ表示するために使いましょう。残るは「hoyukabuTategyokuItem」テーブルと「meigara」テーブルです。2テーブルに分かれていたら見難いので、両方合わせて一覧に表示したいところです。では画面に一覧形式のデータを表示するにはどうすれば良いでしょうか。最もよく利用されているのは「DataGridView」です。表形式で参照出来てデータ数が可変なので便利です。では、画面にDataGridViewを追加します。ボタンなどのようにツールボックスからForm3にドラッグ&ドロップして下さい。DataGridViewの「Name」プロパティは「HoyuKabuGrid」に変更します。Form3の大きさやボタンの配置など、見映えが良くなるようにレイアウトし直しましょう。私はこんな風にしました。HoyuKabuGridを選択した状態でプロパティ「Anchor」を四方全てにすると、実行時にFormの大きさを変えたらHoyuKabuGridの大きさもそれに付いて変わってくれるので便利です。設定しておきましょう。DataGridViewはDataTableなどをバインド(紐付け)すると、DataTableで定義されている列の情報をそのまま表示してくれるので便利ですが、今回は独自で設定した列に手作業でデータを追加していきたいので、まだ列の設定がされていない空のHoyuKabuGridに設定していきます。HoyuKabuGridを選択し、右上角の小さい右向き黒三角のボタンをクリックして下さい。表示される「列の追加」ダイアログを使って列を追加していきますが、この記事では・証券コード(shokenCode)・取得単価(tanka)・保有数量(suryo)の3つに留めておきます。必要に応じて追加して下さい。日本語名称は「ヘッダーテキスト」に。ローマ字名は「名前」に。ユーザーが取得したデータを変更する必要は無いので「読み取り専用」のチェックを付けて下さい。あとのプロパティは変更しなくて結構です。3つの列が追加出来たら「閉じる」をクリックして下さい。次に「列の編集」を行います。もし間違って変な列を追加してしまった場合もここで削除出来ますのでご安心下さい。ここでは、取得単価と保有数量は数値ですので、見映え良く右詰めで表示したいのでプロパティを変更します。取得単価を選択した状態で「DefaultCellStyle」の右にある小さなボタンをクリックして下さい。するとCellStyleビルダが表示されるので「Alignment」の値を「MiddleRight」に変更します。同様の作業を保有数量に対しても行います。そして最後に、HoyuKabuGridに対してユーザーがデータを追加する事が出来ないようにします。HoyuKabuGridを選択してプロパティ「AllowUserToAddRows」を「False」に変更します。同様にして、プロパティ「RowHeadersVisible」も「False」に変更します。一番左にある、いわゆる「レコードセレクタ」の列が非表示になります。今回はデータの取得のみで行を選択する事は無いので不要でしょう。これでHoyuKabuGridの準備は完了です!いよいよ取得結果をHoyuKabuGridに格納していく作業を実装します。保有株一覧取得をダブルクリックするか、ソリューションエクスプローラから「コードの表示」をクリックしてソースコードを表示します。先ほどDataSetの中身を確認するために入れた一番下の行はいらないので削除し、その下にコードを追加していく事になります。・・・さて今回はここまでです。メインとなる部分をほったらかして次回に回してしまいますが、ここまで解説すればあとは自分で実装出来る方も多いのでは無いかと思います。とは言え最後はDataSetとDataGridViewの泥臭い作業ですのでちょっとややこしいです。なるべく早く次の投稿をするつもりですが、時間と気力のある方は挑戦してみて下さい。現在のソースコードは以下のようになっています。ではでは。
Jan 10, 2009
コメント(0)
前回クリック証券へのログインが終了したので、分かる方は既に発注について応用されていると思っています。でもこのまま放っておいてもいけないので、私は今回を含めあと2回記事を書く予定です。1つは、多分一番簡単だと思っている余力情報の確認です。ログインが理解出来た方はすぐに出来ます。もう1つは、一覧形式をやっておこうという事で、保有株の一覧取得をやってみたいと思います。今回はサラッと流します。まずForm3にボタンを配置し、プロパティウィンドウから「Text」の値を"余力確認"に。「Name」の値を"Yoryoku"に変更して下さい。次にそのボタンをダブルクリックし、ソースを開きます。余力情報確認メソッドが出来ましたので、中にコーディングしていきます。ログイン処理では複雑なシーケンスがあったので面倒でしたが、今回は不要です。ログインに使ったクッキーはForm3クラス内にありますので、それを使って余力確認用のURLを呼び出すだけです。その時、ログイン時に確保した基底URLも使います。覚えてますか?(笑)余力確認用のURLは「クリック証券 Webサービス仕様書【株式取引編】- 第2.1.0版 -」の65ページに記載されています。コーディングは、ごちゃごちゃ説明しません。こんな感じになります。'株式余力情報の取得Dim res As WebResponse = HttpPost(baseUrl & "/ws/kabu/kabuYoryokuJoho.do", "")'株式余力情報の取得結果をDataSetに取り込むDim ds As New DataSetUsing resStream As Stream = res.GetResponseStream() ds.ReadXml(resStream)End Using'株式余力情報をダイアログ表示MessageBox.Show(ds.Tables("kabuYoryokuJohoItem").Rows(0).Item("genbutsuKaitsuke") & "円です。")まさにログイン処理の応用で出来ますよね!?一度実行してみて下さい。もちろん先にログインボタンを押し、ログイン出来てから余力情報取得ボタンを押して下さいね。こんな風に出力されたら成功です。ちなみに、この「7円」は私の今の本当の余力ですよ(´д`;最終的にソースは以下のようになっている筈です。・・・今回はちょっと手抜きでしたが、どうだったでしょうか?これで他の発注も基本的に出来るはずですよね!?次回はXML情報の扱いのためだけの解説と言っても過言ではない、保有株一覧の取得を行います。ではでは。
Jan 6, 2009
コメント(4)
前回の投稿から2週間以上が過ぎすみません。クリック証券部分について解説するために自分のプログラムKATSの該当部分も開発当時より少し改良した方が良いと思い作業を進めるうち、Webサービス呼び出しのクラスライブラリ自体の大幅リファクタリングとなってしまい、連載が滞ってしまいました。ブログを読んで下さっている方から「続きを首を長くして待っております・・・がんばってください・・・」というコメントを頂き「早く続きを書かないと!」と思いました。今後も、もし滞っている事があれば声を掛けて頂けたらと思います。皆さんの期待が私の活力になりますので。さて前回はログインボタンの作成まで行いました。いよいよ今回はログイン処理を実装していきます。私は手元にある「クリック証券 Webサービス仕様書【ログイン編】- 第2.1.0版 -」を元に解説を書いていきます。最初ログインシーケンスについての解説を読んで「ん!?」と悩まれた方も多いのでは無いかと思います。でも実際Webサービスを呼び出す時には、2回のリクエスト送信を意識するだけです。では早速書いていきましょう。まずはログインシーケンス1です。仕様書の6ページにある要求URLと、それに付随する要求BODY(リクエストパラメータ)を使ってHTTPリクエストを送信します。<その3>で作成したHttpPost()メソッドを使用します。引数はURLとパラメータですのでそのままですね。呼び出す時にはこう書きます。Dim res As WebResponse = HttpPost("https://~~/ws-redirect", "u=xxxxxx")リクエストURLを伏せていますが、Confidential情報だからです。クリック証券は口座開設した人にのみ仕様書を公開していますので。クリック証券Webサービスを使用される方は仕様書を見ればURLは分かりますので大丈夫です。リクエストパラメータにはユーザーIDを「u=」の形で渡します。もちろんxxxxxxにはご自分のクリック証券ユーザーIDを記述して下さい。ちなみにこの1回の処理で、ログインシーケンス2の終了まで処理が行われます。ログインシーケンス1はリダイレクト応答なので、自動的にログインシーケンス2も行われて戻り値のWebResponseはログインシーケンス2後の応答となります。まずここまでして、戻って来たXML情報を覗いてみる事にしましょう。以下のソースは応答XMLが目に見えるように、仮に記述するものです。Dim sr As New System.IO.StreamReader(res.GetResponseStream())Console.WriteLine(sr.ReadToEnd())記述出来たら早速実行して、ログインボタンを押してみましょう。出力ウィンドウに以下のように表示されたでしょうか?もし結果が失敗の場合は、クリック証券のサービスを有効にしていないか、URLが間違っているか、ユーザーIDが間違っている可能性があるのでチェックして下さい。人間が目で見たら「プレ認証が成功している」と分かります。ですが、ログインシーケンスの続きを行うためには、このXML情報をプログラムが解釈して「OK」を認識しないといけません。色々なやり方がありますが、私が最も有効だと思っているやり方は、DataSetを使う方法です。「ナンじゃそれ!?」と思われた方。確かに.NETでDB処理のプログラミングをされていない方は馴染みの無い名前だと思います。DataSetあるいはDataTableというのは、RDBをメモリ上で表現する非接続型のデータオブジェクトです。元々はデータベースの情報を扱う時に便利なものなのです。DataTableは1テーブルを表し、そのレコードとしてDataRowがあったり。DataTableの集合としてDataSetが存在します。ここではDataSetやDataTableなどの解説は行いません。http://msdn.microsoft.com/ja-jp/library/zb0sdh0b.aspxhttp://www.atmarkit.co.jp/fdotnet/basics/adonet04/adonet04_01.htmlなどで概念が分かるかも知れませんが、少々ややこしいですし今回はDBアクセスに使用する訳では無いのであまり触れないでおきます。でもDataSetはXMLとの親和性が高く、それを利用しない手は無いと私は思っています。DataSetにXML情報を取り込むと、各要素をプロパティで取り出す事が可能になるからです。能書きはこれぐらいにして早速やってみます。先ほど書いた仮の2行の代わりに以下のコードを記述します。Dim ds As New DataSetUsing resStream As Stream = res.GetResponseStream() ds.ReadXml(resStream)End Using「Usingブロック」は楽天RSS編でも解説した事があります。確実にリソースを解放するために記述しています。詳細の解説は割愛します。実際やっているのは、DataSetをインスタンス化してReadXml()を呼んでいるだけです。以上で応答XMLをDataSetに読み込めましたが、データはどのように入っているのでしょうか?応答XMLは<?xml version="1.0" encoding="UTF-8"?><loginResponse> <responseStatus>OK</responseStatus> <message>PreAuthentication Success.</message><loginResponse>でした。1行目の情報はDataSetには入らず、実データの4行が解釈されます。DataSetの中には「loginResponse」というテーブル名のDataTableが1つ。そしてDataTableの中には「responseStatus」というカラムと「message」というカラムを持ったデータ1行が入っています。それを踏まえて「responseStatus」の内容「OK」を取得するためにはどう記述したら良いか。このようになります。Console.WriteLine(ds.Tables("loginResponse").Rows(0).Item("responseStatus"))DataSetの中のloginResponseテーブルの0行目(0行目から始まります)の、responseStatusカラムの値です。実行して出力ウィンドウを確認すると、もちろん「OK」と表示されています。これで応答XML情報の内容を確認する事が可能になりました。プレ認証の結果を元にログインシーケンスの後続処理を続ける事が出来ます。プレ認証に失敗したら結果は「NG」と返って来ますので、NGの場合はメッセージボックスを表示して終了し、それ以外の時だけ後続処理を行うように1文入れます。If ds.Tables("loginResponse").Rows(0).Item("responseStatus") = "NG" Then MessageBox.Show("プレ認証に失敗しました。") ReturnEnd If応答XMLの内容を解釈するのにやや長いコードを記述しなくてはならず、しかも内容が少し複雑なので煩雑なソースになってしまいます。なので、個人的にはDataSetクラスを継承して独自のプロパティを持たせたDataSetを作成する事をお勧めします。以下はログイン応答についてのDataSetの例ですが、理解出来る方はこのように作られてはどうでしょうか?私の提案です。Public Class LoginDataSet Inherits DataSet ReadOnly Property 応答結果() As String Get Return Me.Tables("loginResponse").Rows(0).Item("responseStatus") End Get End Property ReadOnly Property 応答メッセージ() As String Get Return Me.Tables("loginResponse").Rows(0).Item("message") End Get End PropertyEnd Class話が少し脱線してしまいました。ではログインシーケンス3を行います。そのためには「基底URL」なるものを取得しなければなりません。仕様書にはログインシーケンス1での応答ヘッダーに含まれていると書いてありますが、プログラムでは先ほどのレスポンス情報の中にちゃんと持っています。基底URLは、これ以降の全てのWebサービス呼び出しに必要な情報ですので、ずっと保持しておく必要があります。以前定義した「クッキー」と同様、クラス変数として定義します。Private Shared baseUrl As String = ""基底URLは、仕様書の7ページに記載されたURLの赤色部分です。という事は後ろについている「/to~」という部分は不要で、応答URLから切り取らないといけません。その作業は以下のように記述します。baseUrl = res.ResponseUri.ToString.Replace("/to~", "")もちろん「"/to~"」の部分は、仕様書に書いている正式な文字列を書いて下さい。やってる作業は、応答URIを文字列に変換し、不要な部分を空文字に変換する事です。ログインシーケンス3はこの「baseUrl」を使ってこのようになります。WebResponseの変数「res」は使い回します。res = HttpPost(baseUrl & "/ws-login", "j_username=xxxxxx&j_password=xxxxxx")認証処理なのでユーザーIDとパスワードが必要です。xxxxxxの部分には、それぞれ正しいユーザーIDとパスワードを記述して下さい。このリクエスト送信で、ログインシーケンス5まで全て完了してしまいます。結果XMLはレスポンスにちゃんと含まれています。プレ認証の結果はプログラムが解釈する必要がありましたが、ログイン結果は画面にダイアログ表示する事にしましょう。先ほどのコードを参考に、このように書けます。ds = New DataSetUsing resStream As Stream = res.GetResponseStream() ds.ReadXml(resStream)End UsingMessageBox.Show(ds.Tables("loginResponse").Rows(0).Item("message"))実行すると、ログイン処理の結果メッセージがダイアログ表示されます!やっとログイン処理の実装が終わりました。でも、ログイン処理が一番ややこしいと私は思っています。これが実装出来たら、あとの処理はこの応用です。次回以降は余力情報の取得など、仕様書の「株式取引編」から簡単な要求について解説するつもりです。ログイン処理のソースは最終的にこのようになりました。もしご不明な点や、ご意見・ご指摘等があれば遠慮なくコメント下さい。宜しくお願いします。
Dec 27, 2008
コメント(9)
前回「次回はいよいよ、ログイン処理を作成したいと思います!」と書きました。でも実はログイン処理って通常の発注に比べて逆にややこしくて長いです。ログイン処理の解説が終われば後はその応用で済んでしまうぐらい重要な内容です。ですが今日はもう時間も遅いので、ログイン処理の解説を書く気力がありません。かと言って全く書かないのもナンですし、予定を変更して申し訳ないですが今回はログイン処理の解説をする前のつなぎの回とさせて頂きます。すみません。別サイトへのリクエスト送信は、その権限が無いと出来ません。先にご自分で開発してみて、以下のエラーが出た方はいらっしゃいますでしょうか?デフォルトでは、リクエスト送信出来ないんです。本当はセキュリティ要件をしっかり把握して細かく設定しないといけないのですが、今は簡単に解消するために、以下の操作を行います。まずソリューションエクスプローラのプロジェクト名を右クリックして「プロパティ」を選択して下さい。するとプロジェクトのプロパティが開きますので「セキュリティ」タグをクリックしてからClickOnceセキュリティのラジオボタンを「これは完全に信頼するアプリケーションです」に選択してから保存します。これで大丈夫です。では、次回のためにログイン処理の骨格だけ用意しておきます。まずForm3にボタンを配置し、プロパティウィンドウから「Text」の値を"ログイン"に。「Name」の値を"Login"に変更して下さい。そして、ボタンをダブルクリックしてソースを開きます。Login_Click()メソッドが作成されていたら成功です。次回は、このメソッドの中身をコーディングしていく事になります。基本的には、前回作成したHttpPost()メソッドの呼び出しと、レスポンスに含まれているXML情報をどうやって解釈するかだけです。興味のある方は、クリック証券Webサービスの仕様書(ログイン編)を元にログイン処理の実装にチャレンジしてみては如何でしょうか。特にXML形式の結果をどうやって読み取るかは開発する人によって個人差があると思うので私が書く前に「自分ならこうする」というのを見つけられた方が勉強になるかも知れません。出来れば私が書いた時には「自分はこうしてるけど、お前のやり方より良いんじゃないか?」等あれば教えて頂ければ幸いですwではまた(^-^)
Dec 11, 2008
コメント(2)
またまた間が空いてしまいました。すみません。今回は前回作成したHttpPost()メソッドの実装を行います。全てのWebサービス呼び出し時に共通で使う部品のようなものなので大事です。とは言っても、HTTPリクエストについて細かく解説するつもりは無く「VB.NETでHTTP送信するためにはこう書きましょうね」と例を示すだけにしますのでご了承下さい。まずHTTPリクエストをインスタンス化します。WebRequestクラスにはCreate()メソッドというSharedメソッドが存在します。引数は2通り存在しますが、今回使うのはリクエストURLの文字列を渡す方です。'リクエストの作成Dim req As HttpWebRequest = WebRequest.Create(url)あとは、お作法だと思って下さい。もちろん理解するに越した事は無いので、興味のある方は勉強してみて下さい。まずはメソッドがPOSTである事と、コンテンツタイプを指定します。req.Method = "POST"req.ContentType = "application/x-www-form-urlencoded"リクエストパラメータはアスキーのバイト配列に変換します。Dim data As Byte() = Encoding.ASCII.GetBytes(params)この時「Imports System.Text」が必要になります。Dim data As Byte() = System.Text.Encoding.ASCII.GetBytes(params)と書いても良いですが。次にデータ長を設定。req.ContentLength = data.Lengthそして大事なのが次です。Webサービスの呼び出し元には、ログインした情報などをずっと保持しておく必要があります。クッキーと呼ばれるものです。HTTPリクエストにはクッキーを渡し、今後何度も行われるHTTPリクエストのためにそのクッキーを保持して毎回同じものを引き回さないといけません。どこで保持しておくかですが、今回は簡単に考える為に、Form3クラスの変数として直接持っている事にします。クラス変数として'クッキーPrivate Shared cc As New CookieContainerと指定しておき、メソッドの続きはreq.CookieContainer = ccと、そのクッキーを設定しておきます。続いてリクエストパラメータをリクエストに設定し、送信すればOKです。'ポスト・データの書き込みDim reqStream As Stream = req.GetRequestStream()reqStream.Write(data, 0, data.Length)reqStream.Close()'送信Return req.GetResponse()Streamのために「Imports System.IO」が必要です。もちろん、Dim reqStream As System.IO.Stream = req.GetRequestStream()でも良いです。これでHttpPost()メソッドは完成しました。現在のソースはこのようになっているはずです。次回はいよいよ、ログイン処理を作成したいと思います!ログイン処理ではもちろんHttpPost()メソッドを使用するので、私が次回を書くまでにしっかり理解しておいて下さい。今回はここまでです。失礼します。
Dec 10, 2008
コメント(0)
前回「クリック証券Webサービス編」の前振りを行ったまま、期間が空いてしまいました。心待ちにして下さった方、すみませんでした。その間、まだクリック証券の口座をお持ちで無かった人は口座開設出来ましたでしょうか?wWebサービス仕様書については勝手に公開する事は出来ませんので、皆さんのお手元に仕様書があるという前提で話を進めさせて頂きますのでご了承下さい。まずVB.NETのプロジェクトは「楽天RSS編」で使用したSampleApplicationを使用します。但し新しい画面を作って試したいので、まずはプロジェクトに新しいForm(順を追えばForm3になるでしょう)を追加し、そのFormをスタートアップフォームに設定しておくという作業を行います。手順は「VB.NETで楽天RSSからリアルタイム情報を取得する<その9>」でForm2を追加した手順と全く同じなので割愛します。Form3に対して何かする前に、まずクリック証券Webサービスについて少し解説です。Webサービスと言ってもあまり難しく考える必要はありません。WebブラウザにURLを入力して移動したりするのと同様、HTTPリクエストをサーバーに送信してその応答を受けるだけです。自動売買システムをExcel/VBAなどで開発されている方は、ブラウザオブジェクトを使用して証券会社のWebサイトを操作するイメージを持たれると思いますが、やってる事は似ていると思います。但し、ブラウザオブジェクトだと意識せず引き回しているセッション情報(Cookie情報)を意識しないといけません。HTTPリクエストを自分で独立して送信させる場合、Cookie情報を引き継がないとセッションが引き継がれないという事がおきます。・・・細かく説明するとややこしいので、分からない方で興味があればネットで調べて頂けたらと思います。ログインするにも、口座の余力情報を取得するのも、発注するのも、全てHTTPリクエストが必要になるのですが、先に書いた通りWebブラウザを利用する訳ではありません。.NET Frameworkが用意しているクラスを利用してリクエスト送信します。なので、まずはHTTPリクエストを送信するための共通のメソッドを先に準備する作業から始めます。プロジェクトエクスプローラでForm3を選択した状態で「コードの表示」ボタンをクリックします。するとForm3のソースコードが開きます。ここに、内部からだけ呼ばれるようにPrivateメソッドとしてHttpPost()メソッドを作成します。引数と戻り値は、とりあえず以下のように書いて下さい。Imports文は、戻り値の「WebResponse」を修飾せず記述するために必要です。また、メソッド内に何も書かなければコンパイルエラーになるため、とりあえず今は「Return Nothing」と書いています。引数の「url」はリクエストURL。paramsは、リクエストパラメータを文字列で渡します。・・・と、こんな中途半端な状態で申し訳ないですが、今日はここで終わらせて頂きます(汗)。また気力と時間がある時にメソッドの中身を書きます。内容が無くて申し訳ないですがお許し下さい。要望があればなるべく近日中に書きます。
Dec 2, 2008
コメント(4)
以前連載を続けていた「VB.NETで自動売買」入門ですが「VB.NETで楽天RSSからリアルタイム情報を取得する」だけ一応終了してそこでずっと止まっていました。マルチスレッド処理について解説するかどうか。それともこのシリーズを終了して別のテーマに移るのか。それを悩んだままほったらかしでした。このままだと前に進まないので楽天RSSの連載は終了して、次のテーマを開始します。 ※もし質問とかして下さる方がいらっしゃれば、是非遠慮なくブログ内にコメントを 頂けたらと思います。可能な限り答えさせて頂きます。楽天RSSを使ってリアルタイム情報が取得出来るようになりました。これで一応、売買判断を行う材料を手に入れたと言えます。次に考えたいのは、実際に売買する部分です。「VB.NETで楽天RSSからリアルタイム情報を取得する<その1>」で書いた通り、サンプルアプリケーションはクリック証券のWebサービスAPIを使用して行う事を想定しています。自動売買プログラムを開発している人は数多くいらっしゃいます。発注部分については色々な開発方法がありますが、一番選択者が多いと私が思っている実装方法は「Excel/VBAなどからIEなどのWebブラウザオブジェクトを使用して証券会社のWebサイトを操作して発注する」では無いかと思います。楽天RSSからリアルタイムデータを取得するにはExcelからアドインを利用して行うのが最もお手軽な方法だと思いますので、それと親和性の高いExcel/VBAを用いるのは当然の選択肢です。自分がWebブラウザを使って操作するのと同じ手順をプログラムにするのも理解しやすいですし。ですが今回のメインテーマは「VB.NETで自動売買プログラムを開発する」です。VB.NETから証券会社に発注する時、最も優れている方法を検討したところ、一番優れていると確信したのが「クリック証券のWebサービスを用いる」方法だったのです。私がそう思った理由を挙げます。(1)手数料が安い1日定額コースの最低手数料は230円です。他にもっと手数料の安い証券会社はありますが、かなり安い方だと思います。例えば楽天RSSを使用するためには楽天証券の口座開設が必須となりますが、楽天証券の手数料は450円です。少額トレーダーにとっては痛い額です。クリック証券には逆指値注文などの便利な注文はありませんが、逆指値注文なんて自分でプログラムで組んでしまえば簡単です。マーケットスピードのような優れたトレードツールもありません。レーザートレードというツールがありますが正直見劣りします。でも手動売買を主眼に置いている訳ではないので、そういう事より手数料が安い事の方が重要なのです。(2)寿命が長いWebサービスのAPIは、そう簡単に変更される事はありません。もし今後変更される事があったとしても正式に報告され、ちゃんとした仕様が公開されます。なのでWebサービスを利用してプログラムを作っていると安心です。でも、Webサイトを操作する方法を取っていたらどうでしょうか?もしその証券会社のWebサイトのデザインが変わったらプログラムを変更しなくてはならないかも知れません。しかもそれは何の予告も無しに突然行われます。変更される可能性を考えればWebサービスのAPIより断然高いでしょう。ある日自動売買が突然動かなくなる、なんて事が起こる可能性があります。これは恐い事ですよね。(3)レスポンスが速いWebサービスはその処理を行うためだけに通信しているので無駄なデータのやり取りを行いません。余力確認、発注、注文一覧の取得、・・・など全ての処理は単独で無駄の無いAPIが用意されています。ですがWebブラウザを操作する場合は、必要なデータだけでなくWebサイトを表示する為の膨大なHTMLデータを受信する必要があります。画面の描画が終わらないと次の操作を行えない上に、数画面を遷移する手順が必要になるケースがあります。これではWebサービスに比べて明らかにレスポンスは悪くなると思います。他にも色々ありますが、これらの理由により私はクリック証券のWebサービスを利用して発注するのが今自動売買を開発をする時のベストな選択だと思っています。・・・今日は前振りです(笑)。次回から「クリック証券のWebサービスで発注する」を本格的に書いていく前に、どうしてこの実装方法をお勧めするのかを説明すると共に、是非興味のある方はクリック証券の口座を開設してWebサービスAPIの仕様書をダウンロードしておいて欲しいと思ってとっかかりを書きました。クリック証券の口座を持っていない方は、ここから口座開設して下さい。もう既に口座を持っている方は、ログイン後「各種サービス」-「Webサービス」からWebサービス仕様書をダウンロードして、読める方は読んで頂けたらと。私は「ログイン編」「株式取引編」の事しか書くつもりはありませんので、日経225先物の方やFX取引の方は独自に勉強されたらと思います。また「Local API Server」なるものがあります。実際に本番のクリック証券のサーバーに繋ぐのではなく、自PC内に起動させて発注処理に対してダミーの応答を返してくれるテスト用サーバーを用意するキットです。テスト時には重宝しますが、私はこの環境について解説する事は割愛させて頂きます。実際本番環境に対してWebサービスを呼び出す解説をします。恐らくログインと余力情報取得など間違えても資金に影響の出ない機能を使って説明します。なので、発注処理など間違えたらマズい機能を開発する時には是非この「Local API Server」を使ってテストして下さい。あと、VB.NETのプロジェクトは楽天RSS編で作成したものをそのまま使うつもりですので無い方は準備して頂けたら幸いです。では次回からいよいよ説明を開始します。スローペースになるかも知れませんが宜しくお願いします。
Nov 15, 2008
コメント(4)
前回、なぜ自分のソースコードで出来高がちゃんと表示されなかったのか疑問だったので今日確認してみました。すると、大きな見落としがある事に気付きました。。。KATSでもバイト配列を文字列に変換する処理があって、入門編のサンプルでも同じように解説しているつもりでした。でも間違っていました(汗)。今まで<その5><その6><その7><その8><その10>と5回も登場したこのソース。変数名は違う時がありますがここです。Dim priceText As String = Encoding.Default.GetString(byteData).Trim「Encoding.Default.GetString(byteData)」でバイト配列を文字列にしています。ですが、KATSのソースはこうなっています。Encoding.Default.GetString(byteData, 0, byteData.Length - 1).Trim違いは、最後の1バイトを除いて文字列に変換しているところです。最後の1バイトは制御文字が付いているので除去しています。ここが間違っていました。もし過去に出てきたソースを修正する場合は上のコードを参考にして下さい。もちろん、整数に変換する場合は前回ご紹介したCInt(Encoding.Default.GetString(byteData))という方法で、1バイト取り除いたり空白を取り除いたり、あと小数点以下も無くしてくれるので便利です。今回は私の解説の訂正でした。失礼しました。
May 26, 2008
コメント(2)
この「VB.NETで楽天RSSから~」シリーズがこの記事で10回目を迎えました。始めた時には、このネタだけで10回も続けるとは思っても見ませんでした。さて今回は、いよいよ複数銘柄の複数項目について更新通知を受けて処理をするChangeValue()メソッドの実装を行います。「何を言ってるの?」と思われた方は<その9>までをご覧下さい。ChangeValue()メソッドの定義だけは終わっています。中身が空ですが。では中にコードを追加していきます。このメソッドに紐付けたイベントハンドラは、エリアリンク(8914.T)、サイバーファーム(2377.OJ)、YOZAN(6830.Q)の3銘柄について監視している項目に変化があった時でした。監視している項目はそれぞれ、現在値と出来高でした。まずはChangeValue()メソッド中で、どの銘柄についての変更通知か判断する必要があります。それを知るには、引数である「sender」を使用します。senderとはイベント通知を行ったオブジェクトそのものの事です。つまり、監視している3銘柄いずれかのDDEクライアントのインスタンスという事になります。ちょっと専門用語になるので分からない方はやり方だけ参考にして下さい。senderをDDEクライアントに変換しますが、それを「キャスト」と呼びます。イベント通知を行ったDDEクライアントを特定するためにsenderをDdeClientにキャストします。Dim client As DdeClient = DirectCast(sender, DdeClient)これで変数「client」を使って、どの銘柄がこのメソッドを呼び出したのかが分かります。「Topic」というプロパティには「2377.OJ」などが入っています。どの銘柄の更新通知か特定したら、次はどの項目に変更があったかを知る必要があります。今回の場合は現在値か出来高です。この値は、ChangeValue()メソッドのもう1つの引数「e」で分かります。e(型はDdeAdviseEventArgs)には「Item」というプロパティがあり、ここに項目名が入っています。e.Itemが何であるかを確認すれば良いのです。肝心の「変更された項目の値」ですが、これは<その8>で解説しています。引数eのプロパティ「Data」にバイト配列で値を持っているんでしたね。それでは、これらの情報を元にコーディングします。今回は画面に表示する準備はせず監視の開始ボタンと終了ボタンしか作ってません。なので変更通知は「出力」ウィンドウに表示させる事にします。Console.WriteLine("ABC")と書けば、出力ウィンドウに「ABC」と表示されます。「WriteLine()」というメソッドは出力した後改行するという意味なので、次に同じメソッドを呼び出せば次の行に書かれます。もしConsole.Write("ABC")と書いたら出力後改行しないので、2回連続で同じ事を書いてもABCABCになります。参考まで。また、更新された銘柄を特定する時、IF文で条件分岐させても良いのですが今回は「Select~Case文」を使用しています。こんなコードになりました。前回まで使っていた「バイト配列を文字列に変換する方法」だと出来高が文字化けしてしまうので、以前micorosoftさんがコメントしてくれた「CInt」を使って変換しています。この関数を使って変換される方が簡単なので、整数値の項目を変換する時には利用しましょう。引き続き停止ボタンのメソッドも実装しましょう。Form2.VB[デザイン]の監視終了ボタンをダブルクリックします。処理内容は、DdeClientのインスタンスが入ったlistを元に、全てのDDEクライアントを破棄してやれば良いです。この部分に関するコードの解説は、ちゃんとしようと思えばそれなりに長くなるのでここでは「こんな風になります」に留めます(汗)。興味のある方は勉強してみて下さい。これで一旦コーディング終了です。待ち遠しかった方、お待たせしました。では実行してみましょう!!開始ボタンを押してForm2が開いたら「監視開始」ボタンをクリックしてみて下さい。出力ウィンドウに何か出てきましたか?(下はあくまでも例です)何か結果が出てきてます!もしかしたら6項目が全て出ない方もいらっしゃると思います。何度かやったらたまに出てこないとか。それは「デバッグ実行」しているからだと思います。出力ウィンドウの表示を消すにはこのボタンを押して下さい。今回は出力ウィンドウに表示するだけでしたが、実際運用する時にはデータベースに書き込んだりする必要が出てくるでしょう。その時にはChangeValue()メソッドの中身を書き換えてやる必要があります。またその時、一番厄介な「マルチスレッド処理」を実装する事になります。ChangeValue()メソッドは複数のスレッドが同時に呼び出して実行しており、メソッドの書き方によってはそれぞれのスレッドが影響を受けて結果が正しくならない可能性が出てきたり、間違った対処により処理が遅延したり最悪はプログラムが負荷増大により固まったりする事があります。この部分についてどこまで解説するか(出来るか)。悩ましいです。これで「VB.NETで楽天RSSからリアルタイム情報を取得する」シリーズを終了するかそれともマルチスレッド処理についてもう少しだけ書くか。明日以降に考えたいと思います。今回はちょっと含みを持たせたまま終了します。
May 25, 2008
コメント(4)
前回は一応、形だけAdvice()形式でのリアルタイム情報取得が完成したのですが、全く実用的ではありませんでした。NDdeを利用しようとする方の疑問で一番多いのが・複数銘柄の監視をしていた場合にどうやって銘柄を特定すれば良いのか・複数項目の監視をしていて、それらの更新通知をどうさばいたら良いのかという、複数銘柄/複数項目の監視を行った時の実装方法です。今回はその辺りを解説し、より現実的なソースコードにしようと思います。Form1に新しいロジックを追加しようと思いましたが、もう何がなんだか分からなくなりそうですよね(^-^;という訳で心機一転、新しいFormを追加します。ソリューションエクスプローラのプロジェクト「SampleApplication」を右クリックし「追加」-「Windowsフォーム」をクリックします。名前は「Form2」のままで良いので「追加」ボタンをクリックして下さい。複数銘柄を監視する場合は、画面やデータベースから銘柄を指定して行いたいと思います。ですがその辺りを解説すると長くなりますので省略します。画面から入力する場合は、DataGridViewを使うと便利でしょう。興味のある方は調べてみて下さい。今回は、監視の開始と停止を行うボタンのみ作成します。ツールボックスからボタンをドラッグ&ドロップし、作成してみて下さい。大きさは自由で結構です。ボタンに表示されている名前(Text)も分かりやすいように付けて下さい。但し、ボタンの名前(Name)はそれぞれ「StartAdvice」「StopAdvice」として下さい。やり方が分からない場合は<その2>辺りを読んで頂ければと思います。画面はこんな感じになってますか?ボタン名をちゃんと設定した後でボタンをダブルクリックしないとメソッド名がデフォルトのままになってしまいます。では監視を開始するボタン(StartAdvice)をダブルクリックしましょう。上のようなソースになれば正しいです。<その8>でtttさんへのコメントとして書いていますが、DDEクライアントのインスタンスをローカル変数(メソッド内にDim client As DdeClient ・・・などと書く)で定義してしまうと、そのメソッドが終了した時点でプログラムからは制御できなくなります。.NETが不要だと判断したらそのインスタンスは破棄されてしまう可能性があります。また、Adivce()形式はUsingブロックも適していません。停止ボタンがクリックされるまではインスタンスをずっと保持していないといけないのでUsingブロックは使わずにインスタンス化します。まずインスタンスを保持するためには、Form2のメンバ変数(インスタンス変数)としてDDEクライアントを定義します。メソッド内ではなく、クラス内だけどメソッドの外に定義してあげ、Form2のインスタンスがある間は保持されるようにするのです。しかも今回は複数銘柄です。ただ単にDdeClientを定義したらつまらないので、DdeClientを複数保持する「入れ物」を用意します!プログラムをご存知の方は、1つの方法として「DdeClientの配列」を使われる方もいらっしゃると思いますが、今回は「List」を使用します。以下のようにコーディングします。先頭にImport文を書いておかないと「DdeClient」と省略して書けませんのでご注意下さい。Listというクラスは、中に含まれるオブジェクトを複数件保持する事が出来る一覧のような役目をするものです。また、先頭の「Private」はこの変数(list)のスコープを表しています。Form2の外からこの変数を操作する事が出来るか、それとも内部でしか使われない変数か、というのを指定するものです。「list」はForm2のメソッド内からしか扱わないので、外から扱えないようにする為に「Private」という指定をします。では早速、StartAdviceボタンがクリックされた時のソースを書いて行きましょう。前回までに一度やっているので詳細は書きません。Form1のソースを参考に出来ると思いますので、コピーして来て下さいね。今回監視する銘柄は、固定で「エリアリンク(8914.T)」「サイバーファーム(2377.OJ)」「YOZAN(6830.Q)」の3銘柄。監視項目は「現在値」「出来高」の2項目とします。まずエリアリンクのDDEクライアントをインスタンス化します。Dim client As DdeClient = New DdeClient("RSS", "8914.T", Me)そして、接続した後に現在値と出来高の監視を開始します。監視を開始する前にイベントハンドラをメソッドに追加する作業を覚えていますか?「client.Advise」というイベントが発生したらどのメソッドを呼び出すかを紐付けるんでしたよね。値が変化した時のメソッドなので「ChangeValue」とでもしておきましょう。まだメソッドは追加していませんので、今は当然コンパイルエラーになります。client.Connect()AddHandler client.Advise, AddressOf ChangeValue監視の開始はclientのStartAdvice()を使うんでしたね。でも今回は2項目です。どうすれば良いんでしょうか?・・・ただ2行書くだけです(笑)。client.StartAdvise("現在値", 1, True, 60000)client.StartAdvise("出来高", 1, True, 60000)ここで勘の鋭い方は「clientの更新通知イベントはAdviceだけど、現在値と出来高のどちらが変更された時?両方変更された時は?ChangeValue()はどうすれば??」と疑問を持たれるでしょう。そうです。ChangeValue()メソッドの書き方こそが複数銘柄/複数項目監視の肝です。コンパイルエラーが出ていたら気持ち悪いので、ChangeValue()メソッドの枠だけ書いてしまいましょう。ここまで出来たら、こんなソースコードになっている筈です。エリアリンクの監視はスタートしますが、このメソッドが終了してもずっと監視し続けてもらうために、DDEクライアントをListに追加して保持します。clientをlistに追加します!list.Add(client)clientを引数にしてAdd()メソッドを呼び出すだけです。簡単ですね。続けて全く同じように、サイバーファームとYOZANの監視も開始しListに追加します。ソースはコピーすれば簡単でしょう。この時「client」という変数名は一度使用しているのでエラーになると思います。新たに変数名を取っても良いのですが、メソッド中に一時的に定義しているだけなのに新たに名前を取るのも馬鹿らしいです。clientを使いまわします。「Dim client As ・・・」と書くと新たなclientという変数を定義する事になるので単純に「client =」を書くだけで良いのです。client = New DdeClient("RSS", "2377.OJ", Me)これで、3銘柄についてそれぞれ2項目の監視がスタート出来ました。Listには、監視をしているDDEクライアントのインスタンスが3件保持されています。どの銘柄のどの項目に変化があっても、今はChangeValue()メソッドが呼び出されます。項目毎にメソッドを分ける事はNDdeの仕組み上、出来ません。銘柄毎にメソッドを分ける事は可能です。「Add Handler」の時、別のメソッド名に紐付ければ良いのです。どちらが良いかについては、監視する銘柄が固定か可変かによって決めて下さい。毎回監視する銘柄が変化する仕組みを作っている方は、同じメソッドに紐付けるのをお勧めします。どの銘柄を監視しているかはその時によって変わるので、メソッドを分けても書く内容は同じですし、件数が変動した時に動的にメソッド数を変える訳にもいかないからです。逆に、監視する銘柄が決まっている方(例えば日経先物と日経平均、など)は、その銘柄に合わせたロジックが書きやすいのでメソッドを分けた方が良いかも知れません。今回は銘柄の判別を説明するためにも、同じメソッドに紐付けるソースにしています。さてここからいよいよ肝となるChangeValue()メソッドの実装に入ります。・・・が、長くなってきたので次回とさせて頂きます。m(_ _)m次回は肝の実装に加え、停止ボタンの実装も行いたいと思います。最後に、現在の状態だとプログラムを実行した時にForm1が開きます。Form2は出てきません(苦笑)。実行時にForm2が出るようにしておきます。まずソリューションエクスプローラのプロジェクト(SampleApplication)を右クリックしてプロパティを開きます。「アプリケーション」タブの「スタートアップフォーム」を「Form2」に変更して保存しておくと、実行時にForm2が表示されるようになります!では、次回にご期待下さい。最後にStartAdvice_Click()メソッドのソースコードを載せておきます。
May 17, 2008
コメント(2)
現時点での目次です。・VB.NETで楽天RSSからリアルタイム情報を取得する<その1>・VB.NETで楽天RSSからリアルタイム情報を取得する<その2>・VB.NETで楽天RSSからリアルタイム情報を取得する<その3>・VB.NETで楽天RSSからリアルタイム情報を取得する<その4>・VB.NETで楽天RSSからリアルタイム情報を取得する<その5>・VB.NETで楽天RSSからリアルタイム情報を取得する<その6>・VB.NETで楽天RSSからリアルタイム情報を取得する<その7>・VB.NETで楽天RSSからリアルタイム情報を取得する<その8>
May 12, 2008
コメント(0)
ずっと連載が止まっていました。すみません。<その7>までは順調に書いていたのですが、GWを挟んだというのもありますし内容がややこしくなるので「どうやって解説しようか」と悩んでいたら遅くなりました。実は今日、職場の後輩から「入門シリーズ、滞ってますよね」と突っ込まれました(苦笑)。彼は自動売買プログラム「MATS」開発のために私のブログでAdvice()編が進むのを心待ちにしているそうですが、肝心なところで記事が止まったのでヤキモキしていたらしいです。すんませ~~ん。もしかしたら彼以外にも「早く書いてくれよ」と思っていた方がいらっしゃるかも知れません。それに応え、今日は久しぶりに続きを書きたいと思います。もしこの記事を最初に読まれて流れの分からない方は<その1>からご覧頂く事をお勧めします。左のカテゴリから「「VB.NETで自動売買」入門 」をクリックして頂いたら楽です。一番下から順番に見る事が出来ます。さてさて、前回はclient.StartAdvise("現在値", 1, True, 60000)をソースに追加すると書きました。ですが、このメソッドを呼び出しても変更通知イベントは発生しません。何故か分からないのですが、Request()メソッドを呼び出したDDEクライアントはAdvice()メソッドで使い回し出来ないようなのです。テストしてみて改めて分かりました。すみません。なので前回「取得_Click」メソッドからコピーしてこなかったclient.Dispose()で一旦インスタンスを破棄し、その後再び新たなインスタンスを生成しないといけません。そこで、ただコピーしても寂しいので、ついでと言ってはナンですが、新たな豆知識を書きます(笑)。それは「Usingブロック」です。あるインスタンスを生成し、いらなくなった時にそのインスタンスを破棄しないと無意味にメモリを圧迫する事になります。いらなくなる時に今回のようにDispose()を呼び出せば良いですが、もし例外が発生してその部分が処理されなかったりしたら、インスタンスがゴミとして残り、悪影響を及ぼす危険があります。例外処理をご存知の方は「Finallyブロック」内に記述するという方法を思い付くかも知れませんが、それより確実なのが「Usingブロック」です。DDEクライアントをインスタンス化する時に「Using」と記述し、使用する部分の最後に「End Using」と記述して囲めば終わりです。これで、処理が進みUsingブロックの外に制御が移った時に、自動的にDDEクライアントは破棄されるのです。是非そう記述して下さい。念のためにソースを載せます。この下に前回ご紹介した文を追加します。その前に、DDEクライアントを改めてインスタンス化し、接続しないといけないのでご注意下さい。追加するのは3文です。Dim adviceClient As DdeClient = New DdeClient("RSS", topic)adviceClient.Connect()adviceClient.StartAdvise("現在値", 1, True, 60000)あれ?今まで「client」と書いていたDDEクライアントの変数名を変えています。同じ名前だとカブるので、名前は何でも良いのですが今回は「adviceClient」としました。これで、現在値に変更があれば変更通知イベントが発生します。前回ご紹介したadviceClient.Adviseイベントです。ですが、このイベントが発生したからと言って今のままでは何もしません。「adviceClient.Adviseイベントが発生したら、このメソッドを呼んでね」という宣言をしておく必要があるのです。ではまず、肝心の「このメソッド」を作っておく必要があります。メソッド名は何でも良いですが、今回は現在値(現在の株価)が変わった時に動くメソッドなので「PriceChange()メソッド」にしました。以下のように書いて下さい。監視_Click()メソッドの最後の「End Sub」の下に記述して下さいね。Private Sub PriceChange(ByVal sender As Object, ByVal e As DdeAdviseEventArgs)End Sub細かくは解説しませんが、引数の「sender」はこのメソッドを呼んだ人。つまりイベントを発生させた人が入ってきます。つまりDDEクライアントのインスタンスです。「e」は、このメソッドが呼び出されるきっかけとなったイベントから引き渡された色々な値が入ったオブジェクトです。まだ中身は記述してません。まずはこのまま放置して下さい。ではイベントが発生したらこのメソッドを呼び出すようにソースに追加します。こちらもお作法だと思ってこのまま記述して下さい。AddHandler adviceClient.Advise, AddressOf PriceChangeこの行はPriceChange()メソッドにイベントハンドラを追加するという作業ですが、平たく言うと「adviceClientのAdviseイベントが発生したら、PriceChange()メソッドを呼んでね」です。何となく分かりますよね?ちなみにこの行を追加する場所ですが、adviceClient.StartAdvise("現在値", 1, True, 60000)の上にして下さい!「何で?」と思われるかも知れません。別に一番下で良いのではないかと。理由は、adviceClient.StartAdvise()によって更新通知を開始したら、次にAddhandlerが実行されるまでのほんのわずかな時間(数ミリ秒とかの単位)にAdviseイベントが発生する可能性があります。すると、まだPriceChange()メソッドとの紐付けが行われていないので、その通知は無視されてしまいます。出来れば避けたいですよね。という訳で、先に紐付けてから更新通知を開始するようにします。こうです。これで、現在値に変更があるたび(値動きするたび)にPriceChange()メソッドが呼び出されますので、このメソッド内に、画面の現在値を更新する記述を書けば終わりじゃないですか!取得_Click()メソッドから'現在値のバイト配列を取得Dim praceByte As Byte() = client.Request("現在値", 1, 60000)'バイト配列を文字列に変換して画面に表示Dim priceText As String = Encoding.Default.GetString(praceByte).TrimDim dotIndex As Integer = priceText.IndexOf(".")If dotIndex > -1 Then '小数点があれば小数点以下を破棄 priceText = priceText.Substring(0, dotIndex)End If現在値.Text = priceTextをゴッソリコピーしましょう(本当は同じソースが複数箇所にあるのは望ましくないと以前書きましたが、今はそうします)。すると、一箇所コンパイルエラーが出てます。「client」です。このメソッド内にはclientもadviceClientもありません。 ※実はadviceClientは取得出来ますが今は触れませんここではこのメソッドの引数である「e」から現在値を取得します。e(DdeAdviseEventArgsというオブジェクト)は「Data」というプロパティを持っています。ここには、変更通知のあった値そのものがバイト配列で入っているのです。つまり現在値を表すバイト配列。「client.Request("現在値", 1, 60000)」と同じです。なので、代わりに「e.Data」と書いてやれば終わりです!!ソースはこうなりました。ここまでくればそれなりに動作すると思うでしょう。では動かしてみましょう!デバッグ開始ボタン(再生ボタンっぽいやつ)を押します。そして前回のように楽天を・・・と思いましたが、今日は私が印象に残っているオックスHLDGSを検索したいので(笑)「2350」「OJ」と入力します。そして取得ではなく監視ボタンをクリックです!!すると・・・上手く・・・行きません(ぉぃ)。こんなダイアログが表示され、現在値を画面に移送する所で例外が発生しているのが分かります。どうしようもないので停止ボタン(■)をクリックしてプログラムを停止します。興味のある方は勉強されたら良いと思いますが、これはマルチスレッドが原因で起こっています。更新通知のイベントはメイン処理とは別のスレッドが非同期で発生しているのですが、スレッドをまたいでオブジェクトを操作するにはややこしい制御が必要になります。画面の現在値というテキストボックスはメインスレッド上に存在するオブジェクトですがPriceChange()メソッドを実行しているのは別スレッドです。このスレッドが直接画面のオブジェクトを操作すると怒られるのです。最良の解決方法はThreadやBackGroundWorker、Invokeなどというキーワードで勉強されれば良いかと思いますが、今は一番簡単な方法で解決します。DDEクライアントのコンストラクタ(インスタンス化するメソッド)には、別のシグニチャ(引数の組み合わせ)が存在します。今までDim adviceClient As DdeClient = New DdeClient("RSS", topic)と書いてましたが、ヘルプを見ると、引数が3つのものがあります。第三引数は、同期を取るオブジェクトです。詳しくは書きませんが、第三引数で渡すオブジェクト毎にDDEインスタンスのメソッドを同期を取って動作させてくれます。そうする事によって、現在値.Textを直接更新出来るようになるんです!分からない方は理由は考えず、次のように書き換えて下さい(^-^;Dim adviceClient As DdeClient = New DdeClient("RSS", topic, Me)「Me」とは自分自身のオブジェクトの事を指します。ここでは「Form1」の事です。もう一度実行させると、正しく動作する事が分かります。実行するのがザラ場中だったら尚良いんですが。画面上の株価がリアルタイムで更新されるのを見る事が出来ますからね!!・・・今日はここまでにします。一応、更新通知イベントを受けて現在値を更新する処理が出来ました。ですが、監視を停止する処理が無いのでプログラムを止めるしかないですし、例外処理も一切書いていないので、実運用するにはプログラムが異常終了しないようにちゃんと実装する必要があるでしょう。それらを解説するかどうかは決めてませんが、Advice()形式の肝である複数銘柄、複数項目の監視をどうやって実現するかについてまだ書いていませんのでこれについては是非書きたいと思っています。次回にご期待下さい。
May 12, 2008
コメント(7)
今日は本当に、Advice()形式の第一回です。前回、Request()形式で継続的にリアルタイムデータを取得する方法として、Do~Loopなどの繰り返し処理やタイマーイベントをご紹介しました。取得間隔は例として5秒間隔でした。一定間隔で値を取得したい場合はこの方法をお勧めします。ですがそうではない場合もあります。ある時は1秒間の間に数回株価が変動したり、あるいは別のタイミングでは暫く株価が動かなかったり。その変化の頻度は一定ではなく波があります。一定間隔だと細かい変化が全く読み取れなかったり、逆に全く変化が無いのに無駄に取得したりする可能性が出てきます。それを克服するためにAdvice()形式があります。Request()形式は「この情報を下さい」と要求し、そのタイミングで値をもらいます。自分が要求しないと取得出来ませんし、要求したら前回と全く同じ値でも取得処理が流れます。それに対しAdvice()形式は「この情報に更新があれば教えて下さいね」と頼んでおく形式です。値に更新があった時に、イベントハンドラに紐付けられたメソッドが自動的に呼び出されるのでそのメソッド内に「更新時の処理」を記述すれば良いという事になります。自分で繰り返し処理を回す必要はありません。DDEクライアントに「もう監視は結構ですよ」と言うまで変更がある度にイベンドハンドラに対するメソッドを呼び出してくれます。Request()形式が能動的に値を取得するのに対し、Advice()形式は受動的です。また、Advice()形式には何げに嬉しい特典が付いています。前場が終わってから暫くすると(11:00過ぎ)、楽天RSSは一度停止します。これは楽天証券のシステムの動きなのでそれをどうにかする事は出来ません。楽天RSSが停止中、もしDDEクライアントのRequest()メソッドを呼び出すと例外が発生します。なので、停止時間帯はRequest()メソッドは呼び出さないように注意する必要があります。前場が終わった段階でMarketSpeedと楽天RSSを停止し、後場が開始する前に再起動されている人もいらっしゃるようですし、それが無くとも停止時間帯にRequest()メソッドを呼び出さないように制御する必要があります。・・・もちろん、Connect()メソッドなどの他のメソッドに対してもレスポンスが返る事は無いので例外が発生しますよ。Advice()形式は情報に変更があった時に通知してもらうのですが、楽天RSSが停止中もDDEクライアントのインスタンスが死ぬ訳ではありません。ただ「通知が来ない」だけで、プログラムをそのまま実行させていても何ら問題ありません。これって運用が楽だと思いませんか?・・・前置きはこれぐらいにして、Advice()形式のサンプルプログラム作成を始めましょう。「その5」で言った通り、プロジェクトや画面はRequest()形式で作成したものを使用しますのでまだ準備されていない方は宜しくお願いします。まず最初に「現在値の監視を開始してね」という意味で「取得」ボタンの隣に「監視」ボタンを追加します。ツールボックスからボタンをドラッグ&ドロップし、プロパティの「Text(表示名)」と「Name(オブジェクト)」の値を両方「監視」にします(分からない方は「その1」からご覧下さい)。そして、監視ボタンをダブルクリックしてソースにメソッドを追加しましょう。このようになっていますか? 上に見えているのはRequest()編で作ったメソッドの最後の部分です。ここから、ソースコードをコピーします(笑)。本当は同じソース中に同じようなコードが複数ある事は望ましくありません。修正する時に2箇所を直さないといけませんし、修正忘れなどのミスでバグが混入する可能性も高くなるからです。本来なら共通処理としてPrivateメソッドに切り出して、それぞれのメソッドがその共通メソッドを呼ぶようにするなどする方が良いでしょう。 ※読んでて意味の分からない方は、勉強されるか、無理なら読み飛ばして下さいそれはとにかく置いておいて、今回はコピーします。コピーするのは最初から、銘柄名称を取得して画面に設定する所までです。ここまでコピーすると「監視」ボタンを押しても「取得」ボタンと同様、銘柄コードと市場コードに対する銘柄名称をRequest()形式で取得して画面に表示してくれます。あとは現在値をAdvice()形式で取得すれば終わりです!!wさて今回のメインです。DDEクライアントにはStartAdvice()というメソッドがあります。第一引数で指定したアイテム名の監視を開始するメソッドです。インテリセンスを使って入力してみて下さい。client.StartAdvise("現在値", 1, True, 60000)第二引数と第三引数はRequest()メソッド同様、気にしないで下さい。第四引数はタイムアウトまでの待ち時間です。このメソッドを呼び出すと、現在値に変化がある度にイベントが発生します。イベントとは「取得ボタンがクリックされた時」で解説したような「取得.Click」の事です。今回の場合は、DDEクライアントのAdviceイベントが発生しますので、このイベントを受けて実行するメソッドを用意する必要があります。でも、取得_Click()メソッドの宣言の最後に記述されているように「Handles 取得.Click」などと最初から記述しておく事は出来ません。なぜならDDEクライアントのオブジェクトは実行された時に初めて生成されるもので、ボタンのような静的なオブジェクトではなく動的なオブジェクトです。なので、オブジェクトを生成した後、自分で動的にイベントとメソッドとを紐付けてあげないといけないのです。・・・と、もう少し書こうと思っていたのですが、MarketSpeed7.1のダウロードが始まって評価等が出来ないので今日はここまでにしたいと思います。。。
Apr 21, 2008
コメント(2)
今回をAdvice()編の第一回だと期待された方、すみません。その前に、Request()編で言い忘れてたポイントを書いておこうと思いまして。取得するデータには、銘柄名称や前日終値など「定期的に値を取得する必要のないもの」と現在値や出来高など「定期的に情報を取得しないと機能しないもの」の2通りに大別出来ます。Request()編のサンプルで取得した銘柄名称と現在値のうち、現在値については人が取得ボタンを何度もクリックしなくても、自動的に変化してくれた方が便利です。そういう場合、私は2通りの実現方法を考えます。まず1つ目がLoop文などの繰り返し処理を使用する方法。Do System.Threading.Thread.Sleep(5000) {繰り返す処理}Loopと書いてやれば、Do~Loopで囲まれた部分を繰り返し処理してくれます。中に書いてある「System.Threading.Thread.Sleep(5000)」は、処理を5秒待機するという意味です。引数は待機する時間をミリ秒で指定します。上のように書けば、5秒間隔で処理を行います。もう1つの方法は、タイマーイベントを使う方法です。ツールボックスの中に「Timer」が存在するので、それをFormにドラッグ&ドロップします。すると画面の下にタイマーが貼り付けられるので、それを選択した状態でプロパティの「Interval」を5000にします。これで準備は完了です。あとは、取得ボタンが押された時に、Timer1.Start()と書いてやれば、5秒毎にTimer1.Tickイベントが発生します。取得.Clickと同じです。「タイマーの時間が来たら」みたいな意味のイベントです。Form1クラスに、メソッドを追加する必要があります。一番簡単な方法は、Form1のデザイン画面で、Timer1のアイコンをダブルクリックします。するとメソッドが追加されますので、5秒後との処理を追加します。以上2通りの方法をご紹介しましたが、どちらも定期的な処理を行う方法だけで、そのループを中断する処理を一切書いていません(苦笑)。実際使用する時には中断処理も書かないと、プログラムを終了させるまで無限ループする事になってしまいますのでご注意下さい。・・・恐らく次回はAdvice()編を開始すると思います。今回は「つなぎの回」ですみませんでした。
Apr 20, 2008
コメント(0)
前回は、画面に銘柄名称と現在値を表示するコードを追加しました。でも、銘柄名称は良いとして現在値(現在の株価)については金額であるにも関わらず小数点以下2桁まで表示され、しかも数字の手前に空白が表示されていました。これじゃあ見映えが悪いです。という訳で今回は、株価を取得した時に実際どうすれば良いかを解説します。現在のコードはこうなっています。Dim praceByte As Byte() = client.Request("現在値", 1, 60000)現在値.Text = Encoding.Default.GetString(praceByte)「Encoding.Default.GetString(praceByte)」の戻り値であった小数点と空白付きの文字列を、何とか綺麗な数字として扱いたいです。ではまず、画面に表示する見映えの部分に手を入れます。最初に文字列を変数に入れましょう。この時、前後の余分な空白を取り除くメソッドを追加します!Dim priceText As String = Encoding.Default.GetString(praceByte).TrimTrim()は、文字列の前後の空白を取り除いてくれるメソッドで、戻り値はStringです。「Encoding.Default.GetString(praceByte)」の戻り値がStringなので、その戻り値のStringに対してまたTrim()メソッドを呼んで、その戻り値をpriceTextというStringにセットしています。ちなみに「Trim」の後ろにカッコがありませんが、VBは引数が無いメソッドはカッコを省略出来ます(書いても良いですよ)。次に、priceText(空白を除去した小数点付きの数字を表すString)から小数点以下を取り除いて整数値にします。整数値にする方法ですが、私はこんな方法を使っています。 ※もっとスマートにやってる方は教えて下さい(汗)Dim dotIndex As Integer = priceText.IndexOf(".")If dotIndex > -1 Then priceText = priceText.Substring(0, dotIndex)End If1行目のIndexOf()で小数点の位置(priceTextの何桁目にあるか)を調べます。1桁目なら0、2桁目なら1、・・・という風に返ります。小数点が無ければ-1になります。「If」の後は「小数点以下が存在したら」という意味になります。なぜ「小数点以下が存在したら」という条件が必要かは後述します。Substring()は、対象のStringの、何桁目から何桁を切り出すメソッドです。上の例だと、0(1桁目)から小数点位置の桁数を切り出して再びpriceTextにセットします。つまり、小数点以下をちょん切っています。・・・ここで1つポイントがあります。もしDDEクライアントのRequest()メソッドを呼び出した時が8:30とかだったらどうでしょう?現在の株価ってありますか?ありません。そういう時には、実は戻り値は空白になっています。その時のために「小数点が見つかった時だけ」という記述が必要なんです。ちなみに「If~Then~End If」の説明は割愛させて頂きます。あと「表示をカンマ区切りにしたい」等の要望もあると思いますが、その場合は上のpriceTextを一度整数値(Integer型)に変換し、それをまた文字列に変換する時に書式を設定してやれば可能です。整数値に変換する時も、株価が無い時(ザラバ前)を考慮する事を忘れないようにして下さい(やり方はあえて書きません。必要であれば各自組み込んで下さい)。また、プログラム中で数値の大小比較を行ったり計算を行うために株価などの数値を整数で扱いたい時もどうようです。文字列のままでは無理なので整数値に変換してあげましょう。最後に、現在値のテキストボックスを右揃えにしないと、数値なのに左詰めは格好悪いので、そこだけ変更します!現在値のテキストボックスを選択した状態で、プロパティウィンドウの「TextAlign」を「Right」に変更しましょう。実行させると、株価の見映えが前回より良くなっているのが分かりますよね♪今回は短いですがここまで。そして今回で「リクエスト方式」によるリアルタイム情報の取得について解説を終了します。分からない事、また「もう少しこうしたんだけど」など質問があればコメントを下さい。分かる範囲でお応えします。質問が無かったり、その内容が収束したと思ったら、少し日にちを置いてから「アドバイス方式(値に変更があった時に通知してくれる方式)」編を始めようと思います。宜しくお願いします。現在のソースコードはこうなりました。ちなみに「アドバイス方式編」も、画面は同じものを使用しようと考えています(^-^;
Apr 15, 2008
コメント(2)
今回の内容を始める前に、<その3>で記事の修正があったので報告します。トピック名を作るのにDim topic As String = 銘柄名称.Text & "." & 市場コード.Textと書いてしまっていましたが、正しくはDim topic As String = 銘柄コード.Text & "." & 市場コード.Textです。もし間違ったままの方は修正して下さい。すみません。では気を取り直して行きましょう。VB2008EEを立ち上げてSampleApplicationを開き、前回の終了時点の状態にして下さい。前回も書いた「楽天RSSから情報を取得するための基本的な流れ」はこの4ステップでした。(1)DdeClientのインスタンス化(銘柄毎に1つ)(2)楽天RSSに接続(3)欲しい情報を取得(複数項目ある場合は複数回)(4)DdeClientの破棄(1)と(2)は前回終わっているので今回は(3)からです。銘柄名称と現在の株価を取得するんでしたね。インスタンス化し、接続まで終わったDDEクライアントのメソッドを使って情報を取得するのですが、使うのはRequest()メソッドです。ここで前回紹介した「インテリセンス」を使ってみます。仮にclient.rと打ってCTRL+スペースを押してみて下さい。候補が現れますよね?「Request」をマウスでダブルクリックするか、マウスかキーボードで選択してTABキーを押すとちゃんと入力されますよね。あるいは選択している状態でいきなり引数を書くためのカッコ「(」を入力しても良いですよ。ここでRequest()メソッドが2種類ある事に気付きます。Resuest(item As String, timeout As Integer) As StringというのとResuest(item As String, format As Integer, timeout As Integer) As Byte()という2つです。同じメソッド名を引数違いで定義する事をオーバーロードと言いますが、今はそんな事はどうでも良いです(笑)。引数の多い方を使います。理由は戻り値(最後の「As」の後ろの型)です。最初の方はStringと書いてますが、これは文字列の事です。そして2つ目のByte()はバイト配列です。文字列だと何故駄目かと言いますと、文字コードが異なるからです。楽天RSSは文字列をShift-JISで返します。ですが.NET Frameworkでは文字コードをUnicodeで扱っている為、文字列で返されても文字化けを起こして何を書いているか全く読めません。なので、バイト配列を返してもらって、それを自分でUnicodeの文字列にエンコードしてやる必要があります。・・・ウダウダ書いてますが、分からない方はやり方だけ真似して下さい。Request()メソッドの第一引数はアイテム名ですが、これは取得する情報の名前です。楽天RSSの関数一覧を見て書けば良いです。銘柄名称はそのまま「銘柄名称」です。第二引数のフォーマットは整数ですが、何も考えず「1」にして下さい。お作法だと思って下さい。そして第三引数はタイムアウト時間(ミリ秒単位)です。例えば60000にすると60000ミリ秒なので60秒。つまり結果が返って来るまで最長1分待ちますよ、という事になります。どれぐらいが最適かは難しいのですが個人の価値観ですが、私は60000としています。という事で、銘柄名称のバイト配列を返してもらうためにこう書きます。Dim meigaraMeishoByte As Byte() = client.Request("銘柄名称", 1, 60000)「meigaraMeishoByte」は変数名なので何でも良いのですが、そのまま真似してもらった方が後でややこしくならないかも知れません。次に、そのバイト配列を文字列にして画面に表示します。ちなみに画面(Form1)の銘柄名称を表示するテキストボックスの名前を覚えていますか?そうです。「銘柄名称」です(笑)。画面の銘柄名称に移送するには、等号の左辺にどう書いたら良いかは想像出来ます。銘柄名称.Text = です。メソッドを書いているのがForm1なので、いちいち「Form1の」と書く必要が無いからいきなり「銘柄名称」で、Form1上に存在するテキストボックスだと分かります。そしてバイト配列を文字列に変える記述を書きます。銘柄名称.Text = Encoding.Default.GetString(meigaraMeishoByte)Encodingクラスを使います。但しこうやって名前空間を省略するには、ファイルの先頭に「Imports System.Text」と書いておかなないといけないので書いて下さい。インテリセンスを使って下さいよ!あと、ここはかなり込み入った話なので読み流してもらっても結構ですが、取得したバイト配列には末尾に「\0」が付いています。VB.NETで言う「vbNullChar(NULL文字)」です。不要なので切り取ります。Encoding.Default.GetString(meigaraMeishoByte).Replace(vbNullChar, String.Empty)という書き方でNULL文字を空文字に置き換えるという方法がありますが、テストをした結果書き方は長くなりますがEncoding.Default.GetString(meigaraMeishoByte, 0, meigaraMeishoByte.Length - 1)という風にバイト配列の末尾1バイトを切り取る方が高速だと分かりましたのでこちらの方法で記述するのをお勧めします。特に何度も呼び出す部分なのでパフォーマンスは気にしたいですよね。現在の株価を取得するのも全く同様に記述してみましょう。こんな風になります。Dim praceByte As Byte() = client.Request("現在値", 1, 60000)現在値.Text = Encoding.Default.GetString(praceByte)現在の株価は「現在値」という名前です。続けて最後のステップである「(4)DdeClientの破棄」も書きますよ!client.Dispose()これを書かないと、インスタンス化したDDEクライアントは(永久にでは無いですが)長時間生き続けてメモリ、CPUを圧迫します。無意味なので破棄します。Dispose()メソッドを呼び出すと、楽天RSSとの接続も綺麗に切断し、オブジェクトを消してくれます。必ず呼び出して下さい。現時点のソースコードはこうなってます。ご確認下さい。待ち遠しくてウズウズしてる方。せっかくなので試しに実行してみましょう!!画面のこのボタンをクリックすると実行しますよ!画面が表示されましたか?表示されたら、ここは楽天に敬意を表して、銘柄コードと市場コードはそれぞれ「4755」「Q」と入力して「取得」ボタンをクリックしましょう(笑)。銘柄名称と現在値が表示されました!!!(もちろん現在値は実行したタイミングで違います)いやぁ~見事銘柄名称と現在値が表示されましたね。これで「リクエスト形式」の方法については終わり・・・と言いたいところですが(汗)。現在値の表示のされ方に違和感ありませんか!?(汗)だって株価なのに「 60900.00」って。小数点付き!?しかも数値の前の空白は何??次回はその辺りについて解説する必要がありますね。次回に続きます!VB2008EEは実行しているForm1を閉じるか停止ボタン(開始ボタンの2つ右)をクリックすれば止まります。ではでは。
Apr 13, 2008
コメント(0)
さて今回はいよいよコーディングに入っていきますよ!期待して待ってて下さっていた方、有難うございます。前回までは、環境を作ってプロジェクトを作って画面を作っただけです。これからが一番楽しいところですよね。前回の状態にするために、VB2008EEを立ち上げてSampleApplicationを開いて下さい。Form1のソースコードを開いていない方は、Form1.vbを選択した状態で「コードの表示」ボタンをクリックして下さい。解説は、なるべくオブジェクト指向やVBの言語仕様などの細かい話を省略して単純にしていこうと思っています。ですが、初めてプログラムを組む方にはちんぷんかんぷんになる内容も出てくると思います。その場合は、このサンプルが出来上がった後にでも、独学で勉強される事をお勧めします。そうしないと、何かトラブルがあった時や自分で新しい事をしたい時に挫折してしまうので。前置きはこのぐらいにして早速始めていきます。取得_Click()というメソッドは「取得ボタンがクリックされた時の処理」でしたよね。やりたい事は画面の銘柄コード、市場コードを元に、楽天RSSから銘柄名称と現在の株価を取得して画面に表示したいでした。まずは、楽天RSSから情報を取得してくれるNDdeのクラスを準備します。そのクラスは「NDde.Client.DdeClient」です。プログラム中でこのクラスを使用する時には、こうやってフルネームで書いてあげても良いのですが、長くなるので面倒ですし後でソースも読みにくくなります。なので「NDde.Client.」という部分(名前空間と言います)を省略して、最後のクラス名だけ記述すれば良いように定義してやる事が出来ます。そのために、ファイルの先頭に「Imports NDde.Client」と書いてあげます。ここで、非常に便利な開発環境の機能を伝授します(笑)。それは「インテリセンス」と呼ばれるものですが、そこでコーディングすべき内容を予測して候補として表示してくれる機能です。コードの途中で「CTRL+スペースキー」で実現出来ます。どんな時でも記述の途中で押せば非常に効率よくコーディング出来ますし、スペルミスも無くなるので便利ですよ。是非インテリセンスに慣れて下さい。DdeClientクラスには色々なプロパティ(属性)やメソッド(操作)があります。今回使用するもの以外にも沢山あります。楽天RSSから情報を取得するための基本的な流れは、次の4ステップになります。(1)DdeClientのインスタンス化(銘柄毎に1つ)(2)楽天RSSに接続(3)欲しい情報を取得(複数項目ある場合は複数回)(4)DdeClientの破棄では順番にいきます。まずは「DdeClientのインスタンス化」です。クラスというのは「こんな属性でこんな操作を持ったものです」という設計図です。その設計図通りに実際のモノを作る作業がインスタンス化です。分からない方は「そんなもんなんだ」で流して下さいwインスタンス化するためには、引数(渡す情報)としてサービス名とトピック名が必要です。サービス名は、楽天RSSの場合"RSS"という文字列固定です。変わりません。そしてトピック名というのが「銘柄コード.市場コード」です。ここまで書いて「あれ!?」と思われた方。そうです!楽天RSSをExcelから関数で使用していた方は、セルに「=RSS|'4755.Q'!現在値」とか入力していましたよね!まさしくその時の「RSS」がサービス名で、「4755.Q」がトピック名なんです。ExcelからDDEの機能を使って楽天RSSから情報を取得していたんですね。まずはトピック名を作ります。画面の銘柄コードと市場コードに入力された文字列をピリオドでつなげます。Dim topic As String = 銘柄名称コード.Text & "." & 市場コード.Text(2008.4.11訂正)この1行が何を表しているかの説明は、すみませんが割愛させて頂きます。分からない方は調べて頂く事をお勧めします。トピック名が出来たので、サービス名の"RSS"と一緒に引き渡して、DdeClientのインスタンス化を行います。Dim client As New DdeClient("RSS", topic)インスタンス化されたDdeClientのオブジェクトは、今後clientという変数名で扱う事が出来ます。但し「Dim」で宣言した変数はローカル変数ですので、このメソッド(取得_Click())の中でしか使えません。・・・ややこしいのでこの辺りはハショります(苦笑)。さて次は、このオブジェクトを楽天RSSに接続させます。client.Connect()これだけです!この行が実行されている時にMarketSpeedや楽天RSSが立ち上がっていなかったり、MarketSpeedにログインされていない場合は例外が発生します。・・・このサンプルプログラムではエラーのハンドリングを省略するつもりです。異常が起こった時にどうしたら良いか分からない方は頑張って勉強して下さい。省略していますが、非常に大事な部分です。さてこれで、取得したい銘柄のDDEクライアントがインスタンス化されて楽天RSSに接続している状態です。嘘みたいですよね。いよいよ次は、銘柄名称と現在の株価を取得します!!・・・と行きたいところですが長くなったので今日はここまでにします。ほんとチョビットずつで申し訳無いです。m(_ _)m現在のソースはこんな感じになってます。(2008.4.11 ×「銘柄名称」→○「銘柄コード」)一応簡単にコメントを入れました。シングルクォーテーションを入れるとそれ以降がコメントになり、ソースコードとしてコンパイルされません。後からの事を考えると、そこで何をしているか分かりにくいコードにはこまめにコメントを入れる癖を付けましょうね。ではまた次回。。。
Apr 10, 2008
コメント(9)
せっかく昨日始まった「入門シリーズ」。別に毎日更新するつもりは無いのですが、せっかく何人かの方からコメントを頂いて気持ちも高まっているので、今日は飲み会帰りにも関わらず書いてみようと思います。間違った事や意味不明な事を書いてると思ったら後で訂正します(^-^;まず昨日書くのを忘れたのですが、楽天RSSからリアルタイム情報を取得するには、楽天証券の口座を持っていて、MarketSpeedの使用料を払っていて、MarketSpeedと楽天RSSを立ち上げていて尚且つMarketSpeedにログインした状態でないと無理だという事を、前提条件として書いておきます。その辺りは皆さん分かってらっしゃると思いますが。さて今回は早速、NDdeを使ってリアルタイム情報の取得を行ってみましょう。楽天RSSからの情報の取得方法は、以下の日記に書いた通り、2つの方法があります。http://plaza.rakuten.co.jp/acknight/diary/200711190001/その1つである「リクエスト方式」を試してみましょう。VB2008EEを立ち上げ、前回作った「SampleApplication」プロジェクトを開きます。デフォルトの「Form1」が開かれていない場合は、ソリューションエクスプローラからForm1をダブルクリックするか、右クリックで「開く」を選んで、Form1.vbのデザイン画面を開いて下さい。開いたら、Formの右下をマウスでドラッグして、それなりに大きく広げておいて下さい。色々なものを貼り付けるには小さすぎますので(^-^;そして次に、Form上にオブジェクトを貼り付けていきます。今回サンプルでは、銘柄コードと市場コードを入力し「取得」ボタンを押したら画面に銘柄名称と現在の株価が表示されるという処理を実現してみようと思います。貼り付けるのは、銘柄コードと市場コードを入力するためのテキストボックス。そして銘柄名称と現在の株価が表示されるテキストボックス。そして取得ボタンの計5つです。作成は、ツールボックスからドラッグして行います。画面左にあるツールボックスをクリックしたら広がりますので、貼り付けたいオブジェクトをマウスでドラッグしてForm1にドロップします。何も考えずにドロップしただけだと、上のようになってしまいます。これだとあまりに寂しいので、少し手を加えたいと思います。まず銘柄コードは4桁です。左上のテキストボックスを選んだ状態でプロパティウィンドウの「MaxLength」を4に変更し、さらに大きさもそれっぽくするために「Size」を40. 19に変更します。その右の市場コードは3桁。大きさも35. 19程度に縮めておきましょう。市場コードが何故3桁かという事については後で述べます。同様に、左下のテキストボックスは銘柄名称を表示するとして(MaxLengthは変更せず)Sizeのみ220. 19に。右下は株価ですが、まあこのままのSizeで良いでしょうwボタンは「Text」プロパティで表示されている文字を変えます。「Button1」じゃ寂しすぎるので「取得」にでも変更しましょう。そして、見映え良くするように位置を調整して下さい。私はこんな感じになりました。プログラムに入る前に、後からプログラムのソースコードを見て理解しやすいようにオブジェクトに分かりやすい名前を付けます。これは、プログラムのメンテ性の面から見ても非常に重要な事です。後から「TextBox1って何やったっけ?」ってなると意味が無いのです。Form1に対して適当な名前をつけていませんが本当はちゃんと名前を付けて下さい。今回は、貼り付けたオブジェクトに適切な名前を付けます。名前はプロパティウィンドウの上の方にある「(Name)」です。それぞれ「銘柄コード」「市場コード」「取得」「銘柄名称」「現在値」と日本語で付けました。さてこれから、やっとコーディングしていく事になります。VBは「イベントドリブン型」のプログラムです。「○○がXXになったら」というイベントに対してプログラムを記述する事によって処理が実行されます。今回の処理のトリガーは「取得ボタンが押下されたら」です。取得ボタンをダブルクリックします。すると、こんな画面が表示されましたよね?これは、Form1.vbのソースコードです。Form1で行われる処理を記述する場所です。中に「取得_Click(・・・)」という部分がありますが、これは先ほど取得ボタンをダブルクリックした時に自動作成された「取得ボタンがクリックされた時の処理」の骨格部分です。「取得_CLick」という名前は自由に変更可能ですがそのままにしておいて良いでしょう。逆に最後の「Handles 取得.Click」は変更出来ません。「この処理は、『取得』オブジェクトが『CLick』された時に起動される処理ですよ」と定義してあるのです。「.Click」部分を変更する事により「ダブルクリックされた時」やその他色々なイベントに対する処理に変える事が出来ます。・・・「これからやっとコーディング」と書いておきながら、今回はここで終了にします。すみません(^-^;さて、いよいよ次回は本当にコーディングに入ります。
Apr 9, 2008
コメント(7)
BBSでyamahooさんから「初心者向けの記事を書いて欲しい」というリクエストがありました。私はある程度プログラムを書かれている方に参考になるような内容は書いた事がありますがこれからプログラムを始める人向けにあまり書いた事がありませんでした。また今後も「質問されたら答えるけど、自分から記事を書くつもりは無い」と思っていました。 ですが自分の思っている以上に色々な方がこんなショボいブログを見て下さっているんだと分かり、それなら少しでも皆さんの思いに応えたいと思い始めてきました。VB.NETの自動売買仲間を増やしたいというのもあります。なので、今回ちょっとビギナー向けの内容を書いてみたいと思います。 ちなみに解説する内容がベストなプログラム構造という訳ではありません。実際、私は違ったクラス構成で組んでいます。あくまでも初心者の方に分かりやすくなるような形でご紹介しようと思いますので「こんなやり方じゃ応用が利かないじゃないか」等思われる方はご了承下さい。「こういう風に組めば実現出来るんだ」という事を分かってもらえたらそれで成功だと思っています。アプリケーション構成は、KATSと同様にリアルタイム情報の取得を楽天証券のRealtimeSpreadSheetから。発注をクリック証券のWebサービスAPIを使って行います。・・・もしあまり反響が無ければ、この企画はすぐに中止します(笑)。皆さんからコメントを頂き、やりがいを感じたら不定期でぼちぼちと進めていきます。 今回は第一回という事で、プロジェクトの作成とNDdeの参照設定を行うところだけ解説します。焦らずゆっくりと進めます。 (1)VB2008EEのインストールまず何より、開発環境であるVB.NETのダウンロードとインストールをしない事には始まりません。現在最新のVB.NETは、Visual Basic 2008 Express Editionです。 http://www.microsoft.com/japan/msdn/vstudio/express/ にある「Visual Basic 2008 Express Edition」の「Webインストール」をクリックし、ダウンロード~インストールをして下さい。 インストール方法が分からない方もリンクがありますのでそれを読んだら出来ると思います。また、インストール後に必ず「製品の登録」をして下さい(無料です)。登録しないと、継続して利用出来ません。(2)NDdeのダウンロード楽天RSSのリアルタイム情報を取得するためには、DDEという技術を使う必要があります。VB.NETからDDEを使うために「NDde」というクラスライブラリが提供されているので使わない手はないです。以下のURLからダウンロードします。 http://www.codeplex.com/ndde/Release/ProjectReleases.aspx?ReleaseId=4828 ダウンロードしたzipファイルは解凍しておきましょう。ちなみに、Documentationフォルダには英語ながらしっかりしたヘルプと、SamplesフォルダにはVB.NETとC#のサンプルプロジェクトが既に同梱されているのでそれで理解出来る人は私の説明などいらないと思います(苦笑)。 (3)サンプルプロジェクトの作成とNDdeの参照設定まず初めに、VB2008EEを起動した時に表示されるスタートページから「作成: プロジェクト(P)」をクリックします。すると新しいプロジェクトを作成するダイアログが表示されるのでテンプレートから「Windowsフォームアプリケーション」を選択し、好きなプロジェクト名を入力して「OK」をクリックします。ここでは「SampleApplication」にしました。作成されたアプリケーションは「すべてを保存」ボタンで保存しておいて下さい。次に、右側にある「ソリューションエクスプローラ」の「全てのファイルを表示」ボタンをクリックしておく事をお勧めします。次に、解凍したNDdeのzipファイルのBinaryフォルダにあるNDde.dllを、プロジェクトに貼り付けるか、ドラッグ&ドロップでコピーします。その貼り付けたdllファイルをプログラム中で使用するためには、参照指定を行う必要があります。「参照指定」を右クリックし「参照の追加」を選択します。すると参照の追加ダイアログが表示されますので「参照」タグをクリックしてから自プロジェクト内のNDde.dlファイルを選択して「OK」ボタンをクリックします。すると参照指定にNDdeが追加されました。これでプログラムからNDdeが使用出来るようになりました!!・・・すみませんが今日はここまでです(^-^;まだ何もコーディングしていませんが、NDde.dllを使用する前準備が分からなかった方には参考になる内容かも知れません。時間と気力の許す限り続きを書いて行こうと思います。
Apr 8, 2008
コメント(6)
全24件 (24件中 1-24件目)
1