The Marquee Portfolio Service provides a powerful framework for uploading portfolio positions and retrieving analytics including historical performance, factor risk exposure, ESG analytics, and more. GS Quant makes operating the suite of Portfolio Service API's intuitive and fast.
To execute all the code in this tutorial, you will need the following application scopes:
If you are not yet permissioned for these scopes, please request them 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.entities.entitlements import Entitlements, EntitlementBlock, User
from gs_quant.markets.portfolio import Portfolio
from gs_quant.markets.portfolio_manager import PortfolioManager
from gs_quant.markets.report import CustomAUMDataPoint
from gs_quant.markets.position_set import Position, PositionSet
from gs_quant.session import GsSession, Environment
from gs_quant.target.portfolios import RiskAumSource
client = 'ENTER CLIENT ID'
secret = 'ENTER CLIENT SECRET'
GsSession.use(
Environment.PROD,
client_id=client,
client_secret=secret,
scopes=('read_product_data read_financial_data modify_product_data modify_financial_data run_analytics read_user_profile',)
)
print('GS Session initialized.')
The first step is to create a new, empty portfolio in Marquee.
portfolio = Portfolio(name='My New Portfolio')
portfolio.save()
print(f"Created portfolio '{portfolio.name}' with ID: {portfolio.id}")
Once your portfolio has been saved to Marquee, the PortfolioManager
class allows users to interact with their Marquee portfolios directly from GS Quant. We will be using PortfolioManager
to update portfolio positions, entitlements, update custom AUM, and run reports.
By default, an application will have all entitlement permissions to a portfolio it makes. However, if you would like to share the portfolio with others, either Marquee users or other applications, you will need to specify them in the entitlements parameter of the portfolio. Let's walk through how we convert a list of admin and viewer emails into an Entitlements
object:
portfolio_admin_emails = ['LIST OF ADMIN EMAILS']
portfolio_viewer_emails = ['LIST OF VIEWER EMAILS']
admin_entitlements = EntitlementBlock(users=User.get_many(emails=portfolio_admin_emails))
view_entitlements = EntitlementBlock(users=User.get_many(emails=portfolio_viewer_emails))
entitlements = Entitlements(
view=view_entitlements,
admin=admin_entitlements
)
print(f'Entitlements:\n{entitlements.to_dict()}')
pm = PortfolioManager(portfolio.id)
pm.set_entitlements(entitlements)
print(f"Updated entitlements for '{portfolio.name}'")
Portfolio positions in Marquee are stored on a holding basis, when means you only upload positions for days where you are rebalancing your portfolio. Take the following set of positions:
portfolio_position_sets = [
PositionSet(
date=dt.date(day=3, month=5, year=2021),
positions=[
Position(identifier='AAPL UW', quantity=25),
Position(identifier='GS UN', quantity=50)
]
),
PositionSet(
date=dt.date(day=1, month=7, year=2021),
positions=[
Position(identifier='AAPL UW', quantity=26),
Position(identifier='GS UN', quantity=51)
]
)
]
If these positions were to be uploaded correctly, this portfolio would hold 50 shares of GS UN and 25 shares of AAPL UW from May 3, 2021 to June 30, 2021, and it would hold 51 shares of GS UN and 26 shares of AAPL UW from July 1, 2021 to today.
pm.update_positions(portfolio_position_sets)
print(f"Updated positions for '{portfolio.name}'")
pm.schedule_reports()
print('All portfolio reports scheduled.')
The CustomAUMDataPoint
class is used to represent custom AUM data for a specific date. A list of them can be posted to Marquee using our initialized PortfolioManager
. If you do not upload custom AUM data for your portfolio and change your portfolio's AUM Source to Custom AUM
, by default the "AUM" (which is used for calculating risk as percent values) will be your portfolio's long exposure.
performance_report = pm.get_performance_report()
performance_report.set_aum_source(RiskAumSource.Custom_AUM)
custom_aum = [
CustomAUMDataPoint(date=dt.date(2021, 5, 1), aum=100000),
CustomAUMDataPoint(date=dt.date(2021, 7, 1), aum=200000)
]
performance_report.upload_custom_aum(custom_aum, clear_existing_data=False)
print(f"Custom AUM for '{portfolio.name} successfully uploaded'")
Other questions? Reach out to the Portfolio Analytics team!