FOLIOやS株Now!みたいにワン株でテーマ別保有株式を管理しちゃおう!! 【MONELIO(マネリオ)製作記その4】 ~ マネックス証券ワン株で分散テーマ投資を行うエクセルVBAツール ~

このはな綺譚 柚 赤ずきん 20171228-Yuzu_s.jpg

 なんとか年内エントリーに間に合いました。 





MONELIO(マネリオ)計画について。


  少額テーマ投資サイトFOLIOSBI証券S株Now!をパクって、マネックス証券ワン株で分散テーマ投資を行うツールをエクセルVBAで作っちゃおうというのがMONELIO(マネリオ)計画です。

 MONELIO(マネリオ)システムの構成としてはエクセルをプラットフォームとして大きく3つのシステムから構成されています。

monelioシステム

 A:FOLIOからテーマ銘柄情報をパクりエクセルに自動入力

 B:マネックス証券にオートログインしてワン株売買を自動発注

 C:ヤフーファイナンスから株価情報をパクり運用管理


 これまで「その1:自動一括注文編」「その2:注文一括取消編」「その3:一括売却編編」を紹介してきました。

FOLIOやSS株Now!みたいにワン株を一括注文しちゃおう!! 【MONELIO(マネリオ)製作記その1】 ~ マネックス証券ワン株で分散テーマ投資を行うエクセルVBAツール ~ | 富士宮で貯蓄と資産運用

MONELIO(マネリオ)計画始動。 少額テーマ投資サイトFOLIOやSBI証券のS株Now!をパクって、エクセルVBAを駆使してマネックス証券ワン株で分散テーマ投資を行うツールを作っちゃおうというのが本企画の趣旨になります...




 今回はシステムCに関わる部分になります。
 マネックス証券にアクセスして、売買後の保有株数や平均取得単価などを取得するプログラムを紹介していきます。

 前回同様に最初に株式保有状況取得のVBAコードを載せて、前回記事との重複部分を省きながら、VBAコードの内容について順を追って紹介していきます。

 またマネックス証券から株価も取得できますので、基本的な運用管理はヤフーファイナンスに接続せずとも行うことができるようになっています。

 なお手抜きになってしまいますが、ヤフーファイナンスから株価を取得するプログラムについては、下記記事を参考にしてもらえればと思います。

エクセルで株価を自動取得するVBAコードを紹介します。(日本株・米国株・投信対応版) | 富士宮で貯蓄と資産運用

株価や投信の基準価額を自動取得できます。証券会社の一覧だと少々見づらいので、自分用にエクセルシートで管理しています。最新株価はボタンをクリックすると、ヤフーファイナンス(日本株・投信)またはグーグルファイナンス(米国株)から自動取得できるようにしています...



保有株式管理用のVBAコードとエクセルシートです。


 まず下画像のように、セルD8から銘柄コード、セルE8・F8から株価、セルG8から取得単価、セルH8から保有株数を配置したシートを用意しておきます。

MONELIO保有株式管理-エクセルシート


 次にコチラが株式保有状況の取得ルーチンです。


'==================================================
'=== 株式保有状況の取得ルーチン ===
'==================================================
Sub CheckStockHold()
Dim objIE As Object, objclass As Object, objlink As Object
Dim sosa_sh As Worksheet
Dim start_code_cell As String
Dim work_code_cell As Range
Dim start_order_cell As String, work_order_cell As String
Dim org_color As Integer, line_num As Integer
Dim start_stock_price_cell As String, start_before_price_cell As String
Dim start_hold_price_cell As String, start_hold_num_cell As String
Dim stock_price As Double, before_price As Double
Dim hold_price As Double, hold_num As Double
Dim tmp_txt As String

' IEを立ち上げてマネックス証券にログイン
If MonexLogin(objIE) = False Then Exit Sub

' 保有残高・口座管理をクリック
Call IELinkClick(objIE, "保有残高・口座管理")
Call IEWait(objIE) 'IEを待機

