はじめに
以前、楽天証券のマーケットスピードII RSSを使って、市況情報(株価)リスト作成するプログラムをpythonで作りました。
が、パソコンを新しくしたところ、次のようなエラーがよく出るようになりました。
pywintypes.com_error: (-2147418111, '呼び出し先が呼び出しを拒否しました。', None, None)
エクセルとのやり取りでエラーが出ているようでしたので、エラーが出てもプログラムが途中で止まらないように、while文とtry except文を追加しました。
while True:
try:
xl.Cells(no+2, row+2).Formula = "=RssMarket("+str(stock_no)+","+"\""+item+"\")"
break
except pywintypes.com_error:
print("再試行中..")
time.sleep(1)
tryでエラーが出なかった場合、whileを抜け出します。
もしエラーが出たら、1秒待って、再度、tryします。
それでもエラーが出たら、1秒待って、tryというふうにエラーが出なくなるまで繰り返します。
あちこちに、これを入れることによって、最後までエラーを出さないで終わることができました。
プログラムの変更について
株価のリストを作るプログラムを更新しました。
前回より変えたところは、上で示したエラー対策と、RSSで読み取る関数をリストに入れたことです。
また、全銘柄だと数が多すぎるため、プログラムの中で、次のような辞書とif文を入れています。
sel_dic={'PBR':1, '購入可能額':50000, '配当利回り':3} #エクセルにリストとして残す選択条件
if sel_dic['購入可能額']<ws_new.cell(n+2, add_list.index("購入可能額")+2).value:
ws_new.delete_rows(n+2)
elif sel_dic['配当利回り']>ws_new.cell(n+2, add_list.index("配当利回り")+2).value:
ws_new.delete_rows(n+2)
elif sel_dic['PBR']<ws_new.cell(n+2, add_list.index("PBR")+2).value:
ws_new.delete_rows(n+2)
これを使って、PBRが1未満、購入可能額が5万円未満、配当利回りが3%より大きいものを選択したリストを作成しています。
プログラム
プログラムを実行するうえで、次のことが必要ですので、ご注意ください。
- 楽天証券のマーケットスピードIIのログイン
- エクセルの起動とRSSへの接続
#プログラム実行前に次の1~2が必要です
#1. マーケットスピードIIのログイン
#2. エクセルを起動 空白のブックを開く。RSS接続する。
#3. このプログラムを実行する
#4. プログラムが終了するまで待つ
#5. 終了したら、保存されたリストを確認する
#ライブラリのインポート
import win32com.client #RSSへ接続するためのエクセル用
from openpyxl import Workbook #エクセル保存用
import time #時間調整用
import pywintypes
#銘柄収集リスト
rss_list=['銘柄名称','現在日付','現在値','時価総額','単位株数','配当','PER','PBR'] #RSSの関数(例)
cal_list=['購入可能額','配当利回り'] #RSS関数から出た数値を使って計算する
add_list=rss_list+cal_list
sel_dic={'PBR':1, '購入可能額':50000, '配当利回り':3} #エクセルにリストとして残す選択条件
#収集準備
try:
xl = win32com.client.GetObject(Class="Excel.Application") #2 開いている空白のブック
except pywintypes.com_error:
print("エクセルが開いていません。")
xl.Visible=True
#市場コード
start_no=1300 #開始番号
step_no=500 #RSSでは1度に500銘柄まで取得可能のため500
end_no=9999 #終了番号
#エクセルファイルの作成
wb_new=Workbook()
ws_new=wb_new.active
#RSSのタイトル行を記入
xl.Cells(1, 1).value = "市場コード"
for row, item in enumerate(rss_list):
xl.Cells(1, row+2).Value = item
#エクセル表のタイトル作成
ws_new.cell(1, 1).value = "市場コード"
for row, item in enumerate(add_list):
ws_new.cell(1, row+2).value = item
#RSSのデータ取得
n=0
for code_no in range(start_no, end_no, step_no): #500件ずつ繰り返す
xl.Range(xl.Cells(2,1), xl.Cells(step_no+2, len(rss_list)+1)).ClearContents() #表示をクリア
#RSS表読み出し
for no in range(step_no): #500件以下
stock_no=code_no+no
if stock_no<=end_no:
while True:
try:
xl.Cells(no+2, 1).Value = str(stock_no) #銘柄コード 行(no+2) 列(1)
break
except pywintypes.com_error:
print("再試行中..")
time.sleep(1) # エラーが出たら、指定時間(秒)待機して繰り返す
for row, item in enumerate(rss_list):
while True:
try:
xl.Cells(no+2, row+2).Formula = "=RssMarket("+str(stock_no)+","+"\""+item+"\")" #銘柄コード
break
except pywintypes.com_error:
print("再試行中..")
time.sleep(1) # エラーが出たら、指定時間(秒)待機して繰り返す
time.sleep(10) #rss 関数の表示待ち。 時間が短いと表示される前に、次に進んでしまうため。
#エクセル表作成
for no in range(step_no):
stock_no=code_no+no
if stock_no<=end_no:
stock_name=xl.Cells(no+2, rss_list.index("銘柄名称")+2).Value #銘柄が空白かを調べる
if stock_name!="": #空白以外を取り込む
for row in range(len(add_list)):
while True:
try:
ws_new.cell(n+2, row+1).value = xl.Cells(no+2,row+1).Value
break
except pywintypes.com_error:
print("再試行中..")
time.sleep(1) # エラーが出たら、指定時間(秒)待機して繰り返す
ws_new.cell(n+2,add_list.index("購入可能額")+2).value=ws_new.cell(n+2, add_list.index("現在値")+2).value*ws_new.cell(n+2, add_list.index("単位株数")+2).value
try:
ws_new.cell(n+2, add_list.index("配当利回り")+2).value=ws_new.cell(n+2,add_list.index("配当")+2).value/ws_new.cell(n+2, add_list.index("現在値")+2).value*100
except ZeroDivisionError:
ws_new.cell(n+2,add_list.index("配当利回り")+2).value=0
if sel_dic['購入可能額']<ws_new.cell(n+2, add_list.index("購入可能額")+2).value:
ws_new.delete_rows(n+2)
elif sel_dic['配当利回り']>ws_new.cell(n+2, add_list.index("配当利回り")+2).value:
ws_new.delete_rows(n+2)
elif sel_dic['PBR']<ws_new.cell(n+2, add_list.index("PBR")+2).value:
ws_new.delete_rows(n+2)
else:
n=n+1
print(str(int(stock_no/end_no*100))+"%"+"進行中")
#リストを保存 保存先やファイル名は適当に入力してください。
wb_new.save("C:\\○○○○\\銘柄収集.xlsx")
完成表
プログラムを実行すると、次のような表が作成されます。