Esempio n. 1
0
 def download_instrument(self, inst, **kwargs):
     """
     :param kwargs: 'clean=True' will force delete and re-download all data,
                     otherwise db will be updated with the new data
     """
     clean = kwargs.get('clean', False)
     if not clean:  # if clean is False, but no existing data found - force it to be True
         try:
             tmp_data = Store(self.library, '', inst.bitmex_symbol).get()
         except KeyError:
             clean = True
     if clean:
         self.drop_symbol(inst.bitmex_symbol)
         last_timestamp = None
     else:  # get the last timestamp and contract from the sorted index
         last_index = tmp_data.index[-1]
         last_timestamp = last_index[1].to_pydatetime()
         last_contract = last_index[0]
     c = str(inst.first_contract)
     logger.info('Downloading contracts for instrument: %s' % inst.name)
     while c is not None:
         nrows = self.download_contract(inst, c, start_time=last_timestamp)
         logger.debug('Got %d rows for contract %s' % (nrows, c))
         # keep downloading contracts until nothing is returned by the server for the next one.
         # if not doing a clean re-download, most dataframes for historical contracts will be
         # empty, so add another condition: c < last_contract
         try_next = (nrows > 0) or ((not clean) and
                                    (int(c) < last_contract))
         c = inst.next_contract(c) if try_next else None
     return True
Esempio n. 2
0
 def download_table(self, symbol, start_time=None, price_func=None, store_symbol=None):
     # Get bravado client on first download call
     if self.client is None:
         if self.auth:
             self.client = get_request_client()
         else:
             self.client = SwaggerClient.from_url(SPEC_URI, config=api_config)
     # In general we may need separate symbol strings for storage and to pass to API
     # (as for futures), but they also may be equal (as for currencies)
     if store_symbol is None:
         store_symbol = symbol
     if price_func is None:
         price_func = self._augment_trades
     store = Store(self.library, '', store_symbol)
     df = pd.DataFrame()
     i = 0
     n = 0
     while True:
         try:
             res = pd.DataFrame(self.client.Trade.Trade_getBucketed(count=500, start=i*500,
                                  symbol=symbol, binSize='1d', startTime=start_time).result())
         except bravado.exception.HTTPTooManyRequests:
             logger.info('Requests limit exceeded, sleeping for 5 mins...')
             sleep(300)
             logger.info('Resuming download')
             continue
         if len(res) == 0:
             break
         # keep track of total records count for calling functions to know if we got any data
         n += len(res)
         df = df.append(res)
         # send data to db each 150K rows and empty local df so it won't get too big
         if len(df) > 150000:  # make this number a class property?
             store.write(price_func(df.fillna(value=np.nan)))
             df = pd.DataFrame()
         i += 1
     if len(df) > 0:
         store.write(price_func(df.fillna(value=np.nan)))
     return n
Esempio n. 3
0
def _get_data(library, q_type, database, symbol, **kwargs):
    """
    General method to get quotes data from storage
    :param library: storage library name (usually corresponds to a data provider name)
    :param q_type: one of 'futures' | 'currency' | 'others'
    :param database: local storage database name
    :param symbol: local storage symbol name
    :return: pd.DataFrame or None in case of error
    """
    try:
        return Store(library, q_type, database + '_' + symbol).get()
    except Exception as e:
        logger.warning("Something went wrong on symbol %s_%s request from storage: %s" %
                       (database, symbol, e))
        return None
Esempio n. 4
0
    def download_table(self,
                       q_type,
                       database,
                       symbol,
                       db_symbol=None,
                       **kwargs):
        # symbol name for the DB storage may be different from what we send to quandl API (e.g. for futures)
        if db_symbol is None:
            db_symbol = symbol

        # specify the format function for the table (depends on quotes type)
        formnat_fn = self.quotes_formats[q_type]
        # for some spot prices the data column is specified explicitly in instruments.py
        # in such cases we pass this column to a format function and save it to database as 'close'
        if 'col' in kwargs.keys():
            formnat_fn = partial(formnat_fn, column=kwargs.get('col'))
        # pass currency object to scale the rate values where needed
        if 'currency' in kwargs.keys():
            formnat_fn = partial(formnat_fn, currency=kwargs.get('currency'))
        # pass spot object to apply multiplier on data format
        if 'spot' in kwargs.keys():
            formnat_fn = partial(formnat_fn, spot=kwargs.get('spot'))
        # pass instrument and contract to format futures data
        if 'instrument' in kwargs.keys():
            formnat_fn = partial(formnat_fn,
                                 instrument=kwargs.get('instrument'),
                                 contract=kwargs.get('contract'))

        try:
            data = quandl.get(database + '/' + symbol)
            Store(self.library, q_type,
                  database + '_' + db_symbol).update(formnat_fn(data=data))
            logger.debug('Wrote data for %s/%s' % (database, symbol))
            sleep(self.api_delay)
        except JSONDecodeError:
            logger.warning("JSONDecodeError")
            return False
        except quandl.errors.quandl_error.NotFoundError:
            logger.debug('Symbol %s not found on database %s' %
                         (symbol, database))
            return False
        except quandl.errors.quandl_error.LimitExceededError:
            logger.warning('Quandl API limit exceeded!')
            return False
        except Exception as e:
            logger.warning('Unexpected error occured: %s' % e)
            return False
        return True