' 「保有残高・口座管理」画面でない時はログアウトして終了
If H1TagCheck(objIE, "保有残高・口座管理") = False Then
Call MonexLogout(objIE)
Exit Sub
End If

Set sosa_sh = ActiveSheet ' 現在のシートを退避
start_code_cell = "D8" ' セル"D8"から株価コード記載
start_stock_price_cell = "E8" ' セル"E8"から株価記載
start_before_price_cell = "F8" ' セル"F8"から前日株価記載
start_hold_price_cell = "G8" ' セル"G8"から平均取得単価記載
start_hold_num_cell = "H8" ' セル"H8"から保有株数記載

' 銘柄コード記載がなくなるまで繰り返す
line_num = 0
Do While sosa_sh.Range(start_code_cell).Offset(line_num, 0) <> ""
' シートから銘柄コードを取得
Set work_code_cell = sosa_sh.Range(start_code_cell).Offset(line_num, 0)

' 処理銘柄のセルの色番号を一時退避させ黄色に塗る
org_color = work_code_cell.Interior.ColorIndex
work_code_cell.Interior.ColorIndex = 6

stock_price = 0 ' 現在株価をリセット
before_price = 0 ' 前日株価をリセット
hold_price = 0 ' 平均取得単価をリセット
hold_num = 0 ' 保有株数をリセット

