def bdh(tickers, flds=None, start_date=None, end_date='today', adjust=None, **kwargs) -> pd.DataFrame: """ Bloomberg historical data Args: tickers: ticker(s) flds: field(s) start_date: start date end_date: end date - default today adjust: `all`, `dvd`, `normal`, `abn` (=abnormal), `split`, `-` or None exact match of above words will adjust for corresponding events Case 0: `-` no adjustment for dividend or split Case 1: `dvd` or `normal|abn` will adjust for all dividends except splits Case 2: `adjust` will adjust for splits and ignore all dividends Case 3: `all` == `dvd|split` == adjust for all Case 4: None == Bloomberg default OR use kwargs **kwargs: overrides Returns: pd.DataFrame """ logger = logs.get_logger(bdh, **kwargs) if flds is None: flds = ['Last_Price'] e_dt = utils.fmt_dt(end_date, fmt='%Y%m%d') if start_date is None: start_date = pd.Timestamp(e_dt) - pd.Timedelta(weeks=8) s_dt = utils.fmt_dt(start_date, fmt='%Y%m%d') request = process.create_request( service='//blp/refdata', request='HistoricalDataRequest', **kwargs, ) process.init_request(request=request, tickers=tickers, flds=flds, start_date=s_dt, end_date=e_dt, adjust=adjust, **kwargs) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request, **kwargs) res = pd.DataFrame(process.rec_events(process.process_hist, **kwargs)) if kwargs.get('raw', False): return res if res.empty or any(fld not in res for fld in ['ticker', 'date']): return pd.DataFrame() return (res.set_index(['ticker', 'date']).unstack(level=0).rename_axis( index=None, columns=[None, None]).swaplevel( 0, 1, axis=1).reindex(columns=utils.flatten(tickers), level=0).reindex(columns=utils.flatten(flds), level=1))
def beqs(screen, asof=None, typ='PRIVATE', group='General', **kwargs) -> pd.DataFrame: """ Bloomberg equity screening Args: screen: screen name asof: as of date typ: GLOBAL/B (Bloomberg) or PRIVATE/C (Custom, default) group: group name if screen is organized into groups Returns: pd.DataFrame """ logger = logs.get_logger(beqs, **kwargs) service = conn.bbg_service(service='//blp/refdata', **kwargs) request = service.createRequest('BeqsRequest') request.set('screenName', screen) request.set('screenType', 'GLOBAL' if typ[0].upper() in ['G', 'B'] else 'PRIVATE') request.set('Group', group) if asof: overrides = request.getElement('overrides') ovrd = overrides.appendElement() ovrd.setElement('fieldId', 'PiTDate') ovrd.setElement('value', utils.fmt_dt(asof, '%Y%m%d')) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request, **kwargs) res = pd.DataFrame(process.rec_events(func=process.process_ref, **kwargs)) if res.empty: if kwargs.get('trial', 0): return pd.DataFrame() else: return beqs(screen=screen, asof=asof, typ=typ, group=group, trial=1, **kwargs) if kwargs.get('raw', False): return res cols = res.field.unique() return (res.set_index(['ticker', 'field']).unstack(level=1).rename_axis( index=None, columns=[None, None ]).droplevel(axis=1, level=0).loc[:, cols].pipe(pipeline.standard_cols))
def bds(tickers, flds, **kwargs) -> pd.DataFrame: """ Bloomberg block data Args: tickers: ticker(s) flds: field **kwargs: other overrides for query Returns: pd.DataFrame: block data """ logger = logs.get_logger(bds, **kwargs) service = conn.bbg_service(service='//blp/refdata', **kwargs) request = service.createRequest('ReferenceDataRequest') if isinstance(tickers, str): data_file = storage.ref_file(ticker=tickers, fld=flds, has_date=True, ext='pkl', **kwargs) if files.exists(data_file): logger.debug(f'Loading Bloomberg data from: {data_file}') return pd.DataFrame(pd.read_pickle(data_file)) process.init_request(request=request, tickers=tickers, flds=flds, **kwargs) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request, **kwargs) res = pd.DataFrame( process.rec_events(func=process.process_ref, **kwargs)) if kwargs.get('raw', False): return res if res.empty or any(fld not in res for fld in ['ticker', 'field']): return pd.DataFrame() data = (res.set_index(['ticker', 'field']).droplevel( axis=0, level=1).rename_axis(index=None).pipe( pipeline.standard_cols, col_maps=kwargs.get('col_maps', None))) if data_file: logger.debug(f'Saving Bloomberg data to: {data_file}') files.create_folder(data_file, is_file=True) data.to_pickle(data_file) return data return pd.DataFrame( pd.concat( [bds(tickers=ticker, flds=flds, **kwargs) for ticker in tickers], sort=False))
def _bds_( ticker: str, fld: str, logger: logs.logging.Logger, use_port: bool = False, **kwargs, ) -> pd.DataFrame: """ Get data of BDS of single ticker """ if 'has_date' not in kwargs: kwargs['has_date'] = True data_file = storage.ref_file(ticker=ticker, fld=fld, ext='pkl', **kwargs) if files.exists(data_file): logger.debug(f'Loading Bloomberg data from: {data_file}') return pd.DataFrame(pd.read_pickle(data_file)) request = process.create_request( service='//blp/refdata', request='PortfolioDataRequest' if use_port else 'ReferenceDataRequest', **kwargs, ) process.init_request(request=request, tickers=ticker, flds=fld, **kwargs) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request, **kwargs) res = pd.DataFrame(process.rec_events(func=process.process_ref, **kwargs)) if kwargs.get('raw', False): return res if res.empty or any(fld not in res for fld in ['ticker', 'field']): return pd.DataFrame() data = (res.set_index(['ticker', 'field']).droplevel( axis=0, level=1).rename_axis(index=None).pipe(pipeline.standard_cols, col_maps=kwargs.get( 'col_maps', None))) if data_file: logger.debug(f'Saving Bloomberg data to: {data_file}') files.create_folder(data_file, is_file=True) data.to_pickle(data_file) return data
def bdp(tickers, flds, **kwargs) -> pd.DataFrame: """ Bloomberg reference data Args: tickers: tickers flds: fields to query **kwargs: Bloomberg overrides Returns: pd.DataFrame """ logger = logs.get_logger(bdp, **kwargs) if isinstance(tickers, str): tickers = [tickers] if isinstance(flds, str): flds = [flds] request = process.create_request( service='//blp/refdata', request='ReferenceDataRequest', **kwargs, ) process.init_request(request=request, tickers=tickers, flds=flds, **kwargs) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request, **kwargs) res = pd.DataFrame(process.rec_events(func=process.process_ref, **kwargs)) if kwargs.get('raw', False): return res if res.empty or any(fld not in res for fld in ['ticker', 'field']): return pd.DataFrame() return (res.set_index(['ticker', 'field']).unstack(level=1).rename_axis( index=None, columns=[None, None]).droplevel(axis=1, level=0).loc[:, res.field.unique()].pipe( pipeline.standard_cols, col_maps=kwargs.get('col_maps', None)))
def bdtick(ticker, dt, session='allday', time_range=None, types=None, **kwargs) -> pd.DataFrame: """ Bloomberg tick data Args: ticker: ticker name dt: date to download session: [allday, day, am, pm, pre, post] time_range: tuple of start and end time (must be converted into UTC) if this is given, `dt` and `session` will be ignored types: str or list, one or combinations of [ TRADE, AT_TRADE, BID, ASK, MID_PRICE, BID_BEST, ASK_BEST, BEST_BID, BEST_ASK, ] Returns: pd.DataFrame """ logger = logs.get_logger(bdtick, **kwargs) if types is None: types = ['TRADE'] exch = const.exch_info(ticker=ticker, **kwargs) if exch.empty: raise LookupError(f'Cannot find exchange info for {ticker}') if isinstance(time_range, (tuple, list)) and (len(time_range) == 2): cur_dt = pd.Timestamp(dt).strftime('%Y-%m-%d') time_rng = (pd.DatetimeIndex([ f'{cur_dt} {time_range[0]}', f'{cur_dt} {time_range[1]}', ]).tz_localize(exch.tz).tz_convert( process.DEFAULT_TZ).tz_convert('UTC')) else: time_rng = process.time_range(dt=dt, ticker=ticker, session=session, **kwargs) while conn.bbg_session(**kwargs).tryNextEvent(): pass request = process.create_request( service='//blp/refdata', request='IntradayTickRequest', settings=[ ('security', ticker), ('startDateTime', time_rng[0]), ('endDateTime', time_rng[1]), ('includeConditionCodes', True), ('includeExchangeCodes', True), ('includeNonPlottableEvents', True), ('includeBrokerCodes', True), ('includeRpsCodes', True), ('includeTradeTime', True), ('includeActionCodes', True), ('includeIndicatorCodes', True), ], append={'eventTypes': types}, **kwargs, ) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request) res = pd.DataFrame( process.rec_events(func=process.process_bar, typ='t', **kwargs)) if kwargs.get('raw', False): return res if res.empty or ('time' not in res): return pd.DataFrame() return (res.set_index('time').rename_axis( index=None).tz_localize('UTC').tz_convert(exch.tz).pipe( pipeline.add_ticker, ticker=ticker).rename( columns={ 'size': 'volume', 'type': 'typ', 'conditionCodes': 'cond', 'exchangeCode': 'exch', 'tradeTime': 'trd_time', }))
def bdib(ticker: str, dt, session='allday', typ='TRADE', **kwargs) -> pd.DataFrame: """ Bloomberg intraday bar data Args: ticker: ticker name dt: date to download session: [allday, day, am, pm, pre, post] typ: [TRADE, BID, ASK, BID_BEST, ASK_BEST, BEST_BID, BEST_ASK] **kwargs: ref: reference ticker or exchange used as supplement if exchange info is not defined for `ticker` batch: whether is batch process to download data log: level of logs Returns: pd.DataFrame """ from xbbg.core import trials logger = logs.get_logger(bdib, **kwargs) ex_info = const.exch_info(ticker=ticker, **kwargs) if ex_info.empty: raise KeyError(f'Cannot find exchange info for {ticker}') ss_rng = process.time_range(dt=dt, ticker=ticker, session=session, tz=ex_info.tz, **kwargs) data_file = storage.bar_file(ticker=ticker, dt=dt, typ=typ) if files.exists(data_file) and kwargs.get( 'cache', True) and (not kwargs.get('reload', False)): res = (pd.read_parquet(data_file).pipe( pipeline.add_ticker, ticker=ticker).loc[ss_rng[0]:ss_rng[1]]) if not res.empty: logger.debug(f'Loading Bloomberg intraday data from: {data_file}') return res if not process.check_current(dt=dt, logger=logger, **kwargs): return pd.DataFrame() cur_dt = pd.Timestamp(dt).strftime('%Y-%m-%d') q_tckr = ticker if ex_info.get('is_fut', False): is_sprd = ex_info.get( 'has_sprd', False) and (len(ticker[:-1]) != ex_info['tickers'][0]) if not is_sprd: q_tckr = fut_ticker(gen_ticker=ticker, dt=dt, freq=ex_info['freq']) if q_tckr == '': logger.error(f'cannot find futures ticker for {ticker} ...') return pd.DataFrame() info_log = f'{q_tckr} / {cur_dt} / {typ}' trial_kw = dict(ticker=ticker, dt=dt, typ=typ, func='bdib') num_trials = trials.num_trials(**trial_kw) if num_trials >= 2: if kwargs.get('batch', False): return pd.DataFrame() logger.info(f'{num_trials} trials with no data {info_log}') return pd.DataFrame() while conn.bbg_session(**kwargs).tryNextEvent(): pass time_rng = process.time_range(dt=dt, ticker=ticker, session='allday', **kwargs) request = process.create_request( service='//blp/refdata', request='IntradayBarRequest', settings=[ ('security', ticker), ('eventType', typ), ('interval', kwargs.get('interval', 1)), ('startDateTime', time_rng[0]), ('endDateTime', time_rng[1]), ], **kwargs, ) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request, **kwargs) res = pd.DataFrame(process.rec_events(func=process.process_bar, **kwargs)) if res.empty or ('time' not in res): logger.warning(f'No data for {info_log} ...') trials.update_trials(cnt=num_trials + 1, **trial_kw) return pd.DataFrame() data = (res.set_index('time').rename_axis(index=None).rename( columns={ 'numEvents': 'num_trds' }).tz_localize('UTC').tz_convert(ex_info.tz).pipe(pipeline.add_ticker, ticker=ticker)) if kwargs.get('cache', True): storage.save_intraday(data=data[ticker], ticker=ticker, dt=dt, typ=typ, **kwargs) return data.loc[ss_rng[0]:ss_rng[1]]
def bdtick(ticker, dt, session='allday', types=None, **kwargs) -> pd.DataFrame: """ Bloomberg tick data Args: ticker: ticker name dt: date to download session: [allday, day, am, pm, pre, post] types: str or list, one or combinations of [ TRADE, AT_TRADE, BID, ASK, MID_PRICE, BID_BEST, ASK_BEST, BEST_BID, BEST_ASK, ] Returns: pd.DataFrame """ logger = logs.get_logger(bdtick, **kwargs) exch = const.exch_info(ticker=ticker, **kwargs) time_rng = process.time_range(dt=dt, ticker=ticker, session=session, tz=exch.tz, **kwargs) service = conn.bbg_service(service='//blp/refdata', **kwargs) request = service.createRequest('IntradayTickRequest') while conn.bbg_session(**kwargs).tryNextEvent(): pass if types is None: types = ['TRADE'] if isinstance(types, str): types = [types] request.set('security', ticker) for typ in types: request.append('eventTypes', typ) request.set('startDateTime', time_rng[0]) request.set('endDateTime', time_rng[1]) request.set('includeConditionCodes', True) request.set('includeExchangeCodes', True) request.set('includeNonPlottableEvents', True) request.set('includeBrokerCodes', True) request.set('includeRpsCodes', True) request.set('includeTradeTime', True) request.set('includeActionCodes', True) request.set('includeIndicatorCodes', True) logger.debug(f'Sending request to Bloomberg ...\n{request}') conn.send_request(request=request) res = pd.DataFrame( process.rec_events(func=process.process_bar, typ='t', **kwargs)) if kwargs.get('raw', False): return res if res.empty or ('time' not in res): return pd.DataFrame() return (res.set_index('time').rename_axis( index=None).tz_localize('UTC').tz_convert(exch.tz).pipe( pipeline.add_ticker, ticker=ticker).rename( columns={ 'size': 'volume', 'type': 'typ', 'conditionCodes': 'cond', 'exchangeCode': 'exch', 'tradeTime': 'trd_time', }))