Crashing Programm



Random.cpp
//
//
//
// Random1.cpp
//
//

#include "Random1.h"
#include <cstdlib>
#include <cmath>


#if !defined(_MSC_VER)
using namespace std;
#endif


//definitions of functions
double GetOneGaussianBySummation()
{
double result=0;

for (unsigned long j=0; j < 12; j++)
result += rand()/static_cast<double>(RAND_MAX);

result -= 6.0;

return result;

}


double GetOneGaussianByBoxMuller()
{
double result;

double x;
double y;

double sizeSquared;
do
{
x = 2.0*rand()/static_cast<double>(RAND_MAX)-1;
y = 2.0*rand()/static_cast<double>(RAND_MAX)-1;
sizeSquared = x*x + y*y;
}
while
( sizeSquared >= 1.0);

result = x*sqrt(-2*log(sizeSquared)/sizeSquared);

return result;

}

Last edited on
http://www.cplusplus.com/forum/general/112111/

I cannot reproduce your problem. This is my output
Last price of underlying = 164.25
Price of arithmetic Asian Put = 0
Price of geometric Asian Put = 0
calling functions via operator() 
Price of arithmetic Asian Put = 0
Price of geometric Asian Put = 0
mean of myVec is 201.218
stddev of myVec is 28.1681
I see, well maybe I have some error in my system. But thank you for letting me know.
(¿why have you prune your post?)

maybe you have incurred in undefined behaviour.
try to provide a backtrace when you've got a crash.
Ok I have made a little addition,and now it works. except that I am struggling
with one thing. When my barrier is hit, for example if I set it to 250, then it returns 0 and if it doesnt hit then it return option price(so far so good). So I am setting my maturity to .5 (half a year) which is 126 days in finance roughly. So what I need for my code to do, is to get this barrier up only in the last 64 days.So from day 0 to 64 it should not have the barrier, but from day 64 to 126 my barrier should start working. Basically, I should not have the barrier in the first half and have it up in the second. I was thinking something like max.element.path (beging()+64, end ()), But I am not sure. I will provide the codes below, but I think the BarrierOption::arithmeticBarrierPut(int nReps) is where the changes have to be made. This is the input for your info:
126,200,195,0.2,0.06.0.5,300. (The last number 300, is the most important as it could be adjust to 350 or 250 and you will see the result)

Header Files:
#include<vector>
class BarrierOption{
public:
//constructor
BarrierOption(
int nInt_,
double strike_,
double spot_,
double vol_,
double r_,
double expiry_,
double barrier_
);

//destructor
~BarrierOption(){};

//methods
bool generatePath();
double getArithmeticMean();
double getGeometricMean();
void printPath();
double arithmeticBarrierPut(int nReps);
double geometricBarrierPut(int nReps);

//overloaded operator ()
double operator()(char char1, char char2, int nReps);

//members
std::vector<double> thisPath;
int nInt;
double strike;
double spot;
double vol;
double r;
double expiry;
double barrier;

};

Header Function:
//functions prototypes
double mean (std::vector<double> thisVec);
double stdDev (std::vector<double> thisVec);

Header Random:
#ifndef RANDOM1_H
#define RANDOM1_H

//declarations of functions
//(prototypes)
double GetOneGaussianBySummation();
double GetOneGaussianByBoxMuller();

#endif

Source Files:
BarrierOption.cpp
#include"BarrierOption.h"
#include<cmath>
#include<iostream>
#include"Random1.h"
#include<string>


//definition of constructor

BarrierOption::BarrierOption(
int nInt_,
double strike_,
double spot_,
double vol_,
double r_,
double expiry_,
double barrier_)
{
nInt = nInt_;
strike = strike_;
spot = spot_;
vol = vol_;
r = r_;
barrier = barrier_;
expiry = expiry_;
generatePath();
}

bool BarrierOption::generatePath() {
double thisDrift = (r * expiry - 0.5 * vol * vol * expiry) / double(nInt);
double cumShocks = 0;
thisPath.clear();

for(int i = 0; i < nInt; i++) {
cumShocks += (thisDrift + vol * sqrt(expiry / double(nInt)) *
GetOneGaussianByBoxMuller());
double pathvalue = spot * exp(cumShocks);
if (pathvalue >= barrier)
return false;
thisPath.push_back(pathvalue);
}

return true;
}




//method definition
double BarrierOption::getArithmeticMean(){

double runningSum = 0.0;

for(int i = 0; i < nInt; i++){
runningSum += thisPath[i];
}

return runningSum/double(nInt);
}

//method definition
double BarrierOption::getGeometricMean(){

double runningSum = 0.0;

for(int i = 0; i < nInt ; i++){
runningSum += log(thisPath[i]);
}

return exp(runningSum/double(nInt));
}

//method definition
void BarrierOption::printPath(){

for(int i = 0; i < nInt; i++){

std::cout << thisPath[i] << "\n";

}

}