' 保有銘柄を上から順番に検索していく
For Each objclass In objIE.document.getElementsBytagName("TR")
' 銘柄コード一致している時
If InStr(objclass.outerHTML, work_code_cell & " -") > 0 Then
' 最新株価を取得
tmp_txt = objclass.getElementsByClassName("num txt-al-r")(0).innerHTML
If IsNumeric(Mid(tmp_txt, 1, InStr(tmp_txt, "<"") - 1)) = True Then
stock_price = CDbl(Mid(tmp_txt, 1, InStr(tmp_txt, "<"") - 1))
End If
' 前日株価を取得
tmp_txt = Right(tmp_txt, Len(tmp_txt) - InStr(tmp_txt, ">"))
before_price = CDbl(Mid(tmp_txt, 1, InStr(tmp_txt, "<") - 1))
If stock_price = 0 Then stock_price = before_price
' 平均取得単価を取得する
tmp_txt = objclass.getElementsByClassName("num txt-al-r")(1).innerText
hold_price = CDbl(tmp_txt)
' 保有株数を取得する
tmp_txt = objclass.getElementsByClassName("num txt-al-r")(2).innerText
hold_num = CDbl(Mid(tmp_txt, 1, InStr(tmp_txt, "株") - 1))

Exit For ' 該当銘柄があった時はループを抜ける
End If
Next
' 現在株価をセルに書き込み
sosa_sh.Range(start_stock_price_cell).Offset(line_num, 0) = stock_price
' 前日株価をセルに書き込み
sosa_sh.Range(start_before_price_cell).Offset(line_num, 0) = before_price
' 平均取得単価をセルに書き込み
sosa_sh.Range(start_hold_price_cell).Offset(line_num, 0) = hold_price
' 保有株数をセルに書き込み
sosa_sh.Range(start_hold_num_cell).Offset(line_num, 0) = hold_num

work_code_cell.Interior.ColorIndex = org_color ' 退避していたセルの色を戻す
line_num = line_num + 1 ' 次の行の銘柄処理へ
Loop

Call MonexLogout(objIE) 'マネックス証券をログアウトしてIEを閉じる
MsgBox ("株式保有状況の読み出しが完了しました")

End Sub

そして購入や取消などの他処理でも共通に使用しているサブルーチン関数です。
こちらは前回紹介したものと同じです。



'--------------------------------------------------
'--- IEを立ち上げてマネックス証券にログインする ---
'--------------------------------------------------
Function MonexLogin(ByRef objIE As Object) As Boolean
Dim loginid As String
Dim password As String

loginid = InputBox("ログインIDを入力して下さい", "ログインID入力")
If loginid = "" Then
MsgBox ("ログインをキャンセルしました")
MonexLogin = False
Exit Function
End If
password = InputBox("パスワードを入力して下さい", "パスワード入力")
If password = "" Then
MsgBox ("ログインをキャンセルしました")
MonexLogin = False
Exit Function
End If

' IEを起動
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True

' マネックス証券に接続
objIE.navigate "https://mst.monex.co.jp/pc/ITS/login/LoginIDPassword.jsp"

Call IEWait(objIE) ' IEを待機

' ログインIDとパスワードを入力
objIE.document.getElementById("loginid").Value = loginid
objIE.document.getElementById("passwd").Value = password
Call WaitFor(1) ' 1秒停止

' ログインボタンをクリック
Call IEButtonClick(objIE, "ログイン")

Call IEWait(objIE) ' IEを待機

' ログイン後のページでないときは終了
If objIE.document.all.tags("title")(0).innerText _
= "ホーム/マネックス証券 取引サイト" Then
MonexLogin = True
Else
MsgBox ("ログインできませんでした")
objIE.Quit
Set objIE = Nothing
MonexLogin = False
End If

End Function


'--------------------------------------------------
'--- マネックス証券をログアウトしてIEを閉じる ---
'--------------------------------------------------
Sub MonexLogout(ByRef objIE As Object)

' ログアウトボタンをクリック
Call IELinkClick(objIE, "ログアウト")
Call IEWait(objIE) 'IEを待機

' IE終了
objIE.Quit
Set objIE = Nothing

End Sub


'--------------------------------------------------
'--- h1タグタイトルを確認する ---
'--------------------------------------------------
Function H1TagCheck(ByRef objIE As Object, ByVal Title As String) As Boolean
If objIE.document.all.tags("h1")(0).innerText = Title Then
H1TagCheck = True
Else
MsgBox ("例外事象が発生しました")
H1TagCheck = False
End If
End Function


'--------------------------------------------------
'--- リンクをクリックする関数 ---
'--------------------------------------------------
Sub IELinkClick(ByRef objIE As Object, ByVal anchorText As String)
Dim objlink As Object

For Each objlink In objIE.document.getElementsBytagName("A")
If objlink.innerText = anchorText Then
objIE.navigate objlink.href
Exit For
End If
Next
End Sub


'--------------------------------------------------
'--- ボタンを押す関数 ---
'--------------------------------------------------
Sub IEButtonClick(ByRef objIE As Object, buttonValue As String)
Dim objInput As Object

For Each objInput In objIE.document.getElementsBytagName("INPUT")
If objInput.Value = buttonValue Then
objInput.Click
Exit For
End If
Next
End Sub


'--------------------------------------------------
'--- IEを待機する関数 ---
'--------------------------------------------------
Sub IEWait(ByRef objIE As Object)
On Error Resume Next
Do While objIE.Busy = True Or objIE.ReadyState <> 4
DoEvents
Loop
Do While objIE.document.ReadyState <> "complete"
DoEvents
Loop
End Sub


'--------------------------------------------------
'--- 指定した秒だけ停止する関数 ---
'--------------------------------------------------
Sub WaitFor(ByVal second As Integer)
Dim futureTime As Date

futureTime = DateAdd("s", second, Now)

While Now < futureTime
DoEvents
Wend
End Sub


株式保有状況取得の流れを説明します。


(1)マネックス証券にログイン。
 マネックス証券ログイン用関数を呼び出しています。
 パスワード不一致などでログインできなかった時はFlaseが返ってくるので、Exit Subで処理を中断します。
    ' IEを立ち上げてマネックス証券にログイン
If MonexLogin(objIE) = False Then Exit Sub
MONELIO一括売却01-ログイン画面



(2)保有残高の画面に遷移。
 20~28行目で「保有残高・口座管理」タブをクリックし、保有残高画面に遷移したことを確認しています。
    ' 保有残高・口座管理をクリック
Call IELinkClick(objIE, "保有残高・口座管理")
Call IEWait(objIE) 'IEを待機

' 「保有残高・口座管理」画面でない時はログアウトして終了
If H1TagCheck(objIE, "保有残高・口座管理") = False Then
Call MonexLogout(objIE)
Exit Sub
End If
MONELIO一括売却02-ホーム画面



(3)保有残高HTML部分の抜き出し
 保有残高のHTMLを見ると銘柄毎にの単位で区切られています。

 例えば僕が保有している桧家ホールディングスを例にすると赤枠で囲った部分が、下のHTMLコードに相当します。

MONELIO保有株式管理-保有残高画面

<tr class="">
<td>
<a class="link-txt" href="/pc/servlet/ITS/info/TransitionSsoForInsight?encodePrm=2luwtj88nejb3peqdsho6mbpvg9rk7a0fldx29ufjmao4lmeqn2urj3uau40ik&attrSrcKey=160a0cb92df7" onclick="return linkCheck()"><strong>桧家ホールディングス</strong></a><br />
1413 -
</td>
<td class="txt-al-c">特定<br />普通預り</td>
<td class="num txt-al-r">2,475<br />2,447<br />
<span class="gain">28</span></td>
<td class="num txt-al-r">2,035</td>
<td class="num txt-al-r">
5株<br />
0株</td>
<td class="num txt-al-r">12,375</td>
<td class="num txt-al-r">
<div id="changeTangenIconDsp[0]">
<div id="minusTangenIconDsp[0]">
</div>
<div id="minusTangenIconHdn[0]">
</div>
<strong><span class="gain">2,200</span><span class="ico-face_01_r"></span></strong>
</div>
<div id="changeTangenIconHdn[0]">
<strong><span class="gain">2,200</span></strong>
</div>
<span id="tangenPLRate[0]" class="gain">21.62%</span>
</td>
<td class="txt-al-c">
<a href="/pc/servlet/ITS/stock/StkHakabuBuyOrder?encodePrm=84kp120prrbh2vcneojz3h35aqrfr08ygqsuq6pi7qzf08m8k0pqm9euxjz2h465ld47niowwvn3mvw&attrSrcKey=160a0cb92df7"
class="btn-cmn-buy_01 btn-ss"
target="_self"><span>買付</span></a><br />
<a href="/pc/servlet/ITS/stock/StkHakabuOrder?encodePrm=84kp120prrbh2vcneojz3h35aqrfr08ygqsuq6pi7qzf08m8k0pqm9euxjz2h465ld47niowwvn3mvw&attrSrcKey=160a0cb92df7"
class="btn-cmn-sell_01 btn-ss s-mt-05"
target="_self"><span>売却</span></a>
</td>
</tr>

 VBAプログラムの53行目にあるgetElementsBytagName("TR")によって、<tr>~</tr>で囲まれた範囲の要素が抜き出されます。
 それをFor Each ~ Inによって<tr>~</tr>の範囲が順次objclassに繰り返し転送され、いずれ上の桧家ホールディングスの情報が書かれた要素も抜き出されることになります。
 For Each objclass In objIE.document.getElementsBytagName("TR")

 保有銘柄単位でobjclassという要素オブジェクトに転送することによって、それ以降objclassに対する処理も保有銘柄単位で行われることになります。



(4)銘柄検索
 次に<tr>~</tr>範囲で抜き出されたHTMLコードから文字列関数InStrを使って銘柄コード一致箇所の有無を確認していきます。
' 銘柄コード一致している時
If InStr(objclass.outerHTML, work_code_cell & " -") > 0 Then

 銘柄コード4桁だけだと単元株なども取得してしまう可能性もあるため、単元未満株に限定するために銘柄コード4桁+スペース+ハイフンの文字列で検索をかけています。



(5)株価の取得
 HTMLコードを見ると、最初の<td class="num txt-al-r">~</td>で囲まれている部分が現在株価前日株価になっています。
    <td class="num txt-al-r">2,475<br />2,447<br />
<span class="gain">28</span></td>
<td class="num txt-al-r">2,035</td>
<td class="num txt-al-r">
5株<br />
0株</td>

 そこでまず57行目で1番目の<td class="num txt-al-r">~</td>で囲まれたHTMLコードを抜き出します。
 innerTextだとタグ部分が削除されて2種類の株価の切り分けができなくなってしまいますので、innerHTMLを使っています。

 次に58~64行目で現在株価と前日株価を取り出して数値化しています。
' 最新株価を取得
tmp_txt = objclass.getElementsByClassName("num txt-al-r")(0).innerHTML
If IsNumeric(Mid(tmp_txt, 1, InStr(tmp_txt, "<"") - 1)) = True Then
stock_price = CDbl(Mid(tmp_txt, 1, InStr(tmp_txt, "<"") - 1))
End If
' 前日株価を取得
tmp_txt = Right(tmp_txt, Len(tmp_txt) - InStr(tmp_txt, ">"))
before_price = CDbl(Mid(tmp_txt, 1, InStr(tmp_txt, "<") - 1))
If stock_price = 0 Then stock_price = before_price

 58行目と64行目のif文は、休日にアクセスすると現在株価が'-'(ハイフン)で示されることの対応です。



(6)取得単価と保有株数の取得
 同様に取得単価は2番目の、保有株数は3番目の<td class="num txt-al-r">~</td>で囲まれています。
    <td class="num txt-al-r">2,475<br />2,447<br />
<span class="gain">28</span></td>
<td class="num txt-al-r">2,035</td>
<td class="num txt-al-r">
5株<br />
0株</td>

それぞれ取り出して数値化しています。
' 平均取得単価を取得する
tmp_txt = objclass.getElementsByClassName("num txt-al-r")(1).innerText
hold_price = CDbl(tmp_txt)
' 保有株数を取得する
tmp_txt = objclass.getElementsByClassName("num txt-al-r")(2).innerText
hold_num = CDbl(Mid(tmp_txt, 1, InStr(tmp_txt, "株") - 1))



(7)ログアウト
 エクセルシートにある全銘柄の処理が完了したらマネックス証券をログアウトします。
    Call MonexLogout(objIE) 'マネックス証券をログアウトしてIEを閉じる
MsgBox ("売り注文が完了しました")
End Sub


次回は・・・


 どうやらマネックス証券はまた正月にシステム変更を行うようです。

 これにより今まで紹介してきたVBAプログラムに変更が生じる可能性が出てくるのではないかと予想しています。

 それらをフォローしたあとに、ここで一旦今まで紹介したVBAプログラムを含んだエクセルファイルをダウンロードできるようにして、取扱説明などを書いておきたいと思ってます。


今日のアイキャッチ画像は。


 「このはな綺譚」から、(ゆず)ちゃんです。


TVアニメ『このはな綺譚』公式サイト

シリーズ開始から9年、『このはな綺譚』が待望のアニメ化!あの世とこの世の間にある温泉宿【此花亭】で働く6人の狐っ子仲居たちが織りなす摩訶不思議な感動綺譚。


 最終回も、女将さんとの時を超えた心温まるエピソードで、見ていて優しい気持ちになれたような気がします。
 最初から最後まで、ちゃんの実直さ可愛らしさが伝わってくる内容でとても良かったです。

 コメディタッチな場面ではキャラが極端にディフォルメ化されることもありましたが、総じて作画もキレイで萌えアニメとしては素晴らしい出来だったと思います。

 最初の頃に比べるとちゃんの表情に色気が出てきて、舌足らずな感じのしゃべり方とのギャップがクセになってしまいました。

 僕も此花亭に泊まってみたいのですが、この世とあの世の間にあるようなので、行ったら帰ってこれないかもしれません。
 そこまでチャレンジするつもりはないので、ちゃんに会えるのはまだ当分先のことになりそうです。

スポンサーサイト
個別株投資ExcelMONELIOこのはな綺譚

0 Comments

Post a comment