def factor_zscore(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: Time-series of asset factor exposure across available risk model dates """ model = FactorRiskModel.get(risk_model_id) factor = model.get_factor(factor_name) gsid = asset.get_identifier('GSID') # Query risk model data query_results = model.get_data( measures=[Measure.Factor_Name, Measure.Universe_Factor_Exposure, Measure.Asset_Universe], start_date=DataContext.current.start_time, end_date=DataContext.current.end_time, assets=DataAssetsRequest(identifier=RiskModelUniverseIdentifierRequest.gsid, universe=[gsid]) ).get('results', []) # Get the factor data from query results z_scores = {} for result in query_results: exposures = result.get('assetData', {}).get('factorExposure', []) if exposures: z_scores[result['date']] = exposures[0].get(factor.id) return __format_plot_measure_results(z_scores, QueryType.FACTOR_EXPOSURE)
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 factor_covariance(risk_model_id: str, factor_name_1: str, factor_name_2: str, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Covariance time-series between two factors in a risk model :param risk_model_id: risk model entity :param factor_name_1: first factor name :param factor_name_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: Time-series of covariances between the two factors across available risk model dates """ model = FactorRiskModel.get(risk_model_id) factor_1 = model.get_factor(factor_name_1) factor_2 = model.get_factor(factor_name_2) covariance_curve = factor_1.covariance(factor_2, DataContext.current.start_date, DataContext.current.end_date, ReturnFormat.JSON) return __format_plot_measure_results(covariance_curve, QueryType.COVARIANCE)
def get(cls, risk_model_id: str, factor_name: str): risk_model = FactorRiskModel.get(risk_model_id) factor_data = risk_model.get_factor_data(format=ReturnFormat.JSON) name_matches = [factor for factor in factor_data if factor['name'] == factor_name] if not name_matches: raise MqValueError(f'Factor with name {factor_name} does not in exist in risk model {risk_model_id}') factor = name_matches.pop() return Factor(risk_model_id, factor['identifier'], factor['name'], factor['type'], factor.get('factorCategory'))
def mock_risk_model(): 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 actual = Factor_Risk_Model.get(model_id='model_id') replace.restore() return actual
def mock_risk_model(): 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) 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 actual = Factor_Risk_Model.get(model_id='model_id') replace.restore() return actual
def mock_risk_model(mocker): from gs_quant.session import OAuth2Session OAuth2Session.init = mock.MagicMock(return_value=None) GsSession.use(Environment.QA, 'client_id', 'secret') 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_risk_model_obj) mocker.patch.object(GsSession.current, '_get', return_value=mock_risk_model_obj) mocker.patch.object(GsSession.current, '_put', return_value=mock_risk_model_obj) return FactorRiskModel.get('model_id')
def factor_volatility(risk_model_id: str, factor_name: str, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Volatility timeseries for a factor in a risk model :param risk_model_id: risk model entity :param factor_name: factor name :param source: name of function caller :param real_time: whether to retrieve intra-day data instead of EOD :param request_id: server request id :return: Time-series of a factor's volatility across available risk model dates """ model = FactorRiskModel.get(risk_model_id) factor = model.get_factor(factor_name) volatility = factor.volatility(DataContext.current.start_date, DataContext.current.end_date, ReturnFormat.JSON) return __format_plot_measure_results(volatility, QueryType.VOLATILITY, multiplier=100)
def factor_performance(risk_model_id: str, factor_name: str, *, source: str = None, real_time: bool = False, request_id: Optional[str] = None) -> pd.Series: """ Factor returns as a price time-series for a factor in a risk model :param risk_model_id: risk model entity :param factor_name: 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: Time-series of factor returns as a price series across available risk model dates """ model = FactorRiskModel.get(risk_model_id) factor = model.get_factor(factor_name) factor_returns = factor.returns(DataContext.current.start_date, DataContext.current.end_date, ReturnFormat.JSON) factor_return_timeseries = pd.Series(factor_returns) return prices(factor_return_timeseries, 100)