Windows Forms - Black Scholes Calculator Trouble

Pages: 12
I am attempting to build a basic windows forms application that takes several parameters and calculates a price when the button is clicked. I am using the TryParse method to convert the input strings into doubles and implemented some functions to calculate the price of the option but I keep getting an error that says the following:

"1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(271): error C2082: redefinition of formal parameter 'e'
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(297): error C2601: 'callPrice' : local function definitions are illegal
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(303): error C2601: 'N' : local function definitions are illegal
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(325): error C2601: 'd1' : local function definitions are illegal
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(330): error C2601: 'd2' : local function definitions are illegal"

along with some other errors claiming that the identifiers for my variables are undeclared.

My other issue is that I'm not 100% sure where to include the math library in my code i.e. at the top of all the visual code generated or right before my button click event.

Below is my code...PLEASE HELP!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
private: System::Void btCalc_Click(System::Object^  sender, System::EventArgs^  e) {
				 #include <math.h>

				 double callPrice();
				 double d1();
				 double d2();
				 double dblStock;
				 double dblVol;
				 double dblStrike;
				 double dblRate;
				 double temp;
				 long double e =  2.71828182845904523536;
				 System::TimeSpan daysdiff;
				 double yearsDiff;

				 daysdiff = this->dtpExpire->Value - this->dtpCurrent->Value;
				 yearsDiff = ((double) daysdiff.Days/ 365.0);

				 //Boolean variable is used to validate user inputs and becomes true if parse is Successful
				 bool gotStock=false;
				 bool gotVol=false;
				 bool gotStrike=false;
				 bool gotRate=false;

				 //establishing methods by which inputs will be validated/converted
				 gotStock = Double::TryParse(tbStock->Text, dblStock);
				 gotVol = Double::TryParse(tbVol->Text, dblVol);
				 gotStrike = Double::TryParse(tbStrike->Text, dblStrike);
				 gotRate = Double::TryParse(tbRate->Text, dblRate);

				 //calculation of options price
				 if((gotStock) && (gotVol) && (gotStrike) && (gotRate))
				 {

					 tbCall->Text = callPrice().ToString(".00");
				 }

				 double callPrice()
				 {
					return dblStock*N(d1())-dblStrike*pow(e, (-dblRate*yearsDiff))*N(d2());
				 }

				 //
				 double N(double z)
					{
						if (z>6.0){return 1.0; }
						if (z<-6.0){return 0.0; }

						  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.0=b*n;
						  if (z<0.0) n = 1.0 - n;
							return n
					}

				 double d1()
				 {
				 return (log(dblStock/dblStrike) + (dblRate + pow(dblVol,2)/2)*(yearsDiff))/dblVol*sqrt(yearsDiff);
				 }

				 double d2()
				 {
					 return d1()-dblVol*sqrt(yearsDiff);
				 }	 


			 }
};
}
Last edited on
can you post all of your code. I need to see all of it. the include will go in your app's main .cpp file. you're writing this in c++/cli. you can't use e as a variable, it's used by the form already. rename it. it doesn't like the functions listed there. let's see all the code.
Last edited on
The rest of the code is stuff the windows forms application automatically generated for the form I constructed using the gui. The code I posted above is whats supposed to be calculated once you click a button.

The following is the very top of all the code before the automatically generated windows forms code:

1
2
3
4
#pragma once
//I included the two libraries below and my math operations still don't seem to work
#include <stdlib.h>
#include "math.h" 
Just my 1 cent worth :)

If you are including cmath, then you can use M_E for the mathematical constant e, instead of defining your own variable for it.

There are a bunch of math constants defined in math.h which is included into cmath.

Hope all goes well.
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(271): error C2082: redefinition of formal parameter 'e'
1
2
1: private: System::Void btCalc_Click(System::Object^  sender, System::EventArgs^  e)
12: 				 long double e =  2.71828182845904523536;


