def _get_holidays(self, use_usd: bool = True) -> List[date]: holidays = Series() if self.holiday_calendar is not None: if self.usd_calendar is None: return self.holiday_calendar return holidays.append(Series(self.usd_calendar)) try: currencies = self.currencies or [] if use_usd: currencies.append('USD') if self.exchanges: cached_data = _cache.get(hashkey(use_usd, str(currencies), str(self.exchanges))) if cached_data: return cached_data if self.exchanges: self.exchanges = [x.value if isinstance(x, ExchangeCode) else x.upper() for x in self.exchanges] exchange_query = GsDataApi.build_query(start=DATE_LOW_LIMIT, end=DATE_HIGH_LIMIT, exchange=self.exchanges) data = GsDataApi.query_data(exchange_query, 'HOLIDAY') holidays = holidays.append(Series(to_datetime(DataFrame(data)['date']).dt.date)) if len(currencies): currencies = [x.value if isinstance(x, Currency) else x.upper() for x in currencies] currency_query = GsDataApi.build_query(start=DATE_LOW_LIMIT, end=DATE_HIGH_LIMIT, currency=currencies) data = GsDataApi.query_data(currency_query, 'HOLIDAY_CURRENCY') holidays = holidays.append(Series(to_datetime(DataFrame(data)['date']).dt.date)) holidays = holidays.unique().tolist() _cache[hashkey(use_usd, str(currencies), str(self.exchanges))] = holidays return holidays except Exception as e: _logger.warning('Unable to fetch holiday calendar. Try passing your own when applying a rule.', e) return []
def result(self): """ :return: a Pandas DataFrame containing the results of the report job """ status = self.status() if status == ReportStatus.cancelled: raise MqValueError( 'This report job in status "cancelled". Cannot retrieve results.' ) if status == ReportStatus.error: raise MqValueError( 'This report job is in status "error". Cannot retrieve results.' ) if status != ReportStatus.done: raise MqValueError( 'This report job is not done. Cannot retrieve results.') if self.__report_type in [ ReportType.Portfolio_Factor_Risk, ReportType.Asset_Factor_Risk ]: results = GsReportApi.get_factor_risk_report_results( risk_report_id=self.__report_id, start_date=self.__start_date, end_date=self.__end_date) return pd.DataFrame(results) if self.__report_type == ReportType.Portfolio_Performance_Analytics: query = DataQuery(where={'reportId': self.__report_id}, start_date=self.__start_date, end_date=self.__end_date) results = GsDataApi.query_data( query=query, dataset_id=ReportDataset.PPA_DATASET.value) return pd.DataFrame(results) return None
def get_corporate_actions(self, start: dt.date = DateLimit.LOW_LIMIT.value, end: dt.date = dt.date.today() + dt.timedelta(days=10), ca_type: [CorporateActionType] = CorporateActionType.to_list()) -> pd.DataFrame: """ Retrieve corporate actions for a basket across a date range :param start: start date (default minimum date value) :param end: end date (default is maximum date value) :param ca_type: list of corporate action types (default is all) :return: dataframe with corporate actions information **Usage** Retrieve corporate actions for a basket across a date range **Examples** Retrieve historical acquisition corporate actions for a basket >>> from gs_quant.markets.baskets import Basket >>> from gs_quant.markets.indices_utils import CorporateActionType >>> >>> basket = Basket("GSMBXXXX") >>> basket.get_corporate_actions(ca_type=[CorporateActionType.ACQUISITION]) **See also** :func:`get_fundamentals` """ where = dict(assetId=self.id, corporateActionType=ca_type) query = DataQuery(where=where, start_date=start, end_date=end) response = GsDataApi.query_data(query=query, dataset_id=IndicesDatasets.CORPORATE_ACTIONS.value) return pd.DataFrame(response)
def get_many_measures( self, measures: Tuple[str, ...] = None, start_date: dt.date = None, end_date: dt.date = None, return_format: ReturnFormat = ReturnFormat.DATA_FRAME ) -> Union[Dict, pd.DataFrame]: """ Get many historical portfolio metrics :param measures: a list of metrics :param start_date: start date :param end_date: end date :return: returns a Pandas DataFrame with the results """ if measures is None: measures = [] fields = tuple(measure for measure in measures) where = {'reportId': self.id} query = DataQuery(where=where, fields=fields, start_date=start_date, end_date=end_date) results = GsDataApi.query_data( query=query, dataset_id=ReportDataset.PPA_DATASET.value) return pd.DataFrame( results) if return_format == ReturnFormat.DATA_FRAME else results
def __get_constituents_data(basket: Dict, basket_map: Dict, start: dt.date, end: dt.date, fields: List[str]) -> List: _id, _type = get(basket, 'assetId'), get(basket, 'type') if _id not in list(basket_map.keys()): return start_date = dt.datetime.strptime(basket['historyStartDate'], '%Y-%m-%d').date() start_date = start_date if start < start_date else start dataset_id = IndicesDatasets.GSBASKETCONSTITUENTS.value if _type == BasketType.CUSTOM_BASKET.value\ else IndicesDatasets.GIRBASKETCONSTITUENTS.value data = GsDataApi.query_data(query=DataQuery(where=dict(assetId=_id), startDate=start_date, endDate=end), dataset_id=dataset_id) asset_ids = list(set([d['underlyingAssetId'] for d in data])) asset_data = GsAssetApi.get_many_assets_data_scroll(id=asset_ids, fields=fields, limit=2000, scroll='1m') asset_data_map = {get(asset, 'id'): asset for asset in asset_data} for d in data: asset_id = get(d, 'underlyingAssetId', '') asset_id_map = get(asset_data_map, asset_id, {}) for f in fields: d[f] = get(asset_id_map, f) basket_map[_id].update(constituents=data) return basket_map[_id]
def get_portfolio_constituents( self, fields: List[str] = None, start_date: dt.date = None, end_date: dt.date = None, return_format: ReturnFormat = ReturnFormat.DATA_FRAME ) -> Union[Dict, pd.DataFrame]: """ Get historical portfolio constituents :param fields: list of fields to include in the results :param start_date: start date :param end_date: end date :param return_format: return format; defaults to a Pandas DataFrame, but can be manually set to ReturnFormat.JSON :return: Portfolio constituent data for each day in the requested date range """ where = {'reportId': self.id} date_batches = _get_ppaa_batches( self.get_asset_count(start_date, end_date), 3000000) queries = [ DataQuery(where=where, fields=fields, start_date=dates_batch[0], end_date=dates_batch[1]) for dates_batch in date_batches ] results = [ GsDataApi.query_data( query=query, dataset_id=ReportDataset.PORTFOLIO_CONSTITUENTS.value) for query in queries ] results = sum(results, []) return pd.DataFrame( results) if return_format == ReturnFormat.DATA_FRAME else results
def get_many_measures(cls, report_id: str, measures: Tuple[str, ...], start_date: dt.date = None, end_date: dt.date = None): fields = [] for measure in measures: fields.append(measure) where = FieldFilterMap(report_id=report_id) query = DataQuery(where=where, fields=fields, start_date=start_date, end_date=end_date) return GsDataApi.query_data(query=query, dataset_id=PPA_DATASET)
def get_many_measures(self, measures: Tuple[str, ...], start_date: dt.date = None, end_date: dt.date = None) -> Union[MDAPIDataBatchResponse, DataQueryResponse, tuple, list]: fields = tuple(measure for measure in measures) where = {'reportId': self.id} query = DataQuery(where=where, fields=fields, start_date=start_date, end_date=end_date) return GsDataApi.query_data(query=query, dataset_id=ReportDataset.PPA_DATASET.value)
def get_measure(self, field: str, start_date: dt.date = None, end_date: dt.date = None) -> Union[MDAPIDataBatchResponse, DataQueryResponse, tuple, list]: fields = (field,) where = {'reportId': self.id} query = DataQuery(where=where, fields=fields, start_date=start_date, end_date=end_date) return GsDataApi.query_data(query=query, dataset_id=ReportDataset.PPA_DATASET.value)
def get_measure(self, field: str, start_date: dt.date = None, end_date: dt.date = None, return_format: ReturnFormat = ReturnFormat.DATA_FRAME) -> Union[Dict, pd.DataFrame]: fields = (field,) where = {'reportId': self.id} query = DataQuery(where=where, fields=fields, start_date=start_date, end_date=end_date) results = GsDataApi.query_data(query=query, dataset_id=ReportDataset.PPA_DATASET.value) return pd.DataFrame(results) if return_format == ReturnFormat.DATA_FRAME else results
def get_measure(cls, report_id: str, field: str, start_date: dt.date = None, end_date: dt.date = None): fields = [field] where = FieldValueMap(report_id=report_id) query = DataQuery(where=where, fields=fields, start_date=start_date, end_date=end_date) return GsDataApi.query_data(query=query, dataset_id=PPA_DATASET)
def get_corporate_actions( self, start_date: dt.date = DateLimit.LOW_LIMIT.value, end_date: dt.date = DateLimit.HIGH_LIMIT.value ) -> DataQueryResponse: if not self.id: self.__raise_initialization_error( 'retrieve corporate actions data') query = DataQuery(where=dict(assetId=self.id), start_date=start_date, end_date=end_date) return GsDataApi.query_data( query=query, dataset_id=IndicesDatasets.CORPORATE_ACTIONS.value)
def _get_measures(self, fields: List, start_date: dt.date = None, end_date: dt.date = None, basket_ids: List[str] = None, return_format: ReturnFormat = ReturnFormat.DATA_FRAME) -> Union[Dict, pd.DataFrame]: where = {'reportId': self.id} if basket_ids: where['basketId'] = basket_ids dataset = ReportDataset.PTA_DATASET.value if self.position_source_type == PositionSourceType.Portfolio \ else ReportDataset.ATA_DATASET.value query = DataQuery(where=where, fields=fields, start_date=start_date, end_date=end_date) results = GsDataApi.query_data(query=query, dataset_id=dataset) return pd.DataFrame(results) if return_format == ReturnFormat.DATA_FRAME else results
def get_fundamentals( self, start: dt.date = DateLimit.LOW_LIMIT.value, end: dt.date = dt.date.today(), period: FundamentalMetricPeriod = FundamentalMetricPeriod.ONE_YEAR. value, direction: FundamentalMetricPeriodDirection = FundamentalMetricPeriodDirection. FORWARD.value, metrics: List[FundamentalsMetrics] = FundamentalsMetrics.to_list() ) -> pd.DataFrame: """ Retrieve fundamentals data for a basket across a date range :param start: start date (default minimum date value) :param end: end date (default is today) :param period: period for the relevant metric (default is 1y) :param direction: direction of the outlook period (default is forward) :param metrics: list of fundamentals metrics (default is all) :return: dataframe with fundamentals information **Usage** Retrieve fundamentals data for a basket across a date range **Examples** Retrieve historical dividend yield data for a basket >>> from gs_quant.markets.baskets import Basket >>> from gs_quant.markets.indices_utils import FundamentalsMetrics >>> >>> basket = Basket.get("GSMBXXXX") >>> basket.get_corporate_actions(metrics=[FundamentalsMetrics.DIVIDEND_YIELD]) **See also** :func:`get_corporate_actions` """ where = dict(assetId=self.id, period=period, periodDirection=direction, metric=metrics) query = DataQuery(where=where, start_date=start, end_date=end) response = GsDataApi.query_data( query=query, dataset_id=IndicesDatasets.BASKET_FUNDAMENTALS.value) return pd.DataFrame(response)
def get_thematic_beta(self, basket_identifier: str, start: dt.date = DateLimit.LOW_LIMIT.value, end: dt.date = dt.date.today()) -> pd.DataFrame: if not self.positioned_entity_type == EntityType.ASSET: raise NotImplementedError response = GsAssetApi.resolve_assets(identifier=[basket_identifier], fields=['id', 'type'], limit=1)[basket_identifier] _id, _type = get(response, '0.id'), get(response, '0.type') if len(response) == 0 or _id is None: raise MqValueError(f'Basket could not be found using identifier {basket_identifier}.') if _type not in BasketType.to_list(): raise MqValueError(f'Asset {basket_identifier} of type {_type} is not a Custom or Research Basket.') query = DataQuery(where={'assetId': self.id, 'basketId': _id}, start_date=start, end_date=end) response = GsDataApi.query_data(query=query, dataset_id=IndicesDatasets.COMPOSITE_THEMATIC_BETAS.value) df = [] for r in response: df.append({'date': r['date'], 'assetId': r['assetId'], 'basketId': r['basketId'], 'thematicBeta': r['beta']}) df = pd.DataFrame(df) return df.set_index('date')
def get_fundamentals( self, period: FundamentalMetricPeriod = FundamentalMetricPeriod.ONE_YEAR. value, direction: FundamentalMetricPeriodDirection = FundamentalMetricPeriodDirection. FORWARD.value, metrics: [FundamentalsMetrics] = FundamentalsMetrics.to_list(), start_date: dt.date = DateLimit.LOW_LIMIT.value, end_date: dt.date = DateLimit.TODAY.value) -> DataQueryResponse: if not self.id: self.__raise_initialization_error('retrieve fundamentals data') where = dict(assetId=self.id, period=period, periodDirection=direction, metric=metrics) query = DataQuery(where=where, start_date=start_date, end_date=end_date) return GsDataApi.query_data( query=query, dataset_id=IndicesDatasets.BASKET_FUNDAMENTALS.value)
def get_factor_exposure(cls, report_id: str, factor: str, factor_category: str, start_date: dt.date = None, end_date: dt.date = None): where = FieldFilterMap(report_id=report_id, factor=factor, factor_category=factor_category) query = DataQuery(where=where, start_date=start_date, end_date=end_date) return GsDataApi.query_data(query=query, dataset_id=PFR_DATASET)
def get_flagships_constituents( fields: [str] = [], basket_type: List[BasketType] = BasketType.to_list(), asset_class: List[AssetClass] = [AssetClass.Equity], region: List[Region] = None, styles: List[Union[CustomBasketStyles, ResearchBasketStyles]] = None, start: dt.date = None, end: dt.date = None, ) -> pd.DataFrame: """ Retrieve flagship baskets constituents :param fields: Fields to retrieve in addition to mqid, name, ticker, region, basket type, \ styles, live date, and asset class :param basket_type: Basket type(s) :param asset_class: Asset class (defaults to Equity) :param region: Basket region(s) :param styles: Basket style(s) :param start: Start date for which to retrieve constituents (defaults to previous business day) :param end: End date for which to retrieve constituents (defaults to previous business day) :return: flagship baskets constituents **Usage** Retrieve flagship baskets constituents **Examples** Retrieve a list of flagship baskets constituents >>> from gs_quant.markets.indices_utils import * >>> >>> get_flagships_constituents() **See also** :func:`get_flagships_with_assets` :func:`get_flagships_performance` :func:`get_flagship_baskets` """ start = start or prev_business_date() end = end or prev_business_date() fields = list( set(fields).union( set([ 'id', 'name', 'ticker', 'region', 'type', 'styles', 'liveDate', 'assetClass' ]))) query = dict(fields=fields, type=basket_type, asset_class=asset_class, is_pair_basket=[False], flagship=[True]) if region is not None: query.update(region=region) if styles is not None: query.update(styles=styles) basket_data = GsAssetApi.get_many_assets_data_scroll(**query, limit=2000, scroll='1m') basket_map = {get(basket, 'id'): basket for basket in basket_data} coverage = GsDataApi.get_coverage( dataset_id=IndicesDatasets.GSCB_FLAGSHIP.value, fields=['type', 'bbid'], include_history=True) cbs, rbs = [], [] for b in coverage: _id = get(b, 'assetId') _type = get(b, 'type') if _id in list(basket_map.keys()): start_date = dt.datetime.strptime(b['historyStartDate'], '%Y-%m-%d').date() start_date = start_date if start < start_date else start if _type == BasketType.CUSTOM_BASKET.value: data = GsDataApi.query_data( query=DataQuery(where=dict(assetId=_id), startDate=start_date, endDate=end), dataset_id=IndicesDatasets.GSBASKETCONSTITUENTS.value) basket_map[_id].update(constituents=data) cbs.append(basket_map[_id]) elif _type == BasketType.RESEARCH_BASKET.value: data = GsDataApi.query_data( query=DataQuery(where=dict(assetId=_id), startDate=start_date, endDate=end), dataset_id=IndicesDatasets.GIRBASKETCONSTITUENTS.value) basket_map[_id].update(constituents=data) rbs.append(basket_map[_id]) return pd.DataFrame(cbs + rbs)
def get_flagships_performance( fields: [str] = [], basket_type: List[BasketType] = BasketType.to_list(), asset_class: List[AssetClass] = [AssetClass.Equity], region: List[Region] = None, styles: List[Union[CustomBasketStyles, ResearchBasketStyles]] = None, start: dt.date = None, end: dt.date = None, ) -> pd.DataFrame: """ Retrieve performance data for flagship baskets :param fields: Fields to retrieve in addition to bbid, mqid, name, region, basket type, \ styles, live date, and asset class :param basket_type: Basket type(s) :param asset_class: Asset class (defaults to Equity) :param region: Basket region(s) :param styles: Basket style(s) :param start: Date for which to retrieve pricing (defaults to previous business day) :param end: Date for which to retrieve pricing (defaults to previous business day) :return: pricing data for flagship baskets **Usage** Retrieve performance data for flagship baskets **Examples** Retrieve performance data for flagship Asia custom baskets >>> from gs_quant.markets.indices_utils import * >>> >>> get_flagships_performance(basket_type=[BasketType.CUSTOM_BASKET], region=[Region.ASIA]) **See also** :func:`get_flagships_with_assets` :func:`get_flagship_baskets` :func:`get_flagships_constituents` """ start = start or prev_business_date() end = end or prev_business_date() fields = list( set(fields).union( set([ 'name', 'region', 'type', 'flagship', 'isPairBasket', 'styles', 'liveDate', 'assetClass' ]))) coverage = GsDataApi.get_coverage( dataset_id=IndicesDatasets.GSCB_FLAGSHIP.value, fields=fields) basket_regions = [] if region is None else [r.value for r in region] basket_styles = [] if styles is None else [s.value for s in styles] basket_types = [b_type.value for b_type in basket_type] baskets_map = {} for basket in coverage: if get(basket, 'flagship') is False or get(basket, 'isPairBasket') is True or \ region is not None and get(basket, 'region') not in basket_regions or \ get(basket, 'type') not in basket_types or \ get(basket, 'assetClass') not in [a.value for a in asset_class] or \ styles is not None and not any(s in get(basket, 'styles', []) for s in basket_styles): continue baskets_map[get(basket, 'assetId')] = basket response = GsDataApi.query_data( query=DataQuery(where=dict(assetId=list(baskets_map.keys())), startDate=start, endDate=end), dataset_id=IndicesDatasets.GSCB_FLAGSHIP.value) performance = [] for basket in response: basket_data = baskets_map[get(basket, 'assetId')] basket_data.update(closePrice=get(basket, 'closePrice')) basket_data.update(date=get(basket, 'date')) performance.append(basket_data) return pd.DataFrame(performance)