Esempio n. 1
0
 def get_universe_members(self, universe):
     universes = UniversesDatabase()
     members = universes.get_universe_members(universe)
     return members
Esempio n. 2
0
    def fetch_historical_quotes(self, universe):
        logging.info(f"Fetching historical quotes for universe {universe}.")

        # Instanciate necessary objects
        universe_db = UniversesDatabase()
        tws = Tws()
        contracts_db = ContractsDatabase()
        quotes_db = QuotesDatabase()
        quotes_status_db = QuotesStatusDatabase()
        tools = Tools()

        # Get config constants
        REDOWNLOAD_DAYS = int(get_config_value('quotes', 'redownload_days'))

        # Get universe members
        contract_ids = universe_db.get_universe_members(universe=universe)

        # Setup progress bar
        manager = enlighten.get_manager()
        pbar = manager.counter(total=len(contract_ids),
                               desc="Contracts",
                               unit="contracts")

        exiter = GracefulExiter()

        tws.connect()
        logging.info(f"Connnected to TWS.")

        try:
            for contract_id in contract_ids:

                # Abort, don't process further contracts
                if exiter.exit() or tws.has_error():
                    logging.info("Aborting historical quotes fetching.")
                    break

                # Get contracts data
                filters = {'contract_id': contract_id}
                columns = ['broker_symbol', 'exchange', 'currency']
                contract = contracts_db.get_contracts(
                    filters=filters, return_columns=columns)[0]
                quotes_status = quotes_status_db.get_quotes_status(contract_id)
                logging.info(
                    f"Preparing to fetch hiostorical quotes for {contract['broker_symbol']} on {contract['exchange']}"
                )

                # Calculate length of requested data
                if quotes_status is None:
                    duration_str = "15 Y"
                    quotes_from = date.today()
                    fifteen_years = timedelta(days=5479)
                    quotes_from -= fifteen_years
                    quotes_till = date.today().strftime('%Y-%m-%d')

                elif quotes_status['status_code'] == 1:
                    start_date = (quotes_status['daily_quotes_requested_till'])
                    end_date = date.today().strftime('%Y-%m-%d')
                    ndays = np.busday_count(start_date, end_date)
                    if ndays <= REDOWNLOAD_DAYS:
                        logging.info(
                            f"Existing data is only {ndays} days old. Contract aborted."
                        )
                        pbar.total -= 1
                        pbar.update(incr=0)
                        continue
                    if ndays > 360:
                        logging.info(
                            f"Existing data is already {ndays} days old. Contract aborted."
                        )
                        pbar.total -= 1
                        pbar.update(incr=0)
                        continue
                    ndays += 6
                    duration_str = str(ndays) + ' D'
                    quotes_from = quotes_status['daily_quotes_requested_from']
                    quotes_till = end_date

                else:
                    logging.info("Contract already has error status. Skipped.")
                    pbar.total -= 1
                    pbar.update(incr=0)
                    continue

                # Request quotes from tws
                quotes = tws.download_historical_quotes(
                    contract_id=contract_id,
                    symbol=contract['broker_symbol'],
                    exchange=tools.encode_exchange_ib(contract['exchange']),
                    currency=contract['currency'],
                    duration=duration_str)

                if quotes is not None:
                    # Inserting quotes into database
                    logging.info(f"Storing {len(quotes)} quotes to database.")
                    quotes_db.insert_quotes(quotes=quotes)

                    # Write finished info to contracts database
                    quotes_status_db.insert_quotes_status(
                        contract_id=contract_id,
                        status_code=1,
                        status_text="Successful",
                        daily_quotes_requested_from=quotes_from,
                        daily_quotes_requested_till=quotes_till)

                else:
                    # Write error info to contracts database
                    error_code, error_text = tws.get_contract_error()
                    quotes_status_db.insert_quotes_status(
                        contract_id=contract_id,
                        status_code=error_code,
                        status_text=error_text,
                        daily_quotes_requested_from=None,
                        daily_quotes_requested_till=None)
                pbar.update()

            logging.info(
                f"Finished fetching historical quotes for universe {universe}."
            )

        finally:
            tws.disconnect()
            logging.info(f"Disconnnected from TWS.")