Esempio n. 5
0
 def download_currency(self, currency, **kwargs):
     """
     :param currency:  core.trade.Currency object
     :param kwargs: 'clean=True' will force delete and re-download all data,
                     otherwise db will be updated with the new data
     """
     logger.info('Downloading currency data for %s' %
                 currency.bitmex_symbol)
     clean = kwargs.get('clean', False)
     if clean:
         self.drop_symbol(currency.bitmex_symbol)
         last_timestamp = None
     else:  # get the last timestamp and contract from the sorted index
         last_timestamp = Store(
             self.library, '',
             currency.bitmex_symbol).get().index[-1].to_pydatetime()
     n = self.download_table(currency.bitmex_symbol, last_timestamp,
                             self._augment_trades)
     return n > 0
Esempio n. 6
0
 def download_table(self,
                    symbol,
                    start_time=None,
                    price_func=None,
                    store_symbol=None):
     # Get bravado client on first download call
     if self.client is None:
         if self.auth:
             self.client = get_request_client()
         else:
             self.client = SwaggerClient.from_url(SPEC_URI,
                                                  config=api_config)
     # In general we may need separate symbol strings for storage and to pass to API
     # (as for futures), but they also may be equal (as for currencies)
     if store_symbol is None:
         store_symbol = symbol
     if price_func is None:
         price_func = self._augment_trades
     store = Store(self.library, '', store_symbol)
     df = pd.DataFrame()
     i = 0
     n = 0
     while True:
         try:
             res = pd.DataFrame(
                 self.client.Trade.Trade_getBucketed(
                     count=500,
                     start=i * 500,
                     symbol=symbol,
                     binSize='1d',
                     startTime=start_time).result())
         except bravado.exception.HTTPTooManyRequests:
             logger.info('Requests limit exceeded, sleeping for 5 mins...')
             sleep(300)
             logger.info('Resuming download')
             continue
         if len(res) == 0:
             break
         # keep track of total records count for calling functions to know if we got any data
         n += len(res)
         df = df.append(res)
         # send data to db each 150K rows and empty local df so it won't get too big
         if len(df) > 150000:  # make this number a class property?
             store.write(price_func(df.fillna(value=np.nan)))
             df = pd.DataFrame()
         i += 1
     if len(df) > 0:
         store.write(price_func(df.fillna(value=np.nan)))
     return n
Esempio n. 7
0
    def _historical_data_handler(self, msg):
        if int(msg.reqId) not in self.historical_data.keys():
            self.historical_data[int(msg.reqId)] = []

        msg_dict = dict(zip(msg.keys(), msg.values()))
        if msg.close > 0:
            # We've got an incoming history line, save it to a buffer
            self.historical_data[int(msg.reqId)].append(msg_dict)
        else:
            # If msg.close = 0 then we've reached the end of the history. IB sends a zero line to signify the end.
            data = pd.DataFrame(self.historical_data[int(msg.reqId)])
            data['date'] = pd.to_datetime(data['date'], format="%Y%m%d")
            contract = self.historical_data_req_contract[int(msg.reqId)]

            dbg_message = 'Wrote data for symbol %s' % contract.m_symbol
            if contract.m_secType == 'FUT':  # futures
                data = self._format_future(data, contract.m_expiry)
                dbg_message += ', contract %s' % contract.m_expiry
                store_symbol = '_'.join([contract.m_exchange, contract.m_symbol])
                q_type = QuotesType.futures
            elif contract.m_secType == 'CASH':  # currency
                data = self._format_currency(data, contract.currency_object)
                dbg_message += contract.m_currency
                store_symbol = '_'.join([contract.m_exchange, contract.m_symbol + contract.m_currency])
                q_type = QuotesType.currency
            elif contract.m_secType == 'IND':  # indices
                data = self._format_other(data, contract.spot_object)
                dbg_message += ' (index)'
                q_type = QuotesType.others
                store_symbol = '_'.join([contract.m_exchange, contract.m_symbol])
            else:
                raise Exception('Attempt to download data of unsupported secType')

            Store(self.library, q_type, store_symbol).update(data)
            logger.debug(dbg_message)
            self.historical_data_result[int(msg.reqId)] = True
            self.historical_data_event.set()
Esempio n. 8
0
 def drop_symbol(self, q_type, database, symbol, **kwargs):
     Store(self.library, q_type, database + '_' + symbol).delete()
Esempio n. 9
0
 def drop_symbol(self, symbol, database=''):
     store = Store(self.library, database, symbol)
     store.delete()
Esempio n. 10
0
 def drop_symbol(self, q_type, exchange, symbol, **kwargs):
     Store(self.library, q_type, exchange + '_' + symbol).delete()
Esempio n. 11
0
 def drop_symbol(self, symbol, database=''):
     store = Store(self.library, database, symbol)
     store.delete()