When you create and upload positions to a portfolio in Marquee, GS Quant makes it possible to pull factor risk analytics in just a few lines of code.
Before you begin this tutorial, you must have a portfolio in Marquee with positions and a factor risk report that has already been created, scheduled, and completed. If that's not the case, please navigate to our tutorial on creating a new portfolio and/or updating positions and running reports.
Your application also needs to have the run_analytics scope. If it doesn't, please request it on your My Applications Page. If you have any other questions please reach out to the Marquee sales team.
First you will import the necessary modules and add your client id and client secret.
import datetime as dt
from gs_quant.api.gs.risk_models import GsRiskModelApi
from gs_quant.markets.portfolio_manager import PortfolioManager
from gs_quant.markets.report import FactorRiskReport
from gs_quant.session import GsSession, Environment
client = 'ENTER CLIENT ID'
secret = 'ENTER CLIENT SECRET'
GsSession.use(Environment.PROD, client_id=client, client_secret=secret, scopes=('run_analytics',))
print('GS Session initialized.')
The PortfolioManager
class allows for easy retrieval and scheduling of portfolio reports. Simply running:
all_reports = PortfolioManager('ENTER PORTFOLIO ID').get_reports()
print(all_reports)
will return a list of Report
objects that represent the reports associated with the portfolio.
The GS Quant Report
class is inherited by report subclasses, like FactorRiskReport
and PerformanceReport
, each of which corresponds to a type of Marquee report. Each subclass then has additional functions specific to its report type. In this case, we'd like to find the FactorRiskReport
associated with this portfolio, and leverage its functions to retrieve data. First let's retrieve the list of all risk models we can choose from.
list_of_risk_models = []
for report in all_reports:
if isinstance(report, FactorRiskReport):
list_of_risk_models.append(report.get_risk_model_id())
print(f'This portfolio has scheduled factor risk reports with the following risk models:\n {list_of_risk_models}')
If you would like to pull factor risk data off of a risk model not on this list, you can create and schedule a new factor risk report.
If you would like to see all available risk model IDs to choose from, simply run the following
risk_models = GsRiskModelApi.get_risk_models(limit=1000)
for risk_model in risk_models:
print(f'{risk_model}\n')
Now let's pick one risk model ID from the list above and find its correlating FactorRiskReport
.
risk_model_id = 'ENTER RISK MODEL ID'
factor_risk_reports = list(filter(lambda report: isinstance(report, FactorRiskReport) and report.get_risk_model_id() == risk_model_id, all_reports))
if len(factor_risk_reports) == 0:
print(f'This portfolio does not have a factor risk report with the risk model {risk_model_id}. Please create a new factor risk report and schedule it before proceeding.')
factor_risk_report = factor_risk_reports[0]
print(f'Factor risk model found with ID: "{factor_risk_report.id}".')
will return a list of Report
objects that represent the reports associated with the portfolio.
Now that we have our factor risk report, we can leverage the functionality of the FactorRiskReport
class to pull attribution and risk data. In this example, let's pull historical data on factor, specific, and total PnL for the year 2020:
factor_pnl = factor_risk_report.get_factor_pnl(factor_name='Factor', start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
specific_pnl = factor_risk_report.get_factor_pnl(factor_name='Specific', start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
total_pnl = factor_risk_report.get_factor_pnl(factor_name='Total', start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
print(f'Factor: \n{factor_pnl.__str__()}')
print(f'Specific: \n{specific_pnl.__str__()}')
print(f'Total: \n{total_pnl.__str__()}')
Now let's pull the breakdown of proportion of risk among the different factor types over time:
market_prop_of_risk = factor_risk_report.get_factor_proportion_of_risk(factor_name='Market', start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
style_prop_of_risk = factor_risk_report.get_factor_proportion_of_risk(factor_name='Style', start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
industry_prop_of_risk = factor_risk_report.get_factor_proportion_of_risk(factor_name='Industry', start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
country_prop_of_risk = factor_risk_report.get_factor_proportion_of_risk(factor_name='Country', start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
print(f'Market: \n{market_prop_of_risk.__str__()}')
print(f'Style: \n{style_prop_of_risk.__str__()}')
print(f'Industry: \n{industry_prop_of_risk.__str__()}')
print(f'Country: \n{country_prop_of_risk.__str__()}')
If you would like to pull all factor risk data for a list of different factors, you can use the get_results
function:
factor_and_total_results = factor_risk_report.get_results(factors=['Factor', 'Specific'], start_date=dt.date(2020, 1, 1), end_date=dt.date(2021, 1, 1))
print(factor_and_total_results.__str__())