Package: tw-stock-plugin
tw-stock-pluginSome util function when doing Taiwan stock web scraping and some common stock data parser.What can tw-stock-plugin do?Getting the newest stock information from the official website.上市上櫃興櫃Getting daily stock trading data from the official website.上市(全)上市(個股)上櫃(全)上櫃(個股)Getting daily stock institutional investors data from the official website.上市上櫃Getting daily stock margin trading data from the official website.上市上櫃Getting p/e ratio, dividend yield and p/b ratio from the official website.上市(全)上市(個股)上櫃(全)上櫃(個股)Getting stock shareholdings data from the official website.上市/上櫃Check if the date is open date in stock market.Convert specific datetime format more easily.NOTEThe following definition of data and variable are all refer to the official website.To avoiding banned by the official website, I recommend that users who use tw-stock-plugin set delay time at least three seconds after calling each function.How To Use:Stock Information"""Attribute:- code: 股票代碼- name: 股票名稱- ISIN_code: 國際證券辨識號碼(ISIN Code)- listed_date: 上市/上櫃/興櫃 日- category: 市場別- industry: 產業別- CFI_code: CFICode- type: 證券類別(股票/ETF...)"""fromtw_stock_pluginimportStockInfo,UpdateStock# update newest stock infoUpdateStock.main()# init stock info objectstock_info=StockInfo()# get all stocks infoprint(stock_info.get())# get 1101 stock infoprint(stock_info.get('1101'))# get 1101 stock nameprint(stock_info.get('1101').name)# get 1101 B stock name, it will return value error because it doesn't existsprint(stock_info.get('1101 B'))Check If The Date Is Open Datefromdatetimeimportdatetimefromtw_stock_pluginimportStockTools# check if 2020/10/10 is open date, it will return Falseprint(StockTools.check_is_open_date(datetime.strptime('2020/10/10','%Y/%m/%d').date()))# check if 2020/10/23 is open date, it will return Trueprint(StockTools.check_is_open_date(datetime.strptime('2020/10/23','%Y/%m/%d').date()))# check if 2020/10/23 is open date, it will type error because it's not type of datetime.timeprint(StockTools.check_is_open_date('2020/03/18'))Converting Date Between Republic Era And Adfromtw_stock_pluginimportStockTools# convert 109/10/10 to ad, it allow Y/m/d and Y-m-d formatprint(StockTools.republic_era_to_ad(date_='109/10/10'))# convert 2020/10/10 to republic era, it allow Y/m/d and Y-m-d formatprint(StockTools.ad_to_republic_era(date_='2020/10/10'))this tool is very useful when crawlingtpexapi.Daily Trading"""You can get all data with specific date or get only single one stock history data.Attribute:- Daily Trading Data- 上市:- code: 股票代碼- name: 股票名稱- trading_volume: 成交股數- transaction: 成交筆數- trade_value: 成交金額- opening_price: 開盤價- highest_price: 最高價- lowest_price: 最低價- closing_price: 收盤價- change: 漲跌價差- last_best_bid_price: 最後揭示買價- last_best_bid_volume: 最後揭示賣價- last_best_ask_price: 最後揭示買量- last_best_ask_volume: 最後揭示買量- price_earning_rate: 本益比- 上櫃:- code: 股票代碼- name: 股票名稱- closing_price: 收盤價- change: 漲跌價差- opening_price: 開盤價- highest_price: 最高價- lowest_price: 最低價- trading_volume: 成交股數- trade_value: 成交金額- transaction: 成交筆數- last_best_bid_price: 最後揭示買價- last_best_ask_price: 最後揭示買量- last_best_bid_volume: 最後揭示賣價- last_best_ask_volume: 最後揭示買量- issued_shares: 發行股數- next_limit_up: 次日漲停價- next_limit_down: 次日跌停價- Monthly Trading Data- 上市:- trading_volume: 成交股數- transaction: 成交筆數- trade_value: 成交金額- opening_price: 開盤價- highest_price: 最高價- lowest_price: 最低價- closing_price: 收盤價- change: 漲跌價差- 上櫃:- closing_price: 收盤價- change: 漲跌價差- opening_price: 開盤價- highest_price: 最高價- lowest_price: 最低價- trading_volume: 成交股數- trade_value: 成交金額- transaction: 成交筆數"""fromdatetimeimportdatetimefromtw_stock_plugin.core.stock_tradingimportStockTrading# setting target datedate_=datetime(2020,10,30).date()# init stock trading object with specific datestock_trading=StockTrading(date_=date_)# getting all trading data in 2020/10/30trading_all=stock_trading.get_all()# getting 2330 trading data in 2020/10/30trading_2330=trading_all['2330']# getting monthly history trading data of 1101 in 2020/10trading_history_1101=stock_trading.get_history(code=1101)# getting monthly history trading data of 9962 in 2020/10trading_history_9962=stock_trading.get_history(code=9962)Institutional Investors"""You can get all data with specific date.Attribute:- code: 股票代碼- name: 股票名稱- foreign_mainland_area_buy: 外陸資買進股數(不含外資自營商)- foreign_mainland_area_sell: 外陸資賣出股數(不含外資自營商)- foreign_mainland_area_diff: 外陸資買賣超股數(不含外資自營商)- foreign_buy: 外資自營商買進股數- foreign_sell: 外資自營商賣出股數- foreign_diff: 外資自營商買賣超股數- trust_buy: 投信買進股數- trust_sell: 投信賣出股數- trust_diff: 投信買賣超股數- proprietary_dealers_buy: 自營商買進股數(自行買賣)- proprietary_dealers_sell: 自營商賣出股數(自行買賣)- proprietary_dealers_diff: 自營商買賣超股數(自行買賣)- hedge_dealers_buy: 自營商買進股數(避險)- hedge_dealers_sell: 自營商賣出股數(避險)- hedge_dealers_diff: 自營商買賣超股數(避險)- total_diff: 三大法人買賣超股數"""fromdatetimeimportdatetimefromtw_stock_plugin.core.stock_institutional_investorsimportStockInstitutionalInvestorsdate_=datetime(2020,11,6).date()# init stock institutional investors object with specific datestock_institutional_investors=StockInstitutionalInvestors(date_=date_)# getting all institutional investors data in 2020/10/30institutional_investors_all=stock_institutional_investors.get_all()# getting 2330 institutional investors data in 2020/10/30institutional_investors_2330=institutional_investors_all['2330']# getting 3529 institutional investors data in 2020/10/30institutional_investors_3529=institutional_investors_all['3529']Margin Trading"""You can get all data with specific date.Attribute:- 上市:- code: 股票代碼- name: 股票名稱- margin_purchase: 融資買進- margin_sells: 融資賣出- cash_redemption: 現金償還- cash_balance_of_previous_day: 前日餘額- cash_balance_of_the_day: 今日餘額- cash_quota: 限額- short_covering: 融券買進- short_sale: 融券賣出- stock_redemption: 現金償還- stock_balance_of_previous_day: 前日餘額- stock_balance_of_the_day: 今日餘額- stock_quota: 限額- offset: 資券互抵- note: 備註- 備註欄說明:O：停止融資X：停止融券@：融資分配%：融券分配!：停止買賣- 上櫃:- code: 股票代碼- name: 股票名稱- cash_balance_of_previous_day: 前日餘額- margin_purchase: 融資買進- margin_sells: 融資賣出- cash_redemption: 現金償還- cash_balance_of_the_day: 今日餘額- cash_belong_to_securities_finance: 資屬證金- cash_utilization_rate(%): 資使用率(%)- cash_quota: 限額- stock_balance_of_previous_day: 前日餘額- short_covering: 融券買進- short_sale: 融券賣出- stock_redemption: 現金償還- stock_balance_of_the_day: 今日餘額- stock_belong_to_securities_finance: 券屬證金- stock_utilization_rate(%): 券使用率(%)- stock_quota: 限額- offset: 資券互抵- note: 備註- 備註欄說明數字(1、2、3…)：合計降低融資比率、提高融券保證金成數O：停止融資X：停止融券@：融資分配%：融券分配!：停止買賣*：融券餘額占融資餘額百分之六十以上者A：股價波動過度劇烈B：股權過度集中C：成交量過度異常D：監視第二次處置數字(1、2、3…)：監視業務督導會報決議降低融資比率、提高融券保證金成數"""fromdatetimeimportdatetimefromtw_stock_plugin.core.stock_margin_tradingimportStockMarginTradingdate_=datetime(2020,11,6).date()# init stock margin trading object with specific datestock_margin_trading=StockMarginTrading(date_=date_)# getting all margin trading data in 2020/10/30margin_trading_all=stock_margin_trading.get_all()# getting 2330 margin trading data in 2020/10/30margin_trading_2330=margin_trading_all['2330']# print 2330 margin purchaseprint(margin_trading_2330.margin_purchase)# print 2330 short coveringprint(margin_trading_2330.short_covering)# getting 3529 margin trading data in 2020/10/30margin_trading_3529=margin_trading_all['3529']# print 3529 margin purchaseprint(margin_trading_3529.margin_purchase)# print 3529 short coveringprint(margin_trading_3529.short_covering)P/E Ratio"""You can get all data with specific date or get only single one stock history data.Attribute:- P/E Ratio Data- 上市:- code: 股票代碼- name: 股票名稱- yield_ratio: 殖利率(%)- dividend_year: 股利年度- per: 本益比- pbr: 股價淨值比- fiscal_year_quarter: 財報年/季- 上櫃:- code: 股票代碼- name: 股票名稱- yield_ratio: 殖利率(%)- dividend_year: 股利年度- per: 本益比- pbr: 股價淨值比- dividend_per_share: 每股股利- Monthly P/E Ratio Data- 上市:- yield_ratio: 殖利率(%)- dividend_year: 股利年度- per: 本益比- pbr: 股價淨值比- fiscal_year_quarter: 財報年/季- 上櫃:- yield_ratio: 殖利率(%)- dividend_year: 股利年度- per: 本益比- pbr: 股價淨值比"""fromdatetimeimportdatetimefromtw_stock_plugin.core.stock_peratioimportStockPERatiodate_=datetime(2020,11,6).date()# init stock p/e ratio, dividend yield and p/b ratio object with specific datestock_p_e_ratio=StockPERatio(date_=date_)# getting all p/e ratio, dividend yield and p/b ratio data in 2020/10/30p_e_ratio_all=stock_p_e_ratio.get_all()# getting 2330 p/e ratio, dividend yield and p/b ratio data in 2020/10/30p_e_ratio_2330=p_e_ratio_all['2330']# print 2330 pbrprint(p_e_ratio_2330.pbr)# print 2330 perprint(p_e_ratio_2330.per)# getting monthly history p/e ratio, dividend yield and p/b ratio data of 1101 in 2020/10p_e_ratio_history_1101=stock_p_e_ratio.get_history(code=1101)# get only 2020/10/30 p/e ratio, dividend yield and p/b ratio dataprint(p_e_ratio_history_1101[date_])# getting monthly history p/e ratio, dividend yield and p/b ratio data data of 9962 in 2020/10p_e_ratio_history_9962=stock_p_e_ratio.get_history(code=9962)# get only 2020/10/30 p/e ratio, dividend yield and p/b ratio data dataprint(p_e_ratio_history_9962[date_])Shareholdings"""You can get newest data or only specific stock data at specific date.Attribute:- date: 日期- code: 股票代碼- index: 序- number_of_shares: 持股/單位數分級- number_of_shareholders: 人數- total_shares: 股數/單位數- percentage_over_total_shares: 占集保庫存數比例 (%)"""fromdatetimeimportdatetimefromtw_stock_plugin.core.stock_shareholdingsimportStockShareholdings# init stock shareholdings objectstock_shareholdings=StockShareholdings()# getting newest shareholdings datashareholdings_newest=stock_shareholdings.get_newest()# getting level 1 of 0050 shareholdings data form latest releaseprint(shareholdings_newest.get('0050')[1])# getting 0050 shareholdings data at 2020/11/6shareholdings_0050=stock_shareholdings.get_by_query(code='0050',date_=datetime(2020,11,6).date())# getting level 15 of 0050 shareholdings data at 2020/11/6print(shareholdings_0050[15])Sample Code# -*- coding: utf-8 -*"""┏┓       ┏┓┏━┛┻━━━━━━━┛┻━┓┃      ☃      ┃┃  ┳┛     ┗┳  ┃┃      ┻      ┃┗━┓         ┏━┛┗┳        ┗━┓┃          ┣┓┃          ┏┛┗┓┓┏━━━━┳┓┏┛┃┫┫    ┃┫┫┗┻┛    ┗┻┛God Bless,Never Bug"""fromdatetimeimportdatetimefromtw_stock_pluginimportStockInfo,StockTrading,StockInstitutionalInvestors,StockMarginTrading,StockPERatio,\StockShareholdings,StockTools,UpdateStockif__name__=='__main__':""" basic info """# init stock info objectstock_info=StockInfo()# get all stocks infoprint(stock_info.get())# get 1101 stock infoprint(stock_info.get('110'))# get 1101 stock nameprint(stock_info.get('1101').name)# get 1101 B stock name, it will return value error because it doesn't existsprint(stock_info.get('1101 B'))# check if 2020/10/10 is open date, it will return Falseprint(StockTools.check_is_open_date(datetime.strptime('2020/10/10','%Y/%m/%d').date()))# check if 2020/10/23 is open date, it will return Trueprint(StockTools.check_is_open_date(datetime.strptime('2020/10/23','%Y/%m/%d').date()))# check if 2020/10/23 is open date, it will type error because it's not type of datetime.timeprint(StockTools.check_is_open_date('2020/03/18'))# convert 109/10/10 to ad, it allow Y/m/d and Y-m-d formatprint(StockTools.republic_era_to_ad(date_='109/10/10'))# convert 2020/10/10 to republic era, it allow Y/m/d and Y-m-d formatprint(StockTools.ad_to_republic_era(date_='2020/10/10'))# setting target datedate_=datetime(2020,10,30).date()""" daily trading """# init stock trading object with specific datestock_trading=StockTrading(date_=date_)# getting all trading data in 2020/10/30trading_all=stock_trading.get_all()# getting 2330 trading data in 2020/10/30trading_2330=trading_all['2330']# print 2330 nameprint(trading_2330.name)# print 2330 codeprint(trading_2330.code)# print 2330 trade_valueprint(trading_2330.trade_value)# print 2330 closing_priceprint(trading_2330.closing_price)# getting monthly history trading data of 1101 in 2020/10trading_history_1101=stock_trading.get_history(code=1101)# get only 2020/10/30 trading dataprint(trading_history_1101[date_])# getting monthly history trading data of 9962 in 2020/10trading_history_9962=stock_trading.get_history(code=9962)# get only 2020/10/30 trading dataprint(trading_history_9962[date_])""" institutional investors """# init stock institutional investors object with specific datestock_institutional_investors=StockInstitutionalInvestors(date_=date_)# getting all institutional investors data in 2020/10/30institutional_investors_all=stock_institutional_investors.get_all()# getting 2330 institutional investors data in 2020/10/30institutional_investors_2330=institutional_investors_all['2330']# print 2330 foreign mainland area buyprint(institutional_investors_2330.foreign_mainland_area_buy)# getting 3529 institutional investors data in 2020/10/30institutional_investors_3529=institutional_investors_all['3529']# print 3529 foreign mainland area buyprint(institutional_investors_3529.trust_diff)""" margin trading """# init stock margin trading object with specific datestock_margin_trading=StockMarginTrading(date_=date_)# getting all margin trading data in 2020/10/30margin_trading_all=stock_margin_trading.get_all()# getting 2330 margin trading data in 2020/10/30margin_trading_2330=margin_trading_all['2330']# print 2330 margin purchaseprint(margin_trading_2330.margin_purchase)# print 2330 short coveringprint(margin_trading_2330.short_covering)# getting 3529 margin trading data in 2020/10/30margin_trading_3529=margin_trading_all['3529']# print 3529 margin purchaseprint(margin_trading_3529.margin_purchase)# print 3529 short coveringprint(margin_trading_3529.short_covering)""" P/E ratio """# init stock p/e ratio, dividend yield and p/b ratio object with specific datestock_p_e_ratio=StockPERatio(date_=date_)# getting all p/e ratio, dividend yield and p/b ratio data in 2020/10/30p_e_ratio_all=stock_p_e_ratio.get_all()# getting 2330 p/e ratio, dividend yield and p/b ratio data in 2020/10/30p_e_ratio_2330=p_e_ratio_all['2330']# print 2330 pbrprint(p_e_ratio_2330.pbr)# print 2330 perprint(p_e_ratio_2330.per)# getting monthly history p/e ratio, dividend yield and p/b ratio data of 1101 in 2020/10p_e_ratio_history_1101=stock_p_e_ratio.get_history(code=1101)# get only 2020/10/30 p/e ratio, dividend yield and p/b ratio dataprint(p_e_ratio_history_1101[date_])# getting monthly history p/e ratio, dividend yield and p/b ratio data data of 9962 in 2020/10p_e_ratio_history_9962=stock_p_e_ratio.get_history(code=9962)# get only 2020/10/30 p/e ratio, dividend yield and p/b ratio data dataprint(p_e_ratio_history_9962[date_])""" shareholdings """# init stock shareholdings objectstock_shareholdings=StockShareholdings()# getting newest shareholdings datashareholdings_newest=stock_shareholdings.get_newest()# getting level 1 of 0050 shareholdings data form latest releaseprint(shareholdings_newest.get('0050')[1])# getting 0050 shareholdings data at 2020/11/6shareholdings_0050=stock_shareholdings.get_by_query(code='0050',date_=datetime(2020,11,6).date())# getting level 15 of 0050 shareholdings data at 2020/11/6print(shareholdings_0050[15])# update newest stock infoUpdateStock.main()Buy me a coffee, if you like it!