Portfolio payoff routines
These routines take a portfolio of call and put options and plots the payoff functions.
In [ ]:
import matplotlib.pyplot as plt
import numpy as np
def get_beta(beta, x):
if x in beta:
return beta[x]
else:
return 1.0
def scale (prices, x, beta):
return { k : prices[k]*((x-1.0)*get_beta(beta,k)+1.0) for k in prices.keys()}
def merge_dicts(x, y):
'''Given two dicts, merge them into a new dict as a shallow copy.'''
z = x.copy()
z.update(y)
return z
class PortfolioCalculator(object):
def __init__(self, **kwargs):
pass
def portfolio_nav(self, portfolio_list, prices):
retval = 0.0
if portfolio_list == None:
portfolio_list = self.portfolio_list
for portfolio in portfolio_list:
for asset in portfolio:
if asset[1] == "cash":
retval = retval +asset[0]
elif asset[1] == "spot":
quantity = asset[0]
underlying = asset[2]
purchase = asset[3]
retval = retval + quantity * (prices[underlying] - purchase)
elif asset[1] == "put" or asset[1] == "call":
quantity = asset[0]
style = asset[1]
date = asset[2]
strike = asset[3]
underlying = asset[4]
purchase = asset[5]
exercise_value = 0.0
if asset[1] == "put" and prices[underlying] < strike:
exercise_value = strike - prices[underlying]
if asset[1] == "call" and prices[underlying] > strike:
exercise_value = prices[underlying] - strike
retval = retval + quantity * (exercise_value - purchase)
elif asset[1] == "comment":
pass
else:
raise Exception ("unknown asset")
return retval
def plot_one_asset(self, asset, xrange, portfolio_list, prices,marklines=[]):
x = np.arange(*xrange)
for i in range(1,len(portfolio_list)+1):
y = np.vectorize(lambda x: self.portfolio_nav(portfolio_list[:i], merge_dicts(prices, {asset:x})))(x)
plt.plot(x,y)
for i in marklines:
plt.axhline(y=i, xmin=0.0, xmax=1.0, ls='dashed' )
plt.axvline(x=prices[asset],ymin=0.0,ymax=1.0,ls='dashed' )
plt.grid(b=True, which='major', color='0.8', linestyle='--')
def plot_scaled(self, portfolio_list, prices,marklines=[], beta={}):
x = np.arange(0,1.5,0.05)
for i in range(1,len(portfolio_list)+1):
y = np.vectorize(lambda x: self.portfolio_nav(portfolio_list[:i], scale(prices,x,beta)))(x)
plt.plot(x,y)
for i in marklines:
plt.axhline(y=i, xmin=0.0, xmax=1.0, ls='dashed' )
plt.grid(b=True, which='major', color='0.8', linestyle='--')
In [ ]:
if __name__ == '__main__':
%matplotlib inline
portfolio = [
[-10000, "put", "2015-09", 24.00, "3888.HK", 1.0],
[-10000, "put", "2015-07", 25.00, "3888.HK", 0.55],
[-10000, "put", "2015-07", 26.00, "3888.HK", 0.63],
[-10000, "put", "2015-08", 26.00, "3888.HK", 1.06],
[-5000, "call", "2015-08", 26.00, "3888.HK", 1.06],
[-5000, "call", "2015-08", 27.00, "3888.HK", 0.88],
[975928.19, "cash"]
]
trade = [
[-10000, "put","2015-08", 18.50, "3888.HK", 1.05]
]
exercise = [
[10000, "put", "2015-08", 25.00, "3888.HK", 0.0],
[10000, "spot", '3888.HK', 25.00]
]
prices = {
"3888.HK": 22.6
}
marklines = [
250000,374920.00
]
port_calc = PortfolioCalculator()
[port_calc.portfolio_nav([portfolio, trade, exercise],{"3888.HK":28} ), scale(prices, 0.5)]
port_calc.plot_one_asset("3888.HK",[10,35,0.1],[portfolio, trade, exercise], prices)
In [ ]:
if __name__ == '__main__':
port_calc.plot_scaled([portfolio, trade, exercise], prices)
In [ ]: