├── .DS_Store ├── BSDoc.hpp ├── BSLib.cpp ├── BSLib.hpp ├── Option.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── Option.xcscmblueprint │ └── xcuserdata │ │ └── junyan.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ └── junyan.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Option.xcscheme │ └── xcschememanagement.plist ├── PyHeston.cpp ├── build ├── lib.macosx-10.10-x86_64-3.5 │ └── PyHeston.cpython-35m-darwin.so └── temp.macosx-10.10-x86_64-3.5 │ ├── BSLib.o │ └── PyHeston.o ├── figures ├── IVsurface.png ├── test1.png └── test2.png ├── readme.md └── setup.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/.DS_Store -------------------------------------------------------------------------------- /BSDoc.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // BSDoc.hpp 3 | // Option 4 | // 5 | // Created by junyan on 12/17/16. 6 | // Copyright © 2016 junyan. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | This file is used for providing helper documentation to functions in the module 12 | 13 | */ 14 | 15 | #ifndef BSDoc_hpp 16 | #define BSDoc_hpp 17 | 18 | #include 19 | #include 20 | 21 | 22 | namespace doc { 23 | 24 | const char HestonCall[] = "Calculate heston model call option price. The parameters follow the following sequence:\n\n S: Current underlying price\n V0: Current instantaneous volatility square\n K: Strike price\n T: Time to expiry\n r: Interest rate\n Kappa: Mean reversion maganitude\n Theta: Long term mean in Heston model\n Eta: Vol of vol\n Rho: Correlation of underlying stochastic term with vol\n Stepsize: Numerical solution stepsize. Recommend 0.4"; 25 | 26 | const char HestonPut[] = "Calculate heston model put option price. The parameters follow the following sequence:\n\n S: Current underlying price\n V0: Current instantaneous volatility square\n K: Strike price\n T: Time to expiry\n r: Interest rate\n Kappa: Mean reversion maganitude\n Theta: Long term mean in Heston model\n Eta: Vol of vol\n Rho: Correlation of underlying stochastic term with vol\n Stepsize: Numerical solution stepsize. Recommend 0.4"; 27 | 28 | const char HestonMixedGaussianCall[] = "Calculate heston model mixed gaussian call option price. The parameters follow the following sequence:\n\n S: Current underlying price\n V0: Current instantaneous volatility square\n K: Strike price\n T: Time to expiry\n r: Interest rate\n Kappa: Mean reversion maganitude\n Theta: Long term mean in Heston model\n Eta: Vol of vol\n Rho: Correlation of underlying stochastic term with vol\n\n The Mixed Gaussian part has four parameters:\n Up: average maganitude of up log jump\n UpSigma: dispersion maganitude of up log jump\n Down: average maganitude of down log jump\n DownSigma: dispersion maganitude of down log jump\nStepsize: Numerical solution stepsize. Recommend 0.4"; 29 | 30 | const char HestonMixedGaussianPut[] = "Calculate heston model mixed gaussian put option price. The parameters follow the following sequence:\n\n S: Current underlying price\n V0: Current instantaneous volatility square\n K: Strike price\n T: Time to expiry\n r: Interest rate\n Kappa: Mean reversion maganitude\n Theta: Long term mean in Heston model\n Eta: Vol of vol\n Rho: Correlation of underlying stochastic term with vol\n\n The Mixed Gaussian part has four parameters:\n Up: average maganitude of up log jump\n UpSigma: dispersion maganitude of up log jump\n Down: average maganitude of down log jump\n DownSigma: dispersion maganitude of down log jump\nStepsize: Numerical solution stepsize. Recommend 0.4"; 31 | 32 | const char TwoRegimeHestonCall[] = "Calculate two regime heston model call option price. The two regime stand for the different situation before and after the discrete event. The parameter of the heston model are assumed to be different. The parameters follow the following sequence:\n\n S: Current underlying price\n V0: Current instantaneous volatility square\n K: Strike price\n T1: Time to discrete event\n T2: Time from discrete event to expiry\n r: Interest rate\n Kappa1: Mean reversion maganitude before event\n Theta1: Long term mean in Heston model before event\n Eta1: Vol of vol before event\n Rho1: Correlation of underlying stochastic term with vol before event\n\n Kappa2: Mean reversion maganitude after event\n Theta2: Long term mean in Heston model after event\n Eta2: Vol of vol after event\n Rho2: Correlation of underlying stochastic term with vol after event\nStepsize: Numerical solution stepsize. Recommend 0.4"; 33 | 34 | const char TwoRegimeHestonPut[] = "Calculate two regime heston model call option price. The two regime stand for the different situation before and after the discrete event. The parameter of the heston model are assumed to be different. The parameters follow the following sequence:\n\n S: Current underlying price\n V0: Current instantaneous volatility square\n K: Strike price\n T1: Time to discrete event\n T2: Time from discrete event to expiry\n r: Interest rate\n Kappa1: Mean reversion maganitude before event\n Theta1: Long term mean in Heston model before event\n Eta1: Vol of vol before event\n Rho1: Correlation of underlying stochastic term with vol before event\n\n Kappa2: Mean reversion maganitude after event\n Theta2: Long term mean in Heston model after event\n Eta2: Vol of vol after event\n Rho2: Correlation of underlying stochastic term with vol after event\nStepsize: Numerical solution stepsize. Recommend 0.4"; 35 | 36 | } 37 | 38 | 39 | #endif /* BSDoc_hpp */ 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /BSLib.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // BSLib.c 3 | // Option 4 | // 5 | // Created by junyan on 10/21/16. 6 | // Copyright © 2016 junyan. All rights reserved. 7 | // 8 | 9 | #include "BSLib.hpp" 10 | 11 | 12 | 13 | double BSCall (double S, double K, double T, double Sigma, double d, double r){ 14 | if(T == 0){ 15 | return ((S-K)>0? (S-K) : 0); 16 | } 17 | if(Sigma <= 0){ 18 | return ((S*exp((r-d)*T)-K)>0?S*exp(-d)*T-K*exp(-r*T): 0); 19 | } 20 | double d1 = (log(S/K) + T*(r - d) + 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 21 | double d2 = (log(S/K) + T*(r - d) - 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 22 | return S*exp(-d*T)*gsl_cdf_ugaussian_P(d1) - K*exp(-r*T)*gsl_cdf_ugaussian_P(d2); 23 | } 24 | 25 | double BSPut (double S, double K, double T, double Sigma, double d, double r){ 26 | if(T == 0){ 27 | return ((K-S)>0? (K-S) : 0); 28 | } 29 | if(Sigma <= 0){ 30 | return ((S*exp((r-d)*T)-K)<0?-S*exp(-d)*T+K*exp(-r*T): 0); 31 | } 32 | double d1 = (log(S/K) + T*(r - d) + 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 33 | double d2 = (log(S/K) + T*(r - d) - 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 34 | return -S*exp(-d*T)*gsl_cdf_ugaussian_P(-d1) + K*exp(-r*T)*gsl_cdf_ugaussian_P(-d2); 35 | } 36 | 37 | double BSCallDelta(double S, double K, double T, double Sigma, double d, double r){ 38 | double d1 = (log(S/K) + T*(r - d) + 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 39 | return exp(-d*T)*gsl_cdf_ugaussian_P(d1); 40 | } 41 | 42 | double BSPutDelta(double S, double K, double T, double Sigma, double d, double r){ 43 | double d1 = (log(S/K) + T*(r - d) + 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 44 | return exp(-d*T)*(gsl_cdf_ugaussian_P(d1)-1); 45 | } 46 | 47 | double BSVega(double S, double K, double T, double Sigma, double d, double r){ 48 | double d1 = (log(S/K) + T*(r - d) + 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 49 | double d2 = (log(S/K) + T*(r - d) - 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma); 50 | double d1d = -(log(S/K) + T*(r - d) + 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma*Sigma) + 0.5/sqrt(T); 51 | double d2d = -(log(S/K) + T*(r - d) + 0.5*Sigma*Sigma*T)/(sqrt(T)*Sigma*Sigma) - 0.5/sqrt(T); 52 | return S*exp(-d*T)*gsl_ran_gaussian_pdf(d1, 1)*d1d - K*exp(-r*T)*gsl_ran_gaussian_pdf(d2, 1)*d2d; 53 | } 54 | 55 | double BSCallIV(double C, double S, double K, double T, double d, double r){ 56 | double vol_left = 0; 57 | double vol_right = 20; 58 | int count = 0; 59 | double est = BSCall(S,K, T, (vol_left+vol_right)/2, d, r); 60 | while (fabs(est - C) > 0.000000000001) { 61 | if(est > C){ 62 | vol_right = (vol_left + vol_right)/2; 63 | } 64 | else{ 65 | vol_left = (vol_left + vol_right)/2; 66 | } 67 | est = BSCall(S, K, T, (vol_left + vol_right)/2, d, r); 68 | count++; 69 | if(count > 2000){ 70 | return -1; 71 | } 72 | } 73 | return (vol_left + vol_right)/2; 74 | } 75 | 76 | double BSPutIV(double P , double S, double K, double T, double d, double r){ 77 | double vol_left = 0; 78 | double vol_right = 20; 79 | int count = 0; 80 | double est = BSPut(S,K, T, (vol_left+vol_right)/2, d, r); 81 | while (fabs(est - P) > 0.000000000001) { 82 | if(est > P){ 83 | vol_right = (vol_left + vol_right)/2; 84 | } 85 | else{ 86 | vol_left = (vol_left + vol_right)/2; 87 | } 88 | est = BSPut(S, K, T, (vol_left + vol_right)/2, d, r); 89 | count++; 90 | if(count > 2000){ 91 | return -1; 92 | } 93 | } 94 | return (vol_left + vol_right)/2; 95 | } 96 | 97 | void print_complex(gsl_complex s){ 98 | printf("%f + %fi\n", s.dat[0], s.dat[1]); 99 | } 100 | 101 | 102 | gsl_complex operator+(const gsl_complex &a, const gsl_complex &b){ 103 | return gsl_complex_add(a, b); 104 | } 105 | 106 | gsl_complex operator+(gsl_complex a, double b){ 107 | return gsl_complex_add_real(a, b); 108 | } 109 | 110 | gsl_complex operator+(double a, gsl_complex b){ 111 | return gsl_complex_add_real(b, a); 112 | } 113 | 114 | gsl_complex operator*(const gsl_complex &a, const gsl_complex &b){ 115 | return gsl_complex_mul(a, b); 116 | } 117 | 118 | gsl_complex operator*(gsl_complex a, double b){ 119 | return gsl_complex_mul_real(a, b); 120 | } 121 | 122 | gsl_complex operator*(double a, gsl_complex b){ 123 | return gsl_complex_mul_real(b, a); 124 | } 125 | 126 | gsl_complex operator/(const gsl_complex &a, const gsl_complex &b){ 127 | return gsl_complex_div(a, b); 128 | } 129 | 130 | gsl_complex operator/(gsl_complex a, double b){ 131 | return gsl_complex_div_real(a, b); 132 | } 133 | 134 | gsl_complex operator/(double a, gsl_complex b){ 135 | return gsl_complex_pow_real(gsl_complex_div_real(b, a), -1); 136 | } 137 | 138 | gsl_complex operator-(const gsl_complex &a, const gsl_complex &b){ 139 | return gsl_complex_sub(a, b); 140 | } 141 | 142 | gsl_complex operator-(gsl_complex a, double b){ 143 | return gsl_complex_sub_real(a, b); 144 | } 145 | 146 | gsl_complex operator-(double a, gsl_complex b){ 147 | return gsl_complex_mul_real(gsl_complex_sub_real(b, a), -1); 148 | } 149 | 150 | gsl_complex operator^(gsl_complex a, double b){ 151 | return gsl_complex_pow_real(a, b); 152 | } 153 | 154 | gsl_complex operator^(const gsl_complex &a,const gsl_complex& b){ 155 | return gsl_complex_pow(a, b); 156 | } 157 | 158 | gsl_complex log(const gsl_complex &a){ 159 | return gsl_complex_log(a); 160 | } 161 | 162 | gsl_complex exp(const gsl_complex &a){ 163 | return gsl_complex_exp(a); 164 | } 165 | 166 | gsl_complex I(const double& a){ 167 | return gsl_complex_rect(0, a); 168 | } 169 | 170 | /* 171 | 172 | Heston Model Characteristic Function 173 | 174 | */ 175 | 176 | gsl_complex HestonCF(gsl_complex z, double x, double Volsquare, double T, double r, 177 | double Chi, double Theta, double Ita, double Rho){ 178 | gsl_complex zsqurez = (z^2) + z*I(1); 179 | gsl_complex ChiStar = Chi - z * I(Rho*Ita); 180 | gsl_complex Gamma = ((ChiStar^2) + zsqurez * Ita*Ita)^0.5; 181 | gsl_complex em = exp(Gamma * -T); 182 | gsl_complex A = I(r*T)*z + (T*(ChiStar-Gamma)-2*log((ChiStar-Gamma)/2/Gamma*(1 - em) + 1))*Chi*Theta/Ita/Ita; 183 | gsl_complex B = -1*zsqurez*(1-em)/(2*Gamma*em + (Gamma + ChiStar)*(1-em)); 184 | return exp(A+z*I(x) + B*Volsquare); 185 | } 186 | 187 | gsl_complex TwoRegime2DHestonCF(gsl_complex y, gsl_complex z, double x, double Volsquare, double T, double r, 188 | double Chi, double Theta, double Ita, double Rho){ 189 | gsl_complex zsqurez = (z^2) + z*I(1); 190 | gsl_complex ChiStar = Chi - z * I(Rho*Ita); 191 | gsl_complex Gamma = ((ChiStar^2) + zsqurez * Ita*Ita)^0.5; 192 | gsl_complex em = exp(Gamma * -T); 193 | gsl_complex A = I(r*T)*z + (T*(ChiStar-Gamma)-2*log((ChiStar-Gamma - I(1)*y*Ita*Ita)/2/Gamma*(1 - em) + 1))*Chi*Theta/Ita/Ita; 194 | gsl_complex B = I(1)*y-(zsqurez+2*y*I(1)*ChiStar+y*y*Ita*Ita)*(1-em)/(2*Gamma*em + (Gamma + ChiStar-I(1)*y*Ita*Ita)*(1-em)); 195 | return exp(A+z*I(x) + B*Volsquare); 196 | } 197 | 198 | 199 | gsl_complex TwoRegime1DHestonCF(gsl_complex z, double x, double Volsquare, double T1, double T2, double r, 200 | double Chi1, double Theta1, double Ita1, double Rho1, 201 | double Chi2, double Theta2, double Ita2, double Rho2){ 202 | gsl_complex zsqurez2 = (z^2) + z*I(1); 203 | gsl_complex ChiStar2 = Chi2 - z * I(Rho2*Ita2); 204 | gsl_complex Gamma2 = ((ChiStar2^2) + zsqurez2 * Ita2*Ita2)^0.5; 205 | gsl_complex em2 = exp(Gamma2 * -T2); 206 | gsl_complex A = I(r*T2)*z + (T2*(ChiStar2-Gamma2)-2*log((ChiStar2-Gamma2)/2/Gamma2*(1 - em2) + 1))*Chi2*Theta2/Ita2/Ita2; 207 | gsl_complex B = -1*zsqurez2*(1-em2)/(2*Gamma2*em2 + (Gamma2 + ChiStar2)*(1-em2)); 208 | return exp(A)*TwoRegime2DHestonCF(I(-1)*B, z, x, Volsquare,T1, r, Chi1, Theta1, Ita1, Rho1); 209 | } 210 | 211 | 212 | gsl_complex MixedGaussianCF(gsl_complex z, double Up, double UpSigma, double Down, double DownSigma){ 213 | double P; 214 | if(exp(Up+0.5*UpSigma*UpSigma) - exp(Down+0.5*DownSigma*DownSigma) == 0) 215 | P=0.5; 216 | else 217 | P = (1 - exp(Down+0.5*DownSigma*DownSigma))/(exp(Up+0.5*UpSigma*UpSigma) - exp(Down+0.5*DownSigma*DownSigma)); 218 | return exp(z*I(Up)-(z^2)*0.5*UpSigma*UpSigma)*P + exp(z*I(Down)-(z^2)*0.5*DownSigma*DownSigma)*(1-P); 219 | } 220 | 221 | 222 | double HestonCall(double S, double VolSquare, double K, double T, double r, 223 | double Chi, double Theta, double Ita, double Rho, double StepSize) 224 | { 225 | if(K==0){ 226 | return S; 227 | } 228 | if(T==0){ 229 | return S-K>0?S-K:0; 230 | } 231 | double x = log(S); 232 | double logK = log(K); 233 | const double step = StepSize; 234 | const double alpha = 1.5; 235 | const double range = 2000; 236 | double integral = 0; 237 | gsl_complex z; 238 | for (double i=-range; i< range; i=i+step) { 239 | z = i-I(alpha); 240 | integral = integral + GSL_REAL(HestonCF(z - I(1), x, VolSquare, T, r, Chi, Theta, Ita, Rho)*exp(z * I(-logK))/z/(I(1) - z))*step; 241 | } 242 | return integral/(2*M_PI)*exp(-r*T); 243 | } 244 | 245 | /* 246 | double x, double Volsquare, double T1, double T2, double r, 247 | double Chi1, double Theta1, double Ita1, double Rho1, 248 | double Chi2, double Theta2, double Ita2, double Rho2*/ 249 | 250 | double TwoRegimeHestonCall(double S, double VolSquare, double K, double T1, double T2, double r, 251 | double Chi1, double Theta1, double Ita1, double Rho1, 252 | double Chi2, double Theta2, double Ita2, double Rho2, double StepSize) 253 | { 254 | if(K==0){ 255 | return S; 256 | } 257 | if(T1==0 && T2==0){ 258 | return S-K>0?S-K:0; 259 | } 260 | double x = log(S); 261 | double logK = log(K); 262 | const double step = StepSize; 263 | const double alpha = 1.5; 264 | const double range = 2000; 265 | double integral = 0; 266 | gsl_complex z; 267 | for (double i=-range; i< range; i=i+step) { 268 | z = i-I(alpha); 269 | integral = integral + GSL_REAL(TwoRegime1DHestonCF(z - I(1), x, VolSquare, T1, T2, r, Chi1, Theta1, Ita1, Rho1,Chi2, Theta2, Ita2, Rho2)*exp(z * I(-logK))/z/(I(1) - z))*step; 270 | } 271 | return integral/(2*M_PI)*exp(-r*(T1+T2)); 272 | } 273 | 274 | 275 | double HestonMixedGaussianCall(double S, double VolSquare, double K, double T, double r, 276 | double Chi, double Theta, double Ita, double Rho, double Up, 277 | double UpSigma, double Down, double DownSigma, double StepSize){ 278 | if(K==0){ 279 | return S; 280 | } 281 | if(T==0){ 282 | return S-K>0?S-K:0; 283 | } 284 | double x = log(S); 285 | double logK = log(K); 286 | const double step = StepSize; 287 | const double alpha = 1.5; 288 | const double range = 2000; 289 | double integral = 0; 290 | gsl_complex z; 291 | for (double i=-range; i< range; i=i+step) { 292 | z = gsl_complex_rect(i, -alpha); 293 | integral = integral + GSL_REAL(HestonCF(z - I(1), x, VolSquare, T, r, Chi, Theta, Ita, Rho)*MixedGaussianCF(z-I(1), Up, UpSigma, Down, DownSigma) * exp(z*I(-logK))/z/(I(1)-z))*step; 294 | } 295 | return integral/(2*M_PI)*exp(-r*T); 296 | } 297 | 298 | double TwoRegimeHestonMixedGaussianCall(double S, double VolSquare, double K, double T1, double T2, double r, 299 | double Chi1, double Theta1, double Ita1, double Rho1, 300 | double Chi2, double Theta2, double Ita2, double Rho2, 301 | double Up, double UpSigma, double Down, double DownSigma, 302 | double StepSize) 303 | { 304 | if(K==0){ 305 | return S; 306 | } 307 | if(T1==0 && T2==0){ 308 | return S-K>0?S-K:0; 309 | } 310 | double x = log(S); 311 | double logK = log(K); 312 | const double step = StepSize; 313 | const double alpha = 1.5; 314 | const double range = 2000; 315 | double integral = 0; 316 | gsl_complex z; 317 | for (double i=-range; i< range; i=i+step) { 318 | z = i-I(alpha); 319 | integral = integral + GSL_REAL(TwoRegime1DHestonCF(z - I(1), x, VolSquare, T1, T2, r, Chi1, Theta1, Ita1, Rho1,Chi2, Theta2, Ita2, Rho2)*MixedGaussianCF(z-I(1), Up, UpSigma, Down, DownSigma)*exp(z * I(-logK))/z/(I(1) - z))*step; 320 | } 321 | return integral/(2*M_PI)*exp(-r*(T1+T2)); 322 | } 323 | 324 | 325 | -------------------------------------------------------------------------------- /BSLib.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // BSLib.h 3 | // Option 4 | // 5 | // Created by junyan on 10/21/16. 6 | // Copyright © 2016 junyan. All rights reserved. 7 | // 8 | 9 | #ifndef BSLib_h 10 | #define BSLib_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | double BSCall(double S, double K, double T, double Sigma, double d, double r); 21 | double BSPut(double S, double K, double T, double Sigma, double d, double r); 22 | double BSVega(double S, double K, double T, double Sigma, double d, double r); 23 | double BSCallDelta(double S, double K, double T, double Sigma, double d, double r); 24 | double BSPutDelta(double S, double K, double T, double Sigma, double d, double r); 25 | double BSGamma(double S, double K, double T, double Sigma, double d, double r); 26 | double BSTheta(double S, double K, double T, double Sigma, double d, double r); 27 | 28 | 29 | /* 30 | Main stochastics model pricer 31 | */ 32 | 33 | double HestonCall(double S, double VolSquare, double K, double T, double r, 34 | double Chi, double Theta, double Ita, double Rho, 35 | double StepSize); 36 | double HestonMixedGaussianCall(double S, double VolSquare, double K, double T, 37 | double r, double Chi, double Theta, double Ita, 38 | double Rho, double Up, double UpSigma, 39 | double Down, double DownSigma, double StepSize); 40 | double TwoRegimeHestonCall(double S, double VolSquare, double K, double T1, 41 | double T2, double r, double Chi1, double Theta1, 42 | double Ita1, double Rho1, double Chi2, double Theta2, 43 | double Ita2, double Rho2, double StepSize); 44 | 45 | double TwoRegimeHestonMixedGaussianCall(double S, double VolSquare, double K, double T1, double T2, double r, 46 | double Chi1, double Theta1, double Ita1, double Rho1, 47 | double Chi2, double Theta2, double Ita2, double Rho2, 48 | double Up, double UpSigma, double Down, double DownSigma, 49 | double StepSize); 50 | /* 51 | 52 | Compute implied volatility 53 | 54 | */ 55 | 56 | double BSCallIV(double C, double S, double K, double T, double d, double r); 57 | double BSPutIV(double P , double S, double K, double T, double d, double r); 58 | 59 | #endif /* BSLib_h */ 60 | -------------------------------------------------------------------------------- /Option.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A9DCE79A1DBA6A8F009C397C /* BSLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9DCE7981DBA6A8F009C397C /* BSLib.cpp */; settings = {ASSET_TAGS = (); }; }; 11 | A9DCE79D1DBA7559009C397C /* PyHeston.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9DCE79B1DBA7559009C397C /* PyHeston.cpp */; settings = {ASSET_TAGS = (); }; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | A9B4D2AC1DB94103001FE35A /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = /usr/share/man/man1/; 19 | dstSubfolderSpec = 0; 20 | files = ( 21 | ); 22 | runOnlyForDeploymentPostprocessing = 1; 23 | }; 24 | /* End PBXCopyFilesBuildPhase section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | A952B1BF1E059DD200CA63A1 /* BSDoc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = BSDoc.hpp; sourceTree = ""; }; 28 | A9BD3CCF1DECF1F700383108 /* Option */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = Option; path = "/Users/junyan/Desktop/IMC/Option/Python-Heston-Option-Pricer/build/Debug/Option"; sourceTree = ""; }; 29 | A9DCE7981DBA6A8F009C397C /* BSLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BSLib.cpp; sourceTree = ""; }; 30 | A9DCE7991DBA6A8F009C397C /* BSLib.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = BSLib.hpp; sourceTree = ""; }; 31 | A9DCE79B1DBA7559009C397C /* PyHeston.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PyHeston.cpp; sourceTree = ""; }; 32 | /* End PBXFileReference section */ 33 | 34 | /* Begin PBXFrameworksBuildPhase section */ 35 | A9B4D2AB1DB94103001FE35A /* Frameworks */ = { 36 | isa = PBXFrameworksBuildPhase; 37 | buildActionMask = 2147483647; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | A9B4D2A51DB94103001FE35A = { 46 | isa = PBXGroup; 47 | children = ( 48 | A952B1BF1E059DD200CA63A1 /* BSDoc.hpp */, 49 | A9DCE7981DBA6A8F009C397C /* BSLib.cpp */, 50 | A9DCE7991DBA6A8F009C397C /* BSLib.hpp */, 51 | A9DCE79B1DBA7559009C397C /* PyHeston.cpp */, 52 | ); 53 | sourceTree = ""; 54 | }; 55 | /* End PBXGroup section */ 56 | 57 | /* Begin PBXNativeTarget section */ 58 | A9B4D2AD1DB94103001FE35A /* Option */ = { 59 | isa = PBXNativeTarget; 60 | buildConfigurationList = A9B4D2B51DB94103001FE35A /* Build configuration list for PBXNativeTarget "Option" */; 61 | buildPhases = ( 62 | A9B4D2AA1DB94103001FE35A /* Sources */, 63 | A9B4D2AB1DB94103001FE35A /* Frameworks */, 64 | A9B4D2AC1DB94103001FE35A /* CopyFiles */, 65 | ); 66 | buildRules = ( 67 | ); 68 | dependencies = ( 69 | ); 70 | name = Option; 71 | productName = Option; 72 | productReference = A9BD3CCF1DECF1F700383108 /* Option */; 73 | productType = "com.apple.product-type.tool"; 74 | }; 75 | /* End PBXNativeTarget section */ 76 | 77 | /* Begin PBXProject section */ 78 | A9B4D2A61DB94103001FE35A /* Project object */ = { 79 | isa = PBXProject; 80 | attributes = { 81 | LastUpgradeCheck = 0700; 82 | ORGANIZATIONNAME = junyan; 83 | TargetAttributes = { 84 | A9B4D2AD1DB94103001FE35A = { 85 | CreatedOnToolsVersion = 7.0.1; 86 | }; 87 | }; 88 | }; 89 | buildConfigurationList = A9B4D2A91DB94103001FE35A /* Build configuration list for PBXProject "Option" */; 90 | compatibilityVersion = "Xcode 3.2"; 91 | developmentRegion = English; 92 | hasScannedForEncodings = 0; 93 | knownRegions = ( 94 | en, 95 | ); 96 | mainGroup = A9B4D2A51DB94103001FE35A; 97 | productRefGroup = A9B4D2A51DB94103001FE35A; 98 | projectDirPath = ""; 99 | projectRoot = ""; 100 | targets = ( 101 | A9B4D2AD1DB94103001FE35A /* Option */, 102 | ); 103 | }; 104 | /* End PBXProject section */ 105 | 106 | /* Begin PBXSourcesBuildPhase section */ 107 | A9B4D2AA1DB94103001FE35A /* Sources */ = { 108 | isa = PBXSourcesBuildPhase; 109 | buildActionMask = 2147483647; 110 | files = ( 111 | A9DCE79D1DBA7559009C397C /* PyHeston.cpp in Sources */, 112 | A9DCE79A1DBA6A8F009C397C /* BSLib.cpp in Sources */, 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | /* End PBXSourcesBuildPhase section */ 117 | 118 | /* Begin XCBuildConfiguration section */ 119 | A9B4D2B31DB94103001FE35A /* Debug */ = { 120 | isa = XCBuildConfiguration; 121 | buildSettings = { 122 | ALWAYS_SEARCH_USER_PATHS = NO; 123 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 124 | CLANG_CXX_LIBRARY = "libc++"; 125 | CLANG_ENABLE_MODULES = YES; 126 | CLANG_ENABLE_OBJC_ARC = YES; 127 | CLANG_WARN_BOOL_CONVERSION = YES; 128 | CLANG_WARN_CONSTANT_CONVERSION = YES; 129 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 130 | CLANG_WARN_EMPTY_BODY = YES; 131 | CLANG_WARN_ENUM_CONVERSION = YES; 132 | CLANG_WARN_INT_CONVERSION = YES; 133 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 134 | CLANG_WARN_UNREACHABLE_CODE = YES; 135 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 136 | COPY_PHASE_STRIP = NO; 137 | DEBUG_INFORMATION_FORMAT = dwarf; 138 | ENABLE_STRICT_OBJC_MSGSEND = YES; 139 | ENABLE_TESTABILITY = YES; 140 | GCC_C_LANGUAGE_STANDARD = gnu99; 141 | GCC_DYNAMIC_NO_PIC = NO; 142 | GCC_NO_COMMON_BLOCKS = YES; 143 | GCC_OPTIMIZATION_LEVEL = 0; 144 | GCC_PREPROCESSOR_DEFINITIONS = ( 145 | "DEBUG=1", 146 | "$(inherited)", 147 | ); 148 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 149 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 150 | GCC_WARN_UNDECLARED_SELECTOR = YES; 151 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 152 | GCC_WARN_UNUSED_FUNCTION = YES; 153 | GCC_WARN_UNUSED_VARIABLE = YES; 154 | GENERATE_MASTER_OBJECT_FILE = YES; 155 | HEADER_SEARCH_PATHS = /opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m/; 156 | LD_DYLIB_INSTALL_NAME = ""; 157 | LIBRARY_SEARCH_PATHS = ( 158 | /usr/lib/gsl/lib, 159 | /opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib, 160 | ); 161 | LINK_WITH_STANDARD_LIBRARIES = YES; 162 | MACOSX_DEPLOYMENT_TARGET = 10.10; 163 | MTL_ENABLE_DEBUG_INFO = YES; 164 | ONLY_ACTIVE_ARCH = YES; 165 | OTHER_LDFLAGS = ( 166 | "-lgsl", 167 | "-lgslcblas", 168 | "-lpython3.5", 169 | ); 170 | REEXPORTED_LIBRARY_NAMES = ""; 171 | REEXPORTED_LIBRARY_PATHS = ""; 172 | SDKROOT = macosx; 173 | }; 174 | name = Debug; 175 | }; 176 | A9B4D2B41DB94103001FE35A /* Release */ = { 177 | isa = XCBuildConfiguration; 178 | buildSettings = { 179 | ALWAYS_SEARCH_USER_PATHS = NO; 180 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 181 | CLANG_CXX_LIBRARY = "libc++"; 182 | CLANG_ENABLE_MODULES = YES; 183 | CLANG_ENABLE_OBJC_ARC = YES; 184 | CLANG_WARN_BOOL_CONVERSION = YES; 185 | CLANG_WARN_CONSTANT_CONVERSION = YES; 186 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 187 | CLANG_WARN_EMPTY_BODY = YES; 188 | CLANG_WARN_ENUM_CONVERSION = YES; 189 | CLANG_WARN_INT_CONVERSION = YES; 190 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 191 | CLANG_WARN_UNREACHABLE_CODE = YES; 192 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 193 | COPY_PHASE_STRIP = NO; 194 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 195 | ENABLE_NS_ASSERTIONS = NO; 196 | ENABLE_STRICT_OBJC_MSGSEND = YES; 197 | GCC_C_LANGUAGE_STANDARD = gnu99; 198 | GCC_NO_COMMON_BLOCKS = YES; 199 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 200 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 201 | GCC_WARN_UNDECLARED_SELECTOR = YES; 202 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 203 | GCC_WARN_UNUSED_FUNCTION = YES; 204 | GCC_WARN_UNUSED_VARIABLE = YES; 205 | GENERATE_MASTER_OBJECT_FILE = YES; 206 | HEADER_SEARCH_PATHS = /opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m/; 207 | LD_DYLIB_INSTALL_NAME = ""; 208 | LIBRARY_SEARCH_PATHS = ( 209 | /usr/lib/gsl/lib, 210 | /opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib, 211 | ); 212 | LINK_WITH_STANDARD_LIBRARIES = YES; 213 | MACOSX_DEPLOYMENT_TARGET = 10.10; 214 | MTL_ENABLE_DEBUG_INFO = NO; 215 | OTHER_LDFLAGS = ( 216 | "-lgsl", 217 | "-lgslcblas", 218 | "-lpython3.5", 219 | ); 220 | REEXPORTED_LIBRARY_NAMES = ""; 221 | REEXPORTED_LIBRARY_PATHS = ""; 222 | SDKROOT = macosx; 223 | }; 224 | name = Release; 225 | }; 226 | A9B4D2B61DB94103001FE35A /* Debug */ = { 227 | isa = XCBuildConfiguration; 228 | buildSettings = { 229 | HEADER_SEARCH_PATHS = ( 230 | /usr/lib/gsl/include, 231 | /opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m, 232 | ); 233 | "HEADER_SEARCH_PATHS[arch=*]" = ( 234 | /usr/lib/gsl/include, 235 | /opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m, 236 | ); 237 | LD_RUNPATH_SEARCH_PATHS = ""; 238 | OTHER_LIBTOOLFLAGS = "-L/usr/lib/gsl/lib -lgsl -lgslcblas"; 239 | PRODUCT_NAME = "$(TARGET_NAME)"; 240 | REEXPORTED_LIBRARY_NAMES = ""; 241 | REEXPORTED_LIBRARY_PATHS = ""; 242 | USER_HEADER_SEARCH_PATHS = "/usr/lib/gsl/include /opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m/"; 243 | USE_HEADERMAP = NO; 244 | }; 245 | name = Debug; 246 | }; 247 | A9B4D2B71DB94103001FE35A /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | HEADER_SEARCH_PATHS = ( 251 | /usr/lib/gsl/include, 252 | /opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m, 253 | ); 254 | LD_RUNPATH_SEARCH_PATHS = ""; 255 | OTHER_LIBTOOLFLAGS = "-L/usr/lib/gsl/lib -lgsl -lgslcblas"; 256 | PRODUCT_NAME = "$(TARGET_NAME)"; 257 | REEXPORTED_LIBRARY_NAMES = ""; 258 | REEXPORTED_LIBRARY_PATHS = ""; 259 | USER_HEADER_SEARCH_PATHS = "/usr/lib/gsl/include /opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m/"; 260 | USE_HEADERMAP = NO; 261 | }; 262 | name = Release; 263 | }; 264 | /* End XCBuildConfiguration section */ 265 | 266 | /* Begin XCConfigurationList section */ 267 | A9B4D2A91DB94103001FE35A /* Build configuration list for PBXProject "Option" */ = { 268 | isa = XCConfigurationList; 269 | buildConfigurations = ( 270 | A9B4D2B31DB94103001FE35A /* Debug */, 271 | A9B4D2B41DB94103001FE35A /* Release */, 272 | ); 273 | defaultConfigurationIsVisible = 0; 274 | defaultConfigurationName = Release; 275 | }; 276 | A9B4D2B51DB94103001FE35A /* Build configuration list for PBXNativeTarget "Option" */ = { 277 | isa = XCConfigurationList; 278 | buildConfigurations = ( 279 | A9B4D2B61DB94103001FE35A /* Debug */, 280 | A9B4D2B71DB94103001FE35A /* Release */, 281 | ); 282 | defaultConfigurationIsVisible = 0; 283 | defaultConfigurationName = Release; 284 | }; 285 | /* End XCConfigurationList section */ 286 | }; 287 | rootObject = A9B4D2A61DB94103001FE35A /* Project object */; 288 | } 289 | -------------------------------------------------------------------------------- /Option.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Option.xcodeproj/project.xcworkspace/xcshareddata/Option.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "E330942F25C617FD392133BB956D92052F67FD61", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "E330942F25C617FD392133BB956D92052F67FD61" : 0, 8 | "4A2420D035B285BF2CD3388E49915BB9E0EB3DB3" : 0 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "23BFD798-A8C3-413E-BCBA-6DB574ABBA32", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "E330942F25C617FD392133BB956D92052F67FD61" : "Python-Heston-Option-Pricer\/", 13 | "4A2420D035B285BF2CD3388E49915BB9E0EB3DB3" : "" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "Option", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Option.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:junyanxu\/Option.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "4A2420D035B285BF2CD3388E49915BB9E0EB3DB3" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/junyanxu\/Python-Heston-Option-Pricer", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "E330942F25C617FD392133BB956D92052F67FD61" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /Option.xcodeproj/project.xcworkspace/xcuserdata/junyan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/Option.xcodeproj/project.xcworkspace/xcuserdata/junyan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Option.xcodeproj/project.xcworkspace/xcuserdata/junyan.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | IssueFilterStyle 12 | ShowActiveSchemeOnly 13 | LiveSourceIssuesEnabled 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Option.xcodeproj/xcuserdata/junyan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 18 | 19 | 20 | 22 | 32 | 33 | 34 | 36 | 46 | 47 | 48 | 50 | 60 | 61 | 62 | 64 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Option.xcodeproj/xcuserdata/junyan.xcuserdatad/xcschemes/Option.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Option.xcodeproj/xcuserdata/junyan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Option.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | A9B4D2AD1DB94103001FE35A 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /PyHeston.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Option.c 3 | // Option 4 | // 5 | // Created by junyan on 10/21/16. 6 | // Copyright © 2016 junyan. All rights reserved. 7 | // 8 | 9 | #include "BSLib.hpp" 10 | #include "BSDoc.hpp" 11 | #include 12 | 13 | static PyObject *SpamError; 14 | 15 | static PyObject * Option_BSCall(PyObject *self, PyObject *args) 16 | { 17 | double S, K, T, Sigma, d, r; 18 | if (!PyArg_ParseTuple(args, "dddddd", &S, &K, &T, &Sigma, &d, &r)){ 19 | PyErr_SetString(SpamError, "Input is not valid"); 20 | return NULL; 21 | } 22 | return PyFloat_FromDouble(BSCall(S, K, T, Sigma, d, r)); 23 | } 24 | 25 | static PyObject * Option_BSPut(PyObject *self, PyObject *args) 26 | { 27 | double S, K, T, Sigma, d, r; 28 | if (!PyArg_ParseTuple(args, "dddddd", &S, &K, &T, &Sigma, &d, &r)){ 29 | PyErr_SetString(SpamError, "Input is not valid"); 30 | return NULL; 31 | } 32 | return PyFloat_FromDouble(BSPut(S, K, T, Sigma, d, r)); 33 | } 34 | 35 | static PyObject * Option_BSVega(PyObject *self, PyObject *args) 36 | { 37 | double S, K, T, Sigma, d, r; 38 | if (!PyArg_ParseTuple(args, "dddddd", &S, &K, &T, &Sigma, &d, &r)){ 39 | PyErr_SetString(SpamError, "Input is not valid"); 40 | return NULL; 41 | } 42 | return PyFloat_FromDouble(BSVega(S, K, T, Sigma, d, r)); 43 | } 44 | 45 | static PyObject * Option_BSCallIV(PyObject *self, PyObject *args) 46 | { 47 | double C, S, K, T, d, r; 48 | if (!PyArg_ParseTuple(args, "dddddd", &C, &S, &K, &T, &d, &r)){ 49 | PyErr_SetString(SpamError, "Input is not valid"); 50 | return NULL; 51 | } 52 | return PyFloat_FromDouble(BSCallIV(C, S, K, T, d, r)); 53 | } 54 | 55 | static PyObject * Option_BSPutIV(PyObject *self, PyObject *args) 56 | { 57 | double P, S, K, T, d, r; 58 | if (!PyArg_ParseTuple(args, "dddddd", &P, &S, &K, &T, &d, &r)){ 59 | PyErr_SetString(SpamError, "Input is not valid"); 60 | return NULL; 61 | } 62 | return PyFloat_FromDouble(BSPutIV(P, S, K, T, d, r)); 63 | } 64 | 65 | static PyObject * Option_HestonCall(PyObject *self, PyObject *args) 66 | { 67 | double S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, StepSize; 68 | if (!PyArg_ParseTuple(args, "dddddddddd", &S, &VolSquare, &K, &T, &r, &Chi, &Theta, &Ita, &Rho, &StepSize)){ 69 | PyErr_SetString(SpamError, "Input is not valid"); 70 | return NULL; 71 | } 72 | return PyFloat_FromDouble(HestonCall(S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, StepSize)); 73 | } 74 | 75 | static PyObject * Option_HestonPut(PyObject *self, PyObject *args) 76 | { 77 | double S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, StepSize; 78 | if (!PyArg_ParseTuple(args, "dddddddddd", &S, &VolSquare, &K, &T, &r, &Chi, &Theta, &Ita, &Rho, &StepSize)){ 79 | PyErr_SetString(SpamError, "Input is not valid"); 80 | return NULL; 81 | } 82 | return PyFloat_FromDouble(HestonCall(S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, StepSize) + K*exp(-r*T) - S); 83 | } 84 | 85 | static PyObject * Option_HestonMixedGaussianCall(PyObject *self, PyObject *args) 86 | { 87 | double S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, Up, UpSigma, Down, DownSigma, StepSize; 88 | if (!PyArg_ParseTuple(args, "dddddddddddddd", &S, &VolSquare, &K, &T, &r, &Chi, &Theta, &Ita, &Rho, &Up, &UpSigma, &Down, &DownSigma, &StepSize)){ 89 | PyErr_SetString(SpamError, "Input is not valid"); 90 | return NULL; 91 | } 92 | return PyFloat_FromDouble(HestonMixedGaussianCall(S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, Up, UpSigma, Down, DownSigma, StepSize)); 93 | } 94 | 95 | 96 | static PyObject * Option_HestonMixedGaussianPut(PyObject *self, PyObject *args) 97 | { 98 | double S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, Up, UpSigma, Down, DownSigma, StepSize; 99 | if (!PyArg_ParseTuple(args, "dddddddddddddd", &S, &VolSquare, &K, &T, &r, &Chi, &Theta, &Ita, 100 | &Rho, &Up, &UpSigma, &Down, &DownSigma, &StepSize)){ 101 | PyErr_SetString(SpamError, "Input is not valid"); 102 | return NULL; 103 | } 104 | return PyFloat_FromDouble(HestonMixedGaussianCall( 105 | S, VolSquare, K, T, r, Chi, Theta, Ita, Rho, Up, UpSigma, Down, DownSigma, StepSize) + K*exp(-r*T) - S); 106 | } 107 | 108 | static PyObject * Option_TwoRegimeHestonModelCall(PyObject *self, PyObject *args) 109 | { 110 | double S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, Theta2, Ita2, Rho2, StepSize; 111 | if (!PyArg_ParseTuple(args, "ddddddddddddddd", &S, &VolSquare, &K, &T1, &T2, &r, &Chi1, &Theta1, &Ita1, &Rho1, &Chi2, &Theta2, &Ita2, &Rho2, &StepSize)){ 112 | PyErr_SetString(SpamError, "Input is not valid"); 113 | return NULL; 114 | } 115 | return PyFloat_FromDouble(TwoRegimeHestonCall(S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, Theta2, Ita2, Rho2, StepSize)); 116 | } 117 | 118 | static PyObject * Option_TwoRegimeHestonModelPut(PyObject *self, PyObject *args) 119 | { 120 | double S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, Theta2, Ita2, Rho2, StepSize; 121 | if (!PyArg_ParseTuple(args, "ddddddddddddddd", &S, &VolSquare, &K, &T1, &T2, &r, &Chi1, &Theta1, &Ita1, &Rho1, &Chi2, &Theta2, &Ita2, &Rho2, &StepSize)){ 122 | PyErr_SetString(SpamError, "Input is not valid"); 123 | return NULL; 124 | } 125 | return PyFloat_FromDouble(TwoRegimeHestonCall( 126 | S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, Theta2, Ita2, Rho2, StepSize) + K*exp(-r*(T1+T2)) - S); 127 | } 128 | 129 | static PyObject * Option_TwoRegimeHestonMixedGaussianCall(PyObject *self, PyObject *args) 130 | { 131 | double S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, Theta2, Ita2, Rho2, Up, UpSigma, Down, DownSigma, StepSize; 132 | if (!PyArg_ParseTuple( 133 | args, "ddddddddddddddddddd", &S, &VolSquare, &K, &T1, &T2, &r, 134 | &Chi1, &Theta1, &Ita1, &Rho1, &Chi2, &Theta2, &Ita2, &Rho2, 135 | &Up, &UpSigma, &Down, &DownSigma, &StepSize)){ 136 | PyErr_SetString(SpamError, "Input is not valid"); 137 | return NULL; 138 | } 139 | return PyFloat_FromDouble(TwoRegimeHestonMixedGaussianCall( 140 | S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, 141 | Theta2, Ita2, Rho2, Up, UpSigma, Down, DownSigma, StepSize)); 142 | } 143 | 144 | static PyObject * Option_TwoRegimeHestonMixedGaussianPut(PyObject *self, PyObject *args) 145 | { 146 | double S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, Theta2, Ita2, Rho2, Up, UpSigma, Down, DownSigma, StepSize; 147 | if (!PyArg_ParseTuple( 148 | args, "ddddddddddddddddddd", &S, &VolSquare, &K, &T1, &T2, &r, 149 | &Chi1, &Theta1, &Ita1, &Rho1, &Chi2, &Theta2, &Ita2, &Rho2, 150 | &Up, &UpSigma, &Down, &DownSigma, &StepSize)){ 151 | PyErr_SetString(SpamError, "Input is not valid"); 152 | return NULL; 153 | } 154 | return PyFloat_FromDouble(TwoRegimeHestonMixedGaussianCall( 155 | S, VolSquare, K, T1, T2, r, Chi1, Theta1, Ita1, Rho1, Chi2, 156 | Theta2, Ita2, Rho2, Up, UpSigma, Down, DownSigma, StepSize)+ K*exp(-r*(T1+T2)) - S); 157 | } 158 | 159 | extern "C"{ 160 | static PyMethodDef OptionMethods[] = { 161 | {"BSCall", Option_BSCall, METH_VARARGS, "Calculate BS call option price"}, 162 | {"BSPut", Option_BSPut, METH_VARARGS, "Calculate BS put option price"}, 163 | {"BSVega", Option_BSVega, METH_VARARGS, "Calculate BS Vega"}, 164 | {"BSCallIV", Option_BSCallIV, METH_VARARGS, "Calculate BS call option implied vol"}, 165 | {"BSPutIV", Option_BSPutIV, METH_VARARGS, "Calculate BS put option implied vol"}, 166 | {"HestonCall", Option_HestonCall, METH_VARARGS, doc::HestonCall}, 167 | {"HestonPut", Option_HestonPut, METH_VARARGS, doc::HestonPut}, 168 | {"HestonMixedGaussianCall", Option_HestonMixedGaussianCall, METH_VARARGS, doc::HestonMixedGaussianCall}, 169 | {"HestonMixedGaussianPut", Option_HestonMixedGaussianPut, METH_VARARGS, doc::HestonMixedGaussianPut}, 170 | {"TwoRegimeHestonCall", Option_TwoRegimeHestonModelCall, METH_VARARGS, doc::TwoRegimeHestonCall}, 171 | {"TwoRegimeHestonPut", Option_TwoRegimeHestonModelPut, METH_VARARGS, doc::TwoRegimeHestonPut}, 172 | {"TwoRegimeHestonMixedGaussianCall", Option_TwoRegimeHestonMixedGaussianCall, METH_VARARGS, "Calculate Two Regime Heston Gaussian call option price"}, 173 | {"TwoRegimeHestonMixedGaussianPut", Option_TwoRegimeHestonMixedGaussianPut, METH_VARARGS, "Calculate Two Regime Heston Gaussian put option price"}, 174 | {NULL, NULL, 0, NULL} /* Sentinel */ 175 | }; 176 | 177 | static struct PyModuleDef PyHestonmodule = { 178 | PyModuleDef_HEAD_INIT, 179 | "PyHeston", /* name of module */ 180 | NULL, /* module documentation, may be NULL */ 181 | -1, /* size of per-interpreter state of the module, 182 | or -1 if the module keeps state in global variables. */ 183 | OptionMethods 184 | }; 185 | 186 | PyMODINIT_FUNC 187 | PyInit_PyHeston(void) 188 | { 189 | return PyModule_Create(&PyHestonmodule); 190 | } 191 | } 192 | 193 | int main(){ 194 | printf("Result %f\n", HestonMixedGaussianCall(200, 0, 200, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.000001, 0, -0.000001, 0, 0.4)); 195 | printf("Result %f\n", TwoRegimeHestonCall(200, 0, 200, 0.1, 0.05, 0, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.4)); 196 | printf("Result %f\n", TwoRegimeHestonMixedGaussianCall( 197 | 200, 0, 200, 0.1, 0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0, -0.1, 0, 0.4)); 198 | printf("Result %f\n", HestonCall(200, 0, 200, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.4)); 199 | } 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /build/lib.macosx-10.10-x86_64-3.5/PyHeston.cpython-35m-darwin.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/build/lib.macosx-10.10-x86_64-3.5/PyHeston.cpython-35m-darwin.so -------------------------------------------------------------------------------- /build/temp.macosx-10.10-x86_64-3.5/BSLib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/build/temp.macosx-10.10-x86_64-3.5/BSLib.o -------------------------------------------------------------------------------- /build/temp.macosx-10.10-x86_64-3.5/PyHeston.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/build/temp.macosx-10.10-x86_64-3.5/PyHeston.o -------------------------------------------------------------------------------- /figures/IVsurface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/figures/IVsurface.png -------------------------------------------------------------------------------- /figures/test1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/figures/test1.png -------------------------------------------------------------------------------- /figures/test2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junyanxu/Python-Heston-Option-Pricer/90e7b44302a0ca0b51c646861ad32f1196a0782c/figures/test2.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Heston Model Pricing Library[![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) 3 | 4 | 5 | _Author: Junyan Xu_ 6 | _Date: Dec 17th, 2016_ 7 | 8 | 9 | ## 1. Module Introduction 10 | 11 | Before the discrete events happen, there are usually some abnormalities on the theoretically "convex" vol surface. Very often at the ATM part we will see some small bumps. This package provide you a simple way to use combination of Heston and jump model to calibrate these exotic shape. 12 | 13 | The library is designed for providing fast C++ implementation of Heston model pricer for Python. You can download the library to easily compute all kinds of Heston model variation. Currently the package support the pricing of: 14 | * Normal B-S model option 15 | * Heston model 16 | * Heston model with Gaussian jumps(for vol surface calibration before discrete event) 17 | * Two-regime Heston model (assume Heston parameters are different before and after discrete event) 18 | * Two-regime Heston model with Gaussian jumps 19 | 20 | The complex integral shift constant in the formula is set to be 1.5 while the integral range is set to be -2000, 2000. It is recommended that you can choose StepSize to be 0.4. * The standard way using fft to price option can be found in [Option valuation using the fast Fourier transform](http://engineering.nyu.edu/files/jcfpub.pdf) 21 | 22 | ## 2. Pricing Module 23 | 24 | ### Installation 25 | The pricing module is implemented in C++ so it has faster computation speed than directly implementing in Python. To begin with you need to install GNU Scientific Library in your PC. After download latest [GSL](http://ftp://ftp.gnu.org/gnu/gsl/), extract the .tar.gz or .zip into a directory. Now we start to install this C++ library 26 | 27 | * cd to the Python-Heston-Option-Pricer directory, type following command into terminal 28 | ``` 29 | ./configure 30 | ``` 31 | 32 | * Then type 33 | ``` 34 | make 35 | ``` 36 | 37 | * After compliation finished, type 38 | ``` 39 | make install 40 | ``` 41 | Now the gsl has been installed into your computer and the headers are in **\usr\local\include** and libraries object files are in **\usr\local\lib** 42 | 43 | * Switch to my Python-Heston-Option-Pricer directory. you will see setup.py there, type 44 | ``` 45 | sudo python setup.py build install 46 | ``` 47 | 48 | ### A simple exotic volatility surface example 49 | 50 | After installed PyHeston module to your python. Open up your ipython console to try: 51 | ```python 52 | import PyHeston 53 | import numpy 54 | import matplotlib.pyplot as plt 55 | import itertools 56 | from mpl_toolkits.mplot3d import Axes3D 57 | from matplotlib import cm 58 | help(PyHeston.HestonMixedGaussianCall) 59 | ``` 60 | 61 | 62 | Help on built-in function HestonMixedGaussianCall in module PyHeston: 63 | 64 | HestonMixedGaussianCall(...) 65 | Calculate heston model mixed gaussian call option price. The parameters follow the following sequence: 66 | 67 | S: Current underlying price 68 | V0: Current instantaneous volatility square 69 | K: Strike price 70 | T: Time to expiry 71 | r: Interest rate 72 | Kappa: Mean reversion maganitude 73 | Theta: Long term mean in Heston model 74 | Eta: Vol of vol 75 | Rho: Correlation of underlying stochastic term with vol 76 | 77 | The Mixed Gaussian part has four parameters: 78 | Up: average maganitude of up log jump 79 | UpSigma: dispersion maganitude of up log jump 80 | Down: average maganitude of down log jump 81 | DownSigma: dispersion maganitude of down log jump 82 | Stepsize: Numerical solution stepsize. Recommend 0.4 83 | 84 | ```python 85 | # Background parameters 86 | 87 | S = 200 88 | v=0.8 89 | r = 0.1 90 | dividend = 0 91 | Kappa = 1 92 | Theta = 0.4 93 | Eta =15 94 | Rho =-0.5 95 | Up = 0.1 96 | Down = -0.1 97 | UpSigma = 0.02 98 | DownSigma = 0.02 99 | StepSize = 0.4 100 | 101 | # Define a wrapper calling computation func 102 | 103 | def getHestonMixedGaussianCallIV(K, T): 104 | return PyHeston.BSCallIV( 105 | PyHeston.HestonMixedGaussianCall( 106 | S, v, 107 | K, T, 108 | r, 109 | Kappa, Theta, Eta, Rho, 110 | Up, UpSigma, Down, DownSigma, 111 | StepSize 112 | ), 113 | S, K, T, dividend, 0 114 | ) 115 | 116 | Strikes = numpy.arange(140, 260, 5) 117 | T = numpy.arange(0.001, 0.1, 0.001) 118 | Strikes, T = numpy.meshgrid(Strikes, T) 119 | IVsurface = numpy.zeros(Strikes.shape) 120 | for i in range(Strikes.shape[0]): 121 | for j in range(Strikes.shape[1]): 122 | IVsurface[i][j] = getHestonMixedGaussianCallIV( 123 | Strikes[i][j], T[i][j] 124 | ) 125 | fig = plt.figure() 126 | ax = fig.add_subplot(111, projection='3d') 127 | surf = ax.plot_surface( 128 | Strikes, T, IVsurface, rstride=1, cstride=1, 129 | cmap=cm.coolwarm, linewidth=0, antialiased=False) 130 | ax.set_xlabel('Strike price') 131 | ax.set_ylabel('Time to expiry') 132 | ax.set_zlabel('Implied vol') 133 | plt.show() 134 | ``` 135 | ![optional caption text](figures/IVsurface.png) 136 | 137 | ### Function List 138 | 139 | The interface of all functions in **PyHeston** module are listed here: 140 | ```python 141 | from PyHeston import * 142 | BSCall(S, K, T, Sigma, d, r) 143 | BSPut(S, K, T, Sigma, d, r) 144 | BSCallIV(C, S, K, T, d, r) 145 | BSPutIV(P, S, K, T, d, r) 146 | HestonModelCall(S, V0, K, T, r, Kappa, Theta, Ita, Rho, StepSize) 147 | HestonModelPut(S, V0, K, T, r, Kappa, Theta, Ita, Rho, StepSize) 148 | HestonMixedGaussianCall(S, V0, K, T, r, Kappa, Theta, Eta, Rho, Up, UpSigma, Down, DownSigma, StepSize) 149 | HestonMixedGaussianPut(S, V0, K, T, r, Kappa, Theta, Eta, Rho, Up, UpSigma, Down, DownSigma, StepSize) 150 | TwoRegimeHestonModelCall(S, V0, K, T1, T2, r, Kappa1, Theta1, Eta1, Rho1, Kappa2, Theta2, Eta2, Rho2, StepSize) 151 | TwoRegimeHestonModelPut(S, V0, K, T1, T2, r, Kappa1, Theta1, Eta1, Rho1, Kappa, Theta2, Eta2, Rho2, StepSize) 152 | TwoRegimeHestonModelCall(S, V0, K, T1, T2, r, Kappa1, Theta1, Eta1, Rho1, Kappa2, Theta2, Eta2, Rho2, StepSize) 153 | TwoRegimeHestonModelPut(S, V0, K, T1, T2, r, Kappa1, Theta1, Eta1, Rho1, Kappa2, Theta2, Eta2, Rho2, StepSize) 154 | ``` 155 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | 3 | module = Extension( 4 | 'PyHeston', 5 | sources=['PyHeston.cpp', 'BSLib.cpp'], 6 | include_dirs=['/usr/lib/gsl/lib', '/usr/local/include'], 7 | library_dirs=['/usr/local/lib'], 8 | libraries=['gsl', 'gslcblas'] 9 | ) 10 | 11 | setup( 12 | name='PyHeston', 13 | version='2.0', 14 | description='This is a professional package for option pricing', 15 | author='Junyan Paul Xu', 16 | author_email='junyanxu5513@gmail.com', 17 | ext_modules=[module]) 18 | --------------------------------------------------------------------------------