class DataFeed(object): """ API for using database quotes into application """ def __init__(self, level='debug'): self.stock_db = Client() def quotes(self, tickers, start_date=None, end_date=None, download=False): """ Get a series of quotes Return a list of quotes for the given security from start_date to end-date :param ticker: Ticker symbol of the security to quote. :param start_date: Starting date of quote list as a string or ``Datetime.date`` object. :param end_date: Ending date of quote list as a string or a ``Datetime.date`` object. :returns: List of quotes for the given security and date range """ #NOTE Always retrieve adjusted close ? #TODO Frequency management #TODO No available symbols should be downloaded (with a parameter) if isinstance(tickers, str): tickers = [tickers] df_tmp = dict() for ticker in tickers: symbol = self.guess_name(ticker) log.info('Retrieving {} quotes from database'.format(ticker)) data = self.stock_db.get_quotes(symbol, start_date=start_date, end_date=end_date, dl=download) if data is None: continue index = pd.DatetimeIndex([data[i].Date for i in range(len(data))]) index = index.tz_localize(pytz.utc) #NOTE Symbol or name as columns ? df_tmp[ticker] = pd.Series([data[i].AdjClose for i in range(len(data))], index=index) return pd.DataFrame(df_tmp) def infos(self, ticker): symbol = self.guess_name(ticker) return self.stock_db.get_infos(symbol=symbol) def random_stocks(self, n=5, exchange=None): ''' Return n random stock names from database ''' log.info('Generating {} random stocks'.format(n)) stocks = [] if isinstance(exchange, str): exchange = [exchange] for ex in exchange: stocks.extend(self.stock_db.available_stocks(exchange=ex)) random.shuffle(stocks) if n > len(stocks): log.warning('{} asked symbols but only {} availables'.format(n, len(stocks))) n = len(stocks) return stocks[:n] def get_universe(self, exchange=None, limit=10): ''' Get a set of stocks, as the universe on which we will trade ___________________________________________________________ Parameters exhange: str or list(...) Market(s) to search for stocks limit: int Limit of stocks to provide (big amount can make the simulation a mess) ___________________________________________________________ Return stocks: list(limit | max found) Provide stock list according to specified criteria ''' log.info('Generating stock universe') return self.random_stocks(n=limit, exhange=exchange) def guess_name(self, partial_input): ''' Find the closest math of partial_input in stocks database, and return its symbol ''' match = [name for name in self.stock_db.available_stocks(key='name') if re.match(partial_input, name, re.IGNORECASE) is not None] if not match: log.debug('No matching name, trying symbol list...') match = [name for name in self.stock_db.available_stocks(key='symbol') if re.match(partial_input, name, re.IGNORECASE) is not None] if match: infos = self.stock_db.get_infos(symbol=match[0]) else: return None else: infos = self.stock_db.get_infos(name=match[0]) return infos.Ticker
class DataFeed(object): """ API for using database quotes into application """ def __init__(self, level='debug'): self.stock_db = Client() def quotes(self, tickers, start_date=None, end_date=None, download=False): """ Get a series of quotes Return a list of quotes for the given security from start_date to end-date :param ticker: Ticker symbol of the security to quote. :param start_date: Starting date of quote list as a string or ``Datetime.date`` object. :param end_date: Ending date of quote list as a string or a ``Datetime.date`` object. :returns: List of quotes for the given security and date range """ #NOTE Always retrieve adjusted close ? #TODO Frequency management #TODO No available symbols should be downloaded (with a parameter) if isinstance(tickers, str): tickers = [tickers] df_tmp = dict() for ticker in tickers: symbol = self.guess_name(ticker) log.info('Retrieving {} quotes from database'.format(ticker)) data = self.stock_db.get_quotes(symbol, start_date=start_date, end_date=end_date, dl=download) if data is None: continue index = pd.DatetimeIndex([data[i].Date for i in range(len(data))]) index = index.tz_localize(pytz.utc) #NOTE Symbol or name as columns ? df_tmp[ticker] = pd.Series([data[i].AdjClose for i in range(len(data))], index=index) return pd.DataFrame(df_tmp) def infos(self, ticker): symbol = self.guess_name(ticker) return self.stock_db.get_infos(symbol=symbol) def random_stocks(self, n=5): ''' Return n random stock names from database ''' log.info('Generating {} random stocks'.format(n)) stocks = self.stock_db.available_stocks() random.shuffle(stocks) if n > len(stocks): log.warning('{} asked symbols but only {} availables'.format(n, len(stocks))) n = len(stocks) return stocks[:n] def guess_name(self, partial_input): #NOTE Everything could work with symbols, under this interface ''' Find the closest math of partial_input in stocks database, and return its symbol ''' match = [name for name in self.stock_db.available_stocks(key='name') if re.match(partial_input, name, re.IGNORECASE) is not None] if not match: log.debug('No matching name, trying symbol list...') match = [name for name in self.stock_db.available_stocks(key='symbol') if re.match(partial_input, name, re.IGNORECASE) is not None] if match: infos = self.stock_db.get_infos(symbol=match[0]) else: return partial_input else: infos = self.stock_db.get_infos(name=match[0]) return infos.Ticker