Пример #1
0
def update_db_schema(db_path):
    if QMessageBox().warning(
            None, QApplication.translate('DB', "Database format is outdated"),
            QApplication.translate(
                'DB', "Do you agree to upgrade your data to newer format?"),
            QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
        return LedgerInitError(LedgerInitError.OutdatedDbSchema)

    db = sqlite3.connect(get_dbfilename(db_path))
    cursor = db.cursor()
    try:
        cursor.execute("SELECT value FROM settings WHERE name='SchemaVersion'")
    except:
        return LedgerInitError(LedgerInitError.DbInitFailure)

    schema_version = cursor.fetchone()[0]
    for step in range(schema_version, Setup.TARGET_SCHEMA):
        delta_file = db_path + Setup.UPDATES_PATH + os.sep + Setup.UPDATE_PREFIX + f"{step+1}.sql"
        logging.info(
            f"Applying delta schema {step}->{step+1} from {delta_file}")
        try:
            with open(delta_file) as delta_sql:
                try:
                    cursor.executescript(delta_sql.read())
                except sqlite3.OperationalError as e:
                    return LedgerInitError(LedgerInitError.SQLFailure,
                                           e.args[0])
        except FileNotFoundError:
            return LedgerInitError(LedgerInitError.NoDeltaFile, delta_file)
    db.close()
    return LedgerInitError(LedgerInitError.DbInitSuccess)
Пример #2
0
 def update_db_schema(self, db_path) -> JalDBError:
     if QMessageBox().warning(
             None,
             QApplication.translate('DB', "Database format is outdated"),
             QApplication.translate(
                 'DB',
                 "Do you agree to upgrade your data to newer format?"),
             QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
         return JalDBError(JalDBError.OutdatedDbSchema)
     db = db_connection()
     version = readSQL(
         "SELECT value FROM settings WHERE name='SchemaVersion'")
     try:
         schema_version = int(version)
     except ValueError:
         return JalDBError(JalDBError.DbInitFailure)
     for step in range(schema_version, Setup.TARGET_SCHEMA):
         delta_file = db_path + Setup.UPDATES_PATH + os.sep + Setup.UPDATE_PREFIX + f"{step + 1}.sql"
         logging.info(
             f"Applying delta schema {step}->{step + 1} from {delta_file}")
         error = self.run_sql_script(delta_file)
         if error.code != JalDBError.NoError:
             db.close()
             return error
     return JalDBError(JalDBError.NoError)
Пример #3
0
 def attr_timestamp(xml_element, attr_name, default_value):
     if attr_name not in xml_element.attrib:
         return default_value
     time_str = xml_element.attrib[attr_name]
     try:
         if len(time_str) == 19:  # YYYY-MM-DDTHH:MM:SS
             return int(
                 datetime.strptime(time_str, "%Y-%m-%dT%H:%M:%S").replace(
                     tzinfo=timezone.utc).timestamp())
         if len(time_str) == 15:  # YYYYMMDD;HHMMSS
             return int(
                 datetime.strptime(time_str, "%Y%m%d;%H%M%S").replace(
                     tzinfo=timezone.utc).timestamp())
         elif len(time_str) == 8:  # YYYYMMDD
             return int(
                 datetime.strptime(
                     time_str,
                     "%Y%m%d").replace(tzinfo=timezone.utc).timestamp())
         else:
             return default_value
     except ValueError:
         logging.error(
             QApplication.translate("StatementXML",
                                    "Unsupported date/time format: ") +
             f"{xml_element.attrib[attr_name]}")
         return None
Пример #4
0
 def save(self):
     try:
         self.workbook.close()
     except:
         logging.error(
             QApplication.translate('XLSX', "Can't save report into file ")
             + f"'{self.filename}'")
Пример #5
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
Пример #6
0
    def __init__(self, assets_list, symbol, reg_code=''):
        self.id = None

        # Try to find asset in list first by reg.code, next by symbol and as last resort by alt_symbol if it exists
        if reg_code:
            match = [
                x for x in assets_list
                if ('symbol' in x and 'reg_code' in x) and (
                    x['symbol'] == symbol and x['reg_code'] == reg_code)
            ]
            if match:
                if len(match) == 1:
                    self.id = match[0]['id']
                    return
                else:
                    logging.error(
                        QApplication.translate("OpenBroker",
                                               "Multiple asset match for ") +
                        f"'{symbol}':'{reg_code}'")
                    return
        match = [
            x for x in assets_list if 'symbol' in x and x['symbol'] == symbol
        ]
        if match:
            if len(match) == 1:
                self.id = match[0]['id']
                return
            else:
                logging.error(
                    QApplication.translate("OpenBroker",
                                           "Multiple asset match for ") +
                    f"'{symbol}'")
        match = [
            x for x in assets_list
            if 'alt_symbol' in x and x['alt_symbol'] == symbol
        ]
        if match:
            if len(match) == 1:
                self.id = match[0]['id']
                return
            else:
                logging.error(
                    QApplication.translate("OpenBroker",
                                           "Multiple asset match for ") +
                    f"'{symbol}'")
Пример #7
0
 def __init__(self, exchange):
     self.name = ''
     try:
         self.name = self._exchange_types[exchange]
     except KeyError:
         logging.warning(
             QApplication.translate("OpenBroker",
                                    "Exchange isn't supported: ") +
             f"'{exchange}'")
Пример #8
0
 def __init__(self, asset_type):
     self.type = self.NotSupported
     try:
         self.type = self._asset_types[asset_type]
     except KeyError:
         logging.warning(
             QApplication.translate("OpenBroker",
                                    "Asset type isn't supported: ") +
             f"'{asset_type}'")
Пример #9
0
 def __init__(self, asset_type, subtype):
     self.type = self.NotSupported
     try:
         self.type = self._asset_types[asset_type]
     except KeyError:
         logging.warning(QApplication.translate("IBKR", "Asset type isn't supported: ") + f"'{asset_type}'")
     if self.type == FOF.ASSET_STOCK and subtype:  # distinguish ADR and ETF from stocks
         try:
             self.type = self._asset_types[subtype]
         except KeyError:
             pass
Пример #10
0
 def __init__(self, assets_list, code):
     self.id = None
     match = [x for x in assets_list if x['symbol'] == code and x['type'] == FOF.ASSET_MONEY]
     if match:
         if len(match) == 1:
             self.id = match[0]["id"]
         else:
             logging.error(QApplication.translate("IBKR", "Multiple match for ") + f"{code}")
     else:
         self.id = max([0] + [x['id'] for x in assets_list]) + 1
         currency = {"id": self.id, "type": "money", "symbol": code}
         assets_list.append(currency)
Пример #11
0
def get_country_by_code(country_code):
    if not country_code:
        return 0
    country_id = readSQL("SELECT id FROM countries WHERE code=:code",
                         [(":code", country_code)],
                         check_unique=True)
    if country_id is None:
        country_id = 0
        logging.warning(
            QApplication.translate('DB', "Unknown country code: ") +
            f"'{country_code}'")
    return country_id
Пример #12
0
def update_asset_country(asset_id, country_id):
    old_id = readSQL("SELECT country_id FROM assets WHERE id=:asset_id",
                     [(":asset_id", asset_id)])
    if old_id == country_id:
        return
    _ = executeSQL(
        "UPDATE assets SET country_id=:country_id WHERE id=:asset_id",
        [(":asset_id", asset_id), (":country_id", country_id)])
    if old_id == 0:
        return
    old_country = readSQL("SELECT name FROM countries WHERE id=:country_id",
                          [(":country_id", old_id)])
    new_country = readSQL("SELECT name FROM countries WHERE id=:country_id",
                          [(":country_id", country_id)])
    asset_name = readSQL("SELECT name FROM assets WHERE id=:asset_id",
                         [(":country_id", asset_id)])
    logging.warning(
        QApplication.translate('DB', "Country was changed for asset ") +
        f"{asset_name}: f{old_country} -> {new_country}")
Пример #13
0
def request_url(method, url, params=None, json_params=None):
    session = requests.Session()
    session.headers['User-Agent'] = make_user_agent(url=url)
    if method == "GET":
        response = session.get(url)
    elif method == "POST":
        if params:
            response = session.post(url, data=params)
        elif json_params:
            response = session.post(url, json=json_params)
        else:
            response = session.post(url)
    else:
        raise ValueError("Unknown download method for URL")
    if response.status_code == 200:
        return response.text
    else:
        logging.error(f"URL: {url}" + QApplication.translate('Net', " failed: ")
                      + f"{response.status_code}: {response.text}")
        return ''
Пример #14
0
 def __init__(self, accounts_list, number, currency_ids):
     self.id = None
     account_ids = []
     for currency in currency_ids:
         match = [x for x in accounts_list if x['number'] == number and x['currency'] == currency]
         if match:
             if len(match) == 1:
                 account_ids.append(match[0]["id"])
             else:
                 logging.error(QApplication.translate("IBKR", "Multiple account match for ") + f"{number}")
         else:
             new_id = max([0] + [x['id'] for x in accounts_list]) + 1
             account_ids.append(new_id)
             account = {"id": new_id, "number": number, "currency": currency}
             accounts_list.append(account)
     if account_ids:
         if len(account_ids) == 1:
             self.id = account_ids[0]
         else:
             self.id = account_ids
Пример #15
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
Пример #16
0
 def tr(self, text):
     return QApplication.translate("TaxesRus", text)
Пример #17
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
Пример #18
0
 def tr(self, text):
     return QApplication.translate("IBKR", text)
Пример #19
0
 def tr(self, text):
     return QApplication.translate("Quik", text)
Пример #20
0
Файл: xlsx.py Проект: flmnvd/jal
 def tr(self, text):
     return QApplication.translate("XLSX", text)
Пример #21
0
 def tr(self, text):
     return QApplication.translate("SlipsTaxAPI", text)
Пример #22
0
 def tr(self, text):
     return QApplication.translate("DLSG", text)
Пример #23
0
 def tr(self, text):
     return QApplication.translate("Statement", text)
Пример #24
0
 def tr(self, text):
     return QApplication.translate("JalBackup", text)
Пример #25
0
 def __init__(self, action_type):
     self.type = self.NotSupported
     try:
         self.type = self._corporate_action_types[action_type]
     except KeyError:
         logging.warning(QApplication.translate("IBKR", "Corporate action isn't supported: ") + f"{action_type}")