注文照会で証券会社から取得して株てくおーとに注文照会リストとして表示しているのは次の項目です。
分岐先URI(取り消し):https(非表示)
日付:Date
時刻:Time
状況:Status
銘柄名:DealName
銘柄コード:DealCode
取引種別:TradeType
口座:AccountCd
注文数:OrderValue
注文値:OrderPrice
これらの情報を利用し、取り消し注文を行うことができます。
注文照会で証券会社から取得して株てくおーとに注文照会リストとして表示しているのは次の項目です。
分岐先URI(取り消し):https(非表示)
日付:Date
時刻:Time
状況:Status
銘柄名:DealName
銘柄コード:DealCode
取引種別:TradeType
口座:AccountCd
注文数:OrderValue
注文値:OrderPrice
これらの情報を利用し、取り消し注文を行うことができます。
返済注文検索で証券会社から取得して株てくおーとに返済注文リストとして表示しているのは次の項目です。
分岐先URI(返済注文):https(非表示)
取引種別:TradeType
銘柄名:DealName
銘柄コード:DealCode
保有株数:PositionValue
執行中株数:WaitValue(非表示)
建て日:Getyyyymmdd(非表示)
現在値:NowPrice
取得価格:GetPrice(非表示)
損益:Profit
損益率:Profitrate
これらの情報を利用し、返済注文を行うことができます。
注文がエラーになった場合、注文処理を途中で中止する必要があります。
たとえば新規注文の場合、以下のような処理をおこないますが、(2)で誤った価格を指定した場合などはWEBサーバからエラーが通知されるため(3)以降を中止しなければなりません。
(1)新規注文の銘柄検索画面で銘柄コードを入力し、その銘柄の新規注文画面を表示する。
(2)株数や価格、執行条件を設定して注文処理し、注文確認画面を表示する。
(3)取引パスワードを設定して注文確認処理を行う。
(4)約定確認処理
エラーをどう通知しているかは証券会社によって異なるため、その証券会社にあったエラー検知処理を作成する必要があります。
楽天証券の場合は、class="error"があればその後にエラー内容が通知されるのでこの内容を検知し、エラー処理を行います。
例)<span class="error">価格は、半角数字9桁以内で入力してください。</span><BR>
Private Function fncGetErrMsg(ByRef inputdata As String) As String
Dim pattern As String = "span class.*error.*?>(?<errmsg>.*?)<"
Dim re As Regex = New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Singleline)
Dim m As Match = re.Match(inputdata)
fncGetErrMsg=""
If m.Success = True Then
fncGetErrMsg = m.Groups("errmsg").Value
Else
End If
End Function
返済注文も新規注文とやるべき処理は同じです。IEなどで行っている処理と同等のことをするだけです。
URIと必要なパラメタを漏れることなく間違いのないようにセットして、POSTすれば返済注文の発注はできます。
発注ソフトの処理は全然難しくありませんが、証券会社毎に異なるパラメタの調査が面倒です。
そのために、IENaviTr (アイ・イー・ナビトレ)などのツールを利用し、IEで操作したときにどのようなURIに対してどのようなパラメータをPOSTしているのかを調査するわけです。
返済注文にある特殊処理
・返済注文要求された銘柄が返済注文リストにあるかを判断し、あればその銘柄の返済注文を行い、なければエラー処理を行う。
新規注文するためには、以下の処理が必要になります。
(1)新規注文の銘柄検索画面で銘柄コードを入力し、その銘柄の新規注文画面を表示する。
注意すること
(a)action="/app/ord_jp_stk_search.do;BV_SessionID=fTw4JyHC06QFbpGHTSy6!-1493454566"
のようになっている場合は、先頭にベースである"https://member.rakuten-sec.co.jp"を追加する。
(b)input type="hidden" name="trdKbn" value="20"の場合、trdKbn=20として追加する。
(c)input type="hidden" name="offsetRow" value=""のような値のないパラメタであってもoffsetRow=を追加する。
(2)株数や価格、執行条件を設定して注文処理し、注文確認画面を表示する。
注意すること
(a)accountCdパラメタのようにタイプが異なりnameが同じ場合
type="radio"
<input type="radio" name="accountCd" value="1" checked="checked" id="special"> <label for="special">特定</label>
<input type="radio" name="accountCd" value="0" id="general"> <label for="general">一般</label>
type="hidden"
<input type="hidden" name="accountCd" value="1">
パラメタは1つだけセットすればよい。ただ、同じのがある場合、後のパラメタが有効になるので、2つセットする場合は、最初にhiddenのパラメタをセットし、その後、実際指定したaccountCdの値をセットする。
(3)取引パスワードを設定して注文確認処理を行う。
注意すること
(a)input type="hidden" name="commissionCourseName" value="いちにち定額コース"
のような値が漢字の場合は、HttpUtility.UrlEncodeメソッドを使用し、
URLエンコードした値をパラメタにして通知する。
例)commissionCourseName=%82%a2%82%bf%82%c9%82%bf%92%e8%8az%83R%81%5b%83X
(4)約定確認処理
約定したかどうかの確認方法
・返済注文リストを表示し、新規注文した銘柄が返済注文リストにある。
・注文照会リストを表示し、新規注文した銘柄の取り消し可能注文(予約中、執行待ち)がない。
上記の2つが揃ったとき、約定したと判断する。上記の2つが揃わない場合、時間をおいて再度返済注文と注文照会を行う。
約定したことを発注元へ通知
返済注文の分析を行うために、約定(約定時間や、約定価格等)したかどうかが発注元にわかるようにする必要があります。
株てくおーとの場合は、ファイルを出力するようにしています。ファイル名や、ファイルのフォーマットは、2009/04/09の株てくおーとAPI(2)を参照ください。
SessionIDはログインする毎に変化するログイン認識IDです。
ログイン後のページから新規注文のページや返済注文のページに移動するときに必要になります。
ただし、ジョインベスト証券、カブドットコム証券のようにCookieでチェック後はSessionIDのようなものが必要ない所もあります。
また、松井証券のように、ページを移動するたびに変化するattrSrcKeyが必要な証券会社もあります。
自分が利用している証券会社に合うように作成する必要があります。
Webサーバから受信したレスポンスデータからSessionID等を抜き出すにはRegexクラスによる正規表現を使用するのが便利で簡単です。
発注ソフトでは文字の検索や抜き出しが多いので正規表現は必ず理解する必要があります。
正規表現を利用すると処理が非常に簡単になるし、処理ステップを大幅に削減することができます。
例)<frame src="/app/view/com/com_page_footer.jsp;BV_SessionID=2wpHJnnbj4JMdqY1JWQk!503751690?style=small" name="bottomframe" noresize="noresize" scrolling="no">
Private Function fncSessionID(ByRef inputdata As String) As String
Dim pattern As String = "frame.*?BV_SessionID=(?<sessionid>.*?)\?"
Dim re As Regex = New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Singleline)
Dim m As Match = re.Match(inputdata)
fncSessionID=""
If m.Success = True Then
fncSessionID = m.Groups("sessionid").Value
Else
End If
End Function
どのように発注するソフトを作成するのかを楽天証券を例に説明します。
他の証券会社も同様に作成することができます。
先ずは、ログイン処理から説明します。
(1)ログイン画面を表示
ログイン画面のURL(https://www.rakuten-sec.co.jp/ITS/V_ACT_Login.html)を
メソッドにGETを指定してリクエストする。
(2)ログイン画面の解析
メソッドにGETを指定してリクエストすると、Webサーバ(楽天証券)からレスポンスが返ってきます。
この内容を解析します。
返ってきた内容を見ると、以下のような文字列があると思います。
<form name="loginform" action="https://member.rakuten-sec.co.jp/bv/app/Login.do" method="POST" target="_top">
上記のようにaction="URI" method="POST"になっている場合、メソッドにPOSTを指定し、さらに要求パラメタを指定しててリクエストすれば、要求パラメタに従った内容のページがWebサーバ(楽天証券)からレスポンスとして返ってきます。
それではPOSTの場合、どのような要求パラメタを指定すればよいのかを説明します。
ログインIDとパスワードの所が以下のようになっていると思います。
ログインID
<td width="90" align="right" valign="middle" nowrap class="login-bg1 fs100" style="padding-right:5px;color:#fff;font-weight:bold;">ログインID</td>
<td width="166" valign="middle" class="login-bg1"><input type="text" name="loginid" maxlength="18" style="width:200px;" tabindex="1"></td>
パスワード
<td align="right" valign="middle" class="login-bg1 fs100" style="padding-right:5px;color:#fff;font-weight:bold;">パスワード</td>
<td width="166" valign="middle" class="login-bg1"><input type="password" name="passwd" maxlength="18" style="width:200px;" tabindex="2"></td>
ここで大事なのは、input type="text" name="loginid"とinput type="password" name="passwd"の文字列です。
inputという文字列があればこれが入力に必要なものだと思ってください。
そして、nameがパラメタになります。
たとえば、ログインIDが1234567でパスワードがabcの場合、パラメタとして送るのは
loginid=1234567&passwd=abc
になります。
2つ以上パラメタがある場合は、&で連結します。
WebRequestのセット例は以下のようになります。
'パラメタのセット
sendparm="loginid=1234567&passwd=abc"
'バイト型配列に変換
Dim postDataBytes As Byte() = _
System.Text.Encoding.ASCII.GetBytes(sendparm)
'URIのセット"
strURI="https://member.rakuten-sec.co.jp/bv/app/Login.do"
'WebRequestの作成
myRequest = CType(WebRequest.Create(strURI), HttpWebRequest)
'ユーザー エージェントの識別名をセット
myRequest.UserAgent _
= "Mozilla/4.0 (compatible; MSIE 7.0; Windows XP)"
'メソッドにPOSTを指定
myRequest.Method = "POST"
上記をWebサーバに送ると、WebサーバがログインIDとパスワードをチェックし、正しければログイン後の画面がレスポンスとして返されます。誤っていればエラーの画面がレスポンスとして返されます。
例なのでsendparmやstrURIはこの場所でセットしていますが、普通はPOSTルーチンの入力にします。
ちなみに、
<div class="fs90"><a href="http://service.money.rakuten.co.jp/">楽天マネーサービス</a> | <a href="http://www.rakuten.co.jp/"><b>楽天市場へ</b></a></div>
上記のようにa href="URI"になっている場合、そのURLのページを表示したい場合は、メソッドにGETを指定してリクエストすれば、そのページがWebサーバ(楽天証券)からレスポンスとして返ってきます。
'URIのセット"
strURI="http://service.money.rakuten.co.jp/"
'送信データを作成する
myRequest = CType(WebRequest.Create(strURI), HttpWebRequest)
'ユーザー エージェントの識別名をセット
myRequest.UserAgent _
= "Mozilla/4.0 (compatible; MSIE 7.0; Windows XP)"
'メソッドにGETを指定
myRequest.Method = "GET"
<td align="right" style="padding-right: 5px;"><form id="hdr-search1" name="hdr-search1" action="http://www.google.co.jp/custom" method="get" target="_blank" style="margin:0;padding:0;">
上記のようにaction="URI" method="GET"になっている場合も、メソッドにGETを指定してリクエストすれば、そのページがWebサーバ(楽天証券)からレスポンスとして返ってきます。
(1)SSL
WebRequest クラスと WebResponse クラスは SSL を使用して SSL をサポートする Web ホストと通信します。
SSL を使用するかどうかは、受け取った URI に基づいて WebRequest クラスが決定します。
URI が "https:" で始まっている場合は SSL が使用されます。
URI が "http:" で始まっている場合は暗号化されていない接続が使用されます。
つまり、WebRequestクラスとWebResponseクラスを使用していれば、SSLについては意識しなくてもかまいません。
(2)Cookie
HttpWebRequest.CookieContainerプロパティがあるので、特にCookieを意識せずとも認証を行うプログラムを作成する事が出来ます。
GETするときに以下のようにクッキーをセットするコンテナをセット
'クッキーをセットするコンテナをセット(複数のサイトの複数のクッキーがセットされる。)
myRequest.CookieContainer = Cookie
POSTするときに以下のようにクッキーをセットするコンテナをセット
さらに
GetRequestStreamメソッドを呼び出せば、Webサイトから受け取ったクッキーがすべてCookieContainerオブジェクト(変数Cookie)に格納されているのでここから自動的に適切なクッキーがセットされる。
'POST送信するデータの長さを指定
myRequest.ContentLength = postDataBytes.Length
'クッキーをセットするコンテナをセット(複数のサイトの複数のクッキーがセットされる。)
myRequest.CookieContainer = Cookie
'ポスト・データの書き込み
myPostStream = myRequest.GetRequestStream()
myPostStream.Write(postDataBytes, 0, postDataBytes.Length)
myPostStream.Close()
WebRequestクラスとWebResponseクラスはWebサーバへのアクセス用に特化したクラスです。
株てくおーと(発注ソフト)はこれで十分であり、ソケットクラスを使用するより簡単で便利なのでWebRequestクラスとWebResponseクラスを使用して作成しています。
発注ソフト作成方法の説明は、WebRequestクラスとWebResponseクラスを使用して説明します。
詳しい内容や使用方法は、「Visual Basicではじめるネットワークプログラミング超入門」やネットで調べてください。
私はネットワーク関連のプログラミングが初めてだったので、
「Visual Basicではじめるネットワークプログラミング超入門」
の本を読んで、株てくおーとを作成しました。
サンプルプログラムも豊富にあるし、わかりやすく書かれています。
この本一冊で、発注ソフトに必要な以下のことがわかります。
(1)WebRequest/WebResponseクラスの使用方法
・GET/POSTの利用方法や、Cookieの扱い
(2)Webページの文字コードの判定
(3)URLエンコード
また、NTPサーバと交信し、PCの時計をあわせる機能もこの本を参考にして株てくおーとに追加しました。
注)TICKデータ採取時、秒の単位まで取得しているがPCの時計は狂いやすいのでこの機能を利用してPCの時計を正しい時刻にしています。
発注ソフトは証券会社とのやりとりをWebブラウザに代わって行う必要がありますが、実際にどのようなデータをやりとりしているのかを知る必要があります。
このときに役立つのが、やりとりしたGET,POSTデータやCookieの情報を採取するツールです。
私は、IE(インターネットエクスプローラ)の通信データを横取して、送信データを保存するIENaviTr (アイ・イー・ナビトレ)を使用しています。
http://www.vector.co.jp/soft/win95/net/se299115.html
以下は、IENaviTr のREADME.TXTからの抜粋です。
特徴としては次の通りです。
1)プロキシを使うことなく、送信データのダンプや書換えができます。
ここでいう送信データとは、Post/Get/Cookie の3種類です。
例えば、ボタンクリックイベントでJavaScriptが動き、Hidden属性の
テキストボックスに値を設定してから、POSTするようなページであった
としても、POSTデータを編集することができます。
2)フレームページごとに通信時間、ブラウザ処理時間を測定できますの
で、サイト構築時の評価ツールとして使えます。
3)プロキシとは異なり、SSLに代表される暗号化の影響を受けません。
4)日本語エンコードにも対応しています。
5)送信データをファイルに保存できますので、何が送信されたかを残す
ことができます。
6)デバッガのように、送信前にブレイクして、変数の書き換えや日本語
ダンプができます。