def asset_id(self, asset_info) -> int: asset = None asset_info = {k: v for k, v in asset_info.items() if v} # drop keys with empty values if 'isin' in asset_info: asset = self._find_in_list(self._data[FOF.ASSETS], 'isin', asset_info['isin']) if asset is None and 'reg_number' in asset_info: asset_data = self._find_in_list(self._data[FOF.ASSETS_DATA], 'reg_number', asset_info['reg_number']) if asset_data is not None: asset = self._find_in_list(self._data[FOF.ASSETS], 'id', asset_data['asset']) if asset is None and 'symbol' in asset_info: symbol = self._find_in_list(self._data[FOF.SYMBOLS], 'symbol', asset_info['symbol']) if symbol is not None: asset = self._find_in_list(self._data[FOF.ASSETS], 'id', symbol['asset']) if 'isin' in asset and 'isin' in asset_info and asset['isin'] != asset_info['isin']: asset = None if asset is None and 'search_online' in asset_info: if asset_info['search_online'] == "MOEX": search_data = {} self._uppend_keys_from(search_data, asset_info, ['isin', 'reg_number']) symbol = QuoteDownloader.MOEX_find_secid(**search_data) if not symbol and 'symbol' in asset_info: symbol = asset_info['symbol'] currency = asset_info['currency'] if 'currency' in asset_info else None # Keep currency asset_info = QuoteDownloader.MOEX_info(symbol=symbol) asset_info['type'] = FOF.convert_predefined_asset_type(asset_info['type']) if currency is not None: asset_info['currency'] = currency asset_info['note'] = "MOEX" return self.asset_id(asset_info) # Call itself once again to cross-check downloaded data if asset is None: if 'should_exist' in asset_info and asset_info['should_exist']: raise Statement_ImportError(self.tr("Can't locate asset in statement data: ") + f"'{asset_info}'") asset_id = max([0] + [x['id'] for x in self._data[FOF.ASSETS]]) + 1 asset = {"id": asset_id} self._uppend_keys_from(asset, asset_info, ['type', 'name', 'isin', 'country']) self._data[FOF.ASSETS].append(asset) if 'symbol' in asset_info: symbol_id = max([0] + [x['id'] for x in self._data[FOF.SYMBOLS]]) + 1 symbol = {"id": symbol_id, "asset": asset_id} self._uppend_keys_from(symbol, asset_info, ['symbol', 'currency', 'note']) self._data[FOF.SYMBOLS].append(symbol) data = {} self._uppend_keys_from(data, asset_info, ['reg_number', 'expiry', 'principal']) if data: data_id = max([0] + [x['id'] for x in self._data[FOF.ASSETS_DATA]]) + 1 data['id'] = data_id data['asset'] = asset_id self._data[FOF.ASSETS_DATA].append(data) else: if 'type' in asset and asset['type'] != FOF.ASSET_MONEY: self.update_asset_data(asset['id'], asset_info) return asset['id']
def test_MOEX_details(): assert QuoteDownloader.MOEX_find_secid(regcode='') == '' assert QuoteDownloader.MOEX_find_secid(isin='TEST') == '' assert QuoteDownloader.MOEX_find_secid(regcode='2770') == 'RU000A1013V9' assert QuoteDownloader.MOEX_find_secid(regcode='1-01-00010-A') == 'AFLT' assert QuoteDownloader.MOEX_find_secid(isin='IE00B8XB7377') == 'FXGD' assert QuoteDownloader.MOEX_find_secid(isin='JE00B6T5S470') == 'POLY' assert QuoteDownloader.MOEX_find_secid( isin='RU000A1038V6') == 'SU26238RMFS4' assert QuoteDownloader.MOEX_info() == {} assert QuoteDownloader.MOEX_info(special=True) == {} assert QuoteDownloader.MOEX_info(symbol='AFLT', special=True) == { 'symbol': 'AFLT', 'isin': 'RU0009062285', 'name': 'Аэрофлот-росс.авиалин(ПАО)ао', 'principal': 1.0, 'reg_code': '1-01-00010-A', 'engine': 'stock', 'market': 'shares', 'board': 'TQBR', 'type': PredefinedAsset.Stock } assert QuoteDownloader.MOEX_info(isin='RU000A0JWUE9', special=True) == { 'symbol': 'СберБ БО37', 'isin': 'RU000A0JWUE9', 'name': 'Сбербанк ПАО БО-37', 'principal': 1000.0, 'reg_code': '4B023701481B', 'expiry': 1632960000, 'engine': 'stock', 'market': 'bonds', 'board': 'TQCB', 'type': PredefinedAsset.Bond } assert QuoteDownloader.MOEX_info(symbol='SiZ1', isin='', special=True) == { 'symbol': 'SiZ1', 'name': 'Фьючерсный контракт Si-12.21', 'expiry': 1639612800, 'engine': 'futures', 'market': 'forts', 'board': 'RFUD', 'type': PredefinedAsset.Derivative } assert QuoteDownloader.MOEX_info(symbol='', regnumber='2770') == { 'symbol': 'ЗПИФ ПНК', 'isin': 'RU000A1013V9', 'name': 'ЗПИФ Фонд ПНК-Рентал', 'reg_code': '2770', 'type': PredefinedAsset.ETF } assert QuoteDownloader.MOEX_info(isin='IE00B8XB7377', regnumber='IE00B8XB7377', symbol='FXGD ETF') == { 'symbol': 'FXGD', 'isin': 'IE00B8XB7377', 'name': 'FinEx Gold ETF USD', 'type': PredefinedAsset.ETF } assert QuoteDownloader.MOEX_info(isin='JE00B6T5S470', regnumber='', symbol='') == { 'symbol': 'POLY', 'isin': 'JE00B6T5S470', 'name': 'Polymetal International plc', 'type': PredefinedAsset.Stock } assert QuoteDownloader.MOEX_info(isin='RU000A1038V6') == { 'symbol': 'SU26238RMFS4', 'isin': 'RU000A1038V6', 'name': 'ОФЗ-ПД 26238 15/05/2041', 'principal': 1000.0, 'reg_code': '26238RMFS', 'expiry': 2252188800, 'type': PredefinedAsset.Bond }