-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from tejaskamtam/dev
Dev
- Loading branch information
Showing
12 changed files
with
347 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# qol imports | ||
|
||
from .returns import brownian_motion, geometric_brownian_motion | ||
from .equity import EfficientFrontier, BlackScholes | ||
|
||
__all__ = ['brownian_motion', 'geometric_brownian_motion', 'EfficientFrontier', 'BlackScholes'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# import optimizers | ||
|
||
from .efficient_frontier import EfficientFrontier | ||
from .black_scholes import BlackScholes | ||
|
||
__all__ = ['EfficientFrontier', 'BlackScholes'] |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
|
||
from scipy.stats import norm | ||
import numpy as np | ||
|
||
class BlackScholes: | ||
def __init__(self, price, strike, expiration: "T-days", vol: "annualized constant volatility", rate: "risk free rate" = 0.03, div: "dividend"=0): | ||
self.S = price | ||
self.K = strike | ||
self.T = expiration/365 | ||
self.r = rate | ||
self.sigma = vol | ||
self.q = div | ||
|
||
|
||
@staticmethod | ||
def N(x): | ||
return norm.cdf(x) | ||
|
||
@property | ||
def params(self): | ||
return {'S': self.S, | ||
'K': self.K, | ||
'T': self.T, | ||
'r':self.r, | ||
'q':self.q, | ||
'sigma':self.sigma} | ||
|
||
def d1(self): | ||
return (np.log(self.S/self.K) + (self.r -self.q + self.sigma**2/2)*self.T) / (self.sigma*np.sqrt(self.T)) | ||
|
||
def d2(self): | ||
return self.d1() - self.sigma*np.sqrt(self.T) | ||
|
||
def _call_value(self): | ||
return self.S*np.exp(-self.q*self.T)*self.N(self.d1()) - self.K*np.exp(-self.r*self.T) * self.N(self.d2()) | ||
|
||
def _put_value(self): | ||
return self.K*np.exp(-self.r*self.T) * self.N(-self.d2()) - self.S*np.exp(-self.q*self.T)*self.N(-self.d1()) | ||
|
||
def price(self, type_: "call (C), put (P), or both (B)" = 'C'): | ||
if type_ == 'C': | ||
return self._call_value() | ||
if type_ == 'P': | ||
return self._put_value() | ||
if type_ == 'B': | ||
return {'call': self._call_value(), 'put': self._put_value()} | ||
else: | ||
raise ValueError('Unrecognized type') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 7, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# reference: https://www.codearmo.com/python-tutorial/options-trading-black-scholes-model\n", | ||
"\n", | ||
"from scipy.stats import norm\n", | ||
"import numpy as np\n", | ||
"\n", | ||
"class BlackScholes:\n", | ||
" def __init__(self, price, strike, expiration: \"T-days\", vol: \"annualized constant volatility\", rate: \"risk free rate\" = 0.03, div: \"dividend\"=0):\n", | ||
" self.S = price\n", | ||
" self.K = strike\n", | ||
" self.T = expiration/365\n", | ||
" self.r = rate\n", | ||
" self.sigma = vol\n", | ||
" self.q = div\n", | ||
" \n", | ||
" \n", | ||
" @staticmethod\n", | ||
" def N(x):\n", | ||
" return norm.cdf(x)\n", | ||
" \n", | ||
" @property\n", | ||
" def params(self):\n", | ||
" return {'S': self.S, \n", | ||
" 'K': self.K, \n", | ||
" 'T': self.T, \n", | ||
" 'r':self.r,\n", | ||
" 'q':self.q,\n", | ||
" 'sigma':self.sigma}\n", | ||
" \n", | ||
" def d1(self):\n", | ||
" return (np.log(self.S/self.K) + (self.r -self.q + self.sigma**2/2)*self.T) / (self.sigma*np.sqrt(self.T))\n", | ||
" \n", | ||
" def d2(self):\n", | ||
" return self.d1() - self.sigma*np.sqrt(self.T)\n", | ||
" \n", | ||
" def _call_value(self):\n", | ||
" return self.S*np.exp(-self.q*self.T)*self.N(self.d1()) - self.K*np.exp(-self.r*self.T) * self.N(self.d2())\n", | ||
" \n", | ||
" def _put_value(self):\n", | ||
" return self.K*np.exp(-self.r*self.T) * self.N(-self.d2()) - self.S*np.exp(-self.q*self.T)*self.N(-self.d1())\n", | ||
" \n", | ||
" def price(self, type_: \"call (C), put (P), or both (B)\" = 'C'):\n", | ||
" if type_ == 'C':\n", | ||
" return self._call_value()\n", | ||
" if type_ == 'P':\n", | ||
" return self._put_value() \n", | ||
" if type_ == 'B':\n", | ||
" return {'call': self._call_value(), 'put': self._put_value()}\n", | ||
" else:\n", | ||
" raise ValueError('Unrecognized type')\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 10, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"{'call': 0.25237702353658875, 'put': 0.17021901090664926}\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"K = 100\n", | ||
"r = 0.1\n", | ||
"T = 1\n", | ||
"sigma = 0.3\n", | ||
"S = 100\n", | ||
"print(BlackScholes(S, K, T, r, sigma).price('B'))" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "torch", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.9.16" | ||
}, | ||
"orig_nbformat": 4 | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
1 change: 0 additions & 1 deletion
1
quantpyml/optimizers/efficient_frontier.py → quantpyml/equity/efficient_frontier.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# imports | ||
|
||
from .brownian_motion import brownian_motion | ||
from .geometric_brownian_motion import geometric_brownian_motion | ||
|
||
__all__ = ['brownian_motion', 'geometric_brownian_motion'] |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# implementation of arithmetic brownian motion | ||
|
||
import numpy as np | ||
|
||
def brownian_motion(nsims=10, ksteps: "number of time steps"=10000, t: "time step" = 0.01, mu: "drift or mean" = 0, sigma: "scaling or standard deviation" = 1): | ||
""" | ||
Weiner process: W(t) ~ N(0,t) | ||
Brownian Motion: X(t) = mu*t + sigma*W(t) | ||
Standard Brownian Motion: X(t) = W(t) | ||
Geometric Brownian Motion: X(t) = exp[(mu-sigma^2/2)*t + sigma*W(t)] | ||
""" | ||
def X(): | ||
return mu*t + sigma*np.random.normal(loc=0, scale=np.sqrt(t), size=ksteps) | ||
x = np.array([i*t for i in range(ksteps)]) | ||
sims = [] | ||
for i in range(nsims): | ||
y = np.cumsum(X()) | ||
sims.append(y) | ||
return sims, x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# implementation of geometric brownian motion | ||
|
||
import numpy as np | ||
|
||
def geometric_brownian_motion(nsims=10, ksteps: "number of time steps"=1000, t: "time step" = 1, mu: "drift or mean" = 0.0001, sigma: "scaling or standard deviation" = 0.02): | ||
""" | ||
Weiner process: W(t) ~ N(0,t) | ||
Brownian Motion: X(t) = X0 + mu*t + sigma*W(t) | ||
Standard Brownian Motion: X(t) = X0 + W(t) | ||
Geometric Brownian Motion: X(t) = X0 + exp((u-sigma^2/2)*t + sigma*W(t)) | ||
""" | ||
def X(): | ||
return (mu-sigma**2/2)*t + sigma*np.random.normal(loc=0, scale=np.sqrt(t), size=ksteps) | ||
x = np.array([i*t for i in range(ksteps)]) | ||
sims = [] | ||
for i in range(nsims): | ||
y = np.exp(np.cumsum(X())) | ||
sims.append(y) | ||
return sims, x | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from quantpyml import brownian_motion | ||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
sims, x = brownian_motion() | ||
# sims, x = geometric_brownian_motion() | ||
for i in range(len(sims)): | ||
plt.plot(x, sims[i]) | ||
# plot a trend line for all the simulations | ||
plt.plot(x, np.mean(sims, axis=0), color='black', linewidth=3, label='trend') | ||
plt.xlabel('Time') | ||
plt.ylabel('Value') | ||
plt.title('Brownian Motion') | ||
plt.legend() | ||
plt.show() | ||
|