def test_fci(): with pytest.raises(NotImplementedError): mc.fci('IN', real_time=True) data = { 'fci': [101, 102, 103], 'realFCI': [100, 99, 98], 'realTWIContribution': [100, 100, 98] } idx = pd.date_range('2020-01-01', freq='D', periods=3) df = MarketDataResponseFrame(data=data, index=idx) df.dataset_ids = ('FCI', ) replace = Replacer() mock = replace('gs_quant.timeseries.measures.GsDataApi.get_market_data', Mock()) mock.return_value = df with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mc.fci('IN') assert actual.index.equals(idx) assert all(actual.values == data['fci']) mock = replace('gs_quant.timeseries.measures.Dataset.get_data', Mock()) mock.return_value = df with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mc.fci('IN', mc._FCI_MEASURE.REAL_FCI) assert actual.index.equals(idx) assert all(actual.values == data['realFCI']) with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mc.fci('IN', mc._FCI_MEASURE.REAL_TWI_CONTRIBUTION) assert actual.index.equals(idx) assert all(actual.values == data['realTWIContribution']) replace.restore()
def test_fwd_term(): with DataContext('2018-01-01', '2019-01-01'): _fwd_term_typical() _fwd_term_empty() with DataContext('2018-01-16', '2018-12-31'): out = _fwd_term_typical() assert out.empty with pytest.raises(NotImplementedError): tm.fwd_term(..., real_time=True)
def test_vol_term(): with DataContext('2018-01-01', '2019-01-01'): _vol_term_typical(tm.SkewReference.SPOT, 100) _vol_term_typical(tm.SkewReference.NORMALIZED, 4) _vol_term_empty() with DataContext('2018-01-16', '2018-12-31'): out = _vol_term_typical(tm.SkewReference.SPOT, 100) assert out.empty with pytest.raises(NotImplementedError): tm.vol_term(..., tm.SkewReference.SPOT, 100, real_time=True)
def test_aggregate_factor_support(): replace = Replacer() # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = risk_model mock = replace('gs_quant.api.gs.reports.GsReportApi.get_report', Mock()) mock.return_value = factor_risk_report # mock getting report factor data mock = replace('gs_quant.api.gs.reports.GsReportApi.get_factor_risk_report_results', Mock()) mock.return_value = aggregate_factor_data # mock getting risk model dates mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_dates', Mock()) mock.return_value = ['2010-01-01'] # mock getting risk model factor category mock = replace('gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_data', Mock()) mock.return_value = { 'results': [{ 'factorData': [{ 'factorId': 'factor_id', 'factorCategory': 'Factor Name' }]} ]} # mock getting risk model factor entity mock = replace('gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = [{ 'identifier': 'factor_id', 'type': 'Factor', 'name': 'Factor Name', 'factorCategory': 'Factor Name' }] with DataContext(datetime.date(2020, 11, 23), datetime.date(2020, 11, 25)): actual = mr.factor_proportion_of_risk('report_id', 'Factor') assert all(actual.values == [1, 2, 3]) with DataContext(datetime.date(2020, 11, 23), datetime.date(2020, 11, 25)): actual = mr.daily_risk('report_id', 'Factor') assert all(actual.values == [1, 2, 3]) with DataContext(datetime.date(2020, 11, 23), datetime.date(2020, 11, 25)): actual = mr.annual_risk('report_id', 'Factor') assert all(actual.values == [1, 2, 3]) with pytest.raises(MqValueError): mr.daily_risk('report_id', 'Factor Name') with pytest.raises(MqValueError): mr.annual_risk('report_id', 'Factor Name') replace.restore()
def test_var_term(): with DataContext('2018-01-01', '2019-01-01'): _var_term_typical() _var_term_empty() _var_term_fwd() with DataContext('2019-01-01', '2019-07-04'): _var_term_fwd() with DataContext('2018-01-16', '2018-12-31'): out = _var_term_typical() assert out.empty with pytest.raises(MqError): tm.var_term(..., pricing_date=300)
def test_thematic_beta(): replace = Replacer() # mock getting PTA report mock = replace('gs_quant.markets.report.ThematicReport.get', Mock()) mock.return_value = ThematicReport(id='report_id') # mock getting thematic exposure mock = replace('gs_quant.markets.report.ThematicReport.get_thematic_betas', Mock()) mock.return_value = pd.DataFrame(thematic_data) # mock getting asset mock = Stock('MAA0NE9QX2ABETG6', 'Test Asset') xrefs = replace('gs_quant.timeseries.measures.GsAssetApi.get_asset_xrefs', Mock()) xrefs.return_value = [ GsTemporalXRef(datetime.date(2019, 1, 1), datetime.date(2952, 12, 31), XRef(ticker='basket_ticker', )) ] replace('gs_quant.markets.securities.SecurityMaster.get_asset', Mock()).return_value = mock with DataContext(datetime.date(2020, 7, 12), datetime.date(2020, 7, 15)): actual = mr.thematic_beta('report_id', 'basket_ticker') assert all(actual.values == [1, 1, 1, 1]) replace.restore()
def test_financial_conditions_index(): data = { 'pnl': [ 101, 102, 103 ], 'date': [ '2020-01-01', '2020-01-02', '2020-01-03' ] } idx = pd.date_range('2020-01-01', freq='D', periods=3) df = MarketDataResponseFrame(data=data, index=idx) df.dataset_ids = ('PNL',) replace = Replacer() # mock PerformanceReport.get_pnl() mock = replace('gs_quant.markets.report.PerformanceReport.get_pnl', Mock()) mock.return_value = df # mock GsPortfolioApi.get_reports() mock = replace('gs_quant.api.gs.portfolios.GsPortfolioApi.get_reports', Mock()) mock.return_value = [Report.from_dict({'id': 'RP1', 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1', 'type': 'Portfolio Performance Analytics', 'parameters': {'transactionCostModel': 'FIXED'}})] with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mp.pnl('MP1') assert actual.index.equals(idx) assert all(actual.values == data['pnl']) replace.restore()
def test_factor_exposure(): replace = Replacer() # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = risk_model mock = replace('gs_quant.api.gs.reports.GsReportApi.get_report', Mock()) mock.return_value = factor_risk_report # mock getting report factor data mock = replace('gs_quant.api.gs.reports.GsReportApi.get_risk_factor_data_results', Mock()) mock.return_value = factor_data # mock getting risk model factor entity mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = [{ 'identifier': 'factor_id', 'type': 'Factor', 'name': "Factor Name" }] with DataContext(datetime.date(2020, 11, 23), datetime.date(2020, 11, 25)): actual = mr.factor_exposure('report_id', 'Factor Name') assert all(actual.values == [-11.23, -11.24, -11.25]) with pytest.raises(MqValueError): mr.factor_exposure('report_id', 'Wrong Factor Name') replace.restore()
def test_normalized_performance_short(): idx = pd.date_range('2020-01-02', freq='D', periods=3) replace = Replacer() expected = {"Short": pd.Series(data=[1, 1 / 2, 1 / 3], index=idx, name='normalizedPerformance', dtype='float64'), "Long": pd.Series(data=[1, 2, 3], index=idx, name='normalizedPerformance', dtype='float64'), None: pd.Series(data=[1, (2 + 1 / 2) / 2, (3 + 1 / 3) / 2], index=idx, name='normalizedPerformance', dtype='float64')} mock = replace('gs_quant.api.gs.portfolios.GsPortfolioApi.get_reports', Mock()) mock.return_value = [ Report.from_dict({'id': 'RP1', 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1', 'type': 'Portfolio Performance Analytics', 'parameters': {'transactionCostModel': 'FIXED'}})] # mock PerformanceReport.get_portfolio_constituents() mock = replace('gs_quant.markets.report.PerformanceReport.get_portfolio_constituents', Mock()) mock.return_value = MarketDataResponseFrame(data=constituents_data_l_s, dtype="float64") # mock PerformanceReport.get() mock = replace('gs_quant.markets.report.PerformanceReport.get', Mock()) mock.return_value = PerformanceReport(report_id='RP1', position_source_type='Portfolio', position_source_id='MP1', report_type='Portfolio Performance Analytics', parameters=ReportParameters(transaction_cost_model='FIXED')) for k, v in expected.items(): with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mr.normalized_performance('MP1', k) assert all((actual.values - v.values) < 0.01) replace.restore()
def test_custom_aum(): data = { 'aum': [ 101, 102, 103 ], 'date': [ '2020-01-01', '2020-01-02', '2020-01-03' ] } idx = pd.date_range('2020-01-01', freq='D', periods=3) df = MarketDataResponseFrame(data=data, index=idx) df.dataset_ids = ('AUM',) replace = Replacer() # mock GsPortfolioApi.get_reports() mock = replace('gs_quant.api.gs.portfolios.GsPortfolioApi.get_custom_aum', Mock()) mock.return_value = df with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mp.aum('MP1') assert actual.index.equals(idx) assert all(actual.values == data['aum']) replace.restore()
def test_factor_volatility(): replace = Replacer() # mock getting risk model factor entity mock = replace('gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_data', Mock()) mock.return_value = mock_risk_model_data # mock getting risk model factor entity mock = replace('gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = mock_risk_model_factor_data # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = mock_risk_model_obj # mock getting risk model dates mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_dates', Mock()) mock.return_value = ['2020-01-01', '2020-01-02', '2020-01-03'] # mock getting covariances mock = replace('gs_quant.markets.factor.Factor.variance', Mock()) mock.return_value = mock_covariance_curve with DataContext(datetime.date(2020, 1, 1), datetime.date(2020, 1, 3)): actual = mrm.factor_volatility(mock_risk_model(), 'Factor Name') assert all(actual.values == [sqrt(1.01) * 100, sqrt(1.02) * 100, sqrt(1.03) * 100]) with pytest.raises(MqValueError): mrm.covariance(mock_risk_model(), 'Wrong Factor Name', 'Factor Name') replace.restore()
def test_factor_correlation(): replace = Replacer() # mock getting risk model factor entity mock = replace( 'gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_data', Mock()) mock.return_value = mock_risk_model_data # mock getting risk model factor entity mock = replace( 'gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = mock_risk_model_factor_data # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = mock_risk_model_obj # mock getting risk model dates mock = replace( 'gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_dates', Mock()) mock.return_value = ['2020-01-01', '2020-01-02', '2020-01-03'] # mock getting covariances mock = replace('gs_quant.markets.factor.Factor.covariance', Mock()) mock.return_value = mock_covariance_curve with DataContext(datetime.date(2020, 1, 1), datetime.date(2020, 1, 3)): actual = mrm.factor_correlation(mock_risk_model(), 'Factor Name', 'Factor Name') assert all(actual.values == [1.0000000000000002, 1, 1]) replace.restore()
def test_normalized_performance_default_aum(): idx = pd.date_range('2020-01-02', freq='D', periods=3) expected = pd.Series(data=[1, 1 / 0.8, 1 / 0.6], index=idx, name='normalizedPerformance', dtype='float64') with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): df = MarketDataResponseFrame(data=ppa_data, dtype="float64") replace = Replacer() # mock GsPortfolioApi.get_reports() mock = replace('gs_quant.api.gs.portfolios.GsPortfolioApi.get_reports', Mock()) mock.return_value = [ Report.from_dict({ 'id': 'RP1', 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1', 'type': 'Portfolio Performance Analytics', 'parameters': { 'transactionCostModel': 'FIXED' } }) ] # mock PerformanceReport.get_many_measures() mock = replace( 'gs_quant.markets.report.PerformanceReport.get_many_measures', Mock()) mock.return_value = df # mock PerformanceReport.get_custom_aum() mock = replace( 'gs_quant.api.gs.portfolios.GsPortfolioApi.get_custom_aum', Mock()) mock.return_value = aum # mock PerformanceReport.get() mock = replace('gs_quant.markets.report.PerformanceReport.get', Mock()) mock.return_value = PerformanceReport( report_id='RP1', position_source_type='Portfolio', position_source_id='MP1', report_type='Portfolio Performance Analytics', parameters=ReportParameters(transaction_cost_model='FIXED')) mock = replace( 'gs_quant.api.gs.portfolios.GsPortfolioApi.get_portfolio', Mock()) mock.return_value = Portfolio('USD', 'P1', id_='MP1') actual = mr.normalized_performance('MP1', None) assert all(actual.values == expected.values) replace.restore()
def vol_term(asset: Asset, strike_reference: SkewReference, relative_strike: Real, pricing_date: Optional[GENERIC_DATE] = None, *, source: str = None, real_time: bool = False) -> pd.Series: """ Volatility term structure. Uses most recent date available if pricing_date is not provided. :param asset: asset object loaded from security master :param strike_reference: reference for strike level :param relative_strike: strike relative to reference :param pricing_date: YYYY-MM-DD or relative days before today e.g. 1d, 1m, 1y :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :return: volatility term structure """ if real_time: raise NotImplementedError( 'realtime forward term not implemented') # TODO if strike_reference != SkewReference.NORMALIZED: relative_strike /= 100 start, end = _range_from_pricing_date(asset.exchange, pricing_date) with DataContext(start, end): _logger.debug('where strikeReference=%s, relativeStrike=%s', strike_reference.value, relative_strike) where = FieldFilterMap(strikeReference=strike_reference.value, relativeStrike=relative_strike) q = GsDataApi.build_market_data_query([asset.get_marquee_id()], QueryType.IMPLIED_VOLATILITY, where=where, source=source, real_time=real_time) _logger.debug('q %s', q) df = _market_data_timed(q) if df.empty: return pd.Series() latest = df.index.max() _logger.info('selected pricing date %s', latest) df = df.loc[latest] cbd = _get_custom_bd(asset.exchange) df = df.assign(expirationDate=df.index + df['tenor'].map(_to_offset) + cbd - cbd) df = df.set_index('expirationDate') df.sort_index(inplace=True) df = df.loc[DataContext.current.start_date:DataContext.current.end_date] return df['impliedVolatility'] if not df.empty else pd.Series()
def test_normalized_performance_no_custom_aum(): with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): df = MarketDataResponseFrame(data=ppa_data, dtype="float64") replace = Replacer() # mock GsPortfolioApi.get_reports() mock = replace('gs_quant.api.gs.portfolios.GsPortfolioApi.get_reports', Mock()) mock.return_value = [ Report.from_dict({ 'id': 'RP1', 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1', 'type': 'Portfolio Performance Analytics', 'parameters': { 'transactionCostModel': 'FIXED' } }) ] # mock PerformanceReport.get_many_measures() mock = replace( 'gs_quant.markets.report.PerformanceReport.get_many_measures', Mock()) mock.return_value = df # mock PerformanceReport.get_portfolio_constituents() mock = replace( 'gs_quant.markets.report.PerformanceReport.get_portfolio_constituents', Mock()) mock.return_value = MarketDataResponseFrame(data=constituents_data, dtype="float64") # mock PerformanceReport.get_custom_aum() mock = replace( 'gs_quant.api.gs.portfolios.GsPortfolioApi.get_custom_aum', Mock()) mock.return_value = pd.DataFrame({}) # mock PerformanceReport.get() mock = replace('gs_quant.markets.report.PerformanceReport.get', Mock()) mock.return_value = PerformanceReport( report_id='RP1', position_source_type='Portfolio', position_source_id='MP1', report_type='Portfolio Performance Analytics', parameters=ReportParameters(transaction_cost_model='FIXED')) with pytest.raises(MqError): mr.normalized_performance('MP1', 'Custom AUM') replace.restore()
def test_swaption_vol_smile2_returns_no_data(): replace = Replacer() df = ExtendedSeries() 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(2020, 1, 2), dt.date(2020, 1, 2)] replace('gs_quant.timeseries.measures_rates._market_data_timed', Mock()).return_value = df with DataContext('2019-01-01', '2025-01-01'): actual = tm_rates.swaption_vol_smile(Currency("GBP", name="GBP"), '3m', '10y') assert_series_equal(ExtendedSeries(), actual) replace.restore()
def test_swaption_swaption_vol_term2_returns_data(): replace = Replacer() df = MarketDataResponseFrame( data=dict(expirationTenor=['1m', '6m', '1y'], terminationTenor=['1y', '2y', '3y'], swaptionVol=[1, 2, 3]), index=_index * 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(2020, 1, 2), dt.date(2020, 1, 2)] replace('gs_quant.timeseries.measures_rates._market_data_timed', Mock()).return_value = df with DataContext('2019-01-01', '2025-01-01'): actual = tm_rates.swaption_vol_term(Currency("GBP", name="GBP"), tm.SwaptionTenorType.SWAP_MATURITY, '5y', 0) expected = pd.Series([1, 2, 3], index=pd.to_datetime(['2019-02-01', '2019-07-01', '2020-01-01'])) assert_series_equal(expected, pd.Series(actual), check_names=False) with DataContext('2019-01-01', '2025-01-01'): actual = tm_rates.swaption_vol_term(Currency("GBP", name="GBP"), tm.SwaptionTenorType.OPTION_EXPIRY, '5y', 0) expected = pd.Series([1, 2, 3], index=pd.to_datetime(['2020-01-01', '2021-01-01', '2021-12-31'])) assert_series_equal(expected, pd.Series(actual), check_names=False) replace.restore()
def test_swaption_swaption_vol_term2_returns_empty(): replace = Replacer() df = ExtendedSeries() 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(2020, 1, 2), dt.date(2020, 1, 2)] replace('gs_quant.timeseries.measures_rates._market_data_timed', Mock()).return_value = df with DataContext('2019-01-01', '2025-01-01'): actual = tm_rates.swaption_vol_term(Currency("GBP", name="GBP"), tm.SwaptionTenorType.SWAP_MATURITY, '5y', 0) assert_series_equal(ExtendedSeries(), actual, check_names=False) replace.restore()
def test_covariance(): risk_model = RiskModel(coverage=CoverageType.Country, id_='model_id', name='Fake Risk Model', term=Term.Long, universe_identifier=UniverseIdentifier.gsid, vendor='GS', version=1.0) covariances = [ { 'date': '2020-01-01', 'covariance': 1.01 }, { 'date': '2020-01-02', 'covariance': 1.02 }, { 'date': '2020-01-03', 'covariance': 1.03 }, ] replace = Replacer() # mock getting risk model factor entity mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = [{ 'identifier': 'factor_id', 'type': 'Factor', 'name': "Factor Name" }] # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = risk_model # mock getting risk model dates mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_dates', Mock()) mock.return_value = ['2020-01-01', '2020-01-02', '2020-01-03'] # mock getting covariances mock = replace('gs_quant.markets.factor.Factor.get_covariance', Mock()) mock.return_value = covariances with DataContext(datetime.date(2020, 1, 1), datetime.date(2020, 1, 3)): actual = mrm.covariance(mock_risk_model(), 'Factor Name', 'Factor Name') assert all(actual.values == [1.01, 1.02, 1.03]) with pytest.raises(MqValueError): mrm.covariance(mock_risk_model(), 'Wrong Factor Name', 'Factor Name') replace.restore()
def test_swaption_vol_smile2_returns_data(): replace = Replacer() test_data = dict(strikeRelative=["ATM", "ATM+50", "ATM+100"], swaptionVol=[1, 2, 3]) df = MarketDataResponseFrame(data=test_data, index=_index * 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(2020, 1, 2), dt.date(2020, 1, 2)] replace('gs_quant.timeseries.measures_rates._market_data_timed', Mock()).return_value = df with DataContext('2019-01-01', '2025-01-01'): actual = tm_rates.swaption_vol_smile(Currency("GBP", name="GBP"), '3m', '10y') assert_series_equal(pd.Series([1, 2, 3], index=[0.0, 50.0, 100.0]), pd.Series(actual)) replace.restore()
def vol_smile(asset: Asset, tenor: str, strike_reference: VolSmileReference, pricing_date: Optional[GENERIC_DATE] = None, *, source: str = None, real_time: bool = False) -> Series: """ Volatility smile of an asset implied by observations of market prices. :param asset: asset object loaded from security master :param tenor: relative date representation of expiration date e.g. 1m :param strike_reference: reference for strike level :param pricing_date: YYYY-MM-DD or relative days before today e.g. 1d, 1m, 1y :param source: name of function caller :param real_time: whether to retrieve intraday data instead of EOD :return: implied volatility smile """ if real_time: raise NotImplementedError('realtime vol_smile not implemented') mqid = asset.get_marquee_id() start, end = _range_from_pricing_date(asset.exchange, pricing_date) with DataContext(start, end): q = GsDataApi.build_market_data_query( [mqid], QueryType.IMPLIED_VOLATILITY, where=FieldFilterMap(tenor=tenor, strikeReference=strike_reference.value), source=source, real_time=real_time) _logger.debug('q %s', q) df = _market_data_timed(q) if df.empty: return Series latest = df.index.max() _logger.info('selected pricing date %s', latest) df = df.loc[latest] vols = df['impliedVolatility'].values strikes = df['relativeStrike'].values return Series(vols, index=strikes)
def test_get_short_pnl(): idx = pd.date_range('2020-01-02', freq='D', periods=3) replace = Replacer() expected = pd.Series(data=[0, -2, -2], index=idx, name='shortPnl', dtype='float64') mock = replace('gs_quant.api.gs.portfolios.GsPortfolioApi.get_reports', Mock()) mock.return_value = [ Report.from_dict({ 'id': 'RP1', 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1', 'type': 'Portfolio Performance Analytics', 'parameters': { 'transactionCostModel': 'FIXED' } }) ] # mock PerformanceReport.get_portfolio_constituents() mock = replace( 'gs_quant.markets.report.PerformanceReport.get_portfolio_constituents', Mock()) mock.return_value = MarketDataResponseFrame(data=pnl_data_l_s) # mock PerformanceReport.get() mock = replace('gs_quant.markets.report.PerformanceReport.get', Mock()) mock.return_value = PerformanceReport( report_id='RP1', position_source_type='Portfolio', position_source_id='MP1', report_type='Portfolio Performance Analytics', parameters=ReportParameters(transaction_cost_model='FIXED')) with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mr.short_pnl('MP1') assert all(actual.values == expected.values) replace.restore()
def test_get_long_pnl_empty(): replace = Replacer() expected = pd.Series(dtype=float) mock = replace('gs_quant.api.gs.portfolios.GsPortfolioApi.get_reports', Mock()) mock.return_value = [ Report.from_dict({ 'id': 'RP1', 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1', 'type': 'Portfolio Performance Analytics', 'parameters': { 'transactionCostModel': 'FIXED' } }) ] # mock PerformanceReport.get_portfolio_constituents() mock = replace( 'gs_quant.markets.report.PerformanceReport.get_portfolio_constituents', Mock()) mock.return_value = MarketDataResponseFrame(data=constituents_data_s) # mock PerformanceReport.get() mock = replace('gs_quant.markets.report.PerformanceReport.get', Mock()) mock.return_value = PerformanceReport( report_id='RP1', position_source_type='Portfolio', position_source_id='MP1', report_type='Portfolio Performance Analytics', parameters=ReportParameters(transaction_cost_model='FIXED')) with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): actual = mr.long_pnl('MP1') assert all(actual.values == expected.values) replace.restore()
def test_factor_performance(): replace = Replacer() # mock getting risk model factor entity mock = replace( 'gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_data', Mock()) mock.return_value = mock_risk_model_data # mock getting risk model factor entity mock = replace( 'gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = mock_risk_model_factor_data # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = mock_risk_model_obj # mock getting risk model dates mock = replace( 'gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_dates', Mock()) mock.return_value = ['2020-01-01', '2020-01-02', '2020-01-03'] # mock getting factor returns mock = replace('gs_quant.markets.factor.Factor.returns', Mock()) mock.return_value = pd.DataFrame.from_dict(mock_covariance_curve, orient='index', columns=['return']) with DataContext(datetime.date(2020, 1, 1), datetime.date(2020, 1, 3)): actual = mrm.factor_performance(mock_risk_model(), 'Factor Name') assert len(actual.values) == 3 replace.restore()
def test_factor_zscore(): replace = Replacer() # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = mock_risk_model_obj # mock getting risk model factor entity mock = replace( 'gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_data', Mock()) mock.return_value = mock_risk_model_data # mock getting risk model factor entity mock = replace( 'gs_quant.api.gs.risk_models.GsFactorRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = mock_risk_model_factor_data # mock getting asset gsid mock = replace('gs_quant.markets.securities.Asset.get_identifier', Mock()) mock.return_value = '12345' # mock getting risk model dates mock = replace( 'gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_dates', Mock()) mock.return_value = ['2020-01-01', '2020-01-02', '2020-01-03'] # mock getting risk model data mock = replace('gs_quant.models.risk_model.FactorRiskModel.get_data', Mock()) mock.return_value = { 'results': [{ 'date': '2020-01-01', 'assetData': { 'factorExposure': [{ 'factor_id': 1.01, 'factor_id_1': 1.23 }] } }, { 'date': '2020-01-02', 'assetData': { 'factorExposure': [{ 'factor_id': 1.02, 'factor_id_1': 1.23 }] } }, { 'date': '2020-01-03', 'assetData': { 'factorExposure': [{ 'factor_id': 1.03, 'factor_id_1': 1.23 }] } }] } with DataContext(datetime.date(2020, 1, 1), datetime.date(2020, 1, 3)): actual = mrm.factor_zscore(Stock(id_='id', name='Fake Asset'), 'model_id', 'Factor Name') assert all(actual.values == [1.01, 1.02, 1.03]) with pytest.raises(MqValueError): mrm.factor_zscore(Stock(id_='id', name='Fake Asset'), 'model_id', 'Wrong Factor Name') replace.restore()
def test_normalized_performance(): idx = pd.date_range('2020-01-02', freq='D', periods=3) expected = { RiskAumSource.Net: pd.Series(data=[1, 1 + 2 / 4, 1 + 6 / 6], index=idx, name='normalizedPerformance', dtype='float64'), RiskAumSource.Gross: pd.Series(data=[1, 1 + 2 / 1.2, 1 + 6 / 1.3], index=idx, name='normalizedPerformance', dtype='float64'), RiskAumSource.Long: pd.Series(data=[1, 1 + 2 / 1.2, 1 + 6 / 1.3], index=idx, name='normalizedPerformance', dtype='float64'), RiskAumSource.Short: pd.Series(data=[1, 1 + 2 / 1.2, 1 + 6 / 1.3], index=idx, name='normalizedPerformance', dtype='float64'), RiskAumSource.Custom_AUM: pd.Series(data=[1, 1 + 2 / 2.2, 1 + 6 / 2.4], index=idx, name='normalizedPerformance', dtype='float64') } with DataContext(datetime.date(2020, 1, 1), datetime.date(2019, 1, 3)): for k, v in expected.items(): df = MarketDataResponseFrame(data=ppa_data, dtype="float64") replace = Replacer() # mock GsPortfolioApi.get_reports() mock = replace( 'gs_quant.api.gs.portfolios.GsPortfolioApi.get_reports', Mock()) mock.return_value = [ Report.from_dict({ 'id': 'RP1', 'positionSourceType': 'Portfolio', 'positionSourceId': 'MP1', 'type': 'Portfolio Performance Analytics', 'parameters': { 'transactionCostModel': 'FIXED' } }) ] # mock PerformanceReport.get_portfolio_constituents() mock = replace( 'gs_quant.markets.report.PerformanceReport.get_portfolio_constituents', Mock()) mock.return_value = MarketDataResponseFrame(data=constituents_data, dtype="float64") # mock PerformanceReport.get_many_measures() mock = replace( 'gs_quant.markets.report.PerformanceReport.get_many_measures', Mock()) mock.return_value = df # mock PerformanceReport.get_custom_aum() mock = replace( 'gs_quant.api.gs.portfolios.GsPortfolioApi.get_custom_aum', Mock()) mock.return_value = aum # mock PerformanceReport.get() mock = replace('gs_quant.markets.report.PerformanceReport.get', Mock()) mock.return_value = PerformanceReport( report_id='RP1', position_source_type='Portfolio', position_source_id='MP1', report_type='Portfolio Performance Analytics', parameters=ReportParameters(transaction_cost_model='FIXED')) actual = mr.normalized_performance('MP1', k.value) assert all(actual.values == v.values) replace.restore()
def test_bucketize_price(): target = { '7x24': [27.323461], 'offpeak': [26.004816], 'peak': [27.982783], '7x8': [26.004816], '2x16h': [], 'monthly': [], 'CAISO 7x24': [26.518563] } replace = Replacer() replace('gs_quant.timeseries.measures.GsDataApi.get_market_data', mock_commod) mock_pjm = Index('MA001', AssetClass.Commod, 'PJM') mock_caiso = Index('MA001', AssetClass.Commod, 'CAISO') mock_miso = Index('MA001', AssetClass.Commod, 'MISO') with DataContext(datetime.date(2019, 5, 1), datetime.date(2019, 5, 1)): bbid_mock = replace( 'gs_quant.timeseries.measures.Asset.get_identifier', Mock()) bbid_mock.return_value = 'CAISO' actual = tm.bucketize_price(mock_caiso, 'LMP', 'totalPrice', bucket='7x24') assert_series_equal( pd.Series(target['CAISO 7x24'], index=[datetime.date(2019, 5, 1)], name='price'), actual) bbid_mock.return_value = 'PJM' actual = tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', bucket='7x24') assert_series_equal( pd.Series(target['7x24'], index=[datetime.date(2019, 5, 1)], name='price'), actual) actual = tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', bucket='offpeak') assert_series_equal( pd.Series(target['offpeak'], index=[datetime.date(2019, 5, 1)], name='price'), actual) actual = tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', bucket='peak') assert_series_equal( pd.Series(target['peak'], index=[datetime.date(2019, 5, 1)], name='price'), actual) actual = tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', bucket='7x8') assert_series_equal( pd.Series(target['7x8'], index=[datetime.date(2019, 5, 1)], name='price'), actual) actual = tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', bucket='2x16h') assert_series_equal(pd.Series(target['2x16h'], index=[], name='price'), actual) actual = tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', granularity='m', bucket='7X24') assert_series_equal( pd.Series(target['monthly'], index=[], name='price'), actual) with pytest.raises(ValueError): tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', bucket='weekday') with pytest.raises(ValueError): tm.bucketize_price(mock_pjm, 'LMP', 'totalPrice', granularity='yearly') replace.restore()
def test_factor_exposure(): risk_model = RiskModel(coverage=CoverageType.Country, id_='model_id', name='Fake Risk Model', term=Term.Long, universe_identifier=UniverseIdentifier.gsid, vendor='GS', version=1.0) risk_model_data = { 'results': [ { 'date': '2020-01-01', 'assetData': { 'factorExposure': [ { 'factor_id': 1.01, 'factor_id_1': 1.23 } ] } }, { 'date': '2020-01-02', 'assetData': { 'factorExposure': [ { 'factor_id': 1.02, 'factor_id_1': 1.23 } ] } }, { 'date': '2020-01-03', 'assetData': { 'factorExposure': [ { 'factor_id': 1.03, 'factor_id_1': 1.23 } ] } } ] } replace = Replacer() # mock getting risk model entity() mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model', Mock()) mock.return_value = risk_model # mock getting risk model factor entity mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_factor_data', Mock()) mock.return_value = [{ 'identifier': 'factor_id', 'type': 'Factor', 'name': "Factor Name" }] # mock getting asset gsid mock = replace('gs_quant.markets.securities.Asset.get_identifiers', Mock()) mock.return_value = {'GSID': '12345'} # mock getting risk model dates mock = replace('gs_quant.api.gs.risk_models.GsRiskModelApi.get_risk_model_dates', Mock()) mock.return_value = ['2020-01-01', '2020-01-02', '2020-01-03'] # mock getting risk model data mock = replace('gs_quant.markets.risk_model.RiskModel.get_data', Mock()) mock.return_value = risk_model_data with DataContext(datetime.date(2020, 1, 1), datetime.date(2020, 1, 3)): actual = mrm.factor_exposure(Stock(id_='id', name='Fake Asset'), 'model_id', 'Factor Name') assert all(actual.values == [1.01, 1.02, 1.03]) with pytest.raises(MqValueError): mrm.factor_exposure(Stock(id_='id', name='Fake Asset'), 'model_id', 'Wrong Factor Name') replace.restore()
def bucketize_price(asset: Asset, price_method: str, price_component: str, bucket: str = '7x24', granularity: str = 'daily', *, source: str = None, real_time: bool = True) -> pd.Series: """' Bucketized Elec Historical Clears :param asset: asset object loaded from security master :param price_method: price method between LMP and MCP: Default value = LMP :param price_component: price type among totalPrice, energy, loss and congestion: Default value = totalPrice :param bucket: bucket type among '7x24', 'peak', 'offpeak', '2x16h' and '7x8': Default value = 7x24 :param granularity: daily or monthly: default value = daily :param source: name of function caller: default source = None :param real_time: whether to retrieve intraday data instead of EOD: default value = True :return: Bucketized Elec Historical Clears """ # create granularity indicator if granularity.lower() in ['daily', 'd']: granularity = 'D' elif granularity.lower() in ['monthly', 'm']: granularity = 'M' else: raise ValueError('Invalid granularity: ' + granularity + '. Expected Value: daily or monthly.') start_date, end_date = DataContext.current.start_date, DataContext.current.end_date where = FieldFilterMap(priceMethod=price_method, priceComponent=price_component) with DataContext(start_date, end_date + datetime.timedelta(days=2)): q = GsDataApi.build_market_data_query([asset.get_marquee_id()], QueryType.PRICE, where=where, source=source, real_time=True) df = _market_data_timed(q) _logger.debug('q %s', q) # TODO: get timezone info from Asset # default frequency definition df = df.tz_convert('US/Eastern') peak_start = 7 peak_end = 23 weekends = [5, 6] bbid = Asset.get_identifier(asset, AssetIdentifier.BLOOMBERG_ID) if bbid.split(" ")[0] in ['MISO', 'CAISO', 'ERCOT', 'SPP']: df = df.tz_convert('US/Central') peak_start = 6 peak_end = 22 if bbid.split(" ")[0] == 'CAISO': df = df.tz_convert('US/Pacific') weekends = [6] start_time, end_time = pd.to_datetime( start_date), pd.to_datetime(end_date) + datetime.timedelta(hours=23) df['month'] = df.index.month df['date'] = df.index.date df['day'] = df.index.dayofweek df['hour'] = df.index.hour holidays = NercCalendar().holidays(start=start_date, end=end_date).date # checking missing data points ref_hour_range = pd.date_range(start_time, end_time, freq='1h', tz='US/Eastern') missing_hours = ref_hour_range[~ref_hour_range.isin(df.index)] missing_dates = np.unique(missing_hours.date) missing_months = np.unique(missing_hours.month) # drop dates and months which have missing data df = df.loc[(~df['date'].isin(missing_dates))] if granularity == 'M': df = df.loc[(~df['month'].isin(missing_months))] # TODO: get frequency definition from SecDB if bucket.lower() == '7x24': pass # offpeak: 11pm-7am & weekend & holiday elif bucket.lower() == 'offpeak': df = df.loc[df['date'].isin(holidays) | df['day'].isin(weekends) | (~df['date'].isin(holidays) & ~df['day'].isin(weekends) & ((df['hour'] < peak_start) | (df['hour'] > peak_end - 1)))] # peak: 7am to 11pm on weekdays elif bucket.lower() == 'peak': df = df.loc[(~df['date'].isin(holidays)) & (~df['day'].isin(weekends)) & (df['hour'] > peak_start - 1) & (df['hour'] < peak_end)] # 7x8: 11pm to 7am elif bucket.lower() == '7x8': df = df.loc[(df['hour'] < peak_start) | (df['hour'] > peak_end - 1)] # 2x16h: weekends & holidays elif bucket.lower() == '2x16h': df = df.loc[((df['date'].isin(holidays)) | df['day'].isin(weekends)) & ((df['hour'] > peak_start - 1) & (df['hour'] < peak_end))] else: raise ValueError('Invalid bucket: ' + bucket + '. Expected Value: peak, offpeak, 7x24, 7x8, 2x16h.') df = df['price'].resample(granularity).mean() df.index = df.index.date df = df.loc[start_date:end_date] return df