Пример #1
0
 def MOEX_find_secid(**kwargs) -> str:
     secid = ''
     data = []
     if 'reg_number' in kwargs:
         url = f"https://iss.moex.com/iss/securities.json?q={kwargs['reg_number']}&iss.meta=off&limit=10"
         asset_data = json.loads(get_web_data(url))
         securities = asset_data['securities']
         columns = securities['columns']
         data = [
             x for x in securities['data']
             if x[columns.index('regnumber')] == kwargs['reg_number']
             or x[columns.index('regnumber')] is None
         ]
     if not data and 'isin' in kwargs:
         url = f"https://iss.moex.com/iss/securities.json?q={kwargs['isin']}&iss.meta=off&limit=10"
         asset_data = json.loads(get_web_data(url))
         securities = asset_data['securities']
         columns = securities['columns']
         data = securities[
             'data']  # take the whole list if we search by isin
     if data:
         if len(data) > 1:
             # remove not traded assets if there are any outdated doubles present
             data = [x for x in data if x[columns.index('is_traded')] == 1]
         if len(data) > 1:  # and then check again
             logging.info(
                 QApplication.translate(
                     "MOEX", "Multiple MOEX assets found for: ") +
                 f"{kwargs}")
             return secid
         asset_data = dict(zip(columns, data[0]))
         secid = asset_data['secid'] if 'secid' in asset_data else ''
     return secid
Пример #2
0
 def CBR_DataReader(self, _asset_id, currency_code, _currency, _isin,
                    start_timestamp, end_timestamp):
     date1 = datetime.utcfromtimestamp(start_timestamp).strftime('%d/%m/%Y')
     # add 1 day to end_timestamp as CBR sets rate are a day ahead
     date2 = (datetime.utcfromtimestamp(end_timestamp) +
              timedelta(days=1)).strftime('%d/%m/%Y')
     try:
         code = str(
             self.CBR_codes.loc[self.CBR_codes["ISO_name"] == currency_code,
                                "CBR_code"].values[0]).strip()
     except IndexError:
         logging.error(
             self.tr("Failed to get CBR data for: " + f"{currency_code}"))
         return None
     url = f"http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1={date1}&date_req2={date2}&VAL_NM_RQ={code}"
     xml_root = xml_tree.fromstring(get_web_data(url))
     rows = []
     for node in xml_root:
         s_date = node.attrib['Date'] if node is not None else None
         s_val = node.find("Value").text if node is not None else None
         rows.append({"Date": s_date, "Rate": s_val})
     data = pd.DataFrame(rows, columns=["Date", "Rate"])
     data['Date'] = pd.to_datetime(data['Date'], format="%d.%m.%Y")
     data['Rate'] = [x.replace(',', '.') for x in data['Rate']]
     data['Rate'] = data['Rate'].astype(float)
     rates = data.set_index("Date")
     return rates
Пример #3
0
 def get_shop_name_by_inn(self, inn):
     if len(inn) != 10 and len(inn) != 12:
         logging.warning(
             self.tr("Incorrect length of INN. Can't get company name."))
         return inn
     region_list = "77,78,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,"\
                   "30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,"\
                   "61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,79,83,86,87,89,91,92,99"
     params = {
         'vyp3CaptchaToken': '',
         'page': '',
         'query': inn,
         'region': region_list,
         'PreventChromeAutocomplete': ''
     }
     token_data = json.loads(
         post_web_data('https://egrul.nalog.ru/', params))
     if 't' not in token_data:
         return inn
     result = json.loads(
         get_web_data('https://egrul.nalog.ru/search-result/' +
                      token_data['t']))
     try:
         return result['rows'][0]['c']  # Return short name if exists
     except:
         pass
     try:
         return result['rows'][0]['n']  # Return long name if exists
     except:
         logging.warning(self.tr("Can't get company name from: ") + result)
         return inn
