def test_midcurve_vol_return_data(): replace = Replacer() test_data = dict(midcurveVol=[1, 2, 3]) df = MarketDataResponseFrame( data=test_data, index=[dt.date(2019, 1, 1), dt.date(2019, 1, 2), dt.date(2019, 1, 3)]) replace('gs_quant.timeseries.measures.Asset.get_identifier', Mock()).return_value = "GBP" replace('gs_quant.timeseries.measures_rates._get_tdapi_rates_assets', Mock(), Mock()).return_value = ["MADWG3WHCKNE1DJA", "MAH6JK3TZJJGFQ65"] replace('gs_quant.timeseries.measures_rates._range_from_pricing_date', Mock(), Mock()).return_value = [dt.date(2019, 1, 2), dt.date(2019, 1, 5)] replace('gs_quant.timeseries.measures_rates._market_data_timed', Mock()).return_value = df actual = tm_rates.midcurve_vol(Currency("GBP", name="GBP"), "1y", "1y", "1y", 0) assert_series_equal(tm._extract_series_from_df(df, QueryType.MIDCURVE_VOL), actual) replace.restore()
def pnl(portfolio_id: str, start_date: dt.date = None, end_date: dt.date = None, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Returns the PnL of a portfolio :param portfolio_id: id of portfolio :param start_date: start date for getting pnl :param end_date: end date for getting pnl :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :param request_id: server request id :return: portfolio pnl values """ reports = GsPortfolioApi.get_reports(portfolio_id) performance_report_id = "" for report in reports: if report.type == ReportType.Portfolio_Performance_Analytics: performance_report_id = report.id data = PerformanceReport.get_pnl(performance_report_id, start_date, end_date) df = pd.DataFrame.from_records(data) df.set_index('date', inplace=True) return _extract_series_from_df(df, QueryType.PNL, True)
def _get_factor_data(report_id: str, factor_name: str, query_type: QueryType) -> pd.Series: # Check params report = FactorRiskReport.get(report_id) if factor_name not in ['Factor', 'Specific', 'Total']: if query_type in [QueryType.DAILY_RISK, QueryType.ANNUAL_RISK]: raise MqValueError( 'Please pick a factor name from the following: ["Total", "Factor", "Specific"]' ) model = FactorRiskModel.get(report.get_risk_model_id()) factor = model.get_factor(factor_name) factor_name = factor.name # Extract relevant data for each date col_name = query_type.value.replace(' ', '') col_name = decapitalize(col_name) data_type = decapitalize( col_name[6:]) if col_name.startswith('factor') else col_name factor_data = report.get_results(factors=[factor_name], start_date=DataContext.current.start_date, end_date=DataContext.current.end_date, return_format=ReturnFormat.JSON) factor_exposures = [{ 'date': d['date'], col_name: d[data_type] } for d in factor_data if d.get(data_type)] # Create and return timeseries df = pd.DataFrame(factor_exposures) if not df.empty: df.set_index('date', inplace=True) df.index = pd.to_datetime(df.index) return _extract_series_from_df(df, query_type)
def test_swaption_atmFwdRate_return_data(): replace = Replacer() test_data = dict(atmFwdRate=[1, 2, 3]) df = MarketDataResponseFrame( data=test_data, index=[dt.date(2019, 1, 1), dt.date(2019, 1, 2), dt.date(2019, 1, 3)]) replace('gs_quant.timeseries.measures.Asset.get_identifier', Mock()).return_value = "GBP" replace('gs_quant.timeseries.measures_rates._get_tdapi_rates_assets', Mock(), Mock()).return_value = ["MADWG3WHCKNE1DJA", "MAH6JK3TZJJGFQ65"] replace('gs_quant.timeseries.measures_rates._range_from_pricing_date', Mock(), Mock()).return_value = [dt.date(2019, 1, 2), dt.date(2019, 1, 5)] replace('gs_quant.timeseries.measures_rates._market_data_timed', Mock()).return_value = df actual = tm_rates.swaption_atm_fwd_rate(Currency("GBP", name="GBP")) assert_series_equal(tm._extract_series_from_df(df, QueryType.ATM_FWD_RATE), actual) replace.restore()
def _get_factor_data(report_id: str, factor_name: str, query_type: QueryType) -> pd.Series: # Check params report = RiskReport(report_id) if report.get_type() not in [ ReportType.Portfolio_Factor_Risk, ReportType.Asset_Factor_Risk ]: raise MqValueError('This report is not a factor risk report') risk_model_id = report.get_risk_model_id() factor = Factor(risk_model_id, factor_name) if factor.factor is None: raise MqValueError( 'Factor name requested is not available in the risk model associated with this report' ) # Extract relevant data for each date col_name = query_type.value.replace(' ', '') col_name = col_name[0].lower() + col_name[1:] data_type = QUERY_TO_FIELD_MAP[query_type] factor_data = report.get_factor_data(factor=factor.get_name()) factor_exposures = [{ 'date': data['date'], col_name: data[data_type] } for data in factor_data if data.get(data_type)] # Create and return timeseries df = pd.DataFrame(factor_exposures) df.set_index('date', inplace=True) df.index = pd.to_datetime(df.index) return _extract_series_from_df(df, query_type)
def thematic_beta(report_id: str, basket_ticker: str, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Thematic beta values of a portfolio to a requested GS thematic flagship basket :param report_id: portfolio thematic analytics report id :param basket_ticker: ticker for thematic basket :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :param request_id: server request id :return: Timeseries of daily thematic beta of portfolio to requested flagship basket """ thematic_report = ThematicReport.get(report_id) asset = SecurityMaster.get_asset(basket_ticker, AssetIdentifier.TICKER) df = thematic_report.get_thematic_betas( start_date=DataContext.current.start_date, end_date=DataContext.current.end_date, basket_ids=[asset.get_marquee_id()]) if not df.empty: df.set_index('date', inplace=True) df.index = pd.to_datetime(df.index) return _extract_series_from_df(df, QueryType.THEMATIC_BETA)
def factor_exposure(asset: Asset, risk_model_id: str, factor_name: str, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Asset factor Exposure (in the form of z-scores) for a factor using specified risk model :param asset: asset object loaded from security master :param risk_model_id: requested risk model id :param factor_name: requested factor name :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :param request_id: service request id, if any :return: Timeseries of asset factor exposure across available risk model dates """ risk_model = RiskModel(risk_model_id) factor = Factor(risk_model_id, factor_name) if factor.factor is None or risk_model_id != factor.risk_model_id: raise MqValueError( 'Requested factor not available in requested risk model') asset_gsid = asset.get_identifiers().get('GSID') # Establish date interval for data query dates = risk_model.get_dates() start_date = dt.datetime.strptime(min(dates), "%Y-%m-%d").date() if dates else None end_date = dt.datetime.strptime(max(dates), "%Y-%m-%d").date() if dates else None # Query data and append pull requested factor exposure all_exposures = [] query_results = risk_model.get_data( measures=[ Measure.Factor_Name, Measure.Universe_Factor_Exposure, Measure.Asset_Universe ], start_date=start_date, end_date=end_date, assets=DataAssetsRequest(identifier=AssetUniverseIdentifier.gsid, universe=[asset_gsid])).get('results', []) for result in query_results: if result.get('date') in dates: exposures = result.get('assetData', {}).get('factorExposure', []) if exposures: all_exposures.append({ 'date': result['date'], 'factorExposure': exposures[0].get(factor.factor.identifier) }) # Create and return timeseries df = pd.DataFrame(all_exposures) df.set_index('date', inplace=True) df.index = pd.to_datetime(df.index) return _extract_series_from_df(df, QueryType.FACTOR_EXPOSURE)
def __format_plot_measure_results(time_series: Dict, query_type: QueryType, multiplier=1, handle_missing_column=False): """ Create and return panda series expected for a plot measure """ col_name = query_type.value.replace(' ', '') col_name = decapitalize(col_name) time_series_list = [{'date': k, col_name: v * multiplier} for k, v in time_series.items()] df = pd.DataFrame(time_series_list) if not df.empty: df.set_index('date', inplace=True) df.index = pd.to_datetime(df.index) return _extract_series_from_df(df, query_type, handle_missing_column)
def test_vol_swap_strike(): replace = Replacer() base = Cross('MA667', 'EURUSD') xrefs = replace('gs_quant.timeseries.measures.Asset.get_identifier', Mock()) xrefs.return_value = 'EURUSD' mock_asset_1 = GsAsset(asset_class='FX', id='MA123', type_='VolatilitySwap', name='Test_asset', parameters={"lastFixingDate": "1y"}) mock_asset_2 = GsAsset(asset_class='FX', id='MA123', type_='VolatilitySwap', name='Test_asset', parameters={"lastFixingDate": "2y"}) assets = replace('gs_quant.timeseries.measures.GsAssetApi.get_many_assets', Mock()) assets.return_value = [mock_asset_1, mock_asset_2] mock_data = replace('gs_quant.timeseries.measures.GsDataApi.get_market_data', Mock()) mock_data.return_value = mock_df() actual = tm_fxo.vol_swap_strike(base, "1y", location=PricingLocation.LDN, real_time=False) assert_series_equal(tm_rates._extract_series_from_df(mock_df(), QueryType.STRIKE_VOL), actual) actual = tm_fxo.vol_swap_strike(base, "1y", None, real_time=False) assert_series_equal(tm_rates._extract_series_from_df(mock_df(), QueryType.STRIKE_VOL), actual) replace.restore()
def test_swaption_premium_return_data(): replace = Replacer() test_data = dict(swaptionPremium=[1, 2, 3]) df = MarketDataResponseFrame(data=test_data, index=[dt.date(2019, 1, 1), dt.date(2019, 1, 2), dt.date(2019, 1, 3)]) replace('gs_quant.timeseries.measures.Asset.get_identifier', Mock()).return_value = "GBP" replace('gs_quant.timeseries.measures_rates._get_tdapi_rates_assets', Mock(), Mock()).return_value = "MADWG3WHCKNE1DJA" replace('gs_quant.timeseries.measures_rates._range_from_pricing_date', Mock(), Mock()).return_value = [ dt.date(2019, 1, 2), dt.date(2019, 1, 5)] replace('gs_quant.timeseries.measures_rates._market_data_timed', Mock()).return_value = df actual = tm_rates.swaption_premium(Currency("GBP", name="GBP")) assert_series_equal(tm._extract_series_from_df(df, QueryType.SWAPTION_PREMIUM), actual) replace.restore()
def aum(portfolio_id: str, start_date: dt.date = None, end_date: dt.date = None, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Returns the Custom AUM uploaded for the portfolio :param portfolio_id: id of portfolio :param start_date: start date for getting aum :param end_date: end date for getting aum :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :param request_id: server request id :return: portfolio aum values """ data = GsPortfolioApi.get_custom_aum(portfolio_id, start_date, end_date) df = pd.DataFrame.from_records(data) df.set_index(pd.DatetimeIndex(df['date']), inplace=True) return _extract_series_from_df(df, QueryType.AUM, True)
def fci(country_id: str, measure: _FCI_MEASURE = _FCI_MEASURE.FCI, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Daily Financial Conditions Index (FCI) for each of the world's large economies and many smaller ones, as well as aggregate FCIs for regions. :param country_id: id of country/region :param measure: FCI metric to retrieve :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :param request_id: server request id :return: FCI metric value """ if real_time: raise NotImplementedError('real-time FCI data is not available') type_ = QueryType(inflection.titleize(measure.value)) if (measure == _FCI_MEASURE.REAL_FCI or measure == _FCI_MEASURE.REAL_TWI_CONTRIBUTION): ds = Dataset('FCI') df = ds.get_data(geographyId=country_id) if (measure == _FCI_MEASURE.REAL_FCI): measure = 'realFCI' else: measure = 'realTWIContribution' series = ExtendedSeries(dtype=float) if ( measure not in df.columns) else ExtendedSeries(df[measure]) series.dataset_ids = ('FCI', ) return series q = GsDataApi.build_market_data_query([country_id], query_type=type_, source=source, real_time=real_time) df = _market_data_timed(q, request_id) return _extract_series_from_df(df, type_, True)
def _get_factor_data(report_id: str, factor_name: str, query_type: QueryType) -> pd.Series: # Check params report = RiskReport(report_id) if report.get_type() not in [ ReportType.Portfolio_Factor_Risk, ReportType.Asset_Factor_Risk ]: raise MqValueError('This report is not a factor risk report') risk_model_id = report.get_risk_model_id() if factor_name not in ['Factor', 'Specific', 'Total']: if query_type in [QueryType.DAILY_RISK, QueryType.ANNUAL_RISK]: raise MqValueError( 'Please pick a factor name from the following: ["Total", "Factor", "Specific"]' ) factor = Factor(risk_model_id, factor_name) factor_name = factor.name # Extract relevant data for each date col_name = query_type.value.replace(' ', '') col_name = decapitalize(col_name) data_type = decapitalize( col_name[6:]) if col_name.startswith('factor') else col_name factor_data = report.get_factor_data( factor=factor_name, start_date=DataContext.current.start_time, end_date=DataContext.current.end_time) factor_exposures = [{ 'date': data['date'], col_name: data[data_type] } for data in factor_data if data.get(data_type)] # Create and return timeseries df = pd.DataFrame(factor_exposures) if not df.empty: df.set_index('date', inplace=True) df.index = pd.to_datetime(df.index) return _extract_series_from_df(df, query_type)
def covariance(risk_model_id: str, factor_1: str, factor_2: str, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Covariance timeseries between two factors in a risk model :param risk_model_id: risk model entity :param factor_1: first factor name :param factor_2: second factor name :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :param request_id: server request id :return: Timeseries of covariances between the two factors across available risk model dates """ model = RiskModel(risk_model_id) factor_1 = Factor(risk_model_id, factor_1) factor_2 = Factor(risk_model_id, factor_2) if None in [factor_1.factor, factor_2.factor]: raise MqValueError( 'Factor names requested are not available for this risk model') # Find all covariances between two factors for date range dates = model.get_dates() start_date = dt.datetime.strptime(min(dates), '%Y-%m-%d') if dates else None end_date = dt.datetime.strptime(max(dates), '%Y-%m-%d') if dates else None covariances = factor_1.get_covariance(factor_2, start_date, end_date) # Create and return timeseries df = pd.DataFrame(covariances) df.set_index('date', inplace=True) df.index = pd.to_datetime(df.index) return _extract_series_from_df(df, QueryType.COVARIANCE)