In [4]:
cd ..


/Users/miguel/Jottacloud/HedgingRL

In [33]:
%load_ext autoreload
%autoreload 2


The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload

In [49]:
import numpy as np
import pandas as pd
pd.set_option('display.width', 320)
pd.set_option('display.max_rows', 100)
pd.options.display.float_format = '{:,.2f}'.format
from scipy.stats import norm
import matplotlib.pyplot as plt
from blackscholes.mathfin import *

In [51]:
%whos


Variable                    Type                Data/Info
---------------------------------------------------------
CallOption                  type                <class 'blackscholes.mathfin.CallOption'>
K                           float               100.0
Ndays                       int                 4
S                           ndarray             1000: 1000 elems, type `float64`, 8000 bytes
S0                          int                 1
Strike                      float               100.0
blackScholes                function            <function blackScholes at 0x11a5b3510>
blackscholes                module              <module 'blackscholes' fr<...>lackscholes/__init__.py'>
call                        type                <class 'blackscholes.mathfin.CallOption'>
cash                        int                 0
dayToSellCall               int                 1
dt                          float               0.004
fixed                       MetaHasTraits       <class 'ipywidgets.widgets.interaction.fixed'>
geometric_brownian_motion   function            <function geometric_brown<...>an_motion at 0x11a5b3598>
interact                    _InteractFactory    <ipywidgets.widgets.inter<...>ry object at 0x10cee6198>
interact_manual             _InteractFactory    <ipywidgets.widgets.inter<...>ry object at 0x10cee6208>
interactive                 MetaHasTraits       <class 'ipywidgets.widget<...>interaction.interactive'>
mathfin                     module              <module 'blackscholes.mat<...>blackscholes/mathfin.py'>
maturityCall                int                 3
norm                        norm_gen            <scipy.stats._continuous_<...>en object at 0x116154b38>
np                          module              <module 'numpy' from '/us<...>kages/numpy/__init__.py'>
pd                          module              <module 'pandas' from '/u<...>ages/pandas/__init__.py'>
plot_gbm                    function            <function plot_gbm at 0x11a3abea0>
plt                         module              <module 'matplotlib.pyplo<...>es/matplotlib/pyplot.py'>
r                           ndarray             1000: 1000 elems, type `float64`, 8000 bytes
vol                         float               0.3
widgets                     module              <module 'ipywidgets' from<...>/ipywidgets/__init__.py'>

In [8]:
S = 90.
K = 100.
vol = .3
dt = 1/ 250.
cash = 0
dayToSellCall = 1
Ndays = 4
maturityCall = Ndays - 1

call = CallOption(dayToSellCall, maturityCall, K, )

In [19]:
r = np.random.randn((1000))
S0 = 1
S = S0 * np.cumsum(r)

In [20]:
%matplotlib inline
plt.plot(S)


Out[20]:
[<matplotlib.lines.Line2D at 0x11a64c5c0>]

In [40]:
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets

In [52]:
@interact(mu=(-0.02, 0.05, 0.01), sigma=(0.01, 0.1, 0.005), S0=(1,100,10), dt=(0.001, 0.1, 0.001))
def plot_gbm(mu, sigma, S0, dt):
    s, t = geometric_brownian_motion(mu=mu, sigma=sigma, t=2, dt=dt, s0=S0)
    pd.Series(t, s).plot()
    plt.show()



In [53]:
tau = np.clip( np.linspace(1.0, .0, 101), 0.0000001, 100)
S = 1.
K = 1.
sigma = 1
df = pd.DataFrame.from_dict(blackScholes(tau, S, K, sigma))
df.index = tau

In [55]:
df.delta.plot()


Out[55]:
<matplotlib.axes._subplots.AxesSubplot at 0x11ad96438>

In [ ]:


In [64]:
@interact(mu=(-0.02, 0.05, 0.01), sigma=(0.01, 0.1, 0.005), S0=(1,100,10), dt=(0.001, 0.1, 0.001))
def plot_gbm(mu, sigma, S0, dt):
    T = 2.
    t, s = geometric_brownian_motion(mu=mu, sigma=sigma, t=T, dt=dt, s0=S0)
#     df = pd.DataFrame.from_dict(blackscholes())
    print(s)
    pd.Series(s, (T - t ) / T).plot()
    plt.show()



