Excel VBA + RSS2で発注してみた。


RSS2(Realtime Spread Sheet) で発注
RSSでいろいろ情報を取得し、いろんなツールはつっくっているが、発注処理はまだやっていない。昔、HTMLを解析して発注するという処理を作ったことがあるが、地味なテキスト処理が多く、APIできたらなと思っていたのだが。
最近、楽天証券ではアルゴ発注など充実してきたが、買い側の アルゴが欲しいと思っていた。
まあ、とりあえず、発注処理もできるようにしておいた方がいいなと、挑戦。

ウエブでサンプルソースなどをさがすが、簡単な例を見つけた。
やってみると、意外と簡単ですぐ発注で来た。
Sub 監視開始()
' リストの最後まで
Dim i注文数量 As String
Dim i逆指値価格 As String
Dim i逆指値条件価格 As String
Dim s注文期限 As String
Dim lastrow As Integer '変数の宣言
lastrow = Cells(Rows.Count, 1).End(xlUp).Row '最終行の取得
While bExit = False
iProcNum = 0
bProcNon = True
i = 5
For i = 5 To lastrow
If Range("I" & i).Value <> "発注済" Then
' 現在値がいくらになったら値以下になったらそのn%上を逆差し値をして買い注文
If Range("C" & i).Value <= Range("D" & i).Value Then
'次に時間が来たときに、前の基準値より下がっていたら、そのN%上に逆指値に変更
i注文数量 = Range("E" & i).Value
i注文価格 = Range("F" & i).Value
s注文期限 = Now() + 5
i逆指値条件価格 = Range("F" & i).Value
i逆指値価格 = Range("G" & i).Value
Range("H" & i).Value = SET_HA_ID(1)
ret = RssStockOrder_v(Range("H" & i).Value, Range("A" & i).Value, cKai, c注文区分_逆指値, cSOR_SOR, i注文数量, , , c執行条件_今週中, , c口座区分_特定, i逆指値条件価格, c逆指値条件区分_以上, c逆指値価格区分_指値, i逆指値価格)
If ret = "" Then
ダイアログを探して閉じる
Range("I" & i).Value = "発注済" ' 発注終了にする
Range("J" & i).Value = "正常終了" ' 発注終了にする
Else
MsgBox ret
Stop
If ret <> "" Then
MsgBox "エラーを修正してから再起動してください"
Exit Sub
End If
Range("I" & i).Value = "監視中"
End If
Range("J" & i).Value = ret
iProcNum = iProcNum + 1
bProcNon = False
Else
Range("I" & i).Value = "監視中"
bProcNon = True
End If
End If
'
Next i
'
bExit = True
For i = 5 To lastrow
' 監視フラグが一つでも立っていれば継続。すべて処理済なら終わり。
If Range("I" & i).Value = "監視中" Then
bExit = False
End If
Next i
Sleep 1000
Wend
MsgBox "監視終了"
End Sub
しかし、それまでに数々のエラーが発生したのであった。
いくつかの設定をしろとのメッセージがでる。RSS自体の設定である。最初はどこの設定かすぐにわからなかった。
パラメタも非常に多く、わかりにくいので、変数、定数をわかりやすい名前にして指定した。
それでも、指値、指定の時は、売買金額を設定するなとか、意外とうるさい。どうせみないからゴミでもいいだろうと思ったが、厳重に指定させることでミスを防ごうとしているのだろう。
Private ha_id As Long
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Declare PtrSafe Function SetForegroundWindow Lib "user32" ( _
ByVal hwnd As Long) As Long
Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare PtrSafe Function GetWindow Lib "user32" _
(ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare PtrSafe Function GetDesktopWindow Lib "user32" () As Long
Const GW_CHILD = 5
Const GW_HWNDNEXT = 2
Const cUri As Integer = 1
Const cKai As Integer = 3
' 注文区分
Const c注文区分通常 As Integer = 0 Const c注文区分逆指値付き通常 As Integer = 1
Const c注文区分逆指値 As Integer = 2 Const cSOR通常 As Integer = 0
Const cSOR_SOR As Integer = 1
Const c価格区分成行 As Integer = 0 Const c価格区分指値 As Integer = 1
Const c執行条件本日中 As Integer = 0 Const c執行条件今週中 As Integer = 1
Const c執行条件寄付 As Integer = 2 Const c口座区分特定 As Integer = 0
Const c口座区分一般 As Integer = 1 Const c口座区分_NISA As Integer = 2 Const c逆指値条件区分以上 As Integer = 1
Const c逆指値条件区分以下 As Integer = 2 Const c逆指値価格区分成行 As Integer = 0
Const c逆指値価格区分指値 As Integer = 1 Const cセット注文区分予約しない As Integer = 0
Const cセット注文区分_予約する As Integer = 1



自動売買する上での問題
発注処理がうまくいくと、ダイアログが表示される。これを手動でOKボタンを押さなければならない。
自動発注は、PCの前に人がいないことを前提で使うので、ダイアログは自動的に閉じたい。
ChatGPT変更したらに聞いてみると、RSSにはそのような設定はないそうだ。
楽天証券は誤発注責任をなるべく避けるために、このダイアログはユーザに手動で押させようとしているのだろう。
最近というか昨日から、ChatGPTを使ってみているが、これは仕事している人が使うと非常に効率化が図れると思った。
残念ながら、私はリタイヤしているのであまり使うところがないが、例えば管理職など、部下の評価コメントの自動入力とかに使えそう。じつはVBAでそのようねものを組んだことがあるが、ChatGPTがあれば、より充実したものになりそう。、
中堅社員の論文の評価コメントをするという業務もあったが、これにも有効に使えそう。
と、話はとんだが、ChatGPTは、ダイアログに対してエンターキーを送る処理を教えてくれた。
が、別ウインドウが上に あった場合誤動作するので、それに関して聞いたら、いくつか方法を教えてくれた。
なかなか使えるかも。
ウインドウを指定して、それに対して、エンターキーを送信するという方法が手っ取り早そうなので試してみるが、タイトルがマッチしないらしく見つからないと返される。
それについても解決方法をGPT君は教えてくれる。
開いているウインドウタイトル名を全部とるのだが、楽天証券が処理させないような作りをしているのか、名前が取れない。
今日のところはこれであきらめて、とりあえず、ダイアログの消去はできた。

Sub ダイアログを探して閉じる()
Dim hwnd As Long
hwnd = FindWindow(vbNullString, "Realtime Spread Sheet 現物買い注文確認") ' ウィンドウタイトルは日本語表記そのままで
If hwnd <> 0 Then
SetForegroundWindow hwnd
Application.Wait Now + TimeValue("00:00:01")
SendKeys "~", True
Else
' DoEvents
Application.Wait Now + TimeValue("00:00:01")
' 全ウィンドウのタイトル列挙
Application.Wait Now + TimeValue("00:00:01")
SendKeys "~", True
' MsgBox "注文ダイアログが見つかりませんでした。エラーのかおうせいがあります。はっちゅう いちらんしートをひらいてkakuninださい"
' Stop
End If
End Sub
Sub 全ウィンドウのタイトル列挙()
Dim hwnd As Long
Dim strBuff As String * 255
Dim title As String
hwnd = GetWindow(GetDesktopWindow(), GW_CHILD)
Do While hwnd <> 0
If GetWindowText(hwnd, strBuff, 255) > 0 Then
title = Left(strBuff, InStr(strBuff, vbNullChar) - 1)
Debug.Print hwnd & ": " & title
End If
hwnd = GetWindow(hwnd, GW_HWNDNEXT)
Loop
End Sub
各種エラー処理
発注が美味くいっても、手動で発注するのと同じように、別に反対売買していて、クロス取引と判断されしまったり、するときは実際に発注処理がされていない。
それはエラーログを見なければわからない。
この辺も見て処理を追加するなどの機能追加は必要であろう。
また、取消処理や発注内容変更処理も考えられる。
その辺はおいおい。
実装
実装結果は以下となった

最後に
最近はアルゴなども充実してきて、それほど自動売買も自作の必要も少なくなっていると思うが、たまにこういう注文ができればなあと思う時がある。
今後は思いついたら作っていこうとおもう。
また、デイトレなどでいいロジックが見つかれば、PCの前に張り付いている必要もなく、こちらは利用価値がありそうだ。
PCの性能もそれなりに求められるであろう。