├── 30_70_simulation.py ├── LICENSE ├── README.md ├── binomial_1step.py ├── black_scholes.py ├── garman_klass_vol.py ├── greeks └── README.md ├── hedge.py ├── historical_vol.py ├── historical_vol_auto.py └── image ├── Garman-Klass_historical_vol.jpg ├── MC2.png ├── README.md ├── Shout2.png ├── blackscholes.jpg ├── classical_vol.jpg ├── euler_equation.jpg ├── put_call_parity_TEST.jpg ├── rufous.jpg ├── rufous2.jpg └── the_greeks.jpg /30_70_simulation.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author: boyac 3 | # @Date: 2016-05-08 23:03:49 4 | # @Last Modified by: boyac 5 | # @Last Modified time: 2016-05-08 23:54:21 6 | 7 | import numpy as np 8 | import random 9 | 10 | def Money(num_sims, num_participants): 11 | """ 12 | This is the rewritten code of simulations from: 13 | https://www.quora.com/How-can-I-win-a-stock-market-competition-in-1-month-from-scratch 14 | - We have 100 participants other than you 15 | - You pick 1 stock that has 70% chance of going bankrupt and 30% chance of jumping 100% 16 | - Other pick from the universe of stocks with 25%' volatility and 10%' average return. (# strong assumption) 17 | """ 18 | i_won = [] # array to store outcomes 19 | for sim in range(0, num_sims): # for every simulation 20 | stock_returns = np.random.randn(num_participants) * 0.25 + 0.1 21 | best_return = max(stock_returns) 22 | my_return = 1 if np.random.rand() > 0.7 else -1 # a binary outcome for your stock: either win or lose 23 | i_won.append(1 if my_return > best_return else 0) 24 | 25 | win_prop = np.array(i_won).mean() 26 | std_err = 1.96 * np.sqrt(win_prop * (1-win_prop) / num_sims) 27 | upper = win_prop + std_err 28 | lower = win_prop - std_err 29 | return 'Win Probability (Upper): {:.5f} | Win Probability (Lower): {:.5f}'.format(upper, lower) 30 | 31 | 32 | if __name__ == '__main__': 33 | num_sims = 10000 # number of simuations 34 | num_participants = 100 # number of participants 35 | print Money(num_sims, num_participants) # Win Probability (Upper): 0.31120 | Win Probability (Lower): 0.29320 36 | 37 | """ 38 | # a stock has 70% chance of going bankrupt and 30% chance of jumping 100% 39 | # question arises of how do you determine the 30/70 percent chances ratio? 40 | # I got stuck, if it follows a normal distribution and implied Vol 1 (= 100%), 41 | # 1 std, about 70% (actually 68%) confidence interval of bankrupt or double the original investment. 42 | # another 30% chance of either go -0 or more than double the original investment? 43 | # Still couldn't get where 30/70 ratio come from, is it a skewed dataset? 44 | # Besides, 'stock_returns' uses np.random.randn(normal distribution) 45 | """ 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Boya Chiou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, subject to the following conditions: 10 | 11 | 1. **Attribution Requirement:** 12 | If used in a commercial product, you must **credit the original author** as follows: 13 | `"This software includes code developed by Boya Chiou ([https://github.com/boyac])"` 14 | 15 | 2. **Commercial License Option:** 16 | If you wish to **use this software without attribution** or **keep modifications closed-source**, 17 | you must obtain a **commercial license** from the author. 18 | 19 | 3. **No Warranty:** 20 | This software is provided "as is", without warranty of any kind, express or implied. 21 | 22 | For commercial licensing inquiries, please contact: 23 | 🔗 [https://github.com/boyac] 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyOptionPricing 2 | 3 | A collection of Python scripts for option pricing and volatility calculations. 4 | 5 | [![GitHub Sponsors](https://img.shields.io/github/sponsors/boyac?style=for-the-badge)](https://github.com/sponsors/boyac) 6 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/boyac) 7 | 8 | **If you find this project helpful, please consider supporting its development!** Your contribution helps to maintain and expand this valuable resource for the options trading community. 9 | 10 | ## Description 11 | 12 | This repository provides implementations of various option pricing models and volatility calculations in Python 2.7. It's a valuable resource for: 13 | 14 | * Students learning about option pricing theory 15 | * Quantitative analysts and traders 16 | * Anyone interested in exploring financial modeling techniques 17 | 18 | ## Key Features 19 | 20 | * **Traditional Historical Volatility Calculation:** Simple and easy-to-understand implementation. 21 | * **Garman-Klass Historical Volatility:** More sophisticated volatility estimation. 22 | * **Black-Scholes Model:** Classic option pricing model. 23 | * **Exotic Option Example (Shout Options):** Demonstration of Monte Carlo approximation. 24 | * **Clear and Commented Code:** Easy to follow and adapt for your own needs. 25 | 26 | ## Usage 27 | 28 | To use these scripts, you'll need: 29 | 30 | * Python 2.7 31 | * pandas 32 | * pandas_datareader 33 | * scipy 34 | 35 | Install the dependencies using pip: 36 | 37 | ```bash 38 | pip install pandas pandas_datareader scipy 39 | ``` 40 | --- 41 | 42 | ### Traditional Historical Volatility Calculation 43 | ![alt tag](image/classical_vol.jpg) 44 | 45 | ```python 46 | # -*- coding: utf-8 -*- 47 | # @Author: boyac 48 | # @Date: 2016-05-02 18:28:28 49 | # @Last Modified by: boyac 50 | # @Last Modified time: 2016-05-02 19:09:29 51 | 52 | from pandas import np 53 | import pandas_datareader.data as web 54 | 55 | def historical_volatility(sym, days): # stock symbol, number of days 56 | "Return the annualized stddev of daily log returns of picked stock" 57 | try: 58 | # past number of 'days' close price data, normally between (30, 60) 59 | quotes = web.DataReader(sym, 'yahoo')['Close'][-days:] 60 | except Exception, e: 61 | print "Error getting data for symbol '{}'.\n".format(sym), e 62 | return None, None 63 | logreturns = np.log(quotes / quotes.shift(1)) 64 | # return square root * trading days * logreturns variance 65 | # NYSE = 252 trading days; Shanghai Stock Exchange = 242; Tokyo Stock Exchange = 246 days? 66 | return np.sqrt(252*logreturns.var()) 67 | 68 | 69 | if __name__ == "__main__": 70 | print historical_volatility('FB', 30) # facebook: 0.296710526109 71 | ``` 72 | 73 | 74 | ### Garman-Klass Historical Volatility 75 | ![alt tag](image/Garman-Klass_historical_vol.jpg) 76 | ```python 77 | # -*- coding: utf-8 -*- 78 | # @Author: boyac 79 | # @Date: 2016-05-02 18:28:28 80 | # @Last Modified by: boyac 81 | # @Last Modified time: 2016-05-02 19:09:29 82 | 83 | from pandas import np 84 | import pandas_datareader.data as web 85 | 86 | 87 | def gk_vol(sym, days): 88 | """" 89 | Return the annualized stddev of daily log returns of picked stock 90 | Historical Open-High-Low-Close Volatility: Garman Klass 91 | sigma**2 = ((h-l)**2)/2 - (2ln(2) - 1)(c-o)**2 92 | ref: http://www.wilmottwiki.com/wiki/index.php?title=Volatility 93 | """ 94 | 95 | try: 96 | o = web.DataReader(sym, 'yahoo')['Open'][-days:] 97 | h = web.DataReader(sym, 'yahoo')['High'][-days:] 98 | l = web.DataReader(sym, 'yahoo')['Low'][-days:] 99 | c = web.DataReader(sym, 'yahoo')['Close'][-days:] 100 | except Exception, e: 101 | print "Error getting data for symbol '{}'.\n".format(sym), e 102 | return None, None 103 | sigma = np.sqrt(252*sum((np.log(h/l))**2/2 - (2*np.log(2)-1)*(np.log(c/o)**2))/days) 104 | return sigma 105 | 106 | 107 | if __name__ == "__main__": 108 | print gk_vol('FB', 30) # facebook: 0.223351260219 109 | ``` 110 | 111 | 112 | ### Black-Scholes Model 113 | ![alt tag](image/blackscholes.jpg) 114 | ```python 115 | # -*- coding: utf-8 -*- 116 | # @Author: boyac 117 | # @Date: 2016-05-02 18:28:28 118 | # @Last Modified by: boyac 119 | # @Last Modified time: 2016-05-04 00:27:52 120 | 121 | from __future__ import division 122 | from scipy.stats import norm 123 | from math import * 124 | 125 | # Cumulative normal distribution 126 | def CND(X): 127 | return norm.cdf(X) 128 | 129 | # Black Sholes Function 130 | def BlackScholes(CallPutFlag,S,K,t,r,s): 131 | """ 132 | S = Current stock price 133 | t = Time until option exercise (years to maturity) 134 | K = Option striking price 135 | r = Risk-free interest rate 136 | N = Cumulative standard normal distribution 137 | e = Exponential term 138 | s = St. Deviation (volatility) 139 | Ln = NaturalLog 140 | """ 141 | d1 = (log(S/K) + (r + (s ** 2)/2) * t)/(s * sqrt(t)) 142 | d2 = d1 - s * sqrt(t) 143 | 144 | if CallPutFlag=='c': 145 | return S * CND(d1) - K * exp(-r * t) * CND(d2) # call option 146 | else: 147 | return K * exp(-r * t) * CND(-d2) - S * CND(-d1) # put option 148 | 149 | 150 | if __name__ == "__main__": 151 | # Number taken from: http://wiki.mbalib.com/wiki/Black-Scholes期权定价模型 152 | print BlackScholes('c', S=164.0, K=165.0, t=0.0959, r=0.0521, s=0.29) # 5.788529972549341 153 | ``` 154 | 155 | ### Exotic Options Example: Shout Options by Monte Carlo Approximation 156 | ![alt tag](image/MC2.png) 157 | ![alt tag](image/Shout2.png) 158 | 159 | 160 | ## Support 161 | 162 | This project is made possible by the generous support of its users. If you find this project helpful, please consider: 163 | 164 | [![GitHub Sponsors](https://img.shields.io/github/sponsors/boyac?style=for-the-badge)](https://github.com/sponsors/boyac) 165 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/boyac) 166 | ![Downloads](https://img.shields.io/github/downloads/boyac/pyOptionPricing/total) 167 | * Becoming a GitHub Sponsor 168 | * Buying me a coffee on Ko-fi 169 | 170 | -------------------------------------------------------------------------------- /binomial_1step.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author: boyac 3 | # @Date: 2016-05-22 16:12:29 4 | # @Last Modified by: boyac 5 | # @Last Modified time: 2016-05-22 16:12:29 6 | 7 | 8 | from math import * 9 | 10 | def Binomial(S,K,u,d,r,T): # One-Step Binomial Pricing 11 | """ 12 | S = Current stock price 13 | K = Option striking price 14 | u = Size of magnitude of up-jump / upstep 15 | d = Size of magnitude of down-jump / downstep 16 | T = Time until option excercise (years to maturity) 17 | r = Risk-free interest rate 18 | 19 | * u, d can be calculated by volatility assumption 20 | """ 21 | 22 | discount = exp(-r * T) 23 | delta_s = 1 / (S * u - S * d) 24 | portfolio = (S * d) * delta_s 25 | pv = portfolio * discount # portfolio present value 26 | option_price = (S * delta_s) - pv 27 | return option_price 28 | 29 | 30 | if __name__ == "__main__": 31 | print Binomial(20, 21, 1.1, 0.9, 0.12, 0.25) # 0.632995099032 32 | print Binomial(164.0, 165.0, 1.1, 0.9, 0.0521, 0.0959) # 0.522427679626 33 | -------------------------------------------------------------------------------- /black_scholes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author: boyac 3 | # @Date: 2016-05-02 18:28:28 4 | # @Last Modified by: boyac 5 | # @Last Modified time: 2016-05-04 00:27:52 6 | 7 | from __future__ import division 8 | from scipy.stats import norm 9 | from math import * 10 | 11 | # Cumulative normal distribution 12 | def CND(X): 13 | return norm.cdf(X) 14 | 15 | # Black Sholes Function 16 | def BlackScholes(CallPutFlag,S,K,t,r,s): 17 | """ 18 | S = Current stock price 19 | t = Time until option exercise (years to maturity) 20 | K = Option striking price 21 | r = Risk-free interest rate 22 | N = Cumulative standard normal distribution 23 | e = Exponential term 24 | s = St. Deviation (volatility) 25 | Ln = NaturalLog 26 | """ 27 | d1 = (log(S/K) + (r + (s ** 2)/2) * t)/(s * sqrt(t)) 28 | d2 = d1 - s * sqrt(t) 29 | 30 | if CallPutFlag=='c': 31 | return S * CND(d1) - K * exp(-r * t) * CND(d2) # call option 32 | else: 33 | return K * exp(-r * t) * CND(-d2) - S * CND(-d1) # put option 34 | 35 | 36 | if __name__ == "__main__": 37 | # Number taken from: http://wiki.mbalib.com/wiki/Black-Scholes期权定价模型 38 | print BlackScholes('c', S=164.0, K=165.0, t=0.0959, r=0.0521, s=0.29) # 5.788529972549341 39 | -------------------------------------------------------------------------------- /garman_klass_vol.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Author: boyac 3 | # @Date: 2016-05-02 18:28:28 4 | # @Last Modified by: boyac 5 | # @Last Modified time: 2016-05-02 19:09:29 6 | 7 | from pandas import np 8 | import pandas_datareader.data as web 9 | 10 | 11 | def gk_vol(sym, days): 12 | """" 13 | Return the annualized stddev of daily log returns of picked stock 14 | Historical Open-High-Low-Close Volatility: Garman Klass 15 | sigma**2 = ((h-l)**2)/2 - (2ln(2) - 1)(c-o)**2 16 | ref: http://www.wilmottwiki.com/wiki/index.php?title=Volatility 17 | """ 18 | 19 | try: 20 | o = web.DataReader(sym, 'yahoo')['Open'][-days:] 21 | h = web.DataReader(sym, 'yahoo')['High'][-days:] 22 | l = web.DataReader(sym, 'yahoo')['Low'][-days:] 23 | c = web.DataReader(sym, 'yahoo')['Close'][-days:] 24 | except Exception, e: 25 | print "Error getting data for symbol '{}'.\n".format(sym), e 26 | return None, None 27 | sigma = np.sqrt(252*sum((np.log(h/l))**2/2 - (2*np.log(2)-1)*(np.log(c/o)**2))/days) 28 | return sigma 29 | 30 | 31 | if __name__ == "__main__": 32 | print gk_vol('FB', 30) # facebook 33 | -------------------------------------------------------------------------------- /greeks/README.md: -------------------------------------------------------------------------------- 1 | ### ■ Greeks 2 | CALL/Option Price 3 | #### Price 4 | - Delta: has the biggest impact on an option's value. It identifies how much the options premium may change, if the underlying price changes $1.00. 5 | It could also be interpreted as the probability of expiring ITM, e.g. Delta .40 (40% probability of expiring ITM). Lower the Delta, lower probability the option will expire ITM. 6 | One important thing to note about Delta, is that it doesn't have a constant rate of change. It grows as an option moves further ITM, and shringks as it moves furhter OTM. To understand how this works, please refer to Gamma. 7 | - Gamma: Gamma measures Delta's expected rate of change. If an option has a Delta of 0.40, and a Gamma of 0.05, the premium will expect to change $0.40 with the first dollar move in the underlying. Then to figure out the impact of the next dollar move, Simply add Delta and Gamma together, e.g. $1.40 ($1.00 + $0.4 = $1.40), $1.85 ($1.40 + $0.45 = $1.85) 8 | 9 | #### Time 10 | - Theta: Time decay. Theta estimates how much value slips away from an option with each passing day. If an option has a Theta of negative 0.04, it would be expected to lose $0.04 of value every day. Time decay works against buyers and for sellers. 11 | 12 | #### Implied Volatility 13 | - Vega: Vega estimates how much the premium may change with each one percentage point change in impolied volatility. If an option has a Vega 0.03 and implied volatility decreases one percentage point, the premium will be expected to drop $0.03. There are a lot of factors that could cause a spike in implied volatility, e.g. earning announcements, political conditions, and even weather. And the further out an option's expiration is, the higher its Vega will be. In other words, options with a longer expiration may react more to a change in the volatility. 14 | 15 | ### ■ Notes 16 | Implied volatility changes will also have an effect on Gamma. As implied volatility decreases, Gamma of ATM calls and puts increases. When implied volatility goes higher, the Gamma of both ITM and OTM calls and puts will be decreasing. This occurs because low implied volatility options will have a more dramatic change in Delta when the underlying moves. A high implied volatility underlying product will see less of a Delta change with movement as the possibility of more movements is foreseen. 17 | 18 | ### ■ References 19 | n/a 20 | 21 | ![alt tag](/image/the_greeks.jpg) 22 | -------------------------------------------------------------------------------- /hedge.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import math 3 | 4 | class Hedge: 5 | def __init__(self): 6 | pass 7 | 8 | def ratio(self,S,K,u,d,r): 9 | self.S = S # current stock price 10 | self.K = K # strike price 11 | self.u = u # stock up price 12 | self.d = d # stock down price 13 | self.r = r # risk free interest rate 14 | 15 | self.c_price_u = self.u - self.K 16 | self.c_price_d = self.d - self.K 17 | 18 | if (self.c_price_d < 0): 19 | self.c_price_d = 0 20 | 21 | hedge_ratio = (self.c_price_u - self.c_price_d) / (self.u - self.d) # size of exporsure / size of position in the future 22 | return hedge_ratio 23 | 24 | # resize proportion 25 | def hedge_ratio_proportion(self,ratio): 26 | multiplier = 1 / ratio 27 | prop_value = multiplier 28 | v_u = self.u - prop_value * self.c_price_u 29 | v_d = self.d - prop_value * self.c_price_d 30 | 31 | if v_u!=v_d: 32 | print 'Arbitrage Exist!' 33 | else: 34 | print 'NO Arbitrage Opportunity!' 35 | # work on this a bit more; need to check other documents 36 | c = (self.S- v_u / self.r) / prop_value 37 | # / (risk-free interest rate) 38 | print "Call price is {}".format(c) 39 | 40 | 41 | if __name__ == "__main__": 42 | h = Hedge() 43 | r = h.ratio(100,30,125,75,.05) 44 | print h.hedge_ratio_proportion(r) 45 | 46 | # NO Arbitrage Opportunity! 47 | # Call price is -500.0 48 | -------------------------------------------------------------------------------- /historical_vol.py: -------------------------------------------------------------------------------- 1 | from pandas import np 2 | import pandas_datareader.data as web 3 | 4 | def historical_volatility(sym, days): # stock symbol, number of days 5 | "Return the annualized stddev of daily log returns of picked stock" 6 | try: 7 | # past number of 'days' close price data, normally between (30, 60) 8 | quotes = web.DataReader(sym, 'yahoo')['Close'][-days:] 9 | except Exception, e: 10 | print "Error getting data for symbol '{}'.\n".format(sym), e 11 | return None, None 12 | logreturns = np.log(quotes / quotes.shift(1)) 13 | # return square root * trading days * logreturns variance 14 | # NYSE = 252 trading days; Shanghai Stock Exchange = 242; Tokyo Stock Exchange = 246 days? 15 | return np.sqrt(252*logreturns.var()) 16 | 17 | 18 | if __name__ == "__main__": 19 | print historical_volatility('FB', 30) # facebook 20 | -------------------------------------------------------------------------------- /historical_vol_auto.py: -------------------------------------------------------------------------------- 1 | from pandas import np 2 | import pandas_datareader.data as web 3 | import threading 4 | 5 | def hv(sym, days): 6 | """ 7 | Return the annualized stddev of daily log returns of picked stock, 8 | and auto refresh data loading every 5 seconds. 9 | """ 10 | try: 11 | # past number of 'days' close price data, normally between (30, 60) 12 | hv.quotes = web.DataReader(sym, 'yahoo')['Close'][-days:] 13 | except Exception, e: 14 | print "Error getting data for symbol '{}'.\n".format(sym), e 15 | return None, None 16 | logreturns = np.log(hv.quotes / hv.quotes.shift(1)) 17 | # return square root * trading days * logreturns variance 18 | # NYSE 252 trading days, Shanghai Stock Exchange = 242, Tokyo Stock Exchange = 246 days? 19 | return np.sqrt(252*logreturns.var()) 20 | 21 | if __name__ == "__main__": 22 | print hv('FB', 30) # facebook/ 0.294282265956 23 | threading.Timer(5, hv.quotes).start() 24 | 25 | 26 | # [BUG]Cannot read Time Series data 27 | """ 28 | Exception in thread Thread-1: 29 | Traceback (most recent call last): 30 | File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner 31 | self.run() 32 | File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 1073, in run 33 | self.function(*self.args, **self.kwargs) 34 | TypeError: 'Series' object is not callable 35 | """ 36 | -------------------------------------------------------------------------------- /image/Garman-Klass_historical_vol.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/Garman-Klass_historical_vol.jpg -------------------------------------------------------------------------------- /image/MC2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/MC2.png -------------------------------------------------------------------------------- /image/README.md: -------------------------------------------------------------------------------- 1 | ### University of Tokyo | GraSPP_Macroeconomics_2012 2 | - Prerequisites: Algebra II (algebra, trigonometry, arithmetic), Precalculus, AP Calculus BC, Linear Algebra 3 | - Over 30 credits in advanced economics, statistics and econometrics from Economics Dept. (Literally, almost another degree in Economics) 4 | - Plus, additional credits of Securities Law, Financial Institutions and applied econometrics by practitioners, economists from Nomura, World Bank and IMF. 5 | 6 | ![alt tag](euler_equation.jpg) 7 | -------------------------------------------------------------------------------- /image/Shout2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/Shout2.png -------------------------------------------------------------------------------- /image/blackscholes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/blackscholes.jpg -------------------------------------------------------------------------------- /image/classical_vol.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/classical_vol.jpg -------------------------------------------------------------------------------- /image/euler_equation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/euler_equation.jpg -------------------------------------------------------------------------------- /image/put_call_parity_TEST.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/put_call_parity_TEST.jpg -------------------------------------------------------------------------------- /image/rufous.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/rufous.jpg -------------------------------------------------------------------------------- /image/rufous2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/rufous2.jpg -------------------------------------------------------------------------------- /image/the_greeks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boyac/pyOptionPricing/af32fbb55afa1874fd77380e863a5ce430f5fa5d/image/the_greeks.jpg --------------------------------------------------------------------------------