米株Python [3-5] Finvizスクリーニング
こんにちわ!トミィ(@toushi_tommy)です!前回YahooFinanceでのスクリーニング結果を出力する方法を紹介いたしましたが、今回はFinvizでのスクリーニングを出力させてみます。こちらの方がよりパワフルなスクリーニングが出来るように思えます。一度、スクリーニング出力設定を作ってしまうと、次回からはFinvizにアクセスせずに、pythonを実行するだけで表で出力することができます。また有料部分ではありますが、日本の証券会社(楽天証券)で買える商品に絞って出力させることもできますので、是非確認してみてください。(追記:有料部分に、スクリーニング結果をチャートサマリで見ることができるようにコード追加しました)
サークルは無料で運営しております。記事内容も無料です。トミィにジュースでもおごってあげようと思った方は投げ銭いただけると、今後の運営の励みになります。(楽天証券で購入できる銘柄リストへの絞り方コードのみ有料記事にしておりますので、下記をご覧ください。さらにスクリーニング結果をチャートで出力するコードも追記しました)
Finvizでの米国株スクリーニング
ヒートマップで有名なFinvizのサイトはこちらになります。
Finvizと言えば、毎日、毎月などのヒートマップですが、上記のページにアクセスし「Maps」を押すとよく見るこんな画面にになります。
実は、ヒートマップのみでなく、強力なスクリーニング機能があります。「Maps」ボタンの左にある「Screener」を押してみてください。このような画面になると思います。
このフィルター機能を使って、好きな条件で銘柄を探すことができるのですが、まさに色んな項目があります。まず、非常に簡単なスクリーニングですが、Signalメニューのドロップダウンメニューを使います。
例えば、この中から「Top Gainers」を選ぶと昨日の値上がりトップ銘柄が出力されます。いろいろ試してみてください。pythonで出力するには、この時に表示されるURLを使います。これを選んだ時のURLはこんな感じになると思います。
https://finviz.com/screener.ashx?v=111&s=ta_topgainers
このように、自分が見たいスクリーニングのURLを作ってください。さらにパワフルなスクリーニングですが、Signalメニューの下の「Descriptive」「Fundamental」「Technical」「All」から自分が好きな条件を作ってください。
スクリーニング結果のpython出力
それでは、作ったスクリーニング条件を元にpythonで出力してみます。まずは、先ほどの値上がりトップ銘柄を出力してみます。コードはこちらになります。
##############################################
output_dir = '/content/drive/MyDrive/output/'
font_dir = '/content/drive/MyDrive/fonts/'
##############################################
from bs4 import BeautifulSoup
import re
import requests
import pandas as pd
# URL ###################################################
# TOP GAIN
url = 'https://finviz.com/screener.ashx?v=111&s=ta_topgainers'
#########################################################
site = requests.get(url, headers={'User-Agent': 'Custom'})
data = BeautifulSoup(site.text,'html.parser')
da = data.find_all("tr", align="center")
tables = re.findall('<td class="table-top.*</td>', str(da[0]))
names = [re.sub('.*>(.+)</td>.*', r'\1', s) for s in tables]
cntns = re.findall('<a class="screener-link.*</a>', str(da[0]))
contents = [[re.sub('<a .*">(.+)</a>.*', r'\1', s).replace('</span>','').replace('&','&') for s in re.findall('<a .*?</a>', i)] for i in cntns]
df = pd.DataFrame(contents, columns = names)
######################################################
# 表出力
######################################################
from PIL import Image, ImageDraw, ImageFont
import IPython
import os
######################################################
def xycenter(xp, yp, xw, yw, tx, fn):
x,y = draw.textsize(tx,fn)
return xp+(xw-x)/2, yp+(yw-y)/2
######################################################
def adjust_font(txt_data, check_width, fnt_name, max_size):
tmp_font = ImageFont.truetype(fnt_name, max_size)
x_size = draw.textsize(txt_data,tmp_font)[0]
while (check_width-5)<x_size:
max_size-=1
tmp_font = ImageFont.truetype(fnt_name, max_size)
x_size = draw.textsize(txt_data,tmp_font)[0]
return tmp_font
######################################################
jap_font = '/content/drive/MyDrive/module/japanize_matplotlib/fonts/ipaexg.ttf'
japb_font = '/content/drive/MyDrive/module/japanize_matplotlib/fonts/ipaexg.ttf'
jap2_font = font_dir+'meiryo.ttc'
jap2b_font = font_dir+'meiryob.ttc'
if os.path.exists(jap2_font): jap_font = jap2_font
if os.path.exists(jap2b_font): japb_font = jap2b_font
######################################################
# 表の幅を設定
max_font = 14
y_height_hd = 30 # ヘッダ用 縦サイズ
y_height = 30 # 縦サイズ
color_cel = ["Change"] # 出力時に数字に応じて色付け
x_width = {
"No." :40,"Ticker" :80,"Company" :250,
"Sector" :150,"Industry" :200,"Country" :90,"Market Cap" :90,
"P/E" :80,"Price" :80,"Change" :80,"Volume" :120
}
x_default = 80
x_start = 10
y_start = 10
######################################################
x_sum=0
for i in df.columns.to_list():
x_width[i]=x_default if i not in x_width else x_width[i]
x_sum+=x_width[i]
######################################################
im = Image.new('RGB', (x_sum+20, y_height_hd+(len(df))*y_height+20), 'white')
draw = ImageDraw.Draw(im)
outfile = output_dir+'out.png'
xpos = x_start
ypos = y_start
# ヘッダ出力 #####
font_head=ImageFont.truetype(japb_font, max_font)
for i in df.columns.to_list():
draw.rectangle([(xpos, ypos), (xpos+x_width[i], ypos+y_height_hd)], fill=(247, 203, 77), outline=(0,0,0), width=1)
font_head=adjust_font(i,x_width[i],japb_font,max_font)
draw.text((xycenter(xpos,ypos,x_width[i],y_height_hd,i,font_head)),i, (0,0,0),font=font_head)
xpos+=x_width[i]
# データ出力 ####
font_txt=ImageFont.truetype(jap_font, max_font)
ypos+=y_height_hd
for i in range(len(df)):
xpos = x_start
draw.rectangle([(xpos, ypos), (xpos+x_sum, ypos+y_height)], outline=(0,0,0), width=1
, fill=((255,255,255) if i%2 == 0 else (254, 248, 227)))
# データ ####
for j in df.columns.to_list():
font_txt=adjust_font(str(df[j][i]),x_width[j],jap_font,max_font)
draw.rectangle([(xpos, ypos), (xpos+x_width[j], ypos+y_height)], outline=(0,0,0), width=1)
txt_color = (0,0,0) if j not in color_cel else 'red' if str(df[j][i])[:1]=='-' else 'blue'
draw.text((xycenter(xpos,ypos,x_width[j],y_height,str(df[j][i]),font_txt)),str(df[j][i]), txt_color,font=font_txt)
xpos+=x_width[j]
ypos+=y_height
######################################################
# 枠線
draw.rectangle([(x_start, y_start), (xpos, y_start+y_height_hd)], outline='black', width=3)
draw.rectangle([(x_start, y_start), (xpos, ypos)], outline='black', width=3)
im.save(outfile)
IPython.display.Image(outfile)
出力はこのような結果になります。
こちらの部分を変更することで、Finvizにアクセスせずに、簡単にスクリーニング結果を見ることができると思いますので、ご活用ください。
# URL ###################################################
# TOP GAIN
url = 'https://finviz.com/screener.ashx?v=111&s=ta_topgainers'
#########################################################
課題:
新高値を更新した成長・中小型株を出力してみましょう。また、色んな条件を試して出力してみましょう。
例)
url = 'https://finviz.com/screener.ashx?v=111&s=ta_newhigh&f=cap_midunder,fa_epsyoy1_o25,fa_salesqoq_o25&ft=4'
楽天証券で購入できる銘柄に絞る方法
以下、ジュースをおごっていただいた方のみ、コードを公開しております。値上がり率ランキングの場合はこのような出力になります。(実際買える銘柄になるとかなり減りますね・・・)
さらに、スクリーニング結果をチャートで出力するコードも追記しました。このような出力結果になります。(一番最後のコードです)
以下、コード部分です。
ここから先は
¥ 150
サポートいただけますと、うれしいです。より良い記事を書く励みになります!