In [1]:
S = 90.0
Strike = 100.0
vol = .30
dt = 1/250.
cash = 0
dayToSellCall = 1
maturityCall = Ndays-1
Ndays = 
call = CallOption(dayToSellCall,maturityCall,Strike,-10)# sell one call on dayToSellCall day

columns = ('spot','vol','shares','cash','option','npv','vega','gamma','theta','pnlPredict')
df = pd.DataFrame([[S,vol,0,0,0,0,0,0,0,0]], columns=columns)


def deltahedge(Ndays, option=None, Sdynamics="S*=(1.0+vol*np.sqrt(dt)*np.random.randn())", volDynamics="vol=.30"):
    for day in range(1,Ndays+1):
        exec(Sdynamics)
        print(S)
        exec(volDynamics)

        if day==dayToSellCall: #sell call
          callValue=call.calc(day,vol,S)
          cash-=callValue['npv']

        #delta hedge
        callValue=call.calc(day,vol,S)
        delta=callValue['delta']
        currentNumberShares=df.iloc[day-1].shares
        sharesBuy=-currentNumberShares-delta
        cash-=sharesBuy*S
        if day==maturityCall:
            cash+=call.calc(day,vol,S)['intrinsic'] #settle call

        gamma=callValue['gamma']
        theta=callValue['theta']
        dS=S-df.iloc[day-1].spot
        pnlPredict=0.5*gamma*dS*dS+theta*dt
        dfnew=pd.DataFrame([[S,vol,-delta,cash,-callValue['npv'],cash+callValue['npv']-delta*S,callValue['vega'],gamma,theta/250.,pnlPredict]],columns=columns)
        df=df.append(dfnew,ignore_index=True)

    df['pnl'] = df['npv'] - df['npv'].shift(1)
    df['vol']=100.0*df['vol']
    df['error']=df['pnl']-df['pnlPredict']
    df.set_value(dayToSellCall, "error", 0)
    #df.loc[:,['vol','spot']].plot(title='Spot and implied Volatility')
    df.loc[:,['npv','spot','option']].plot(title='-Call+delta*S+cash vs Spot {0} {1}'.format(Sdynamics,volDynamics))
    df.loc[:,['theta']].plot(title='Theta {0} {1}'.format(Sdynamics,volDynamics))
    df.loc[:,['pnl']].hist(bins=50)
    return df
    #df.loc[:,['error']].hist(bins=50)
    #print df.loc[:,['pnl']].describe()


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-25795e74b8ec> in <module>()
      5 cash = 0
      6 dayToSellCall = 1
----> 7 maturityCall = Ndays-1
      8 call = CallOption(dayToSellCall,maturityCall,Strike,-10)# sell one call on dayToSellCall day
      9 

NameError: name 'Ndays' is not defined

In [39]:
df