Пример #4
0
    def MOEX_DataReader(self,
                        asset_id,
                        asset_code,
                        isin,
                        start_timestamp,
                        end_timestamp,
                        update_symbol=True):
        asset = self.MOEX_info(symbol=asset_code, isin=isin, special=True)
        if (asset['engine'] is None) or (asset['market'] is
                                         None) or (asset['board'] is None):
            logging.warning(f"Failed to find {asset_code} on moex.com")
            return None
        if (asset['market'] == 'bonds') and (asset['board'] == 'TQCB'):
            asset_code = isin  # Corporate bonds are quoted by ISIN
        if (asset['market'] == 'shares') and (asset['board'] == 'TQIF'):
            asset_code = isin  # ETFs are quoted by ISIN

        isin = asset['isin'] if 'isin' in asset else ''
        reg_code = asset['reg_code'] if 'reg_code' in asset else ''
        expiry = asset['expiry'] if 'expiry' in asset else 0
        if update_symbol:
            JalDB().update_asset_data(asset_id,
                                      new_isin=isin,
                                      new_reg=reg_code,
                                      expiry=expiry)

        # Get price history
        date1 = datetime.utcfromtimestamp(start_timestamp).strftime('%Y-%m-%d')
        date2 = datetime.utcfromtimestamp(end_timestamp).strftime('%Y-%m-%d')
        url = f"http://iss.moex.com/iss/history/engines/{asset['engine']}/markets/{asset['market']}/" \
              f"boards/{asset['board']}/securities/{asset_code}.xml?from={date1}&till={date2}"
        xml_root = xml_tree.fromstring(get_web_data(url))
        history_rows = xml_root.findall("data[@id='history']/rows/*")
        quotes = []
        for row in history_rows:
            if row.attrib['CLOSE']:
                if 'FACEVALUE' in row.attrib:  # Correction for bonds
                    price = float(row.attrib['CLOSE']) * float(
                        row.attrib['FACEVALUE']) / 100.0
                    quotes.append({
                        "Date": row.attrib['TRADEDATE'],
                        "Close": price
                    })
                else:
                    quotes.append({
                        "Date": row.attrib['TRADEDATE'],
                        "Close": row.attrib['CLOSE']
                    })
        data = pd.DataFrame(quotes, columns=["Date", "Close"])
        data['Date'] = pd.to_datetime(data['Date'], format="%Y-%m-%d")
        data['Close'] = pd.to_numeric(data['Close'])
        close = data.set_index("Date")
        return close
Пример #5
0
 def Yahoo_Downloader(self, _asset_id, asset_code, _currency, _isin,
                      start_timestamp, end_timestamp):
     url = f"https://query1.finance.yahoo.com/v7/finance/download/{asset_code}?" \
           f"period1={start_timestamp}&period2={end_timestamp}&interval=1d&events=history"
     file = StringIO(get_web_data(url))
     try:
         data = pd.read_csv(file)
     except ParserError:
         return None
     data['Date'] = pd.to_datetime(data['Date'], format="%Y-%m-%d")
     data = data.drop(
         columns=['Open', 'High', 'Low', 'Adj Close', 'Volume'])
     close = data.set_index("Date")
     return close
Пример #6
0
 def PrepareRussianCBReader(self):
     rows = []
     try:
         xml_root = xml_tree.fromstring(
             get_web_data("http://www.cbr.ru/scripts/XML_valFull.asp"))
         for node in xml_root:
             code = node.find(
                 "ParentCode").text.strip() if node is not None else None
             iso = node.find(
                 "ISO_Char_Code").text if node is not None else None
             rows.append({"ISO_name": iso, "CBR_code": code})
     except xml_tree.ParseError:
         pass
     self.CBR_codes = pd.DataFrame(rows, columns=["ISO_name", "CBR_code"])
