見出し画像

(文系のPython - 完成版3) ティッカーシンボルを複数入力するだけで成長率、営業利益率、PSR等々を計算し、結果を比較して表示するプログラム

(目的)
銘柄を決めるときの手掛かりとなる指標をYahoo Financeにある決算データをもとに自動で計算しコマンドプロンプトに表示する。
今回は若い銘柄を検討する際に参考になりそうな指標である、成長率(YOY)、営業利益率、営業キャッシュフロー・マージン、R&Dコスト比率、セールス&マーケティング+アドミンコスト比率、PSR、売上高、を比較する。

アウトプットは下記。

(前提条件)
・Pythonをインストールしている
・コマンドプロンプトからpyファイルを呼び出せる
・BeautifulSoupをインストールしている
・Pandasをインストールしている

(今回使うワザ - 除く既出)
・自作関数を独立したpyファイルに保存し使いまわす
・Pandasのデータフレームに一行ずつデータを入れた後、転置する

(やり方)
下準備。コマンドプロンプトから呼び出すファイルの他に、自作関数をファイルmy_module内に格納する。
(今回の例ではコマンドプロンプトから呼び出すファイルのファイル名をSaaSKPIs.pyとしている)

呼び出すファイル(SaaSKPIs.py)の中身。
まず、from xxx import で呼び出すモジュールと呼び出す自作関数を列挙。

from urllib.request import urlopen
from bs4 import BeautifulSoup
from my_module import SaaSfourtyRule
from my_module import getPSR
from my_module import CostStructure
from my_module import getOPCFmargin
from my_module import TotalRevenue

import re
import pandas as pd

次に、比較したい銘柄のティッカーシンボルの入力を促す。doneと入力されたら次へ進む。存在しないティッカーシンボルを入力したらエラー出るかも。

ticklst = []
while True:
    x = input('input Ticker symbol (input \"done\" when you finish):')
    if x == ("done"):
        break
    ticklst.append(x)

print("")

次に、コラム名だけであとは空のデータフレーム(行列みたいなもの)SaaSKPI_dfを作成。

SaaSKPI_df = pd.DataFrame( columns = ['YOY revenue growth', 'Operating Margin', 'Operating Cash Flow margin', 'RDcostRatio', 'SGAcostRatio', 'PSR', 'Revenue'])

次に、下記のforループで自作関数から1~数年分のデータをYahoo Financeから取得。

for x in ticklst:
    OperatingMarginList, YOYrevGrowthList = SaaSfourtyRule.getfourtyRule(x)
    PSR = getPSR.getPSR(x)
    RDcostRatioList, SGAcostRatioList = CostStructure.getCostStructure(x)
    OPCFmarginList= getOPCFmargin.getOPCFmargin(x)
    RevenueList = TotalRevenue.getTotalRevenue(x)

最新年のデータをからのリストlstに追加。

(for x in ticklst: の続き)

    lst = []
    lst.append('{:.2%}'.format(YOYrevGrowthList[-1]))
    lst.append('{:.2%}'.format(OperatingMarginList[-1]))
    lst.append('{:.2%}'.format(OPCFmarginList[-1]))
    lst.append('{:.2%}'.format(RDcostRatioList[-1]))
    lst.append('{:.2%}'.format(SGAcostRatioList[-1]))
    lst.append('{:15,d}'.format(int(PSR)))
    lst.append('{:15,d}'.format(RevenueList[-1]))

こうして作られたリストを、データフレームに行挿入する。

    SaaSKPI_df.loc[x] = lst

forループを抜けたら、行列を転置してprint.

SaaSKPI_df = SaaSKPI_df.T
print(SaaSKPI_df)以下、コード全文。

あとは、フォルダmy_module内に自作関数のファイルを置いて、空の__init__.pyファイルを置いておしまい。

(参考させていただいたURL)

以下コード全文。
まずは自作関数の中身。

#他の関数でも使いまわされている関数

