def test_is_digit(self): assert Util.is_digit('1') assert Util.is_digit('-1') assert Util.is_digit('1.1') assert Util.is_digit('1.') assert not Util.is_digit('.1') assert not Util.is_digit(' 1') assert not Util.is_digit('1 ') assert not Util.is_digit('+1') assert not Util.is_digit('.') assert not Util.is_digit('-')
def get_now_price_from_yahoo_stock_detail(html): """Yahooファイナンスの銘柄ページのHTMLから現在株価を取得する""" m = re.search('<td class="stoksPrice">(.+)</td>', html) if m: price = m.group(1).replace(',', '') price = re.sub('\.\d*$', '', price) if Util.is_digit(price): return price return ""
def outstanding_share(self, t, search_row): """発行済株式""" ret = {} for r in t['table']: td_cnt = r.count('<td>') if td_cnt > 0: m = re.search('<td>(.*?)</td>' * td_cnt, r) if m: ttl = self.tag_remove(m.group(1)) if '種類' in ttl: buf = self.norm(self.tag_remove(m.group(3))) if '年' in buf and '月' in buf and '日' in buf: ret['date'] = self.convert_date(buf) if '普通株式' in ttl: try: str_hakkou = self.tag_remove(m.group(3)).replace( ',', '') ret['hutuu_hakkou'] = str_hakkou if not Util.is_digit( str_hakkou) else str( int(str_hakkou.split('.')[0])) mm = re.search('([\d,]+)株', m.group(5)) if mm: str_tan = mm.group(1).replace(',', '') ret['unit'] = str_tan if not Util.is_digit( str_tan) else str(int(str_tan)) else: ret['unit'] = str(1) except: print('outstanding_share: 普通株式 err') if 'date' not in ret or ret['date'] == '-': Log.warn('発行済株式日付不正: {}'.format(search_row['company_name'])) return '-' if 'hutuu_hakkou' not in ret: Log.warn('発行済株式数不正: {}'.format(search_row['company_name'])) return '-' if 'unit' not in ret: Log.warn('発行済株式単元数不正: {}'.format(search_row['company_name'])) return '-' return ret
def get_now_price_from_yahoo_stock_detail(self, cd): """Yahooファイナンスの銘柄ページのHTMLから現在株価を取得する""" html = requests.get(YAHOO_STOCK_DETAIL, {'code': cd}, timeout=15) m = re.search('<td class="stoksPrice">(.+)</td>', html.text) if m: price = m.group(1).replace(',', '') if cd == 'USDJPY': price = re.sub('0000$', '', price) else: price = re.sub('\.\d*$', '', price) if Util.is_digit(price): return price return "-"
def major_shareholders(self, t, search_row): """大株主の状況""" holders, vol_unit = [], '' for r in t['table']: if not vol_unit and self.find_text(r, '所有株式数'): vol_unit = self.tag_remove(r).replace('所有株式数', '') m = re.search( '<td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td>', r) if not m or '住所' in m.group(2): continue holder = self.tag_remove(m.group(1)) holder = re.sub('\(常任代理人.+$', '', holder) vol = self.tag_remove(m.group(3)).replace(',', '') rate = self.tag_remove(m.group(4)).replace(',', '') if Util.is_digit(vol): vol = re.sub('\.\d+$', '', vol) vol = str(int(vol)) if Util.is_digit(rate): rate = str(float(rate)) holders.append([holder, vol, rate]) if 'dec_date' not in t: Log.warn('大株主報告日付不正: {}'.format(search_row['company_name'])) return '-' if not vol_unit: Log.warn('大株主株式数単位不正: {} dec_date, vol_unit: {}'.format( search_row['company_name'], t['dec_date'])) return '-' dec = self.convert_date(t['dec_date']) unit = self.convert_unit(vol_unit) return {'holders': holders, 'date': dec, 'unit': unit}
def run(self, dao: Dao, req): Log.info("Task004 invoked.") tweet_stocks = req['param']['stocks'] tweet_id = req['param']['tweet_id'] for brand in tweet_stocks.values(): if 'ccode' in brand: stock_repos = self.model.find_stock_report_by_ccode(brand['ccode']) if stock_repos: result = MqCaller('Task004').call_wait('Task002', JSON.dumps([brand['ccode']]), timeout=40) p_dic = JSON.loads(result) if not p_dic or not p_dic['prices']: continue price = p_dic['prices'][brand['ccode']] # 現在価格 history = self.model.find_last_price_history(brand['ccode']) # 前日と前々日価格 if price and history: price = price.replace(',', "") repo_tweets = stock_repos['tweets'] for rt in repo_tweets: if rt['id_str'] == tweet_id: Log.debug('price add. price={}, ccode={}, tweet={}', price, stock_repos['ccode'], tweet_id) if Util.is_digit(price): Log.debug("price is digit. price={}, history[0][close]={}".format( price, history[0]['close'])) rt['price'] = int(price) rt['last_price'] = history[0]['close'] rt['last_price_date'] = history[0]['date'] else: Log.debug("price is not digit. price={}".format(price)) rt['price'] = history[0]['close'] rt['last_price'] = history[1]['close'] rt['last_price_date'] = history[1]['date'] self.dao.table('stock_report_pre').update_one( {'ccode': brand['ccode'], 'name': brand['name']}, {"$set": stock_repos}, upsert=True) Log.info("Task004 end.")
def holder_rate_status(self, t, search_row): """所有者別状況""" # gov: 政府及び地方公共団体, fin: 金融機関, sec: 金融商品取引業者, cop: その他法人 # frc: 外国法人, frp: 外国個人, otp:個人その他, tot: 計, lwu: 単元未満株式 col_flg = OrderedDict({ 'gov': False, 'fin': False, 'sec': False, 'cop': False, 'frc': False, 'frp': False, 'otp': False, 'tot': False, 'lwu': False }) ret = { 'gov': [], 'fin': [], 'sec': [], 'cop': [], 'frc': [], 'frp': [], 'otp': [], 'tot': [], 'lwu': [] } reach_kabunushi_su = False for r in t['table']: td_cnt = r.count('<td>') if td_cnt > 0: m = re.search('<td>(.*?)</td>' * td_cnt, r) if m: if not reach_kabunushi_su: for i in range(td_cnt): row = self.tag_remove(m.group(i + 1)).replace( ' ', '') if not col_flg['gov'] and '政府及び地方公共団体' in row: col_flg['gov'] = True if not col_flg['fin'] and '金融機関' in row: col_flg['fin'] = True if not col_flg['sec'] and ('金融商品取扱業者' in row or '金融商品取引業者' in row): col_flg['sec'] = True if not col_flg['cop'] and 'その他の法人' in row: col_flg['cop'] = True if not col_flg['frc'] and '個人以外' in row: col_flg['frc'] = True if not col_flg['frp'] and '個人' == row: col_flg['frp'] = True if not col_flg['otp'] and '個人その他' in row: col_flg['otp'] = True if not col_flg['tot'] and '計' in row: col_flg['tot'] = True if not col_flg['lwu'] and '単元未満株式の状況' in row: col_flg['lwu'] = True if '株主数' in row: reach_kabunushi_su = True break if reach_kabunushi_su: kbn = self.tag_remove(m.group(1)) if re.search(r'所有株式数\s*\(', kbn): ret['unit'] = kbn.replace('所有株式数', '') if '株主数' in kbn or '所有株式数' in kbn or kbn in '所有株式数の割合': row_cnt = 2 for k, v in col_flg.items(): if v: if row_cnt < len(m.groups()): val = self.tag_remove( m.group(row_cnt)).replace(',', '') val = self.norm(val) val = '0' if val == '-' or val == '-' or val == '―' else val if Util.is_digit(val): ret[k].append(str(float(val))) else: ret[k].append(str(0)) row_cnt = row_cnt + 1 if 'dec_date' not in t: Log.warn('所有者別日付不正: {}'.format(search_row['company_name'])) return '-' if 'unit' not in ret: Log.warn('株式単位不正: {}'.format(search_row['company_name'])) return '-' ret['date'] = self.convert_date(t['dec_date']) return ret