1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(297): error C2601: 'callPrice' : local function definitions are illegal
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(303): error C2601: 'N' : local function definitions are illegal
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(325): error C2601: 'd1' : local function definitions are illegal
1>c:\users\rodrigo\documents\visual studio 2010\projects\optionscalc\optionscalc\Form1.h(330): error C2601: 'd2' : local function definitions are illegal"
1
2
3
4: 				 double callPrice();
5: 				 double d1();
6: 				 double d2();
And you must have N() somewhere, but I can't see it. You've declared/defined them as local functions. You (or that code generator) need to define them outside of that button-click handler.
Last edited on
I realize the gui created much of that code. if you can post all of your form code (all of it) I can help sort out the errors and post it back.
I just attempted to post all the code including the GUI code but I received an error that said I can't post mssgs longer that 9000 words.

However, I made the "N()" function declaration correction and the "e" variable corrections. Also attempted to declare the functions at the top of all the code but to no avail.

Can anyone advise me on how to make these functions work inside of of this private button click event??
just below your #pragma endregion from your gui produced code add the function here's a snippet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(292, 266);
			this->Controls->Add(this->button1);
			this->Controls->Add(this->treeView1);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
			this->ResumeLayout(false);

		}
#pragma endregion
		//add some functions
		int addNumbers()
		{
			int answer = 1 + 5;
			return answer;
		}

Then in your button click do so:
1
2
 int someAnswer = addNumbers();
				 MessageBox::Show(someAnswer.ToString());


now tweak it to fit your code.
This is a good point to learn classes, too.
and the class route:
myFunctions.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "stdafx.h"
using namespace System;

namespace myFunctions
{
	public class ints
	{
	public: static Int32 addNumbers()
			   {
				   Int32 someAnswer = 99+94;
				   return someAnswer;
			   }
	};//end class

};//end namespace 


then in your form1.h or whatever its called. right after the #pragma once at the top
#include "myFunctions.cpp"

and finally in your button click event
1
2
 int question = myFunctions::ints::addNumbers();
				MessageBox::Show(question.ToString());
I am actually currently taking my second course in c++ and we're learning about classes now so I apologize for my inexperience.

When I add the functions under "#pragma endregion" am I also declaring the functions there before the definition?

And when I create the separate .cpp, am I defining all my functions under the "ints" class?
sorry for the confusion: separate my two examples. you don't have to define it below pragma if you make a class. if it's not clear, I'll post more code.
so if you make a class: include the .cpp file below the pragma at the top and call it in the buttonclick.

if you don't make a class: define the function below pragma once and call it in the button click.

let me know if that helps. stick with it, you'll get it.
bob, thanks a million I got the code below to work as far as the functions go but when I run the code, the answer returns NaN (not a number). I realized the reason was that its not retrieving the user input from inside the click event so I tried moving the boolean variables and the TryParse variables to right below #pragma and received an error stating that only static variables can be defined outside a class (or something along those lines.