def getfouryeardata(tag):      #繰り返し使うので関数化
    tagx = tag
    periodlist = []
    for x in range(4):      #4回繰り返し(探しあてたtdタグの右4つを取得)
        if tagx.next_sibling == None:
            break
        tagx = tagx.next_sibling
        #print(tagx.span)    #エラーを見つけたときのprint
        if tagx.span:
            try:
                text = int(tagx.span.text.replace(",",""))
            except:
                text = tagx.span.text
            if text == "-":
                text = 0
            periodlist.append(text)
        else:
            periodlist.append(0)
    periodlist.reverse()    # 左から右の時系列に並び替え
    return periodlist
#PSRを返す
from my_module import TotalRevenue
from my_module import MarketCap

def getPSR(x):
    MC = MarketCap.getMarketCap(x)
    revlist = TotalRevenue.getTotalRevenue(x)
    rev = revlist[-1]

    PSR = float(MC)/float(rev)

    return PSR
#成長率と営業利益率を返す。成長率+営業利益率>40%なら赤字でも健全らしい。
#シバタナオキさんのcakes本参照

from urllib.request import urlopen
from bs4 import BeautifulSoup
from my_module import fouryeardata

#import re

def getfourtyRule(x):
    url = "https://sg.finance.yahoo.com/quote/%s/financials" %x

    html = urlopen(url).read()
    soup = BeautifulSoup(html,'html.parser')

    td_tags = soup('td')

    for tag in td_tags:
        try:
            if tag.span.text == "Revenue":
                PeriodList = fouryeardata.getfouryeardata(tag)
        except:
            pass
        try:
            if tag.span.text == "Total revenue":
                RevenueList = fouryeardata.getfouryeardata(tag)
        except:
            pass
        try:
            if tag.span.text == "Net income from continuing ops": #頭文字が大文字になったり小文字になったり・・
                NetIncomeList = fouryeardata.getfouryeardata(tag)
        except:
            pass

    OperatingMarginList = [0 if y ==0 else x/y for x, y in zip(NetIncomeList, RevenueList)]

    YOYrevGrowthList = [0 if r ==0 else (l / r)-1 for l, r in zip(RevenueList[1:], RevenueList)]

    return OperatingMarginList, YOYrevGrowthList
#R&Dコスト率とセールス&マーケティング+アドミンコスト率を返す

from urllib.request import urlopen
from bs4 import BeautifulSoup
from my_module import fouryeardata

def getCostStructure(x):
    url = "https://sg.finance.yahoo.com/quote/%s/financials" %x

    html = urlopen(url).read()
    soup = BeautifulSoup(html,'html.parser')

    td_tags = soup('td')

    for tag in td_tags:
        try:
            if tag.span.text == "Revenue":
                PeriodList = fouryeardata.getfouryeardata(tag)
        except:
            pass
        try:
            if tag.span.text == "Total revenue":
                RevenueList = fouryeardata.getfouryeardata(tag)
        except:
            pass
        try:
            if tag.span.text == "Cost of revenue":
                CostOfSalesList = fouryeardata.getfouryeardata(tag)
        except:
            pass
        try:
            if tag.span.text == "Research development":
                RDcostList = fouryeardata.getfouryeardata(tag)
        except:
            pass
        try:
            if tag.span.text == "Selling general and administrative":
                SGAcostList = fouryeardata.getfouryeardata(tag)
        except:
            pass

    RDcostRatioList = [x/y for x, y in zip(RDcostList, RevenueList)]
    SGAcostRatioList = [x/y for x, y in zip(SGAcostList, RevenueList)]

    return RDcostRatioList, SGAcostRatioList
#営業キャッシュフロー・マージンを返す
from urllib.request import urlopen
from bs4 import BeautifulSoup
from my_module import fouryeardata

