def _update_daily_quotation(self, row, stock ): try: row['daycode'] = stock['daycode'] row['change'] = stock['change'] row['volume'] = Utils.to_int(stock['成交股數']) row['deal'] = Utils.to_int(stock['成交筆數']) row['amount'] = Utils.to_int(stock['成交金額']) row['open_price'] = Utils.to_float(stock['開盤價']) row['top_price'] = Utils.to_float(stock['最高價']) row['low_price'] = Utils.to_float(stock['最低價']) row['close_price'] = Utils.to_float(stock['收盤價']) row['final_reveal_buy_price'] = Utils.to_float(stock['最後揭示買價']) row['final_reveal_buy_vol'] = Utils.to_int(stock['最後揭示買量']) row['final_reveal_sell_price'] = Utils.to_float(stock['最後揭示賣價']) row['final_reveal_sell_vol'] = Utils.to_int(stock['最後揭示賣量']) except: raise ValueError('Parsing Error!') #Update StockInfo if this is not found in StockInfo if ( self.stockinfo_get_by_code( stock["證券代號"]) == None ): new_stockinfo = StockInfo() new_stockinfo.market = stock['market'] new_stockinfo.code = stock['證券代號'] new_stockinfo.name = stock['證券名稱'] new_stockinfo.tags = ("UNKNOWN",) self.stockinfo_set(new_stockinfo)
def _update_daily_quotation(self, row, stock): try: row['daycode'] = stock['daycode'] row['change'] = stock['change'] row['volume'] = Utils.to_int(stock['成交股數']) row['deal'] = Utils.to_int(stock['成交筆數']) row['amount'] = Utils.to_int(stock['成交金額']) row['open_price'] = Utils.to_float(stock['開盤價']) row['top_price'] = Utils.to_float(stock['最高價']) row['low_price'] = Utils.to_float(stock['最低價']) row['close_price'] = Utils.to_float(stock['收盤價']) row['final_reveal_buy_price'] = Utils.to_float(stock['最後揭示買價']) row['final_reveal_buy_vol'] = Utils.to_int(stock['最後揭示買量']) row['final_reveal_sell_price'] = Utils.to_float(stock['最後揭示賣價']) row['final_reveal_sell_vol'] = Utils.to_int(stock['最後揭示賣量']) except: raise ValueError('Parsing Error!') #Update StockInfo if this is not found in StockInfo if (self.stockinfo_get_by_code(stock["證券代號"]) == None): new_stockinfo = StockInfo() new_stockinfo.market = stock['market'] new_stockinfo.code = stock['證券代號'] new_stockinfo.name = stock['證券名稱'] new_stockinfo.tags = ("UNKNOWN", ) self.stockinfo_set(new_stockinfo)
def stockinfo_get_by_code(self, stock_code): table = self.tbl_stockinfo enc_stock_code = stock_code.encode(self.encoding, errors="replace") for row in table.where("code == enc_stock_code" ): ret_stockinfo = StockInfo() ret_stockinfo.market = row['market'].decode(self.encoding) ret_stockinfo.code = row['code'].decode(self.encoding) ret_stockinfo.name = row['name'].decode(self.encoding) ret_stockinfo.tags = row['tags'].decode(self.encoding) return ret_stockinfo return None
def stockinfo_get_by_code(self, stock_code): table = self.tbl_stockinfo enc_stock_code = stock_code.encode(self.encoding, errors="replace") for row in table.where("code == enc_stock_code"): ret_stockinfo = StockInfo() ret_stockinfo.market = row['market'].decode(self.encoding) ret_stockinfo.code = row['code'].decode(self.encoding) ret_stockinfo.name = row['name'].decode(self.encoding) ret_stockinfo.tags = row['tags'].decode(self.encoding) return ret_stockinfo return None
def get_stock_info(self, daycode, DEBUG=False ): #0. Return structure ret_stock_info = {} stock_list = [] if daycode.to_int() < self.sincewhen.to_int(): return ret_stock_info #1.Get soup object (1st time) self._config_url_web_format() soup = self._get_bs_obj(daycode) if(soup == None): return ret_stock_info #2. Get option to retrieve stock categories #sect options = soup.select("#sect option") ''' 02 : 食品工業 03 : 塑膠工業 04 : 紡織纖維 05 : 電機機械 06 : 電器電纜 21 : 化學工業 08 : 玻璃陶瓷 10 : 鋼鐵工業 11 : 橡膠工業 14 : 建材營造 15 : 航運業 16 : 觀光事業 17 : 金融業 18 : 貿易百貨 20 : 其他 22 : 生技醫療類 23 : 油電燃氣類 24 : 半導體類 25 : 電腦及週邊類 26 : 光電業類 27 : 通信網路類 28 : 電子零組件類 29 : 電子通路類 30 : 資訊服務類 31 : 其他電子類 32 : 文化創意業 33 : 農業科技業 80 : 管理股票 AA : 受益證券 EE : 上櫃指數股票型基金(ETF) TD : 台灣存託憑證(TDR) WW : 認購售權證 GG : 認股權憑證 BC : 牛證熊證 EW : 所有證券(不含權證、牛熊證) AL : 所有證券 OR : 委託及成交資訊(16:05提供) ''' stock_cat = {} #==> { "01":"水泥工業" } for op in options: if op["value"] in ("AA", "WW", "GG", "BC", "EW","AL","OR",): #exclude categories continue stock_cat[op["value"]] = op.text.strip() #3. Get stock daily quotation (2nd time bs obj) for cat in sorted(stock_cat): #for each category print("List tags " + stock_cat[cat] + "...") self._config_url_print_format(daycode, cat) soup = self._get_bs_obj(daycode) try: fields_name_tr = soup.select("body > table > thead > tr")[1] #body > table > thead > tr:nth-child(2) except: print("table not valid.") continue data_tbody = soup.select("body > table > tbody")[0] #3-1. Parse Table temp_sl = self.parse_table(fields_name_tr, data_tbody ) for stock in temp_sl: stock["cat"] = stock_cat[cat] #3-2. append all to return list stock_list.extend(temp_sl) if(DEBUG==True): break #DEBUG: run only one category,only for debug #4. Prepare to return for stock in stock_list: #fill a stock data code = stock["代號"] name = stock["名稱"] cat = stock["cat"] if code not in ret_stock_info: ret_stock_info[code] = StockInfo() ret_stock_info[code].tags = "" # ret_stock_info[code].market = "TPEX" ret_stock_info[code].code = code ret_stock_info[code].name = name ret_stock_info[code].tags = ret_stock_info[code].tags + "/" + cat #5. Info print("[info] Stock Info (%s): %d stocks done." % (daycode, len(ret_stock_info))) #6 return return ret_stock_info
def get_stock_info(self, daycode, DEBUG=False ): #0. Return structure ret_stock_info = {} stock_list = [] if daycode.to_int() < self.sincewhen.to_int(): return ret_stock_info #1.Get soup object (1st time) self._config_url(daycode) soup = self._get_bs_obj(daycode) if(soup == None): return ret_stock_info #2. Get option to retrieve stock categories options = soup.select("#main-content form select option") ''' "MS":大盤統計資訊 "MS2":委託及成交統計資訊 "ALL":全部 "ALLBUT0999":全部(不含權證、牛熊證、可展延牛熊證) "0049":封閉式基金 "0099P":ETF "019919T":受益證券 "0999":認購權證(不含牛證) "0999P":認售權證(不含熊證) "0999C":牛證(不含可展延牛證) "0999B":熊證(不含可展延熊證) "0999X":可展延牛證 "0999Y":可展延熊證 "0999GA":附認股權特別股 "0999GD":附認股權公司債 "0999G9":認股權憑證 "CB":可轉換公司債 "01":水泥工業 "02":食品工業 "03":塑膠工業 "04":紡織纖維 "05":電機機械 "06":電器電纜 "07":化學生技醫療 "21":化學工業 "22":生技醫療業 "08":玻璃陶瓷 "09":造紙工業 "10":鋼鐵工業 "11":橡膠工業 "12":汽車工業 "13":電子工業 "24":半導體業 "25":電腦及週邊設備業 "26":光電業 "27":通信網路業 "28":電子零組件業 "29":電子通路業 "30":資訊服務業 "31":其他電子業 "14":建材營造 "15":航運業 "16":觀光事業 "17":金融保險 "18":貿易百貨 "9299":存託憑證 "23":油電燃氣業 "19":綜合 "20":其他 ''' stock_cat = {} #==> { "01":"水泥工業" } for op in options: if op["value"] in ("ALL", "ALLBUT0999", "MS", "MS2", "0049","0999","0999P","0999C","0999B", "0999X","0999Y","0999GA","0999GD","0999G9","CB",): #exclude 2 ALLs categories continue stock_cat[op["value"]] = op.text.strip() #3. Get stock daily quotation (2nd time bs obj) for cat in sorted(stock_cat): #for each category print("List tags " + stock_cat[cat] + "...") self._config_url(daycode, cat) soup = self._get_bs_obj(daycode) try: fields_name_tr = soup.select("#main-content table thead tr")[1] # tr:nth-child(2) except: print("table not valid.") continue data_tbody = soup.select("#main-content table tbody")[0] #3-1. Parse Table temp_sl = self.parse_table(fields_name_tr, data_tbody) for stock in temp_sl: stock["cat"] = stock_cat[cat] #3-2. append all to return list stock_list.extend(temp_sl) if(DEBUG==True): break #DEBUG: run only one category,only for debug #4. Prepare to return for stock in stock_list: #fill a stock data code = stock["證券代號"] name = stock["證券名稱"] cat = stock["cat"] if code not in ret_stock_info: ret_stock_info[code] = StockInfo() ret_stock_info[code].tags = "" # ret_stock_info[code].market = "TWSE" ret_stock_info[code].code = code ret_stock_info[code].name = name ret_stock_info[code].tags = ret_stock_info[code].tags + "/" + cat #5. Info print("[info] Stock Info (%s): %d stocks done." % (daycode, len(ret_stock_info))) #6 return return ret_stock_info