I try to build a pyd-file with QuantLib and Boost where I want to calculate the NPV for a barrier option. However the QuantLib pyd throws:
RuntimeError: end must be large than start
The error originates from the following Quantlib class in uniform1dmesher.hpp:
class Uniform1dMesher : public Fdm1dMesher {
public:
Uniform1dMesher(Real start, Real end, Size size)
: Fdm1dMesher(size) {
QL_REQUIRE(end > start, "end must be large than start");
const Real dx = (end-start)/(size-1);
for (Size i=0; i < size-1; ++i) {
locations_[i] = start + i*dx;
dplus_[i] = dminus_[i+1] = dx;
}
locations_.back() = end;
dplus_.back() = dminus_.front() = Null<Real>();
}
};
My c++-code is the following:
struct OptionInputs
{
QuantLib::Real S;
QuantLib::Real K;
QuantLib::Spread f;
QuantLib::Rate r;
QuantLib::Volatility vol;
QuantLib::Date maturity;
QuantLib::DayCounter dayCounter;
};
double FxOptEx(const OptionInputs &in,
const QuantLib::Date &todaysDate,
const QuantLib::Date &settlementDate)
{
using namespace QuantLib;
Calendar calendar = TARGET();
Settings::instance().evaluationDate() = todaysDate;
QuantLib::Real rebate = 0.05;
Size timeGird = 365;
Size underlyingGird = 100;
Size dampingSteps = 0;
Real theta = 0.05;
bool localVolatility = true;
boost::shared_ptr<Exercise> europeanExercise(
new EuropeanExercise(
in.maturity));
Handle<Quote>
underlyingH(boost::shared_ptr<Quote>(new SimpleQuote(in.S)));
Handle<YieldTermStructure>
rTS(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate,
in.r,
in.dayCounter)));
Handle<YieldTermStructure>
fTS(boost::shared_ptr<YieldTermStructure>(new FlatForward(settlementDate,
in.f,
in.dayCounter)));
Handle<BlackVolTermStructure>
flatVolTS(boost::shared_ptr<BlackVolTermStructure>(new BlackConstantVol(settlementDate,
calendar,
in.vol,
in.dayCounter)));
boost::shared_ptr<StrikedTypePayoff>
payoff(new PlainVanillaPayoff(Option::Put,
in.K));
boost::shared_ptr<BlackScholesMertonProcess> blackScholesMertonProcess(new BlackScholesMertonProcess(
underlyingH,
fTS,
rTS,
flatVolTS));
BarrierOption barrierOption(
QuantLib::Barrier::UpIn,
QuantLib::Option::Put,
rebate,
payoff,
europeanExercise);
barrierOption.setPricingEngine(
boost::shared_ptr<PricingEngine>(
new FdBlackScholesBarrierEngine (
blackScholesMertonProcess,
timeGird,
underlyingGird,
dampingSteps,
FdmSchemeDesc::ImplicitEuler(),
localVolatility,
-Null< Real >())));
return barrierOption.NPV();
}
struct FXOption
{
double value;
void set(int S, int K, double f, double r, double vol, std::string maturity, std::string dayCounter)
{
OptionInputs in;
in.S=S;
in.K=K;
in.f=f;
in.r=r;
in.vol=vol;
in.maturity=QuantLib::DateParser::parseISO(maturity);
if (dayCounter == "Actual365Fixed")
{
in.dayCounter = Actual365Fixed();
}
value = FxOptEx(in, Date(15, May, 1998), Date(17, May, 1998));
}
double get()
{
return value;
}
};
using namespace boost::python;
BOOST_PYTHON_MODULE(quant)
{
class_<FXOption>("FXOption")
.def("get", &FXOption::get)
.def("set", &FXOption::set)
;
}
Any idea why this error is thrown?
Sorry I'm late to the party.
Difficult to say without seeing the actual invocation, but could it be that the maturity of the option is earlier than the settlement date?
Related
I'm designing a strategy pattern based on the following diagram:
I have to base the entire program on two things: the contents of the main function, and the Sale function getTotal() - which I was provided with;
Here's what I managed to write so far:
class Product {
private:
int code;
string type;
string description;
int price;
public:
Product(int code, string type, string description, int price): code{code}, type{type}, description{description}, price{price}{}
int getPrice() {
return price;
}
};
class SaleItem {
private:
Product product;
public:
int quantity;
Product getProduct() {
return product;
}
int getQuantity() {
return quantity;
}
};
class Sale {
public:
SaleItem s;
Sale(SaleItem s) : s{ s }{}
vector<SaleItem> items;
void additem(int n, Product p) {
items.push_back(s(n,p));
}
double getTotal();
};
class DiscountPolicy {
public:
virtual double getDiscount(const Sale* s, SaleItem si) = 0;
};
class CreditCardDiscount : public DiscountPolicy {
public:
virtual double getDiscount(const Sale* s, SaleItem si) {
return si.getQuantity() * si.getProduct().getPrice() * 0.02;
}
};
class NoDiscount : public DiscountPolicy {
public:
virtual double getDiscount(const Sale* s, SaleItem si) {
return si.getQuantity() * si.getProduct().getPrice() * 0.00;
}
};
double Sale::getTotal() {
double total = 0;
for (int i = 0; i < items.size(); i++) {
SaleItem sIt = items[i];
double price = sIt.getQuantity() * sIt.getProduct().getPrice();
//apply discount
price -= discountPolicy->getDiscount(this, sIt);
total += price;
}
return total;
}
int main() {
Sale s(new NoDiscount());
Product p1(1, "Apple", "food", 2.0);
Product p2(1, "TV", "electronics", 2000.0);
s.addItem(3, p1);
s.addItem(1, p2);
assert(s.getTotal() == 2006);
Sale s2(new CreditCardDiscount());
s2.addItem(3, p1);
s2.addItem(1, p2);
//total with discount for card
assert(s2.getTotal() == 1965.88);
}
I'm currently encountering two issues:
I can't wrap my head around designing the Sale class so that "Sale s(new NoDiscount());" and " Sale s2(new CreditCardDiscount());", from the main class, make sense.
I'm fairly certain there should be some code where the //apply discount comment is found in the getTotal() function, but I'm not sure how to implement it so that "price -= discountPolicy->getDiscount(this, sIt);" works.
The rest of the program should be implemented correctly, since I've seen similar designs, it's mainly the Sale function that I don't understand.
Appreciate the help!
I'm trying to compare two variables and the type of these variables are "Time". I can't seem to use the == / != function for these.
#include<iostream>
#include "Stock.h"
using namespace std;
void Stock::setShares(int d, int m, int y, int h, int mts, double p, int vol, double val)
{
date.setDate(d, m, y);
time.setTime(h, mts);
price = p;
value = val;
volume = vol;
}
Date Stock::getDate() const
{
return date;
}
Time Stock::getTime() const
{
return time;
}
This is in my main program:
Time t1, t2;
for (int i = 1; i < counter; ++i)
{
if (V1.at(i).getPrice() == highestPrice)
{
time2 = V1.at(i).getTime;
if (time2 != time1)
{
cout << time2;
}
}
}
How can I compare time1 & time2? I'm trying to avoid printing duplicate values of time in my program. V1 is a vector loaded with data from Stock object.
Check first whether == or != operator is overloaded for type Time. You must provide your own meaning to operators which you are gonna to use in your code for user-defined types else you will get compiler errors.
something like below,
class Time
{
public:
bool operator==(Time const & t1) const
{
return this.hour == t1.hour && this.min==t1.min;
}
private:
int min;
int hour;
};
In order to be able to answer your question completely, it would be necessary to know the details of the type "Time". Since you talk about comparing two objects, let's assume it is class.
If it was simple class like this:
class Time {
public:
int getValue();
void setValue(int value);
private:
int value;
}
You would need to use getValue method:
if( t1.getValue() == t2.getValue())
If you want to compare the objects directly, you need to overload the necessary operators:
bool operator==(const Time& anotherTime) const {
return (anotherTime.getValue()==this->getValue());
}
I'm trying to create a memory mapped file using this answer, but I'm getting compile errors. This is my code:
namespace bi = boost::interprocess;
std::string vecFile = "vector.dat";
bi::managed_mapped_file file_vec(bi::open_or_create,vecFile.c_str(), sizeof(struct Rectangle) * data_size);
typedef bi::allocator<struct Rectangle, bi::managed_mapped_file::segment_manager> rect_alloc;
typedef std::vector<struct Rectangle, rect_alloc> MyVec;
MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(file_vec.get_segment_manager());
vecptr->push_back(random_rectangle);
The struct is this:
struct Rectangle{
Rectangle(float *minArr, float *maxArr, int arr, int exp, int ID){
this->arrival = arr;
this->expiry = exp;
this->id = ID;
for(int i=0; i < 2; i++){
min[i] = minArr[i];
max[i] = maxArr[i];
}
int arrival, expiry, id;
float min[2];
float max[2];
}
The error I get is: Compiler could not deduce the template argument for '_Ty*' from 'boost::interprocess::offset_ptr'. What am I doing wrong?
It looks okay to me:
Live On Coliru
#include <boost/interprocess/managed_mapped_file.hpp>
#include <vector>
namespace bi = boost::interprocess;
struct Rectangle {
Rectangle(float *minArr, float *maxArr, int arr, int exp, int ID) {
this->arrival = arr;
this->expiry = exp;
this->id = ID;
for (int i = 0; i < 2; i++) {
min[i] = minArr[i];
max[i] = maxArr[i];
}
};
int arrival, expiry, id;
float min[2];
float max[2];
};
namespace Shared {
using segment = bi::managed_mapped_file;
using mgr = segment::segment_manager;
using alloc = bi::allocator<Rectangle, mgr>;
using vector = std::vector<Rectangle, alloc>;
}
Rectangle random_rectangle() {
float dummy[2] = { };
return { dummy, dummy, 0, 0, 0 };
}
int main() {
#define data_size 10
std::string vecFile = "vector.dat";
Shared::segment mmem(bi::open_or_create, vecFile.c_str(), (10u<<10) + sizeof(struct Rectangle) * data_size);
Shared::vector *vecptr = mmem.find_or_construct<Shared::vector>("myvector")(mmem.get_segment_manager());
vecptr->push_back(random_rectangle());
}
If it doesn't compile exactly as above, please note versions of your library and compiler. Consider upgrading.
I see this error when running the below code:
Segmentation fault (core dumped)
I can't find the reason.
#ifndef DQMCBASE__H
#define DQMCBASE__H
const double pi=3.141592645;
#define rnd() ((double)rand())/ RAND_MAX
/**
* The basic walker class. This class serves the purpose of providing
* a structure that can be reused by inheriting.
*/
class DQMCWalker {
double _x; ///< dummy variable to implement basic 1D Harmonioscillator example.
This variable will be removed in future versions.
double _timeStep; ///< is the timestep in between to simultanious simulations
public:
DQMCWalker();
~DQMCWalker();
/**
* implements a normal distribution that can be used for the walking
* process defined in
* #see WalkNormal()
*
* #param variance the variance of the distribution.
* #param meanvalue the mean value of the distribution.
*
* #return A double distributed according to a normal distribution.
*/
double NormalDistribution(double variance, double meanvalue);
/**
* a virtual function that describes the walking process of the walker.
*
* #return returns 0, always.
*/
virtual int WalkNormal();
virtual double Potential();
virtual double Weight(double);
int Copy(DQMCWalker);
double SetDeltaT(double);
double GetDeltaT();
};
/* *
* The simulation class is a basic class that implements the basic features of walking, branching
* TODO
*/
template <class walker>
class DQMCSimulation {
walker* _walkers;
walker* _copies;
double _refE;
double _timeStep;
int _population;
int _max_walkers;
int _last_pop,_cur_pop,_nCopies;
public:
/**
* The constructor is used to define the simulation parameters of an instance. It takes two parameters,
* namely, the number of walkers and the time step in between two iterations.
*
* #param n the number of walkers used in the simulation.
* #param dt the time step in between two iterations.
*/
DQMCSimulation(int n, double dt);
~DQMCSimulation();
/**
* This function is used to perform one iteration. Every time this function is called
* a walkers are move according to the implementation of DQMCWalker::Walk(), next the
* reference energy is calculted according to the formula
* TODO
* and lastly, a birth-death process is performed.
*/
int Iterate();
double GetReferenceEnergy();
walker* WalkerArray();
};
#endif
up to here can be embeded into DQMCBase.h file
/* DQMCBase.cpp */
#include <iostream>
#include<math.h>
#include<stdlib.h>
#include<ctime>
//#include <DQMCBase.h>
using namespace std;
DQMCWalker::DQMCWalker() {
_timeStep=0.1;
_x=0.0;
}
DQMCWalker::~DQMCWalker() {
_x=0.0;
}
double DQMCWalker::NormalDistribution(double variance=1.0, double meanvalue=0.0) {
int samples=12;
double res = 0.0;
for(int i=0;i<samples;i++)
res +=rnd();
res = (res - samples*0.5)*sqrt(variance)+meanvalue;
return res;
}
int DQMCWalker::WalkNormal() {
_x+=NormalDistribution(1.0,0.0)*sqrt(_timeStep);
return 0;
}
double DQMCWalker::Potential() {
return 0.5*_x*_x;
}
double DQMCWalker::Weight(double refE) {
return exp(-(Potential()-refE)*_timeStep);
}
int DQMCWalker::Copy(DQMCWalker w) {
_x = w._x;
return 0;
}
double DQMCWalker::SetDeltaT(double timeStep) {
return (_timeStep = timeStep);
}
double DQMCWalker::GetDeltaT() {
return _timeStep;
}
template <class walker>
DQMCSimulation<walker>::DQMCSimulation(int n, double dt) {
_max_walkers = n;
_timeStep = dt;
_population = n;
_last_pop = _cur_pop = _population;
_walkers = new walker[2*n];
_copies = new walker[2*n];
for(int i=0;i<2*n; i++) {
_walkers[i].SetDeltaT(dt);
_copies[i].SetDeltaT(dt);
}
}
template<class walker>
DQMCSimulation<walker>::~DQMCSimulation() {
delete[] _walkers;
}
template <class walker>
int DQMCSimulation <walker>::Iterate() {
int i;
/* Make the walkers walk */
for(i=0;i<_cur_pop;i++)
_walkers[i].WalkNormal();
/* Calculating the reference energy */
double avg=0.0;
for(i=0;i<_cur_pop;i++)
avg += _walkers[i].Potential();
avg/=_cur_pop;
_refE =avg - (_cur_pop-_population)/(_population*_timeStep);
_last_pop = _cur_pop;
/* This is the part where walkers spawn and die */
int m,j;
_nCopies = 0;
for(i=0;i<_cur_pop;i++) {
m = floor(_walkers[i].Weight(_refE)+rnd());
if(m<3) m=3;
if(m==0) { /* The poor Walker dies */
if(_cur_pop>1) {
_walkers[i].Copy(_walkers[_cur_pop]);
i--, _cur_pop--;
} else {
cout << "WARNING :: Your population is dying!" << endl;
}
} else {
for(j=1;j<m;j++) {
_copies[_nCopies].Copy(_walkers[i]);
_nCopies++;
}
}
}
/* Adding the copies */
for(j=0;j<_nCopies; j++) {
_walkers[_cur_pop].Copy(_copies[j]);
_cur_pop++;
}
return 0;
}
template<class walker>
double DQMCSimulation<walker>::GetReferenceEnergy() {
return _refE;
}
template<class walker>
walker* DQMCSimulation<walker>::WalkerArray() {
return _walkers;
}
/*************************
* 1D Harmonic Oscillator
************************/
class DQMCHarmonic1DWalker : public DQMCWalker {
double _x;
public:
DQMCHarmonic1DWalker() {
_x=0.0;
}
int WalkNormal() {
double dt = sqrt(GetDeltaT());
_x+=NormalDistribution(1.0,0.0)*dt;
return 0;
}
double Potential() {
return 0.5*(_x*_x);
}
int Copy(DQMCHarmonic1DWalker w) {
_x = w._x;
return 0;
}
};
this is the main of the program
int main() {
srand ( time(NULL) );
int i,j, count;
double refE;
cout << "Hamonic 1D:" << endl;
DQMCSimulation<DQMCHarmonic1DWalker> simulation1(500,0.1);
refE = 0.0;
for(i=1; i<1000; i++) {
simulation1.Iterate();
refE += simulation1.GetReferenceEnergy();
if(i%50==0)
cout << refE/i << ", ";
}
return 0;
}
The first and easily noticeable problem is that You need to follow the Rule of Three/Five for DQMCSimulation class.
I'm trying to play with some code..keep getting an compile error RND not declared in scope I found a part of the code that defined it if it ran on linux and if defined it on windows thus ignoring Mac users(no biggie, I would ignore them too!). I removed that part of the code and defined it using the linux settings(since I figured my Mac is more closer to linux than windows), but then I get the same error but for seed. The odd thing is those seed errors are at the same spot at the RND error was. So my question is what the heck is RND/Seed? My searches found them specific to VB but not sure if its useful since I'm using C++.
Here's an offensive code snipped(viewers discretion is advised):
mi = (int)(round(RND*(dimc-1)));
Any tips/suggestions would be great. I'm just starting to learn about c++ so I maybe missing something very simple.
Here's the entire code(stole it from here http://cg.iit.bme.hu/~zsolnai/gfx/genetic/ ):
// a fast genetic algorithm for the 0-1 knapsack problem
// by karoly zsolnai - keeroy#cs.bme.hu
// test case: 1000 items, 50 knapsack size
//
// compilation by: g++ genetic.cpp -O3 -ffast-math -fopenmp
#include <math.h>
#include <time.h>
#include <algorithm>
#include <vector>
#include <fstream>
#include <limits.h>
#define RND ((double)rand_r(&seed)/RAND_MAX) // reentrant uniform rnd
using namespace std;
struct chromo {
chromo(int dimc) { items = new bool[dimc]; }
~chromo() { items = NULL; }
void mutate(const int dimc, const int count) {
int mi;
for(int i=0;i<count;i++) {
mi = (int)(round(RND*(dimc-1)));
items[mi] = !items[mi];
}
}
bool* items;
int f;
};
int fitness(bool*& x, const int dimc, const vector<int>& v, const vector<int>& w, const int limit) {
int fit = 0, wsum = 0;
for(int i=0;i<dimc;i++) {
wsum += x[i]*w[i];
fit += x[i]*v[i];
}
if(wsum>limit) fit -= 7*(wsum-limit); // penalty for invalid solutions
return fit;
}
void crossover1p(const chromo& c1, const chromo& c2, const chromo& c3, const int dimc, const int cp) {
for(int i=0;i<dimc;i++) {
if(i<cp) { c3.items[i] = c1.items[i]; }
else { c3.items[i] = c2.items[i]; }
}
}
void crossover1p_b(const chromo &c1, const chromo &c2, const chromo &c3, int dimc, int cp) {
for(int i=0;i<dimc;i++) {
if(i>=cp) { c3.items[i] = c1.items[i]; }
else { c3.items[i] = c2.items[i]; }
}
}
void crossoverrand(const chromo &c1, const chromo &c2, const chromo &c3, const int dimc) {
for(int i=0;i<dimc;i++) {
if(round(RND)) { c3.items[i] = c1.items[i]; }
else { c3.items[i] = c2.items[i]; }
}
}
void crossoverarit(const chromo &c1, const chromo &c2, const chromo &c3, int dimc) {
for(int i=0;i<dimc;i++) {
c3.items[i] = (c1.items[i]^c2.items[i]);
}
}
bool cfit(const chromo &c1,const chromo &c2) { return c1.f > c2.f; }
bool cmpfun(const std::pair<int,double> &r1, const std::pair<int,double> &r2) { return r1.second > r2.second; }
int coin(const double crp) { // a cointoss
if(RND<crp) return 1; // crossover
else return 0; // mutation
}
// initializes the chromosomes with the results of a greedy algorithm
void initpopg(bool**& c, const std::vector<int> &w, const std::vector<int> &v, const int dimw, const int limit, const int pop) {
std::vector<std::pair<int,double> > rvals(dimw);
std::vector<int> index(dimw,0);
for(int i=0;i<dimw;i++) {
rvals.push_back(std::pair<int,double>(std::make_pair(i,(double)v[i]/(double)w[i])));
}
std::sort(rvals.begin(),rvals.end(),cmpfun);
int currentw = 0, k;
for(int i=0;i<dimw;i++) {
k = rvals[i].first;
if(currentw + w[k] <= limit) { // greedy fill
currentw += w[k];
index[k] = 1;
}
}
for(int i=0;i<pop;i++) {
for(int j=0;j<dimw;j++) {
c[i][j] = index[j];
}
}
}
int main() {
printf("\n");
srand(time(NULL));
vector<int> w, v; // items weights and values
int info=0;
FILE *f = fopen("1000_weights.txt","r");
FILE *f2 = fopen("1000_values.txt","r");
while(!feof(f) || !feof(f2) ) {
fscanf(f," %d ",&info);
w.push_back(info);
info=0;
fscanf(f2," %d ",&info);
v.push_back(info);
} // omitted fclose(f1) and fclose(f2) on purpose
const int limit = 50; // knapsack weight limit
const int pop = 250; // chromosome population size
const int gens = INT_MAX; // maximum number of generations
const int disc = (int)(ceil(pop*0.8)); // chromosomes discarded via elitism
const int dimw = w.size();
int best = 0, ind = 0, ind2 = 0; // a few helpers for the main()
int parc = 0; // parent index for crossover
double avg = 0, crp = 0.35; // crossover probability
vector<chromo> ch(pop,chromo(dimw));
bool **c = new bool*[pop];
for(int i=0;i<pop;i++) c[i] = new bool[dimw];
clock_t start = clock();
printf("Initializing population with a greedy algorithm...");
initpopg(c,w,v,dimw,limit,pop);
printf("done!");
for(int i=0;i<pop;i++) {
ch[i].items = c[i];
ch[i].f = fitness(ch[i].items, dimw ,v, w, limit);
}
printf("\n\n");
for(int p=0;p<gens;p++) {
std::sort(ch.begin(), ch.end(), cfit);
#pragma omp parallel for shared(ch)
for(int i=0;i<pop;i++) {
if(i>pop-disc) { // elitism - only processes the discarded chromosomes
if(coin(crp)==1) { // crossover section
ind = parc+round(10*RND); // choosing parents for crossover
ind2 = parc+1+round(10*RND);
// choose a crossover strategy here
crossover1p(ch[ind%pop],ch[ind2%pop],ch[i],dimw,round(RND*(dimw-1)));
// crossoverrand(ch[ind],ch[ind2],ch[i],dimw);
// crossoverarit(ch[0],ch[1],ch[i],dimw);
ch[i].f = fitness(ch[i].items, dimw ,v, w, limit);
parc += 1;
}
else { // mutation section
ch[i].mutate(dimw,1);
ch[i].f = fitness(ch[i].items, dimw ,v, w, limit);
}
}
avg += ch[i].f;
if(ch[i].f>best) best=ch[i].f;
}
parc = 0;
if(p%5==0) {
printf("\n#%d\t",p);
printf("best fitness: %d \t",best);
printf("avg fitness: %f",avg/pop);
if(best == 675) goto end; // psst...don't tell anyone
}
best = avg = 0;
}
end:
printf("\n\n");
clock_t end = clock();
double t = (double)(end-start)/CLOCKS_PER_SEC;
printf("\nCompletion time: %fs.\n",t);
return 0;
}
The problem is you've inexpertly cut apart the code you've got:
#if defined(__linux) || defined(__linux__)
unsigned int seed = time(NULL);
#define RND ((double)rand_r(&seed)/RAND_MAX) // reentrant uniform rnd
#endif
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#define RND ((double)rand()/RAND_MAX) // uniform rnd
#endif
This defines the seed variable based on the current time for Linux systems; perhaps the Windows systems do not need a seed?
In any event, if you include both lines from the if defined (__linux) ... branch, instead of only one line, it should work without trouble on your OS X system.