def getOPCFmargin(x):
    url = "https://sg.finance.yahoo.com/quote/%s/financials" %x

    html = urlopen(url).read()
    soup = BeautifulSoup(html,'html.parser')

    td_tags = soup('td')

    for tag in td_tags:
        try:
            if tag.span.text == "Total revenue":
                RevenueList = fouryeardata.getfouryeardata(tag)
        except:
            pass

    url = "https://finance.yahoo.com/quote/%s/cash-flow" %x

    html = urlopen(url).read()
    soup = BeautifulSoup(html,'html.parser')

    td_tags = soup('td')

    for tag in td_tags:
        try:
            if tag.span.text == "Total Cash Flow From Operating Activities":
                CFFrmOPList = fouryeardata.getfouryeardata(tag)
        except:
            pass

    OPCFmargin = [0 if y ==0 else x / y for x, y in zip(CFFrmOPList, RevenueList)]

    return OPCFmargin
#売上高を返す
from urllib.request import urlopen
from bs4 import BeautifulSoup
from my_module import fouryeardata

def getTotalRevenue(x):
    url = "https://sg.finance.yahoo.com/quote/%s/financials" %x

    html = urlopen(url).read()
    soup = BeautifulSoup(html,'html.parser')

    td_tags = soup('td')

    for tag in td_tags:
        try:
            if tag.span.text == "Revenue":
                PeriodList = fouryeardata.getfouryeardata(tag)
        except:
            pass
        try:
            if tag.span.text == "Total revenue":
                RevenueList = fouryeardata.getfouryeardata(tag)
        except:
            pass

    return RevenueList

大元のファイル。

#大元のファイル
from urllib.request import urlopen
from bs4 import BeautifulSoup
from my_module import SaaSfourtyRule
from my_module import getPSR
from my_module import CostStructure
from my_module import getOPCFmargin
from my_module import TotalRevenue

import re
import pandas as pd

ticklst = []
while True:
    x = input('input Ticker symbol (input \"done\" when you finish):')
    if x == ("done"):
        break
    ticklst.append(x)

print("")
#print("operating margin + growth (OK if >40%)")
#print(" "*6, "[YOY revenue growth, Operating Margin, PSR, RDcostRatio, SGAcostRatio]")

#40% rule
SaaSKPI_df = pd.DataFrame( columns = ['YOY revenue growth', 'Operating Margin', 'Operating Cash Flow margin', 'RDcostRatio', 'SGAcostRatio', 'PSR', 'Revenue'])

for x in ticklst:
    OperatingMarginList, YOYrevGrowthList = SaaSfourtyRule.getfourtyRule(x)
    PSR = getPSR.getPSR(x)
    RDcostRatioList, SGAcostRatioList = CostStructure.getCostStructure(x)
    OPCFmarginList= getOPCFmargin.getOPCFmargin(x)
    RevenueList = TotalRevenue.getTotalRevenue(x)

    lst = []
    lst.append('{:.2%}'.format(YOYrevGrowthList[-1]))
    lst.append('{:.2%}'.format(OperatingMarginList[-1]))
    lst.append('{:.2%}'.format(OPCFmarginList[-1]))
    lst.append('{:.2%}'.format(RDcostRatioList[-1]))
    lst.append('{:.2%}'.format(SGAcostRatioList[-1]))
    lst.append('{:15,d}'.format(int(PSR)))
    lst.append('{:15,d}'.format(RevenueList[-1]))

    SaaSKPI_df.loc[x] = lst

SaaSKPI_df = SaaSKPI_df.T
print(SaaSKPI_df)
ありがとうございます!褒められるって、うれしいですね。
1

ゆう:D

1986年生まれ / シンガポール在住中

文系のPython

文系の仕事を効率化するためにPythonを扱っています。やっていることは単純作業の自動化です(ネット上にある情報をコマンドプロンプトから操作して取ってくるのが主です)。Pythonで何ができるかに重きを置いているのでコード的には似たような内容を繰り返しています。どうやってコ...
1つ のマガジンに含まれています

コメント1件

http://joytothe-world.info/

スピリチュアルの小説をいくつか書きました。現在valuに申請中。可能性があるかもしれませんね・。スゴイ優待あり
コメントを投稿するには、 ログイン または 会員登録 をする必要があります。