def _get_mdapi_rates_assets(**kwargs) -> Union[str, list]: assets = GsAssetApi.get_many_assets(**kwargs) # change order of basis swap legs and check if swap in dataset if len(assets) == 0 and ('asset_parameters_payer_rate_option' in kwargs): # flip legs kwargs['asset_parameters_payer_rate_option'], kwargs['asset_parameters_receiver_rate_option'] = \ kwargs['asset_parameters_receiver_rate_option'], kwargs['asset_parameters_payer_rate_option'] kwargs['asset_parameters_payer_designated_maturity'], kwargs['asset_parameters_receiver_designated_maturity'] =\ kwargs['asset_parameters_receiver_designated_maturity'], \ kwargs['asset_parameters_payer_designated_maturity'] assets = GsAssetApi.get_many_assets(**kwargs) if len(assets) > 1: # term structure measures need multiple assets if ('asset_parameters_termination_date' not in kwargs) or ('asset_parameters_effective_date' not in kwargs): return [asset.id for asset in assets] else: raise MqValueError('Specified arguments match multiple assets') elif len(assets) == 0: raise MqValueError( 'Specified arguments did not match any asset in the dataset') else: return assets[0].id
def _get_tdapi_inflation_rates_assets(allow_many=False, **kwargs) -> Union[str, list]: # sanitize input for asset query. if "pricing_location" in kwargs: del kwargs["pricing_location"] assets = GsAssetApi.get_many_assets(**kwargs) if len(assets) == 0 and ('asset_parameters_clearing_house' in kwargs): # test without the clearing house if kwargs[ 'asset_parameters_clearing_house'] == tm_rates._ClearingHouse.NONE.value: del kwargs['asset_parameters_clearing_house'] assets = GsAssetApi.get_many_assets(**kwargs) if len(assets) > 1: # term structure measures need multiple assets if ('asset_parameters_termination_date' not in kwargs) or ('asset_parameters_effective_date' not in kwargs) or allow_many: return [asset.id for asset in assets] else: raise MqValueError('Specified arguments match multiple assets') elif len(assets) == 0: raise MqValueError( 'Specified arguments did not match any asset in the dataset' + str(kwargs)) else: return assets[0].id
def test_get_many_assets(mocker, monkeypatch): marquee_id_1 = 'MQA1234567890' marquee_id_2 = 'MQA4567890123' query = {'id': [marquee_id_1, marquee_id_2]} as_of = dt.datetime.utcnow() inputs = EntityQuery(where=FieldFilterMap(**query), fields=None, asOfTime=as_of, limit=100) mock_response = { 'results': (GsAsset.from_dict({ 'id': marquee_id_1, 'assetClass': 'Equity', 'type': 'Single Stock', 'name': 'Test 1' }), GsAsset.from_dict({ 'id': marquee_id_2, 'assetClass': 'Equity', 'type': 'Single Stock', 'name': 'Test 2' })) } expected_response = (GsAsset(id=marquee_id_1, assetClass='Equity', type='Single Stock', name='Test 1'), GsAsset(id=marquee_id_2, assetClass='Equity', type='Single Stock', name='Test 2')) # mock GsSession mocker.patch.object(GsSession.__class__, 'default_value', return_value=GsSession.get(Environment.QA, 'client_id', 'secret')) mocker.patch.object(GsSession.current, '_post', return_value=mock_response) # run test monkeypatch.delenv(ENABLE_ASSET_CACHING, raising=False) response = GsAssetApi.get_many_assets(id=[marquee_id_1, marquee_id_2], as_of=as_of) GsSession.current._post.assert_called_with('/assets/query', cls=GsAsset, payload=inputs) assert response == expected_response monkeypatch.setenv(ENABLE_ASSET_CACHING, 1) # run 2x with cache on response = GsAssetApi.get_many_assets(id=[marquee_id_1, marquee_id_2], as_of=as_of) assert response == expected_response response = GsAssetApi.get_many_assets(id=[marquee_id_1, marquee_id_2], as_of=as_of) assert response == expected_response
def _get_tdapi_crosscurrency_rates_assets(allow_many=False, **kwargs) -> Union[str, list]: # sanitize input for asset query. if "pricing_location" in kwargs: del kwargs["pricing_location"] assets = GsAssetApi.get_many_assets(**kwargs) # change order of basis swap legs and check if swap in dataset if len(assets) == 0 and ('asset_parameters_payer_rate_option' in kwargs): # flip legs kwargs['asset_parameters_payer_rate_option'], kwargs['asset_parameters_receiver_rate_option'] = \ kwargs['asset_parameters_receiver_rate_option'], kwargs['asset_parameters_payer_rate_option'] if 'asset_parameters_payer_designated_maturity' in kwargs: kwargs['asset_parameters_payer_designated_maturity'], kwargs[ 'asset_parameters_receiver_designated_maturity'] = \ kwargs['asset_parameters_receiver_designated_maturity'], kwargs[ 'asset_parameters_payer_designated_maturity'] if 'asset_parameters_payer_currency' in kwargs: kwargs['asset_parameters_payer_currency'], kwargs['asset_parameters_receiver_currency'] = \ kwargs['asset_parameters_receiver_currency'], kwargs['asset_parameters_payer_currency'] assets = GsAssetApi.get_many_assets(**kwargs) if len(assets) == 0 and ('asset_parameters_clearing_house' in kwargs): # test without the clearing house if kwargs[ 'asset_parameters_clearing_house'] == tm_rates._ClearingHouse.NONE.value: del kwargs['asset_parameters_clearing_house'] assets = GsAssetApi.get_many_assets(**kwargs) # change order of basis swap legs and check if swap in dataset if len(assets) == 0 and ('asset_parameters_payer_rate_option' in kwargs): # flip legs kwargs['asset_parameters_payer_rate_option'], kwargs['asset_parameters_receiver_rate_option'] = \ kwargs['asset_parameters_receiver_rate_option'], kwargs['asset_parameters_payer_rate_option'] if 'asset_parameters_payer_designated_maturity' in kwargs: kwargs['asset_parameters_payer_designated_maturity'], kwargs[ 'asset_parameters_receiver_designated_maturity'] = \ kwargs['asset_parameters_receiver_designated_maturity'], kwargs[ 'asset_parameters_payer_designated_maturity'] if 'asset_parameters_payer_currency' in kwargs: kwargs['asset_parameters_payer_currency'], kwargs['asset_parameters_receiver_currency'] = \ kwargs['asset_parameters_receiver_currency'], kwargs['asset_parameters_payer_currency'] assets = GsAssetApi.get_many_assets(**kwargs) if len(assets) > 1: # term structure measures need multiple assets if ('asset_parameters_termination_date' not in kwargs) or ('asset_parameters_effective_date' not in kwargs) or allow_many: return [asset.id for asset in assets] else: raise MqValueError('Specified arguments match multiple assets') elif len(assets) == 0: raise MqValueError( 'Specified arguments did not match any asset in the dataset' + str(kwargs)) else: return assets[0].id
def __get_gs_asset(identifier: str) -> GsAsset: """ Resolves basket identifier during initialization """ response = GsAssetApi.resolve_assets(identifier=[identifier], fields=['id'], limit=1)[identifier] if len(response) == 0 or get(response, '0.id') is None: raise MqValueError( f'Basket could not be found using identifier {identifier}') return GsAssetApi.get_asset(get(response, '0.id'))
def from_asset_id(asset_id: str, date=None): asset = GsAssetApi.get_asset(asset_id) response = GsAssetApi.get_asset_positions_for_date(asset_id, date) if date else \ GsAssetApi.get_latest_positions(asset_id) response = response[0] if isinstance(response, tuple) else response positions = response.positions if isinstance(response, PositionSet) else response['positions'] instruments = GsAssetApi.get_instruments_for_positions(positions) ret = Portfolio(instruments, name=asset.name) ret.__id = asset_id return ret
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 __populate_current_attributes_for_existing_basket( self, gs_asset: GsAsset): self.__description = get(gs_asset, 'description', None) self.__gs_asset_type = get(gs_asset, 'type', None) self.__live_date = get(gs_asset, 'live_date', None) self.__ticker = get(gs_asset, 'xref.ticker', None) self.__clone_parent_id = get(gs_asset, 'parameters.clone_parent_id', None) self.__default_backcast = get(gs_asset, 'parameters.default_backcast', None) self.__flagship = get(gs_asset, 'parameters.flagship', None) self.__hedge_id = get(gs_asset, 'parameters.hedge_id', None) self.__return_type = get(gs_asset, 'parameters.index_calculation_type', None) last_positions = GsAssetApi.get_latest_positions(self.__id) self.__divisor = get(last_positions, 'divisor', None) last_initial_price = GsIndexApi.initial_price(gs_asset.id, DateLimit.TODAY.value) self.__initial_price = get(last_initial_price, 'price', None) report = self.__get_last_create_report() self.__include_price_history = get(report, 'parameters.include_price_history', None) self.__publish_to_bloomberg = get(report, 'parameters.publish_to_bloomberg', None) self.__publish_to_factset = get(report, 'parameters.publish_to_factset', None) self.__publish_to_reuters = get(report, 'parameters.publish_to_reuters', None)
def get_latest_position_set( self, position_type: PositionType = PositionType.CLOSE) -> PositionSet: if self.positioned_entity_type == EntityType.ASSET: response = GsAssetApi.get_latest_positions(self.id, position_type) return PositionSet.from_target(response) raise NotImplementedError
def _get_tdapi_fxo_assets_vol_swaps(**kwargs) -> Union[str, list]: # sanitize input for asset query. expiry_tenor = kwargs.get("expiry_tenor") ignore_list = ["expiry_tenor", "pricing_location"] inputs = {k: v for k, v in kwargs.items() if k not in ignore_list} assets = GsAssetApi.get_many_assets(**inputs) # For vol swaps we are not restricting assets using a filter # as asset service isn't setup for the parameters we pass in # instead query all assets and apply the filter in code here if len(assets) == 0: raise MqValueError('No assets found matching search criteria' + str(kwargs)) if expiry_tenor is not None: for asset in assets: if asset.parameters["lastFixingDate"].lower( ) == expiry_tenor.lower(): return asset.id raise MqValueError( 'Specified arguments did not match any asset in the dataset' + str(kwargs))
def create(self) -> Dict: """ Create a new custom basket in Marquee :return: dictionary containing asset id and report id **Usage** Create a new custom basket in Marquee **See also** :func:`get_details` :func:`poll_status` :func:`update` """ inputs, pricing, publish = {}, {}, {} for prop in CustomBasketsCreateInputs.properties(): set_(inputs, prop, get(self, prop)) for prop in CustomBasketsPricingParameters.properties(): set_(pricing, prop, get(self, prop)) for prop in PublishParameters.properties(): set_(publish, prop, get(self, prop)) set_(inputs, 'position_set', self.position_set.to_target(common=False)) set_(inputs, 'pricing_parameters', CustomBasketsPricingParameters(**pricing)) set_(inputs, 'publish_parameters', PublishParameters(**publish)) create_inputs = CustomBasketsCreateInputs(**inputs) response = GsIndexApi.create(create_inputs) gs_asset = GsAssetApi.get_asset(response.asset_id) self.__latest_create_report = GsReportApi.get_report( response.report_id) self.__init__(gs_asset=gs_asset, _finish_init=True) return response.as_dict()
def get_constituent_instruments( self, start: dt.date = DateLimit.LOW_LIMIT.value, end: dt.date = dt.date.today() ) -> Tuple[Tuple[Instrument]]: """ Fetch the constituents of the index as instrument objects for the given date range :return: Tuple of Tuples, containing all instrument objects for each date. **Usage** Get the constituents of the index for the given date range as instrument objects. **Examples** Get index constituent instruments: >>> import datetime as dt >>> from gs_quant.markets.index import Index >>> >>> index = Index.get("GSMBXXXX") >>> index.get_constituent_instruments(dt.date(2021, 6, 1), dt.date(2021, 6, 10)) """ position_sets = self.get_position_sets(start, end) return [ GsAssetApi.get_instruments_for_positions( position_set.to_target().positions) for position_set in position_sets ]
def from_portfolio_id(portfolio_id: str): response = GsPortfolioApi.get_latest_positions(portfolio_id) positions = response.positions if isinstance(response, PositionSet) else response['positions'] instruments = GsAssetApi.get_instruments_for_positions(positions) ret = Portfolio(instruments) ret.name = portfolio_id return ret
def save(self, overwrite: Optional[bool] = False): if self.portfolios: raise ValueError('Cannot save portfolios with nested portfolios') if self.__id: if not overwrite: raise ValueError( f'Portfolio with id {id} already exists. Use overwrite=True to overwrite' ) else: if not self.__name: raise ValueError('name not set') self.__id = GsPortfolioApi.create_portfolio( MarqueePortfolio('USD', self.__name)).id _logger.info( f'Created Marquee portfolio {self.__name} with id {self.__id}') position_set = PositionSet( position_date=self.__position_context.position_date, positions=tuple( Position( asset_id=GsAssetApi.get_or_create_asset_from_instrument(i)) for i in self.instruments)) if len(position_set.positions) > 0: GsPortfolioApi.update_positions(self.__id, [position_set])
def update(self) -> Dict: """ Update your custom basket :return: dictionary containing asset id and report id **Usage** Make updates to your basket's metadata, pricing options, publishing options, or composition **See also** :func:`get_details` :func:`poll_status` :func:`create` """ self.__finish_populating_attributes_for_existing_basket() edit_inputs, rebal_inputs = self.__get_updates() if edit_inputs is None and rebal_inputs is None: raise MqValueError('Update failed: Nothing on the basket was changed') elif edit_inputs is not None and rebal_inputs is None: response = GsIndexApi.edit(self.id, edit_inputs) elif rebal_inputs is not None and edit_inputs is None: response = GsIndexApi.rebalance(self.id, rebal_inputs) else: response = self.__edit_and_rebalance(edit_inputs, rebal_inputs) gs_asset = GsAssetApi.get_asset(self.id) self.__latest_create_report = GsReportApi.get_report(response.report_id) self.__error_messages.remove(ErrorMessage.UNMODIFIABLE) self.__init__(gs_asset=gs_asset) return response.as_dict()
def __get_positions_data(mqids: List[str]) -> Dict: response = GsAssetApi.get_many_assets_data( id=mqids, fields=['id', 'name', 'bbid']) data = {} for asset in response: data[get(asset, 'id')] = dict(name=get(asset, 'name'), bbid=get(asset, 'bbid')) return data
def _convert_asset_for_mdapi_swap_rates(**kwargs) -> str: assets = GsAssetApi.get_many_assets(**kwargs) if len(assets) > 1: raise MqValueError('Specified arguments match multiple assets') elif len(assets) == 0: raise MqValueError('Specified arguments did not match any asset in the dataset') else: return assets[0].id
def get_entitlements(self) -> Entitlements: if self.positioned_entity_type == EntityType.PORTFOLIO: response = GsPortfolioApi.get_portfolio(self.id) elif self.positioned_entity_type == EntityType.ASSET: response = GsAssetApi.get_asset(self.id) else: raise NotImplementedError return Entitlements.from_target(response.entitlements)
def get_positions_for_date(self, position_date: dt.date, position_type: PositionType = PositionType.CLOSE, format: ReturnFormat = ReturnFormat.DICT) -> Union[PositionSet, Dict, pd.DataFrame]: if self.positioned_entity_type == EntityType.ASSET: position_set = GsAssetApi.get_asset_positions_for_date(self.id, position_date, position_type)[0] return self.__convert_position_set(position_set, format) raise MqTypeError(f'{self.__invalid_entity_message} {self.positioned_entity_type}')
def __resolve_identifier(self, identifier: str) -> Dict: response = GsAssetApi.resolve_assets(identifier=[identifier], fields=['id', 'name'], limit=1)[identifier] if len(response) == 0: raise MqValueError( f'Asset could not be found using identifier {identifier}') self.__name = get(response, '0.name') self.__asset_id = get(response, '0.id')
def __get_gs_asset(self, identifier: str) -> GsAsset: response = GsAssetApi.resolve_assets(identifier=[identifier], limit=1)[identifier] gs_asset = None if len(response) == 0 else GsAsset.from_dict( response[0]) if gs_asset is None: raise MqValueError( f'Basket could not be found using identifier {identifier}') return gs_asset
def get_latest_positions(self, position_type: PositionType = PositionType.CLOSE, format: ReturnFormat = ReturnFormat.DICT) -> Union[PositionSet, Dict, pd.DataFrame]: if self.positioned_entity_type == EntityType.ASSET: response = GsAssetApi.get_latest_positions(self.id, position_type) position_set = response if type(response) == PositionSet else PositionSet.from_dict(response) return self.__convert_position_set(position_set, format) raise MqTypeError(f'{self.__invalid_entity_message} {self.positioned_entity_type}')
def get_position_set_for_date( self, date: dt.date, position_type: PositionType = PositionType.CLOSE) -> PositionSet: if self.positioned_entity_type == EntityType.ASSET: response = GsAssetApi.get_asset_positions_for_date( self.id, date, position_type)[0] return PositionSet.from_target(response) raise NotImplementedError
def get_positions_data(self, start_date: dt.date = DateLimit.LOW_LIMIT.value, end_date: dt.date = DateLimit.TODAY.value, fields: [str] = None, position_type: PositionType = PositionType.CLOSE) -> List[Dict]: if self.positioned_entity_type == EntityType.ASSET: return GsAssetApi.get_asset_positions_data(self.id, start_date, end_date, fields, position_type) raise MqTypeError(f'{self.__invalid_entity_message} {self.positioned_entity_type}')
def get_identifiers(self, as_of: dt.date = None) -> dict: """ Get asset identifiers :param as_of: As of date for query :return: dict of identifiers **Usage** Get asset identifiers as of a given date. Where the identifiers are temporal (and can change over time), this function will return the identifiers as of that point in time. If no date is provided as a parameter, will use the current PricingContext. **Examples** Get current asset identifiers: >>> gs = SecurityMaster.get_asset("GS", AssetIdentifier.TICKER) >>> gs.get_identifiers() Get identifiers as of 1Jan18: >>> gs.get_identifiers(dt.date(2018,1,1)) Use PricingContext to determine as of date: >>> with PricingContext(dt.date(2018,1,1)) as ctx: >>> gs.get_identifiers() **See also** :class:`AssetIdentifier` :func:`get_asset` """ if not as_of: as_of = PricingContext.current.pricing_date if isinstance(as_of, dt.datetime): as_of = as_of.date() valid_ids = set(item.value for item in AssetIdentifier) xrefs = GsAssetApi.get_asset_xrefs(self.__id) identifiers = {} for xref in xrefs: start_date = xref.startDate end_date = xref.endDate if start_date <= as_of <= end_date: identifiers = { k.upper(): v for k, v in xref.identifiers.as_dict().items() if k.upper() in valid_ids } return identifiers
def get_positions(self, start_date: dt.date = DateLimit.LOW_LIMIT.value, end_date: dt.date = DateLimit.TODAY.value, position_type: PositionType = PositionType.CLOSE, format: ReturnFormat = ReturnFormat.DICT) -> Union[Tuple[PositionSet], Dict, pd.DataFrame]: if self.positioned_entity_type == EntityType.ASSET: position_sets = GsAssetApi.get_asset_positions_for_dates(self.id, start_date, end_date, position_type) return self.__convert_position_sets(position_sets, format) raise MqTypeError(f'{self.__invalid_entity_message} {self.positioned_entity_type}')
def get_positions_data(self, start: dt.date = DateLimit.LOW_LIMIT.value, end: dt.date = dt.date.today(), fields: [str] = None, position_type: PositionType = PositionType.CLOSE) -> List[Dict]: if self.positioned_entity_type == EntityType.ASSET: return GsAssetApi.get_asset_positions_data(self.id, start, end, fields, position_type) if self.positioned_entity_type == EntityType.PORTFOLIO: return GsPortfolioApi.get_positions_data(self.id, start, end, fields, position_type) raise NotImplementedError
def get_latest_position_set(self, position_type: PositionType = PositionType.CLOSE) -> PositionSet: if self.positioned_entity_type == EntityType.ASSET: response = GsAssetApi.get_latest_positions(self.id, position_type) return PositionSet.from_target(response) if self.positioned_entity_type == EntityType.PORTFOLIO: response = GsPortfolioApi.get_latest_positions(portfolio_id=self.id, position_type=position_type.value) return PositionSet.from_target(response) raise NotImplementedError
def test_get_asset_xrefs(mocker): marquee_id = 'MQA1234567890' mock_response = { 'xrefs': ({ 'startDate': '1952-01-01', 'endDate': '2018-12-31', 'identifiers': { 'ric': '.GSTHHOLD', 'bbid': 'GSTHHOLD', 'cusip': '9EQ24FOLD', 'ticker': 'GSTHHOLD' } }, { 'startDate': '2019-01-01', 'endDate': '2952-12-31', 'identifiers': { 'ric': '.GSTHHVIP', 'bbid': 'GSTHHVIP', 'cusip': '9EQ24FPE5', 'ticker': 'GSTHHVIP', } }) } expected_response = (GsTemporalXRef( dt.date(1952, 1, 1), dt.date(2018, 12, 31), XRef( ric='.GSTHHOLD', bbid='GSTHHOLD', cusip='9EQ24FOLD', ticker='GSTHHOLD', )), GsTemporalXRef( dt.date(2019, 1, 1), dt.date(2952, 12, 31), XRef( ric='.GSTHHVIP', bbid='GSTHHVIP', cusip='9EQ24FPE5', ticker='GSTHHVIP', ))) # mock GsSession mocker.patch.object(GsSession.__class__, 'current', return_value=GsSession.get(Environment.QA, 'client_id', 'secret')) mocker.patch.object(GsSession.current, '_get', return_value=mock_response) # run test response = GsAssetApi.get_asset_xrefs(marquee_id) GsSession.current._get.assert_called_with( '/assets/{id}/xrefs'.format(id=marquee_id)) testfixtures.compare(response, expected_response)
def test_get_asset_positions_data(mocker): marquee_id = 'MQA1234567890' position_date = dt.date(2019, 2, 19) mock_response = { 'results': [ { 'underlyingAssetId': 'MA4B66MW5E27UAFU2CD', 'divisor': 8305900333.262549, 'quantity': 0.016836826158, 'positionType': 'close', 'bbid': 'EXPE UW', 'assetId': 'MA4B66MW5E27U8P32SB', 'positionDate': '2019-11-07', 'assetClassificationsGicsSector': 'Consumer Discretionary', 'closePrice': 98.29, 'ric': 'EXPE.OQ' }, ] } expected_response = [ { 'underlyingAssetId': 'MA4B66MW5E27UAFU2CD', 'divisor': 8305900333.262549, 'quantity': 0.016836826158, 'positionType': 'close', 'bbid': 'EXPE UW', 'assetId': 'MA4B66MW5E27U8P32SB', 'positionDate': '2019-11-07', 'assetClassificationsGicsSector': 'Consumer Discretionary', 'closePrice': 98.29, 'ric': 'EXPE.OQ' }, ] # mock GsSession mocker.patch.object(GsSession.__class__, 'current', return_value=GsSession.get(Environment.QA, 'client_id', 'secret')) mocker.patch.object(GsSession.current, '_get', return_value=mock_response) # run test response = GsAssetApi.get_asset_positions_data(marquee_id, position_date, position_date) position_date_str = position_date.isoformat() GsSession.current._get.assert_called_with( '/assets/{id}/positions/data?startDate={start_date}&endDate={end_date}' .format(id=marquee_id, start_date=position_date_str, end_date=position_date_str)) testfixtures.compare(response, expected_response)