システムトレード

楽天マーケットスピードとRSSとの自動起動

ここでは、マーケットスピードとRSSとをできるだけ確実に自動で起動させる方法を記します。
自動売買を行うには、この2つが必要になることが多いですが、これらの自動起動を確実に行おうと思ったら意外と難しいのです。

2009-8-5 mss(Market Speed Shortcut)を利用しない方法に変更。「RSS 接続中」の確認処理を内部化しました。
2009-8-9 メール送信 方法2を追加。

RSS

マーケットスピード

ログイン方法

マーケットスピード8.0を例にします。

マーケットスピードを起動した時に、「総合サマリー」画面に移動し、Enterキーを押すと、ログインウインドウを開くことができます。(参考:楽天RSSの使い方4

「総合サマリー」画面

マーケットスピードの設定

ショートカットキー設定

「総合サマリー」へのショートカットキーを設定します。例では、ALT+F10。

ログインID設定

ログインIDの設定を行います。

起動とログイン (ファイル名:MSSstart.UWS)

表示される可能性のあるダイアログ

ログイン時に表示されるかもしれないダイアログは3つ。表示された場合、OKボタンを押して処理を続行します。

ネットワークに接続できません
「未読の重要なお知らせ」があります。
お知らせがあります。

// 設定
MSNAME = "Market Speed Ver8.0"	// マーケットスピードの名前を設定する。
PassWord = "*****"	//ログイン用パスワードを設定
MSFolderPath = "C:\Program Files\MarketSpeed\MarketSpeed" //MarketSpeed.exeのあるフォルダを設定

// 変数を設定
PUBLIC エラーチェック
エラーチェック = 0	// MSSstart.UWSでは使用しない。

// Market Speedが起動していたら一端終了させる。
IFB GETID(MSNAME) >= 0 THEN
	CTRLWIN(GETID(MSNAME, "MDIFrame"), CLOSE)
	SLEEP(5)
ENDIF

// Market Speedを起動する。
EXEC(MSFolderPath + "\MarketSpeed.exe")

// Market Speedが起動するまでSleepする。
現在時刻秒 = GETTIME(0)
WHILE (GETID(MSNAME) < 0 ) AND (GETTIME(0) < 現在時刻秒 + 60)	//60秒間で中断
	SLEEP(1)
WEND
SLEEP(5)

// ログインする。
CTRLWIN(GETID(MSNAME, "MDIFrame"), ACTIVATE)
SLEEP(1)
SCKEY(GETID(MSNAME, "MDIFrame"), VK_ALT, VK_F10)	// 「総合サマリー」画面に設定したショーカットキーを送る。
SCKEY(GETID(MSNAME, "MDIFrame"), VK_RETURN)
SLEEP(5)
LoginWindow = GETID("Market Speed - ログイン")
SENDSTR(LoginWindow, PassWord)
SLEEP(1)
SCKEY(LoginWindow, VK_RETURN)

// ログインに失敗した場合に備えたログイン処理。(ログインが出来ないのは、サーバが混んでいる時か?)
// Market Speed - ログインの表示は出ており、パスワード入力が出来なかった状態を想定する。
// 未読の重要なお知らせのウインドウを閉じる処理。
現在時刻秒 = GETTIME(0)
WHILE (GETID("Market Speed - ログイン") > 0) AND (GETTIME(0) < 現在時刻秒 + 60)	//60秒間で中断
	id = GETID("Market Speed", "#32770")
	wks = GETSTR(id, 2, STR_STATIC)
	IF POS("ネットワークに接続できません", wks) > 0 THEN CLKITEM(id, "OK", CLK_BTN)
	IF POS("「未読の重要なお知らせ」があります。", wks) > 0 THEN CLKITEM(id, "OK", CLK_BTN)
	IF POS("お知らせがあります。", wks) > 0 THEN CLKITEM(id, "OK", CLK_BTN)

	ID2 = GETID("Market Speed - ログイン")
	IFB ID2 >= 0 THEN
		SENDSTR(ID2, PassWord , 2)
		CLKITEM(ID2, "OK", CLK_BTN)
		SLEEP(2)
	ENDIF
WEND

// RSSを起動する。
EXEC(MSFolderPath + "\RSS.exe")

CALL MSScheck.UWS	// RSSの接続を確認するなら呼び出す。

昼にRSSが一端途切れるのを回避する方法

2009-8-5追記 2009年7月頃から、為替を表示していても、昼に接続が途切れることもあるようになりました。

ツールバーで為替を表示しておくと途切れないようです。為替(USD)は昼も更新されるため。

マーケットスピード ツールバー

環境設定画面 設定方法

昼のRSS切断対策

方法は2つあります。

  • MSSstart.UWSを実行し、マーケットスピードを一端終了させ、ログインする。
    単純で良いと思います。

  • MSSreStart.UWSを実行し、マーケットスピードを終了させることなく、ログアウト→ログインする。
    複雑です。


ログアウト→ログイン(ファイル名:MSSreStart.UWS)

マケスピをログアウト→ログインすることで接続し直す方法を示します。(Excelファイルを閉じて再び開くことでも接続し直す方法があるみたいだ。)

「ログアウトします」のダイアログ

右上のログアウトボタンをクリックし、ログアウトのダイアログを表示させます。「ログアウトします」のダイアログのボタンには、「はい」と「OK」との2種類があります。両方に対応させます。
ログアウトします 2 ログアウトします 1

「ログアウトします」のダイアログが表示されない場合

お客様情報に未読の重要なお知らせがあると、ログインしたときに自動的にお客様情報の画面に変更される。お客様情報が表示されている時にログアウトすると、この「ログアウトします」のダイアログは表示されない。従って、お客様情報に未読が残っている場合に、MSSstart.UWS実行後MSSreStart.UWSを実行するとログアウト・再ログインに成功していても、エラーNo.2となる。これを避けるには、例えばF10に先物OP市況情報を設定し、UWSCでF10のキー操作をマーケットスピードに送り、ログイン後の画面を常に先物OP市況情報にする方法が考えられる。(2008-04-01)

「サーバとの接続が切断されました」のダイアログ

同様に、「サーバとの接続が切断されました」のダイアログのボタンにも、「はい」と「OK」との2種類があります。両方に対応させます。
サーバとの接続が切断されました2 サーバとの接続が切断されました1

また、ONLINE ONLINEの表示の状態のままで、「サーバとの接続が切断されました」ダイアログが表示される時があります。このダイアログの「OK」ボタンを押すと、OFFLINE OFFLINEになります。ただし、サーバとの接続が切断されたのであるから、ONLINEと表示されていても、タスクトレイのRSSアイコンは「接続処理中」になるようです。

MSNAME = "Market Speed Ver8.0"	// マーケットスピードの名前を設定する。
PassWord = "*****"	//ログイン用パスワードを設定

// 変数を設定
PUBLIC エラーチェック
エラーチェック = 0

// ログアウトをし再ログインする。
CTRLWIN(GETID(MSNAME, "MDIFrame"), SHOW)
CTRLWIN(GETID(MSNAME, "MDIFrame"), NORMAL)	//ウインドウが表示されていないと、ログアウト確認などダイアログのボタンのクリックがうまくいかない。
CTRLWIN(GETID(MSNAME, "MDIFrame"), ACTIVATE)
SLEEP(1)
	
ID = GETID("Market Speed", "#32770")
IFB POS("サーバとの接続が切断されました。再ログインが必要です。", GETSTR(ID, 2, 1)) > 0 THEN
	// 例えばプロバイダとの接続を切断して再接続した場合、
	// Market Speedには「サーバとの接続が切断されました。再ログインが必要です。」のダイアログが表示され、
	// OKボタンを押すとログアウトした状態になる。(ルータ再起動で確認)
	CLKITEM(ID, "はい", clk_acc OR CLK_SHORT, TRUE, 1)	// 「はい」「OK」の2種類のダイアログがあるため、それら2つに対応。
	CLKITEM(ID, "OK", clk_acc OR CLK_SHORT, TRUE, 1)
ELSE
	// ログアウトを行う処理。
	// ログアウトボタンをクリックする。
	// 仮に「サーバとの接続が切断されました。再ログインが必要です。」のダイアログが表示されたままの状態で、
	// この処理を行うと、「ログアウトしますか?」のダイアログは表示される。「はい」ボタンも押すことはできる。

	//ウインドウのサイズを取得し、右上からログアウトボタンのある位置をクリックする。
	wNum = GETID(MSNAME, "MDIFrame")
	CTRLWIN( wNum, ACTIVATE)

	xx = STATUS( wNum, ST_X )
	yy = STATUS( wNum, ST_Y )
	width = STATUS( wNum, ST_CLWIDTH )
	// height =  STATUS( wNum, ST_CLHEIGHT )
	BTN(LEFT, CLICK, xx + width - 30, yy + 45, 300)	//「ログアウト」のボタンをクリック。 - 30, + 45はウインドウの右上からの補正した位置。適宜調節が必要。VISTAは + 45, XPのクラシック表示は + 30あたり。
	SLEEP(1)
	
	現在時刻秒 = GETTIME(0)
	WHILE (GETID("ログアウト確認", "#32770") < 0 ) AND (GETTIME(0) < 現在時刻秒 + 60)
		SLEEP(1)
	WEND
	SLEEP(2)

	// この時点で「サーバとの接続が切断されました。再ログインが必要です。」が出る可能性はある。
	// この場合、「ログアウトしますか?」の「はい」ボタンは押せる。(ルータ再起動で確認)

	id = GETID("ログアウト確認", "#32770")
	wks = GETSTR(id, 2, STR_STATIC)
	IFB POS("ログアウトしますか?", wks) > 0 THEN
	CLKITEM(id, "はい", CLK_BTN)
	ELSE
		エラーチェック = 1
	ENDIF
	SLEEP(3)

	// この時点で「サーバとの接続が切断されました。再ログインが必要です。」のダイアログは出る可能性がある。
	// ただし、この場合、「ログアウトしますか?」で「はい」を押しても、「ログアウトします。」のダイアログが出ない。
	// (再ログインが必要です。で、OKボタンを押したら、OFFLINEになるからか?)
	
	現在時刻秒 = GETTIME(0)
	WHILE (GETID("Market Speed", "#32770") < 0 ) AND (GETTIME(0) < 現在時刻秒 + 60)
		SLEEP(1)
	WEND
	SLEEP(3)	// ログアウトしますのOKボタンが押されない場合があるので、ここにSleepを入れてうまくいくかどうかテストする。

	// 「ログアウトします。」のダイアログが表示されているこの時点で
	// 「サーバとの接続が切断されました。再ログインが必要です。」のダイアログは出ないようだ。
	// 「ログアウトします。」で、「はい」を押してOFFLINEになる。

	エラーチェックB = 0
	現在時刻秒 = GETTIME(0)
	WHILE (GETID("Market Speed", "#32770") > 0) AND (GETTIME(0) < 現在時刻秒 + 60)	//60秒間で中断
		id = GETID("Market Speed", "#32770")
		wks = GETSTR(id, 2, STR_STATIC)
		IFB POS("サーバとの接続が切断されました。再ログインが必要です。", wks ) > 0 THEN
			CLKITEM(id, "はい", clk_acc OR CLK_SHORT, TRUE, 1)
			CLKITEM(id, "OK", clk_acc OR CLK_SHORT, TRUE, 1)
			エラーチェックB = 1
			SLEEP(2)
			// OKボタンを押したら、自動的にOFFLINEの状態になる。従って、ログアウトしますダイアログが表示される必要はないようだ。
			// PRINT "「再ログインが必要です」ダイアログが、ログアウト確認以後に表示されました。"
		ENDIF
		IFB POS("ログアウトします。", wks) > 0 THEN
			CLKITEM(id, "はい", clk_acc OR CLK_SHORT, TRUE, 1)	// 「はい」「OK」の2種類のダイアログがあるため、それら2つに対応。
			CLKITEM(id, "OK", CLK_BTN)
			エラーチェックB = 2
			SLEEP(2)
		ENDIF
	WEND
	IF エラーチェックB = 0 THEN エラーチェック = 2
ENDIF

SLEEP(2)

// ログインする。
CTRLWIN(GETID(MSNAME, "MDIFrame"), ACTIVATE)
SLEEP(1)
SCKEY(GETID(MSNAME, "MDIFrame"), VK_ALT, VK_F10)	// 「総合サマリー」画面に設定したショーカットキーを送る。
SCKEY(GETID(MSNAME, "MDIFrame"), VK_RETURN)
SLEEP(5)
LoginWindow = GETID("Market Speed - ログイン")
SENDSTR(LoginWindow, PassWord)
SLEEP(1)
SCKEY(LoginWindow, VK_RETURN)

// ログインに失敗した場合に備えたログイン処理。(ログインが出来ないのは、サーバが混んでいる時か?)
// Market Speed - ログインの表示は出ており、パスワード入力が出来なかった状態を想定する。
// 未読の重要なお知らせのウインドウを閉じる処理。
現在時刻秒 = GETTIME(0)
WHILE (GETID("Market Speed - ログイン") > 0) AND (GETTIME(0) < 現在時刻秒 + 60)	//60秒間で中断
	id = GETID("Market Speed", "#32770")
	wks = GETSTR(id, 2, STR_STATIC)
	IF POS("ネットワークに接続できません", wks) > 0 THEN CLKITEM(id, "OK", CLK_BTN)
	IF POS("「未読の重要なお知らせ」があります。", wks) > 0 THEN CLKITEM(id, "OK", CLK_BTN)
	IF POS("お知らせがあります。", wks) > 0 THEN CLKITEM(id, "OK", CLK_BTN)

	ID2 = GETID("Market Speed - ログイン")
	IFB ID2 >= 0 THEN
		SENDSTR(ID2, PassWord , 2)
		CLKITEM(ID2, "OK", CLK_BTN)
		SLEEP(2)
	ENDIF
WEND

// MSScheck.UWSが処理中の間に再びログイン処理を行うと、
// タスクトレイのアイコンが、「接続処理中」の場合に重なり(と思われる)エラーメールが送信される場合がある。
CALL MSScheck.UWS	// RSSの接続を確認するなら呼び出す。

RSSが接続したかをチェックする(ファイル名:MSScheck.UWS)

コンピュータ名 = DOSCMD("echo %computername%")	//http://www.nagomi-jp.net/~liners/p01.htm

// タスクトレイのチェック
DIM Check = FALSE
FOR i = 0 TO GETITEM(GETID("", "Shell_TrayWnd"), ITM_TOOLBAR) - 1
	//PRINT ALL_ITEM_LIST[i]
	IF ALL_ITEM_LIST[i] = "RSS  接続中" THEN Check = TRUE
NEXT

GETTIME(0)

IFB Check = TRUE AND エラーチェック = 0 THEN
	件名   = コンピュータ名 + "定時確認"
	文書   = コンピュータ名 + "マーケットスピードを起動/再ログインしました<#CR>" + G_TIME_HH2 + "時" + G_TIME_NN2 + "分" + G_TIME_SS2 + "秒"
ELSE
	件名   = コンピュータ名 + "MSS Error"
	文書   = コンピュータ名 + "エラーチェックNo." + エラーチェック + "<#CR>マーケットスピードにログインできませんでした。<#CR>" + G_TIME_HH2 + "時" + G_TIME_NN2 + "分" + G_TIME_SS2 + "秒"
ENDIF

// メール送信
CALL mail.uws
送信元 = "HOGE@FUGA.or.jp"
送信先 = "FUGE@HOGA.or.jp"
sendMail(送信元, 送信先, 件名, 文書)	// mailfrom,mailto,subject,body

EXIT

マーケットスピードにログインしRSSに接続している、ということをできるだけ確実に確認する方法として、色々試したみた上で、タスクトレイのRSSのアイコンのポップアップを利用することにした。画像のように、RSSの接続の状態によってポップアップの内容が変わる。

ポップアップ

通知のカスタマイズで、アイコンを常に表示する設定にして下さい。

常に表示

タスクトレイにあるアイコンのポップアップ文字列の取得

ALL_ITEM_LIST[i]に、タスクトレイのアイコンなどのポップアップの文字列が代入されます。「RSS 接続中」の文字があればログインしたと判断できます。

ただし、昼のMSSreStart.UWSでログアウトに失敗した場合は、RSSの接続が途切れていても「RSS 接続中」と表示される(はず)なので、これを回避するために、ログアウトかログインに失敗した場合、エラーチェック = 1 または 2 または 3にして、処理に失敗したと判断します。

処理結果をメールで送信 方法1

// メール送信には、UWSCでメール送信mail.uws利用します。
mail.uwsMSScheck.UWSと同じフォルダに配置します。

処理結果をメールで送信 方法2

basp21.dllを利用して、メールを送信する方法もあります。
(basp21.dllをWindows VISTA,7 64bitで利用するには設定すれば出来るかもしれませんが、詳細は調べていません。)
basp21.dllをインストールし、次のように、// メール送信以下のスクリプトを変更します。

// basp21.dll を利用して、メールを送信
bobj = CreateOLEObj("basp21")

svname = "mail.example.com"	//通常、SMTPサーバ名
mailfrom = "HOGE@FUGA.or.jp"	//送信元
mailto = "FUGE@HOGA.or.jp"	//送信先
files = ""

output = bobj.SendMail(svname,mailto,mailfrom, 件名,文書,files)

まとめ

私が行っている方法

  1. タスクを使って、8:45頃に、UWSCを起動させます。(Windowsのアクセサリ>システムツール>タスクで設定します。)
  2. UWSCのスケジュール設定から、8:50頃に、MSSstart.UWS を起動し、ログインを行います。
  3. 複数のPCでログイン処理を行うなら、ログイン処理が重ならないように起動時間をずらした方が良いみたいです(検証はしていません)。
  4. 昼の切断に対しては、再ログインすることで対策。

メモ

MSSreStart.UWSを利用したログアウト・再ログインは、エラー処理が複雑なため、これを避け、別の方法として、「一端マーケットスピードを閉じて再起動・ログインを行う」やり方もある。最初は、私もマーケットスピードを閉じ再起動する方法を行っていたが、これは力業な方法でよろしく無いだろうと考えたので、ログアウト・再ログインのスクリプトを作った。しかし、こんなに苦労するとは思わなかった。

以前の解説

履歴

  • 2009-12-31 「処理結果をメールで送信 方法1」をUWSCでメール送信の利用に変更。
  • 2009-11-29 「ログインIDの設定」を追記。
  • 2009-08-14 「表示される可能性のあるダイアログ」を追記。
  • 2009-08-09 メール送信 方法2を追加。スクリプト部分の細かい修正。
  • 2009-08-05 mss(Market Speed Shortcut)を利用しない方法に変更。「RSS 接続中」の確認処理を内部化。UWSCのスクリプトを修正。
  • 2009-03-15 「昼にRSSが一端途切れるのを回避する方法」を追記。
  • 2008-08-12 細かい修正。
  • 2008-04-01 エラーNo.2が発生する場合の条件に追記。
  • 2008-03-28 エラーNo.2が発生する場合の条件を追記。
  • 2007-08-27 「ログアウトします」のダイアログと「サーバとの接続が切断されました」のダイアログとに対応するようにMSSreStart.UWSを変更。
  • 2007-08-17 MSSreStart.UWSの処理の不具合を修正。MSScheck.UWSを変更。
  • 2007-07-02 MSSstart.UWSとMSSreStart.UWSとに、「CTRLWIN(GETID(MSNAME,"MDIFrame"),NORMAL) 」などを追加。
  • 2007-07-01 ログイン状態を確認しメールで送信する処理について掲載。その他大幅に変更。
  • 2007-02-27 UWSCのスクリプトを、マーケットスピード6.0に対応しかつ改善した。
  • 2006-12-12 別所で記載したことを、修正し再掲載