# My first C++ Black-Scholes-Merton program

#### IlyaKEightSix

Copy-pasted from my Code::Blocks compiler ^_^. First time ever doing classes in C++. Took me around...3 hours to write up. Write a few similar lines, compile, get a bunch of errors thrown at me, look at Savitch book, fix errors, rinse, repeat, run program, get ridiculous numbers, check code, rewrite some code, fix code, rerun program, profit!

Hopefully I'm not a lost cause.

C++:
#include <iostream>
#include <math.h>
#include <cmath>
#include <cstdlib>

using namespace std;

double N(double z);

class BlackScholes
{
public:
double d1();
double d2();
double Price();
BlackScholes(double callFlagInput, double SInput, double XInput, double rInput, double volInput, double TInput);
void printTest();
void ErrorChecker();
BlackScholes();
~BlackScholes();
double callFlag;
private:
double S;
double X;
double r;
double vol;
double T;
};

BlackScholes::BlackScholes(double callFlagInput, double SInput, double XInput, double rInput, double volInput, double TInput)//Yay constructor ^_^
{
callFlag=callFlagInput;
S=SInput;
X=XInput;
r=rInput/100;
vol=volInput;
T=TInput/365;
}

BlackScholes::BlackScholes()//default constructor ^_^
{
}

double BlackScholes::d1()//calculates d1 ^_^
{

return (log(S/X)+(r+pow(vol,2)/2)*T)/(vol*sqrt(T));
}

double BlackScholes::d2()//calculates d2 ^_^
{

return d1()-vol*sqrt(T);
}

double BlackScholes::Price()//Options pricing!  Yay!  Okay, fine, I know that BSM is outdated -_-...but I don't know much else >_<
{

double x=S*N(callFlag*d1());
double y=X*exp(-1*r*T)*N(callFlag*d2());
if(callFlag==1)
{
cout<<"The price of the call is "<<callFlag*(x-y)<<endl;
}
if(callFlag==-1)
{
cout<<"The price of the put is "<<callFlag*(x-y)<<endl;
}
}

void BlackScholes::ErrorChecker()
{
if(S<=0)
{
cout<<"All stocks cost something!  Illegal input!  CRASH!"<<endl;
exit(1);
}
if(X<=0)
{
cout<<"No such thing as a strike price of 0!  Illegal input!  CRASH!"<<endl;
exit(1);
}
if(vol<=0)
{
cout<<"There's always volatility!  Illegal input!  CRASH!"<<endl;
exit(1);
}
if(T<=0)
{
cout<<"You can't go back in time!  Illegal input!  CRASH!"<<endl;
exit(1);
}
if(callFlag!=-1&&callFlag!=1)
{
cout<<"Illegal input!  CRASH!"<<endl;
exit(1);
}
}

void BlackScholes::printTest()//This allows me to keep track of variables in case something looks screwy =P
{
if(callFlag==1)
{
cout<<"The option is a call."<<endl;
}
if(callFlag==-1)
{
cout<<"The option is a put."<<endl;
}
cout<<"The volatility is "<<vol<<endl;
cout<<"The stock price is "<<S<<endl;
cout<<"The strike price is "<<X<<endl;
cout<<"LIBOR is "<<r<<endl;
cout<<"The time in years to expiration is "<<T<<endl;
cout<<"d1 is "<<d1()<<endl;
cout<<"d2 is "<<d2()<<endl;
cout<<"The normalized d1 is "<<N(callFlag*d1())<<endl;
cout<<"The normalized d2 is "<<N(callFlag*d2())<<endl;

}

BlackScholes::~BlackScholes()//Destructors!  My first time writing one ^_^
{

}

double N(double z)//Cumulative Normal approximation here.  I pulled this thing off the net.
{
const double b1 =  0.319381530;
const double b2 = -0.356563782;
const double b3 =  1.781477937;
const double b4 = -1.821255978;
const double b5 =  1.330274429;
const double p  =  0.2316419;
const double c2  =  0.39894228;

double a=fabs(z);
double t=1.0/(1.0+a*p);
double b=c2*exp((-z)*(z/2.0));
double n=((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t;
n=1-b*n;
if(z<0) n=1-n;
return n;
}

int main(){//test method ^_^...hey, I might be a good programmer yet ^_^
cout<<"I has a black-scholes!"<<endl;
double callFlag;
double S;
double X;
double r;
double vol;
double days;
cout<<"Please enter -1 if the option is a put or 1 if the option is a call."<<endl;
cin>>callFlag;
cin>>S;
cin>>X;
cout<<"Please enter LIBOR as a percentage.  (If Libor is 4%, please enter 4.)"<<endl;
cin>>r;
cout<<"Please enter the volatility.  Yes, I know, I should calculate the volatility from an array of stock prices.  Oh well.  You do that instead."<<endl;
cin>>vol;
cout<<"Please enter the time to expiration in days.  This is because I'm too lazy to import a calendar into the program."<<endl;
cin>>days;
BlackScholes IMK(callFlag,S,X,r,vol,days);
IMK.ErrorChecker();
IMK.Price();
int repeat;
cout<<"Would you like to use the program again?  If so, please press 0."<<endl;
cin>>repeat;
if(repeat==0)
{
main();
}
else
{
cout<<"Thanks for using my Black Scholes program.  Bye!"<<endl;
return(0);
}
}
//182 lines of code for a preliminary Black-Scholes ^_^. Sheesh, this thing took me a while because of all the bumps >_<.
//I'm not sure if writing BSM as a class is the best way to implement it.

#### Stefan Zota

Good start. After you understand a bit more about C++, the next step is to slowly incorporate design patterns. They will come as answers to something like ...
How would you change the code if r or volatilty is a known function of time?
How would you change the code if you want to add another closed formula option?
How would you incorporate implied volatility?
How would you be able to add other methods for computing option value?

#### IlyaKEightSix

1) I'd change the code by removing the r parameter, and instead create a method which computes that value as a function of time.
2) I'd write another class to value a different option (swaps, futures, forwards)
3) See, I don't know many good numerical methods. I guess there's the usual newton/bisect/secant method, but I doubt that's what the masters use. But anyhow, it'd just be a plug-and-chug approximation, so find whatever has the lowest big-O notation.
4) Other methods for computing option value? Depends on the inputs. But my price method is like four lines, and the rest of that is error checking, a test printing function, and a normal CDF approximation.