//method definition
double BarrierOption::arithmeticBarrierPut(int nReps){
double rollingSum = 0.0;
double thisMean = 0.0;
//int barrier=250;

for(int i = 0; i < nReps; i++){
if (!generatePath())
return 0;
thisMean = getArithmeticMean();
rollingSum += (thisMean < strike) ? (strike - thisMean) : 0;
}

return rollingSum / nReps;
}

//method definition
double BarrierOption::geometricBarrierPut(int nReps){

double rollingSum = 0.0;
double thisMean = 0.0;

for(int i = 0; i < nReps; i++){
if (!generatePath())
return 0;
thisMean=getGeometricMean();
rollingSum += (thisMean < strike)? (strike - thisMean) : 0;
}

return rollingSum/double(nReps);

}

//overloaded operator ();
double BarrierOption::operator()(char char1, char char2, int nReps){
if ((char1 == 'A') & (char2 =='P')) return arithmeticBarrierPut(nReps);
else if ((char1 == 'G') & (char2 =='P')) return geometricBarrierPut(nReps);
else return -99;
}


Function.cpp

#include<cmath>
#include<iostream>
#include<vector>

// general function for mean
double mean (std::vector<double> thisVec) {

double runningSum = 0.0;
int thisSize = thisVec.size();

for(int i = 0; i < thisSize; i++){
runningSum += thisVec[i];
}

return runningSum/double(thisSize);
}


// general function for standard deviation
double stdDev (std::vector<double> thisVec) {

double runningSum = 0.0;
int thisSize = thisVec.size();

for ( int i = 0; i < thisSize; i++ ){
runningSum += pow((thisVec[i]- mean(thisVec) ), 2);
}

return sqrt(runningSum/(thisSize - 1));
}

Random.cpp

//
//
//
// Random1.cpp
//
//

#include "Random1.h"
#include <cstdlib>
#include <cmath>

// the basic math functions should be in namespace std but aren't in VCPP6
#if !defined(_MSC_VER)
using namespace std;
#endif


//definitions of functions
double GetOneGaussianBySummation()
{
double result=0;

for (unsigned long j=0; j < 12; j++)
result += rand()/static_cast<double>(RAND_MAX);

result -= 6.0;

return result;

}


double GetOneGaussianByBoxMuller()
{
double result;

double x;
double y;

double sizeSquared;
do
{
x = 2.0*rand()/static_cast<double>(RAND_MAX)-1;
y = 2.0*rand()/static_cast<double>(RAND_MAX)-1;
sizeSquared = x*x + y*y;
}
while
( sizeSquared >= 1.0);

result = x*sqrt(-2*log(sizeSquared)/sizeSquared);

return result;

}

Main Function.cpp

#include<iostream>
#include<vector>
#include"BarrierOption.h"
#include<ctime>
#include<cstdlib>
#include"functions.h"

using std::vector;
using std::cout;
using std::cin;

int main(){

// set the seed
srand( time(NULL) );


int nInt_;
double strike_,spot_,vol_,r_,expiry_,barrier_;

cout << "Enter the number of iterations: ";
cin >> nInt_;

cout << "Enter the stike price: ";
cin >> strike_;

cout << "Enter the spot price: ";
cin >> spot_;

cout << "Enter the volatility rate: ";
cin >> vol_;

cout << "Enter the interest rate: ";
cin >> r_;

cout << "Enter the expiration time: ";
cin >> expiry_;

cout << "Enter the barrier level: ";
cin >> barrier_;


//create a new instance of class
BarrierOption myBarrier(nInt_,strike_,spot_,vol_,r_,expiry_,barrier_);
/*(126, 200, 195, 0.2, 0.06, 0.5,300)*/

//get last price of underlying
cout << "Last price of underlying = " << myBarrier.thisPath.back() << "\n";

//run Monte Carlo to obtain theoretical price of arithmetic asian call

cout << "Price of arithmetic Asian Put = " << myBarrier.arithmeticBarrierPut(10000) << "\n";

cout << "Price of geometric Asian Put = " << myBarrier.geometricBarrierPut(10000) << "\n";


//call Monte Carlo via overloaded () operator
cout << "calling functions via operator() \n";

cout << "Price of arithmetic Asian Put = " << myBarrier('A', 'P', 10000) << "\n";

cout << "Price of geometric Asian Put = " << myBarrier('G', 'P', 10000) << "\n";

//check whether data generating process runs correctly
//(is the expected price and volatility of underlying close to option parameters?)
vector<double> myVec2;
for(int i = 0; i < 1000; i++){
myBarrier.generatePath();
myVec2.push_back(myBarrier.thisPath.back());
}

cout << "mean of myVec is " << mean(myVec2) << "\n";
cout << "stddev of myVec is " << stdDev(myVec2) << "\n";



//cout << "\nPress Enter to continue...";
//cin.get();
system ("Pause");
return 0;
}

Thank you very much in advance.
In Barrier.option.cpp in //method definition
double BarrierOption::arithmeticBarrierPut(int nReps)
it should return:
return rollingSum / double(nReps); I missed the "double"
Topic archived. No new replies allowed.