{ "cells": [ { "cell_type": "markdown", "source": [ "# Performance Hedge\n", "\n", "The Performance Hedge provides a framework to replicate an asset's performance without\n", "direct exposure by using historical performance correlation.\n", "\n", "## Step 1: Authenticate and Initialize Your Session\n", "\n", "First you will import the necessary modules and add your client id and client secret." ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "import datetime as dt\n", "\n", "from IPython.display import display\n", "\n", "from gs_quant.markets.hedge import HedgeConstraints, HedgeExclusions, Constraint, PerformanceHedge, \\\n", " PerformanceHedgeParameters\n", "from gs_quant.markets.position_set import Position, PositionSet\n", "from gs_quant.session import GsSession, Environment\n", "from gs_quant.timeseries.helper import Window\n", "from gs_quant.timeseries.econometrics import correlation\n", "\n", "# external users should substitute their client id and secret; please skip this step if using internal jupyterhub\n", "GsSession.use(Environment.PROD, client_id=None, client_secret=None)\n", "\n", "print('GS Session initialized.')" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "## Step 2: Define Your Positions to Hedge and Your Hedge Universe\n", "\n", "The hedger takes in the initial portfolio as a `PositionSet` object. You can define your positions\n", "as a list of identifiers with quantities or alternatively, as a list of identifiers with weights, along with a\n", "reference notional value. The `date` corresponds to the hedge date.\n", "\n", "In addition, you need to define your universe of candidates for hedge constituents as a list of identifiers.\n", "\n", "*GS Quant will resolve all identifiers (Bloomberg IDs, SEDOLs, RICs, etc) historically as of the hedge date*" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "positions = PositionSet(\n", " date=dt.date(day=24, month=9, year=2021),\n", " positions=[\n", " Position(identifier='AAPL UW', quantity=26),\n", " Position(identifier='GS UN', quantity=51)\n", " ]\n", " )\n", "\n", "positions.resolve()\n", "\n", "universe = ['SPX']" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "## Step 3: Define Your Hedge Exclusions\n", "\n", "The `HedgeExclusions` class offers a clean way to specify any assets, countries, regions, sectors, and/or industries you\n", "would like to exclude from your hedge. Each attribute takes in a list of strings. In this example, let's try excluding\n", "Goldman Sachs and all assets in Mexico, Europe, the Utilities sector, the Airlines industry." ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "exclusions = HedgeExclusions(assets=['GS UN'],\n", " countries=['Mexico'],\n", " regions=['Europe'],\n", " sectors=['Utilities'],\n", " industries=['Airlines'])" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "## Step 4: Define Your Hedge Constraints\n", "\n", "Rather than excluding an industry or region entirely, you can also constrain how much each makes up in\n", "your hedge, and you can do so by leveraging the `HedgeConstraints` class. Each attribute takes in a list of `Constraint`\n", "objects, each of which has a `name` attribute, along with `minimum` and `maximum` that should be expressed as positive\n", "numbers between 0 and 100.\n", "\n", "In addition to constraining assets, countries, regions, sectors, and industries, it's also\n", "possible to constrain your hedge to only include assets that have an ESG score between a specified range. All data is\n", "pulled as of your hedge date from the GIR SUSTAIN ESG Headline Metrics Dataset. For more information on the various\n", "ESG metrics available, please visit the dataset page\n", "[here](https://marquee.gs.com/s/developer/datasets/ESG_HEADLINE_METRICS).\n", "\n", "In this example, let's constrain our hedge to only include at most 20% Software assets by weight. In addition, let's\n", "request a hedge with only assets that have a G Headline Percentile Score of above 75%." ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "constraints = HedgeConstraints(sectors=[Constraint(constraint_name='Software', minimum=0, maximum=20)],\n", " esg=[Constraint(constraint_name='gPercentile', minimum=75, maximum=100)])" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "## Step 5: Define Any Other Parameters\n", "\n", "The `PerformanceHedgeParameters` wraps all the performance hedge parameters, including the positions, exclusions, and\n", "constraints, into an object to be passed into a `PerformanceHedge`. Along with the parameters defined above, the\n", "following optional parameters can also be passed in:\n", "\n", "| Parameter | Description | Type| Default Value|\n", "|-----------------|---------------|-------------|-------------\n", "| `observation_start_date` | Date on which to start the observation of historical performance correlation |`datetime.date`| One year before the hedge date |\n", "| `sampling_period` | The length of time in between return samples |`str`| 'Daily' |\n", "| `max_leverage` | Maximum percentage of the notional that can be used to hedge | `float` | 100 |\n", "| `percentage_in_cash` | Percentage of the hedge notional that will be in cash | `float` | None |\n", "| `explode_universe` | Explode the assets in the universe into their underliers to be used as the hedge universe | `boolean` | True |\n", "| `exclude_target_assets` | Exclude assets in the target composition from being in the hedge |`boolean`| True |\n", "| `exclude_corporate_actions_types` | Set of of corporate actions to be excluded in the hedge |`List[CorporateActionsTypes]`| None |\n", "| `exclude_hard_to_borrow_assets` | Whether hard to borrow assets should be excluded in the universe | `boolean` | False |\n", "| `exclude_restricted_assets` | Whether to exclude assets in restricted trading lists | `float` | False |\n", "| `max_adv_percentage` | Maximum percentage notional to average daily dollar volume allowed for any hedge constituent | `float` | 15 |\n", "| `max_return_deviation` | Maximum percentage difference in annualized return between the target and the hedge result |`float`| 5 |\n", "| `max_weight` | Maximum weight of any constituent in hedge |`float`| 100 |\n", "| `min_market_cap` | Lowest market cap allowed for any hedge constituent | `float` | None |\n", "| `max_market_cap` | Highest market cap allowed for any hedge constituent | `float` | None |\n", "| `market_participation_rate` | Maximum market participation rate used to estimate the cost of trading a portfolio of stocks | `float` | 10 |\n", "| `lasso_weight` | Value of the lasso hyperparameter for machine learning hedges |`float`| 0 |\n", "| `ridge_weight` | Value of the ridge hyperparameter for machine learning hedges |`float`| 0 |\n" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "parameters = PerformanceHedgeParameters(\n", " initial_portfolio=positions,\n", " universe=universe,\n", " exclusions=exclusions,\n", " constraints=constraints\n", ")" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "## Step 6: Calculate Your Hedge\n", "\n", "It's finally time to run the parameters into the Marquee Hedger. Once defined, a `PerformanceHedge` can be calculated\n", "in just one line.\n" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "hedge = PerformanceHedge(parameters)\n", "all_results = hedge.calculate()" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "## Step 7: Pull Hedge Results\n", "\n", "That's it! Once calculated, you can pull the results right from the `PerformanceHedge` object.\n", "\n", "### Constituents\n", "Let's pull the constituents metadata of the resulting hedge:\n" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "hedge_constituents = hedge.get_constituents()\n", "display(hedge_constituents)" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### Stats\n", "\n", "Next let's pull a table of general stats like transaction cost, annualized volatility, annualized return, and more:\n" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "stats = hedge.get_statistics()\n", "display(stats)" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### Backtest Performance\n", "\n", "It's also possible to pull a timeseries of the performance of both the initial portfolio and the hedge for the\n", "observation period:\n" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "backtest_performance = hedge.get_backtest_performance()\n", "\n", "backtest_performance.plot(title='Backtest Performance')" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### Backtest Correlation\n", "\n", "It's also possible to pull a timeseries of the correlation between the hedge and portfolio for the\n", "observation period by leveraging GS Quant econometric function `correlation`:\n" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "backtest_correlation = correlation(backtest_performance['Portfolio'], backtest_performance['Hedge'], Window(44, 0))\n", "backtest_correlation.plot(title='Backtest Correlation')" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### You're all set; Congrats!\n", "\n", "*Other questions? Reach out to the [Portfolio Analytics team](mailto:gs-marquee-analytics-support@gs.com)!*" ], "metadata": { "collapsed": false } } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }