goldmansachs / gs-quant

Python toolkit for quantitative finance
https://developer.gs.com/discover/products/gs-quant/
Apache License 2.0
7.85k stars 970 forks source link

Portfolios #37

Open DerekTiggelaar opened 5 years ago

DerekTiggelaar commented 5 years ago

Describe the problem. What is the best way to represent a Portfolio that can consists of so many types of investments?

Describe the solution you'd like I would like to leverage the concept of an Instrument to describe a Position in a gs-quant Portfolio. An Instrument is an object with industry-standard required fields that all-together describe a unique investment. Using instruments to represent positions in a portfolio will allow a gs-quant user to quickly understand how to add investments of any type to their portfolio and calculate analytics such as pricing or risk in a way that is agnostic to the portfolio's contents.

Here are a few code examples:

Example 1:

from gs_quant.session import *
from gs_quant.portfolio import GsPositionSet, GsPortfolio
from gs_quant.instrument import IRSwaption, EqOption
import matplotlib.pyplot as plt

with GsSession.get(Environment.PROD):

    positions = GsPositionSet([
        IRSwaption(PayReceive.Receive, '5y', 'USD', expirationDate='13m', strike='atm+40', notionalAmount=1e8),
        EqOption('SPX', date(2020, 12, 31), 2800, OptionType.Call, OptionStyle.European)
    ], date(2019, 05, 10))

    positions.calculate_prices('USD')

    portfolio = GsPortfolio('Derek's Example Portfolio', 'USD', [positions])
    portfolio.create_performance_report()
    portfolio.schedule_reports()

    performance = portfolio.get_normalized_performance()
    plt.plot(performance, label='Portfolio Performance')
    plt.show()

Example 2:

from gs_quant.session import *
from gs_quant.portfolio import GsPositionSet
from gs_quant.index import GsBasket
from gs_quant.instrument import Equity

with GsSession.get(Environment.PROD):

    positions = GsPositionSet([
        Equity('GS', 24222, AssetIdentifier.TICKER),
        Equity('AAPL', 23984, AssetIdentifier.TICKER)
    ], date(2019, 05, 10))

    positions.calculate_prices('USD')
    positions.calculate_liquidity('APEX', '.10') # 10% participation rate

    SPX = SecurityMaster.get_asset("SPX", AssetIdentifier.TICKER, asset_type=AssetType.INDEX)
    hedge = positions.hedge('Replicate Performance', universe=SPX.getUnderlyingAssetIds())

    hedge_positions = GsPositionSet(hedge.get_constituents())
    hedge_positions.calculate_liquidity('APEX', '.10') # 10% participation rate

    hedge_positions = [p for p in hedge_positions if p['adv22DayPct'] < 5.0]
    hedge_positions = [p for p in hedge_positions if p['transactionCostBps'] < 14.50]

    hedge_basket = GsBasket(
        "GSCBMARQ",
        "Basket From Hedge",
        hedge_positions,
        PublishParameters(False, False, False),
        100
    )

    hedge_basket.create()

Are you willing to contribute Yes

Additional context Let's build context from the ground up...

francisg77 commented 5 years ago

Cool stuff. I think we can drop the 'Gs' from the GsPositionSet? Definition doesn't have to be GS specific I think. Same for GsBasket.

andrewphillipsn commented 5 years ago

some questions / comments on this:

@nick-young-gs please also take a look!

DerekTiggelaar commented 5 years ago
andrewphillipsn commented 5 years ago