Out[39]:
spot vol shares cash option npv vega gamma theta pnlPredict pnl error
0 90.00 30.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 nan nan
1 90.00 30.00 5.49 -317.22 177.16 0.00 -711.89 -0.07 0.11 0.11 0.00 0.00
2 90.00 30.00 5.49 -317.14 177.05 0.11 -711.55 -0.07 0.11 0.11 0.11 -0.00
3 90.00 30.00 5.49 -317.05 176.94 0.21 -711.22 -0.07 0.11 0.11 0.11 -0.00
4 90.00 30.00 5.49 -316.97 176.84 0.32 -710.88 -0.07 0.11 0.11 0.11 -0.00
5 90.00 30.00 5.49 -316.88 176.73 0.43 -710.55 -0.07 0.11 0.11 0.11 -0.00
6 90.00 30.00 5.49 -316.80 176.62 0.54 -710.21 -0.07 0.11 0.11 0.11 -0.00
7 90.00 30.00 5.49 -316.71 176.51 0.64 -709.87 -0.07 0.11 0.11 0.11 -0.00
8 90.00 30.00 5.49 -316.63 176.41 0.75 -709.54 -0.07 0.11 0.11 0.11 -0.00
9 90.00 30.00 5.49 -316.54 176.30 0.86 -709.20 -0.07 0.11 0.11 0.11 -0.00
10 90.00 30.00 5.48 -316.46 176.19 0.97 -708.86 -0.07 0.11 0.11 0.11 -0.00
11 90.00 30.00 5.48 -316.37 176.08 1.07 -708.52 -0.07 0.11 0.11 0.11 -0.00
12 90.00 30.00 5.48 -316.29 175.98 1.18 -708.18 -0.07 0.11 0.11 0.11 -0.00
13 90.00 30.00 5.48 -316.20 175.87 1.29 -707.85 -0.07 0.11 0.11 0.11 -0.00
14 90.00 30.00 5.48 -316.11 175.76 1.40 -707.51 -0.07 0.11 0.11 0.11 -0.00
15 90.00 30.00 5.48 -316.03 175.65 1.50 -707.17 -0.07 0.11 0.11 0.11 -0.00
16 90.00 30.00 5.48 -315.94 175.55 1.61 -706.83 -0.07 0.11 0.11 0.11 -0.00
17 90.00 30.00 5.48 -315.86 175.44 1.72 -706.49 -0.07 0.11 0.11 0.11 -0.00
18 90.00 30.00 5.48 -315.77 175.33 1.83 -706.15 -0.07 0.11 0.11 0.11 -0.00
19 90.00 30.00 5.48 -315.68 175.22 1.94 -705.81 -0.07 0.11 0.11 0.11 -0.00
20 90.00 30.00 5.48 -315.60 175.11 2.04 -705.47 -0.07 0.11 0.11 0.11 -0.00
21 90.00 30.00 5.47 -315.51 175.01 2.15 -705.13 -0.07 0.11 0.11 0.11 -0.00
22 90.00 30.00 5.47 -315.42 174.90 2.26 -704.79 -0.07 0.11 0.11 0.11 -0.00
23 90.00 30.00 5.47 -315.34 174.79 2.37 -704.45 -0.07 0.11 0.11 0.11 -0.00
24 90.00 30.00 5.47 -315.25 174.68 2.48 -704.11 -0.07 0.11 0.11 0.11 -0.00
25 90.00 30.00 5.47 -315.16 174.57 2.58 -703.77 -0.07 0.11 0.11 0.11 -0.00
26 90.00 30.00 5.47 -315.08 174.46 2.69 -703.43 -0.07 0.11 0.11 0.11 -0.00
27 90.00 30.00 5.47 -314.99 174.36 2.80 -703.09 -0.07 0.11 0.11 0.11 -0.00
28 90.00 30.00 5.47 -314.90 174.25 2.91 -702.75 -0.07 0.11 0.11 0.11 -0.00
29 90.00 30.00 5.47 -314.82 174.14 3.02 -702.40 -0.07 0.11 0.11 0.11 -0.00
30 90.00 30.00 5.47 -314.73 174.03 3.13 -702.06 -0.07 0.11 0.11 0.11 -0.00
31 90.00 30.00 5.46 -314.64 173.92 3.24 -701.72 -0.07 0.11 0.11 0.11 -0.00
32 90.00 30.00 5.46 -314.55 173.81 3.34 -701.38 -0.07 0.11 0.11 0.11 -0.00
33 90.00 30.00 5.46 -314.47 173.70 3.45 -701.03 -0.07 0.11 0.11 0.11 -0.00
34 90.00 30.00 5.46 -314.38 173.59 3.56 -700.69 -0.07 0.11 0.11 0.11 -0.00
35 90.00 30.00 5.46 -314.29 173.49 3.67 -700.35 -0.07 0.11 0.11 0.11 -0.00
36 90.00 30.00 5.46 -314.20 173.38 3.78 -700.01 -0.07 0.11 0.11 0.11 -0.00
37 90.00 30.00 5.46 -314.12 173.27 3.89 -699.66 -0.07 0.11 0.11 0.11 -0.00
38 90.00 30.00 5.46 -314.03 173.16 4.00 -699.32 -0.07 0.11 0.11 0.11 -0.00
39 90.00 30.00 5.46 -313.94 173.05 4.11 -698.97 -0.07 0.11 0.11 0.11 -0.00
40 90.00 30.00 5.46 -313.85 172.94 4.22 -698.63 -0.07 0.11 0.11 0.11 -0.00
41 90.00 30.00 5.45 -313.77 172.83 4.33 -698.28 -0.07 0.11 0.11 0.11 -0.00
42 90.00 30.00 5.45 -313.68 172.72 4.44 -697.94 -0.08 0.11 0.11 0.11 -0.00
43 90.00 30.00 5.45 -313.59 172.61 4.54 -697.59 -0.08 0.11 0.11 0.11 -0.00
44 90.00 30.00 5.45 -313.50 172.50 4.65 -697.25 -0.08 0.11 0.11 0.11 -0.00
45 90.00 30.00 5.45 -313.41 172.39 4.76 -696.90 -0.08 0.11 0.11 0.11 -0.00
46 90.00 30.00 5.45 -313.32 172.28 4.87 -696.56 -0.08 0.11 0.11 0.11 -0.00
47 90.00 30.00 5.45 -313.24 172.17 4.98 -696.21 -0.08 0.11 0.11 0.11 -0.00
48 90.00 30.00 5.45 -313.15 172.06 5.09 -695.87 -0.08 0.11 0.11 0.11 -0.00
49 90.00 30.00 5.45 -313.06 171.95 5.20 -695.52 -0.08 0.11 0.11 0.11 -0.00
... ... ... ... ... ... ... ... ... ... ... ... ...
951 90.00 30.00 2.31 -30.68 14.93 162.23 -120.02 -0.26 0.38 0.38 0.37 -0.00
952 90.00 30.00 2.28 -28.18 14.56 162.60 -117.96 -0.26 0.38 0.38 0.38 -0.00
953 90.00 30.00 2.25 -25.62 14.18 162.98 -115.87 -0.26 0.38 0.38 0.38 -0.00
954 90.00 30.00 2.22 -22.99 13.80 163.36 -113.76 -0.26 0.38 0.38 0.38 -0.00
955 90.00 30.00 2.19 -20.30 13.42 163.74 -111.62 -0.26 0.38 0.38 0.38 -0.00
956 90.00 30.00 2.16 -17.55 13.04 164.12 -109.46 -0.26 0.38 0.38 0.38 -0.00
957 90.00 30.00 2.13 -14.72 12.66 164.50 -107.26 -0.26 0.38 0.38 0.38 -0.00
958 90.00 30.00 2.10 -11.83 12.27 164.88 -105.04 -0.26 0.38 0.38 0.38 -0.00
959 90.00 30.00 2.07 -8.85 11.89 165.27 -102.78 -0.26 0.39 0.39 0.38 -0.00
960 90.00 30.00 2.03 -5.80 11.50 165.65 -100.49 -0.27 0.39 0.39 0.39 -0.00
961 90.00 30.00 2.00 -2.66 11.12 166.04 -98.18 -0.27 0.39 0.39 0.39 -0.00
962 90.00 30.00 1.96 0.56 10.73 166.43 -95.82 -0.27 0.39 0.39 0.39 -0.00
963 90.00 30.00 1.93 3.87 10.34 166.82 -93.44 -0.27 0.39 0.39 0.39 -0.00
964 90.00 30.00 1.89 7.28 9.95 167.21 -91.01 -0.27 0.39 0.39 0.39 -0.00
965 90.00 30.00 1.85 10.79 9.56 167.60 -88.55 -0.27 0.39 0.39 0.39 -0.00
966 90.00 30.00 1.81 14.40 9.17 167.99 -86.05 -0.27 0.39 0.39 0.39 -0.00
967 90.00 30.00 1.77 18.12 8.78 168.38 -83.52 -0.27 0.39 0.39 0.39 -0.00
968 90.00 30.00 1.72 21.95 8.38 168.77 -80.94 -0.27 0.39 0.39 0.39 -0.00
969 90.00 30.00 1.68 25.91 7.99 169.16 -78.31 -0.27 0.39 0.39 0.39 0.00
970 90.00 30.00 1.64 29.99 7.60 169.56 -75.65 -0.27 0.39 0.39 0.39 0.00
971 90.00 30.00 1.59 34.20 7.21 169.95 -72.94 -0.27 0.39 0.39 0.39 0.00
972 90.00 30.00 1.54 38.55 6.82 170.34 -70.18 -0.27 0.39 0.39 0.39 0.00
973 90.00 30.00 1.49 43.04 6.43 170.73 -67.38 -0.27 0.39 0.39 0.39 0.00
974 90.00 30.00 1.44 47.69 6.04 171.11 -64.52 -0.27 0.39 0.39 0.39 0.00
975 90.00 30.00 1.39 52.50 5.66 171.50 -61.62 -0.26 0.39 0.39 0.39 0.00
976 90.00 30.00 1.33 57.47 5.27 171.88 -58.66 -0.26 0.38 0.38 0.38 0.00
977 90.00 30.00 1.27 62.62 4.89 172.27 -55.65 -0.26 0.38 0.38 0.38 0.00
978 90.00 30.00 1.21 67.95 4.51 172.64 -52.59 -0.26 0.38 0.38 0.38 0.00
979 90.00 30.00 1.15 73.46 4.14 173.02 -49.48 -0.25 0.37 0.37 0.37 0.00
980 90.00 30.00 1.09 79.18 3.77 173.38 -46.31 -0.25 0.37 0.37 0.37 0.00
981 90.00 30.00 1.02 85.09 3.41 173.75 -43.09 -0.25 0.36 0.36 0.36 0.00
982 90.00 30.00 0.95 91.22 3.05 174.10 -39.82 -0.24 0.35 0.35 0.36 0.00
983 90.00 30.00 0.88 97.54 2.71 174.45 -36.50 -0.23 0.34 0.34 0.35 0.00
984 90.00 30.00 0.81 104.08 2.37 174.79 -33.15 -0.23 0.33 0.33 0.34 0.01
985 90.00 30.00 0.74 110.81 2.05 175.11 -29.76 -0.22 0.32 0.32 0.33 0.01
986 90.00 30.00 0.66 117.72 1.73 175.42 -26.35 -0.21 0.30 0.30 0.31 0.01
987 90.00 30.00 0.58 124.79 1.44 175.72 -22.93 -0.20 0.29 0.29 0.30 0.01
988 90.00 30.00 0.50 131.97 1.16 176.00 -19.54 -0.18 0.27 0.27 0.28 0.01
989 90.00 30.00 0.42 139.20 0.91 176.25 -16.19 -0.17 0.24 0.24 0.25 0.01
990 90.00 30.00 0.34 146.39 0.68 176.48 -12.94 -0.15 0.22 0.22 0.23 0.01
991 90.00 30.00 0.26 153.39 0.48 176.68 -9.85 -0.13 0.18 0.18 0.20 0.02
992 90.00 30.00 0.19 160.01 0.31 176.85 -7.00 -0.10 0.15 0.15 0.17 0.02
993 90.00 30.00 0.12 165.98 0.18 176.98 -4.49 -0.08 0.11 0.11 0.13 0.02
994 90.00 30.00 0.07 170.94 0.08 177.07 -2.45 -0.05 0.07 0.07 0.09 0.02
995 90.00 30.00 0.03 174.54 0.03 177.13 -1.01 -0.03 0.04 0.04 0.06 0.02
996 90.00 30.00 0.01 176.52 0.01 177.15 -0.24 -0.01 0.01 0.01 0.02 0.01
997 90.00 30.00 0.00 177.12 0.00 177.16 -0.02 -0.00 0.00 0.00 0.01 0.00
998 90.00 30.00 0.00 177.16 0.00 177.16 -0.00 -0.00 0.00 0.00 0.00 0.00
999 90.00 30.00 0.00 177.16 0.00 177.16 0.00 0.00 0.00 0.00 0.00 0.00
1000 90.00 30.00 0.00 177.16 0.00 177.16 0.00 0.00 0.00 0.00 0.00 0.00

1001 rows × 12 columns


In [47]:
%matplotlib inline
df[['shares', 'cash', 'option', 'npv']].plot()


Out[47]:
<matplotlib.axes._subplots.AxesSubplot at 0x116b072b0>

In [44]:
#df = deltahedge(1000)#constant vol
# df = deltahedge(1000, volDynamics="vol*=(1.0+0.5*np.sqrt(dt)*np.random.randn())")#stochastic vol
df = deltahedge(1000, Sdynamics="S=90") #consant OTM
# deltahedge(10000, Sdynamics="S=100") #consant ATM
# deltahedge(10000, Sdynamics="S=110")#consant ITM
# deltahedge(10000, Sdynamics="S+=S*dt") #growing stock
plt.show()