Any ideas as to how I can get the user input variables into my functions to perform the calculations?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#pragma endregion
#include <math.h>
				 double dblStock;
				 double dblVol;
				 double dblStrike;
				 double dblRate;
				 double temp;
				 double static natE =  2.71828182845904523536;
				 System::TimeSpan daysdiff;
				 double yearsDiff;

		
				 /*double callPrice();
				 double d1();
				 double d2();
				 double N(double z);*/

				 double callPrice()
				 {
					return dblStock*N(d1())-dblStrike*pow(natE, (-dblRate*yearsDiff))*N(d2());
				 }

				 double N(double z)
					{
						if (z>6.0){return 1.0; }
						if (z<6.0){return 0.0; }

						  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.0-b*n;
						  if (z<0.0) 
							  n = 1.0 - n;
							return n;
					}

				 double d1()
				 {
				   return (log(dblStock/dblStrike) + (dblRate + pow(dblVol,2)/2)*(yearsDiff))/dblVol*sqrt(yearsDiff);
				 }

				 double d2()
				 {
					 return d1()-dblVol*sqrt(yearsDiff);
				 }	 
	private: System::Void btCalc_Click(System::Object^  sender, System::EventArgs^  e) {

				 /*double callPrice();
				 double d1();
				 double d2();
				 double N(double z);*/
				 double dblStock;
				 double dblVol;
				 double dblStrike;
				 double dblRate;
				 double temp;
				 double static natE =  2.71828182845904523536;
				 System::TimeSpan daysdiff;
				 double yearsDiff;

				 daysdiff = this->dtpExpire->Value - this->dtpCurrent->Value;
				 yearsDiff = ((double) daysdiff.Days/ 365.0);

				 //Boolean variable is used to validate user inputs and becomes true if parse is Successful
				 bool gotStock=false;
				 bool gotVol=false;
				 bool gotStrike=false;
				 bool gotRate=false;

				 //establishing methods by which inputs will be validated/converted
				 gotStock = Double::TryParse(tbStock->Text, dblStock);
				 gotVol = Double::TryParse(tbVol->Text, dblVol);
				 gotStrike = Double::TryParse(tbStrike->Text, dblStrike);
				 gotRate = Double::TryParse(tbRate->Text, dblRate);

				 //calculation of options price
				 if((gotStock) && (gotVol) && (gotStrike) && (gotRate))
				 {

					 tbCall->Text = callPrice().ToString(".00");
				 }

			 }
};
}
#include <math.h>

Including math.h is deprecated - you should use :

#include <cmath>

Did you see my earlier comment about using the built in constant M_E instead of defining your own constant? You will have access to it by including cmath.

Why are these variable declared twice?
1
2
3
4
5
double dblStock;
				 double dblVol;
				 double dblStrike;
				 double dblRate;
				 double temp;


Perhaps they should be member variables?

Any ideas as to how I can get the user input variables into my functions to perform the calculations?


Use a constructor to take your arguments and use them to set the member variables - then any class function will have access to them. Is that what you meant?
I'm just trying to get the code to work so I haven't edited it completely hence the variables declared twice...will remove now.

However, class functions having access to set the member variables is not what I meant. My tryparse method which parses the user input and converts them into doubles to then be manipulated by my arguments in the functions declared outside of the click event is what I'm referring to. Any ideas?
If the functions declared outside the click event, were member functions of a class (CCalc say)- then you could pass the values to an object via it's constructor. In this way your functions will have access to the values.

So in your tryParse function you could create a CCalc object and pass the values to it via it's constructor, like this:

 
CCalc MyCalcObj(a, b, c,d) //a, b , c, d are of type double say 


The CCalc constructor would have code to set member variables to be equal to the arguments.

The CCalc class would also contain functions that do calculations on the member variable values.

HTH
I don't anything about windows specifically, but here are some thoughts about GUI's generally:

Can the type of the input be set for a text box? That is the input must be a double, say.

Can you restrict input into text boxes, so that the input can only be a number?

Consider having a validate function for each text box, so that validation of the input is done as soon as it is entered. That way the Button_Click function can send the valid input straight to a calculation object.

HTH
I'm not sure of your question. here are some variables i've defined below the namespace declaration in the form.
1
2
3
4
5
6
7
8
9
10
using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	
	//myadd here
Int32 input1 = 0;
Int32 input2 = 0;

now those are accessible from my button click so i don't have to define those in the button click. how are you getting the values from the user? or was that your question?
Ok, you're asking me how to obtain the user values so you can access them in your form1, right?
Last edited on
Bob,

Yes, I'm asking how to obtain the user input values to access them in my form1.

TheIdeasMan suggested creating a class that will implement my functions as member functions and establishing a getter function to obtain the tryParsed user input, if I understood him correctly. So I will try to do what he has suggested.
Pages: 12