Пример #7
0
 def MOEX_find_secid(**kwargs) -> str:
     secid = ''
     try:
         search_key = kwargs['regcode'] if 'regcode' in kwargs else kwargs[
             'isin']
     except KeyError:
         return secid
     if not search_key:
         return secid
     url = f"https://iss.moex.com/iss/securities.json?q={search_key}&iss.meta=off&limit=10"
     asset_data = json.loads(get_web_data(url))
     securities = asset_data['securities']
     columns = securities['columns']
     if 'regcode' in kwargs:
         # Take only records that have given regnumber to get rid of additional issues
         data = [
             x for x in securities['data']
             if x[columns.index('regnumber')] == search_key
             or x[columns.index('regnumber')] is None
         ]
     else:
         data = securities[
             'data']  # take the whole list if we search by isin
     if data:
         if len(data) > 1:
             # remove not traded assets if there are any outdated doubles present
             data = [x for x in data if x[columns.index('is_traded')] == 1]
         if len(data) > 1:  # and then check again
             logging.info(
                 QApplication.translate(
                     "MOEX", "Multiple MOEX assets found for reg.number: ")
                 + search_key)
             return secid
         asset_data = dict(zip(columns, data[0]))
         secid = asset_data['secid'] if 'secid' in asset_data else ''
     return secid
Пример #8
0
    def MOEX_download_info(asset_code, currency='') -> dict:
        mapping = {
            'SECID': 'symbol',
            'NAME': 'name',
            'SHORTNAME': 'short_name',
            'ISIN': 'isin',
            'REGNUMBER': 'reg_number',
            'FACEVALUE': 'principal',
            'MATDATE': 'expiry',
            'LSTDELDATE': 'expiry',
            'GROUP': 'type'
        }
        asset_type = {
            'stock_shares': PredefinedAsset.Stock,
            'stock_dr': PredefinedAsset.Stock,
            'stock_bonds': PredefinedAsset.Bond,
            'stock_etf': PredefinedAsset.ETF,
            'stock_ppif': PredefinedAsset.ETF,
            'futures_forts': PredefinedAsset.Derivative
        }
        asset = {}
        if not asset_code:
            return asset
        url = f"http://iss.moex.com/iss/securities/{asset_code}.xml"
        xml_root = xml_tree.fromstring(get_web_data(url))
        info_rows = xml_root.findall("data[@id='description']/rows/*")
        boards = xml_root.findall("data[@id='boards']/rows/*")
        if not boards:  # can't find boards -> not traded asset
            return asset
        for info in info_rows:
            asset.update({
                mapping[field]: info.attrib['value']
                for field in mapping if info.attrib['name'] == field
            })
        if 'isin' in asset:
            # replace symbol with short name if we have isin in place of symbol
            asset['symbol'] = asset['short_name'] if asset['symbol'] == asset[
                'isin'] else asset['symbol']
        del asset['short_name']  # drop short name as we won't use it further
        if 'principal' in asset:  # Convert principal into float if possible or drop otherwise
            try:
                asset['principal'] = float(asset['principal'])
            except ValueError:
                del asset['principal']
        if 'expiry' in asset:  # convert YYYY-MM-DD into timestamp
            date_value = datetime.strptime(asset['expiry'], "%Y-%m-%d")
            asset['expiry'] = int(
                date_value.replace(tzinfo=timezone.utc).timestamp())
        try:
            asset['type'] = asset_type[asset['type']]
        except KeyError:
            logging.error(
                QApplication.translate("MOEX",
                                       "Unsupported MOEX security type: ") +
                f"{asset['type']}")
            return {}

        boards_list = [board.attrib for board in boards]
        primary_board = [
            x for x in boards_list
            if "is_primary" in x and x["is_primary"] == '1'
        ]
        if primary_board:
            if currency == 'USD':
                board_id = primary_board[0]['boardid'][:-1] + 'D'
            elif currency == 'EUR':
                board_id = primary_board[0]['boardid'][:-1] + 'E'
            else:
                board_id = primary_board[0]['boardid']
            board = [
                x for x in boards_list
                if "boardid" in x and x["boardid"] == board_id
            ]
            if board:
                asset.update({
                    'engine': board[0]['engine'],
                    'market': board[0]['market'],
                    'board': board[0]['boardid']
                })
        return asset