In the meantime, in terms of the IV, I'd have to set up a new constructor for that to take different arguments.

#### Stefan Zota

Some ideas for you ...

1) I'd change the code by removing the r parameter, and instead create a method which computes that value as a function of time.

Fine. One problem is that the function is linked to this class. Is function to compute r linked to your Black Scholes class or is it independent?
Another problem is that each time you need to set a different function, you need to recompile everything and of course introduce possible errors ...

2) I'd write another class to value a different option (swaps, futures, forwards)

Do these options have anything in common? If you have a common interface, maybe other classes can use this generic interface.

3) See, I don't know many good numerical methods. I guess there's the usual newton/bisect/secant method, but I doubt that's what the masters use. But anyhow, it'd just be a plug-and-chug approximation, so find whatever has the lowest big-O notation.

Thinking about implied volatility with newton's method it leads you to vega, maybe other greeks too ...
By the way, swaps and futures are not options. They can be replicated using options but they are not literally contigent claims ...

4) Other methods for computing option value? Depends on the inputs. But my price method is like four lines, and the rest of that is error checking, a test printing function, and a normal CDF approximation.
In the meantime, in terms of the IV, I'd have to set up a new constructor for that to take different arguments.

The question is to look back at the code and try to see if it is flexible. You don't need to add other methods yet. Yes constructor can be adjusted.

#### IlyaKEightSix

Ohh, right, I was thinking about derivatives in general. Other options, such as the exotic ones.

Interesting stuff. I'll have to add to my program then sometime later, because I am pretty sure I can code all of this stuff.

As for a time dependent rate, I'm guessing you're talking about the yield curve. In all honesty, I've never actually seen a model of the yield curve. It's just always been "well, right now, if you want to take out a 5-year loan, your interest will be X", not to mention that the yield curve is always in flux anyway.

Though once I have a slightly better grip on coding, I'll start looking over the D.E. Shaw and Microsoft coding interview questions in earnest.

#### ExSan

Greeks maybe considered later:

C++:
                                               Wed Jan 21 16:32:10 2009
EXSAN v.0.3.18.S - [EMAIL="exsan.software@gmail.com"]exsan.software@gmail.com[/EMAIL]   [EMAIL="exsan@uio.satnet.net"]exsan@uio.satnet.net[/EMAIL]
E X S A N     M E N U
6 Quantitative Finance Room
a Black-Scholes:  Just plug-in the numbers
[URL="http://en.wikipedia.org/wiki/Greeks_(finance"]Greeks (finance - Wikipedia, the free encyclopedia[/URL])
Price of the Stock St                     ->    100
exercise price K (strike)                ->    120
Vol  (percent)                               ->     33
risk-free interest rate r                ->     10
time to expiration (weeks)           ->     26
d1 = -0.450391    d2 = -0.683736
Black-Sholes Price
delta    gamma      vega       theta     rho    volga    vanna
CALL =   4.4189    0.326214 0.0154476 25.4886 -11.3466  14.6767  23.7854  0.746854
PUT  =  18.5664    0.673786 0.0154476 25.4886 0.534004  -44.7262  23.7854  0.746854

#### IlyaKEightSix

Thanks for raining on my parade -_-...I'll go dry off now.
Okay, I kid. Nice stuff. I see you put a lot of work into it. I'm not at all sold on the command line for matrices interface, though, so once the GUI gets done, it should be a nice piece of work (let me beta test it, please?).

#### ExSan

Black-Sholes Calculator / Just plug-in numbers

Black-Sholes Calculator / Just plug-in numbers
added value : Graphs + Greeks

C++:
   - 0 EXIT- Price of the Stock St       --->  110
exercise price K (strike)             --->  115
Vol  (percent)                        --->   20
risk-free interest rate r (percent)   --->    5
time to expiration (weeks)            --->   26
d1 =  -0.0668341   d2 =  -0.208255

Black-Sholes Price
delta          gamma          vega            theta           rho
CALL =  5.24054 	 0.473357 	 0.0255878 	 30.9612 	 8.58696 	 23.4144
PUT  =  7.40118 	 -0.526643 	 0.0255878 	 30.9612 	 2.85131 	 -32.666

#### Attachments

• ExSan4.00.M_Black_Sholes.zip
2 MB · Views: 153

#### alain

##### Older and Wiser
Ilya, get Joshi's book so you can see a good approach.

Replies
0
Views
1K
Replies
2
Views
1K
Replies
26
Views
3K
Replies
5
Views
1K
Replies
0
Views
808