0% found this document useful (0 votes)
50 views

C++ Classes For Empirical Nancial Data: Bernt Arne Ødegaard April 2007

The document describes C++ classes for working with financial time series data. It includes a date class that allows storing and manipulating dates. A dated template class is also described, which maps dates to data values of a user-defined type. The dated class allows adding, removing, and querying data by date. Functions are provided for common time series operations like selecting observations between dates or at specific frequencies.

Uploaded by

Giuseppe Luongo
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
50 views

C++ Classes For Empirical Nancial Data: Bernt Arne Ødegaard April 2007

The document describes C++ classes for working with financial time series data. It includes a date class that allows storing and manipulating dates. A dated template class is also described, which maps dates to data values of a user-defined type. The dated class allows adding, removing, and querying data by date. Functions are provided for common time series operations like selecting observations between dates or at specific frequencies.

Uploaded by

Giuseppe Luongo
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

C++ classes for empirical nancial data

Bernt Arne degaardI April 2007

Norwegian School of Management BI and Norges Bank

Chapter 1

Introduction
In this document we describe a self-contained set of utilities that should be of use for academics (and practitioners) working with nancial data.

Chapter 2

Date

This is the documentation for a C++ date class. The date class is pretty rough. A date is stored as three integers (year, month, day). Functions for comparing dates, incrementing dates are provided. Also calculation of time between dates.

2.1 Setting up.


Compile date.cc, put into library libdate.a, make library available. Put date.h on header le path.

2.2 Dening dates.


Examples of date denitions

date d; date d(19930624) date d(24,6,1993) Note the day, month, year sequence.

2.3 Operations on dates.


Let d, d1, d2 be dates. The following operations are dened: Iteration: d++, ++d, d, d . Logical comparisions >, >=, <, <=, ! =, ==. Some aritmetric operations are dened, which has a meaning that may seem strange at rst, but they are natural for usage purposes. Adding/Subtracting x number of days from a data: d=d1+7 gives d the date 7 days after date d1. d=d1-7 gives d the date 7 days before date d1. Finding the number of days between 2 dates. i=d1-d2. Here i is an integer that is the number of days between d1 and d2. i will be negative if d1 < d2. Example:

date d1(30,6,1993); date d2(19930610); i = d1-d2 Gives i the value 20, the number of days between 10 jun 93 and 30 jun 93.

// le: date.h // author: Bernt A Oedegaard.

#ifndef hei r #dene hei r #include <iostrem> using namespace std;

class dte { protected: int yer ; int month int dy ; public: bool int int int

dte(); dte(const

int&

d,

const int&

m,

const int&

y);

vlid(void)

const;

dy() const; month() const; yer() const; set dy (const int& dy ); set month (const int& month set yer (const int& yer );
);

void void void


dte dte dte dte
};

operator operator operator operator

++(); // prex ++(

(); // (int);

int);

// postx prex // postx

bool bool bool bool bool bool

operator operator operator operator operator operator

== ( != (

const dte&, const dte&); const dte&, const dte&); < (const dte&, const dte&); > (const dte&, const dte&); <= (const dte&, const dte&); >= (const dte&, const dte&);
<<
(

// comparison operators

ostrem& #endif

operator

ostrem& os,

const

dte& d);

// output operator

Header le 2.1:

Header le

#include "date.h"
///////////////////////////// construction //////////

dteXXdte(const dy = d; month = m; yer = y; //


};

int&

d,

const int&

m,

const int&

y)

this assumes year is given fully, not Y2K corrections

///////////////////////////// inline denitions //////////

dteXXdte(){ yer

= 0;

month

= 0;

dy

= 0;};

int int int

dteXXdy() const { return dy ; }; dteXXmonth() const { return month dteXXyer() const { return yer ; };

; };

void void void bool


//

dteXXset dy (const int& dy) { dteXXdy = dy; }; dteXXset month(const int& month) { dteXXmonth = month; dteXXset yer (const int& yer) { dteXXyer = yer; }; dteXXvlid()

};

// This function will check the given date is valid or not. // If the date is not valid then it will return the value false. Need some more checks on the year, though

const

if if if if if if

<0) return false; >12 | | month <1) return false; (dy >31 | | dy <1) return false;
(yer (month ((dy ==31 &&

( (

dy ==30 && month ==2) return false; yer <2000){ if ((dy ==29 && month ==2) && !((yer 1900)%4==0)) yer >2000){ if ((dy ==29
&&

return false;

month

==2

| | month

==4

| | month

==6

| | month

==9

| | month

==11) ) )

return false; return false;

};

if

month

==2) && !((yer

2000)%4==0))

};

return true;
};

C++ Code 2.1:

Dening the basic operations

#include "date.h"

bool operator

== (

// check for equality

const

dte& dI,const dte& dP){


}; };

if (!dI.vlid()) { return false; if (!dP.vlid()) { return false; if ( (dI.dy()==dP.dy()) return true;

&& (dI.yer()==dP.yer())) {

&& (dI.month()==dP.month())

}; }

return false; bool operator !=(const return !(dI==dP);


}

dte& dI,

const

dte& dP){

bool operator < (const dte& dI, const dte& dP){ if (!dI.vlid()) { return false; }; // not meaningful, return anything if (!dP.vlid()) { return false; }; // should really be an exception, but if (dI.yer()<dP.yer()) { return true;} else if (dI.yer()>dP.yer()) { return false;} else { // same year if (dI.month()<dP.month()) { return true;} else if (dI.month()>dP.month()) { return false;} else { // same month if ( dI.dy()<dP.dy()) { return true;} else { return false; }
}; }; };

return false; bool operator > (const dte& dI, const dte& dP) { if (dI==dP) { return false;}; // this is strict inequality if (dI<dP) { return false; }; return true;
}

bool operator <=(const dte& if (dI==dP) { return true; } return (dI<dP);


}

dI,

const

dte& dP){

bool operator >=(const dte& dI, const if (dI==dP) { return true;}; return (dI>dP);
};

dte& dP)

C++ Code 2.2:

Comparisons

#include "date.h"

inline

dte next dte(const dte& d){ dte ndt; if (!d.vlid()) { return ndt; }; ndt=dte((d.dy()+1),d.month(),d.yer()); if (ndt.vlid()) return ndt; ndt=dte(1,(d.month()+1),d.yer()); if (ndt.vlid()) return ndt; ndt = dte(1,1,(d.yer()+1)); return ndt;

inline

dte previous dte(const dte& d){ dte ndt; if (!d.vlid()) { return ndt; }; // return zero ndt = dte((d.dy()1),d.month(),d.yer()); if (ndt.vlid()) return ndt; ndt = dte(31,(d.month()1),d.yer()); if (ndt.vlid()) return ndt; ndt = dte(30,(d.month()1),d.yer()); if (ndt.vlid()) return ndt; ndt = dte(29,(d.month()1),d.yer()); if (ndt.vlid()) return ndt; ndt = dte(28,(d.month()1),d.yer()); if (ndt.vlid()) return ndt; ndt = dte(31,12,(d.yer()1)); return ndt;
// postx operator

};

dte dteXXopertor ++(int){ dte d = *this; *this = next dte(d); return d;


}

dte dteXXopertor ++(){ // *this = next dte(*this);

prex operator

return *this;

dte dteXXopertor (int){ // dte d = *this; *this = previous dte(*this); return d;


}

postx operator, return current value

dte dteXXopertor (){ // prex *this = previous dte(*this);

operator, return new value

return *this;

};

inline long long dte(const dte& d) { if (d.vlid()){ return d.yer() * 10000 return 1;
};

d.month()

* 100 +

d.dy();

};

ostrem & operator << (ostrem& os, const dte& d){ if (d.vlid()) { os << " " << long dte(d) << " " else { os << " invalid date "; }; return os;
}

; }

C++ Code 2.3:

Iteration

Chapter 3

Dated

3.1 Introduction
A convenient data structure is a mapping of dates with some variable. For example, a time series of economic variables. The mapping is assumed to be onetoone.

3.2 Implementation
This is implemented as a template class, where the data is two vectors. One of type date, the other of type <T>, the user dened type.

3.3 User functions


Adding data: insert, append Removing data: clear, remove, remove_between, remove_after, remove_before... Querying: contains, first_date, last_date Picking data: date_at, element_at, dates(), elements()

#ifndef heih r #dene heih r #include <vetor> #include "date.h"


// my date class

template <class private: public:

>

class

dted

vetor<dte> dtes ; vetor<> elements ; dted<>(); dted<>(const dted<>&); dted<> operator= (const dted<>&); dted() { ler(); }; void ler(); // erasing void insert(const dte&, const &); // insert

somewhere

bool empty() const ; int size() const ; bool ontins(const dte& d) const ; dte dte t(const int& t) const ; // accessing elements, here dates element t(const int& t) const ; // index directly element t(const dte& d) const ; // index indirectly, specify what
urrent element t(const dte& d)

date

// next: the element either on date d, if d is here, else the last observation before d.

const

vetor<> elements() const; // all elements as vector<T> vetor<dte> dtes() const; // all dates as vector<date> dte (rst dte() const; // dte lst dte() const; (rst element() const; lst element() const;
simple queries

int int int

index of dte(const dte& d) const; // when searching in the data, index of lst dte efore(const dte& d) const; // these are useful functions index of (rst dte fter(const dte& d) const; remove(const dte&); // removing one or more elements remove etween inluding end points(const dte&, const dte&); remove etween(const dte&, const dte&); remove efore(const dte&); remove fter(const dte&);

void void void void void


};

#include "dated_main.h" #include "dated_search.h" #include "dated_remove.h"

template<class template<class template<class template<class template<class template<class template<class

> > > > > > >

dted<> dted<> dted<> dted<> dted<> dted<> dted<>

oservtions etween(const dted<>& os,const dte&(rst, const dte& lst); oservtions fter(const dted<>& os, const dte& (rst); oservtions efore(const dted<>& os, const dte& lst); end of yer oservtions(const dted<>&); eginning of month oservtions(const dted<>&); end of month oservtions(const dted<>&); oservtions mthing dtes(const dted<>& os, const vetor<dte>& dtes);

#include "dated_util.h" #endif

Header le 3.1:


8

dated h

template<class template<class

> dted<>XXdted(){;};

// not necessary to do anything,


{

dtes =vetor<dte>(dos.size()); elements =vetor<>(dos.size()); for (int t=0;t<dos.size();++t){ dtes [t] = dos.dte t(t); elements [t] = dos.element t(t);
}; };

// for speed, initialize rst with correct size and then copy

>dted<>XXdted(const dted<>& dos)

template<class > dted<> dted<>XXopertor= (const dted<>& if (this==&dos) return *this; // check against self assignment;
ler(); dtes =vetor<dte>(dos.size()); elements =vetor<>(dos.size()); for (int t=0;t<dos.size();++t){ dtes [t] = dos.dte t(t); = dos.element t(t); elements [t]

dos)

}; };

return *this; template<class template<class template<class


> dted<>XXdted(); > >

bool int

dted<>XXempty()

const
{

return
t)

(dtes .size()<1); }; };

dted<>XXsize()

const

return

dtes .size();

template<class > dte dted<>XXdte t(const int& if ( (t>=0) && (t<size()) ) return dtes [t]; return dte();
};

const

{ // accessing with counds checking

template<class > dted<>XXelement t(const int& if ( (t>=0) && (t<size()) ) return elements [t]; return ();
};

t)

const

{ // accessing with counds checking

template<class > dted<>XXelement if (!ontins(d)) return (); return elements [index of dte(d)];
};

t(const dte& d)

const

template<class

if (size()<1) return (); if (ontins(d)) return element t(d); if (d<(rst dte()) { return (); }; return elements [index of lst dte efore(d)];
};

// the element either on date d, if d is here, else the last observation before d.

> dted<>XXurrent element t(const dte& d)

const

template<class

> vetor<> dted<>XXelements() const { vetor<> elements(size()); for (int t=0; t<size(); ++t){ elements[t]=element t(t); }; return elements;

};;

template<class

> vetor<dte> dted<>XXdtes() vetor<dte> ds(size()); for (int t=0;t<size();++t){ ds[t]=dte t(t); }; return ds;

const

};

template <class > void dted<>XXinsert(const if (!d.vlid()) return; if ( (empty() ) | | (d>lst dte()) ) {
dtes .push k(d); elements .push k(os);

dte& d,

const

& os)

return;

};

if

(d<(rst

dte()) { dtes .insert(dtes .egin(),d); elements .insert(elements .egin(),os);

template<class > bool dted<>XXontins(const dte& return inry serh(dtes .egin(),dtes .end(),d);
};

d)

const

template<class > dte dted<>XX(rst if (empty()) return dte(); return dtes .front();
};

dte()

const

template<class > dte dted<>XXlst if (empty()) return dte(); return dtes .k();
};

dte()

const

template<class > dted<>XX(rst if (empty()) return (); return elements .front();


};

element()

const

template<class > dted<>XXlst if (empty()) return (); return elements .k();


};

element()

const

template <class

>

// this routine returns the index at which date d is, or -1 if not found.

int

dted<>XXindex of dte(const dte& d)

const

if (!d.vlid()) return 1; if (!ontins(d)) return 1; int dist=0; for (int i=0;i<dtes .size();++i){ if (dtes [i]==d) return i; //
}; };

slow implementation, but works (for now),

return

dist; >

template <class

if (!d.vlid()) return 1; if (d>=lst dte()) return 1; if (d<(rst dte()) return 0; int dist=0; for (int i=0;i<dtes .size();++i){ if (dtes [i]>d) return i;
}; };

// this routine returns the index of the rst date after d.

int

dted<>XXindex of (rst dte fter(const dte& d)

const

return

dist; >

template <class

// this routine returns the index of the rst date after d.

int

dted<>XXindex of lst dte efore(const dte& d)

const

if (!d.vlid()) return 1; if (d<=(rst dte()) return 1; if (d>lst dte()) return index of dte(lst dte()); for (int i=0;i<dtes .size();++i){ if (dtes [i]>=d) return i1; // slow implementation,
}; };

but works (for now)

return

1;

Header le 3.3:

Searching

10

template<class
};

> void dted<>XXler() { dtes .erse(dtes .egin(),dtes .end()); elements .erse(elements .egin(),elements .end()); dted<>XXremove(const dte& d)
{

template<class > void int i=index of dte(d); if (i>=0) {


}; };

dtes .erse(dtes .egin()+i); elements .erse(elements .egin()+i);

template<class > void dted<>XXremove if (!dI.vlid()) return; if (!dP.vlid()) return; for (int t=size()1;t>=0;t){ // this is

etween(const dte& dI,

const

dte& dP)

dte d=dte t(t); if ( (d>dI) && (d<dP) ) { dtes .erse(dtes .egin()+t); elements .erse(elements .egin()+t);
};

very slow, to be replaced with one using vector erase.

}; };

template<class > void dted<>XXremove if (!dI.vlid()) return; if (!dP.vlid()) return; for (int t=size()1;t>=0;t){ // this is

etween inluding end points(const dte& dI,

const

dte& dP)

dte d=dte t(t); if ( (d>=dI) && (d<=dP) ) { dtes .erse(dtes .egin()+t); elements .erse(elements .egin()+t);
};

very slow, to be replaced with one using vector erase.

}; };

template<class
};

> void dted<>XXremove efore(const dte& d) remove etween((rst dte(),d);


{

template<class
};

> void dted<>XXremove fter(const dte& d) remove etween(d,++lst dte());


<< (ostrem& outf,

template <class > ostrem& operator if (dos.empty()) return outf ; for (int t=0; t<dos.size(); ++t) {
}; };

const

dted<>& dos

) {

outf << dos.dte t(t) << " " << dos.element t(t) << endl; outf ;

return

Header le 3.4:

Removing elements

11

#ifndef heih sv r #dene heih sv r

template<class

> dted<> oservtions etween( const dted<>& os, const dte& (rst, dted<> piked = os; // assume that the rst and last date should be included. piked.remove fter(lst);// just copy and then remove. Fast enough piked.remove efore((rst); return piked; > dted<> oservtions fter(

const

dte& lst)

};

template<class

// assume that the rst date is to be included in the result // should maybe be observations on and after. . . .

const

dted<>& os,

const

dte& (rst)

dted<> dos = os; // dos.remove efore((rst); return dos;

just copy and then remove. Fast enough

};

template<class

> dted<> oservtions efore( const dted<>& os, const dte& lst) dted<> dos = os; // assume that the last date is to be included in the result dos.remove fter(lst); return dos; > dted<> end of yer oservtions(const dted<>& dos) { dted<> eoy os; if (dos.(rst dte().month()==1) {// take rst obs in january as end of previous year eoy os.ppend(dos.dte t(0),dos.element t(0));
};

};

template<class

for (int t=0;t<dos.size()1;++t) { if (dos.dte t(t).yer()!=dos.dte


}; };

t(t+1).yer()) { eoy os.ppend(dos.dte t(t),dos.element t(t));

if
} }

(eoy

os.lst dte().yer() != dos.lst dte().yer()) { eoy os.ppend(dos.lst dte(),dos.element t(dos.size()1)); eoy os;

return

template<class

> dted<> eginning of month oservtions(const dted<>& dos) { dted<> eom os; eom os.ppend(dos.dte t(0),dos.element t(0));// take rst observation always for (int t=1;t<dos.size();++t) { if ( (dos.dte t(t).month()!=dos.dte t(t1).month())| | (dos.dte t(t).yer()!=dos.dte t(t1).yer()) eom os.ppend(dos.dte t(t),dos.element t(t));
}; };

) {

return
}

eom os;

template<class

> dted<> end of month oservtions(const dted<>& dos) { dted<> eom os; for (int t=0;t<dos.size()1;++t) { if ( (dos.dte t(t).month()!=dos.dte t(t+1).month()) | | (dos.dte t(t).yer()!=dos.dte t(t+1).yer())) eom os.ppend(dos.dte t(t),dos.element t(t));
}; ( (eom

};

if
} };

os.lst dte().month() != dos.lst dte().month()) | | (eom os.lst dte().yer() eom os.ppend(dos.lst dte(),dos.element t(dos.size()1)); eom os;

!=

dos.lst dte().yer())

) {

return

template<class

> dted<> oservtions mthing dtes( dted<> dos; for (unsigned int t=0;t<dtes.size();++t){ if (os.ontins(dtes[t])) { 12 dos.ppend(dtes[t],os.element t(dtes[t]));
};

const

dted<>& os,

const

vetor<dte>& dtes){

}; };

return

dos;

#endif

Header le 3.5:

Utilities (nonmember functions)

Chapter 4

Dated observations
A specialization of the general dated<T> class to be used for time series of numbers.
#ifndef heih yf r #dene heih yf r #include "dated.h" // templated dated<> #include <string> // ANSI string class
class

class dted private: public:


string

oservtions X title
;

public

dted<double>{

dted oservtions() void ler();

ler();
// title

};

void set title(string s); string title() const; int int int int
};

no no no no

os() const; os etween(const dte& dI, const dte& dP) os efore(const dte& d) const; os fter(const dte& d) const;

const;

///// io

ostrem& operator << (ostrem&, const dted oservtions& ); void print dted oservtions(ostrem& of, const dted oservtions& d,
//// mischellaneous utilities

int

preision=3);

double mx os(dted oservtions& dos); double min os(dted oservtions& dos); bool dtes mth(const dted oservtions&
dted dted dted dted dted dted dted dted
///// picking subsets.

osI,

const

dted oservtions& osP);

oservtions oservtions oservtions oservtions oservtions oservtions oservtions oservtions

oservtions oservtions oservtions oservtions

etween(const dted oservtions& os,const dte& (rst,const dte& lst); fter(const dted oservtions& os, const dte& (rst); efore(const dted oservtions& os, const dte& lst); mthing dtes(const dted oservtions& os, const vetor<dte>& dtes);

///// picking periodic elements

eginning of month oservtions(const dted oservtions&); end of month oservtions(const dted oservtions&); end of yer oservtions(const dted oservtions&); end of yer urrent oservtions(const dted oservtions&);

#endif

Header le 4.1:

dated obs h

13

#include "dated_obs.h" #include <lgorithm>

void void
};

dted oservtionsXXset title(string s)


{

title

s;

};

dted oservtionsXXler() title = string(); dted<double>XXler();

string dted oservtionsXXtitle()

const

return

title

;};

int

// count number of observations between given dates.

dted oservtionsXXno os etween(const dte& dtI,

const

dte& dtP)

const

if (!dtI.vlid()) return 1; if (!dtP.vlid()) return 1; int noos=0; int = size(); for (int t=0;t<;++t) { if ( (dtI<=dte t(t) ) &&
};

(dte

t(t)<=dtP)

) ++noos;

return
};

noos; dte& d)

int dted oservtionsXXno os efore(const return no os etween((rst dte(),d);


};

const

int dted oservtionsXXno os fter(const return no os etween(d,lst dte());


};

dte& d)

const

C++ Code 4.1:

dated obs cc

#include "dated_obs.h"

bool dtes mth(const dted oservtions& if (dI.size()!=dP.size()) { return false; } for (int t=0;t<dI.size();++t){ if
}; }; (dI.dte

dI,

const

dted oservtions& dP){

// slow, careful check that the time series match exactly

t(t)

!=

dP.dte t(t))

return false;

return true; double


};

mx os(dted oservtions& dos){ vetor<double> os = dos.elements(); return *mx element(os.egin(),os.end());

double
};

min os(dted oservtions& dos){ vetor<double> os = dos.elements(); return *min element(os.egin(),os.end());

C++ Code 4.2:


14

calc

#include "dated_obs.h" #include <iomnip>

void

print dted oservtions(ostrem& of, const dted oservtions& os, int preision) { if (os.title().length()>0) of << os.title() << endl; for (int t=0;t<os.size();t++) { of << os.dte t(t) << " " << setpreision(preision) << (xed << os.element t(t) << endl;
};

};

ostrem& operator << (ostrem& os, print dted oservtions(os,os,4); return os;
};

const

dted oservtions& os)

C++ Code 4.3:

io

15

#include "dated_obs.h" dted oservtions end of yer oservtions(const dted oservtions& dos) if (dos.size()<1) return dted oservtions(); dted oservtions eoy os; eoy os.set title(dos.title()); if (dos.(rst dte().month()==1) { // include beginning of rst year eoy os.insert(dos.dte t(0),dos.element t(0));
}; {

for (int t=0;t<dos.size()1;++t) { if (dos.dte t(t).yer()!=dos.dte


}; };

t(t+1).yer()) { eoy os.insert(dos.dte t(t),dos.element t(t));

if
} };

(eoy

os.lst dte().yer() != dos.lst dte().yer()) { eoy os.insert(dos.lst dte(),dos.element t(dos.size()1)); eoy os;

return

dted oservtions end of yer urrent oservtions(const dted oservtions& dos) { if (dos.size()<1) return dted oservtions(); dted oservtions eoy os; eoy os.set title(dos.title()); if (dos.(rst dte().month()==1) { eoy os.insert(dos.dte t(0),dos.element t(0)); for (int yer=dos.(rst dte().yer(); yer<=dos.lst dte().yer(); ++yer){ eoy os.insert(dte(31,12,yer),dos.urrent element t(dte(31,12,yer)));
}; }

};

return

eoy os;

dted oservtions eginning of month oservtions(const dted oservtions& dos) { if (dos.size()<1) return dted oservtions(); dted oservtions eom os; eom os.set title(dos.title()); if (dos.(rst dte().dy()<5) { eom os.insert(dos.dte t(0),dos.element t(0)); }; for (int t=1;t<dos.size();++t) { if ( (dos.dte t(t).month()!=dos.dte t(t1).month()) | | (dos.dte t(t).yer()!=dos.dte t(t1).yer()) ) { eom os.insert(dos.dte t(t),dos.element t(t));
}; }; }

return

eom os;

dted oservtions end of month oservtions(const dted oservtions& dos) { if (dos.size()<1) return dted oservtions(); dted oservtions eom os; eom os.set title(dos.title()); if (dos.(rst dte().dy()<10) { eom os.insert(dos.dte t(0),dos.element t(0)); for (int t=0;t<dos.size()1;++t) { if ( (dos.dte t(t).month()!=dos.dte t(t+1).month()) | | (dos.dte t(t).yer()!=dos.dte t(t+1).yer()) ) { eom os.insert(dos.dte t(t),dos.element t(t));
}; };

};

if
} };

( (eom

dos.lst dte().month()) dos.lst dte().yer()) ) { eom os.insert(dos.lst dte(),dos.element t(dos.size()1));


| | (eom os.lst dte().yer()
!= !=

os.lst dte().month()

return

eom os;

C++ Code 4.4:


16

Periodic

#include "dated_obs.h" dted oservtions oservtions etween(

// assume that the rst and last date should be included.

const dted oservtions& const dte& (rst, const dte& lst) {

os,

dted oservtions piked = os; piked.remove fter(lst); piked.remove efore((rst); return piked;

// just copy and then remove. Fast enough

};

dted oservtions oservtions fter(

// assume that the rst date is to be included in the result // should maybe be observations on and after. . . .

const dted const dte&

oservtions& os, (rst) {

dted oservtions dos = os; dos.remove efore((rst); return dos;

// just copy and then remove. Fast enough

};

dted oservtions oservtions efore( dted oservtions dos dos.remove fter(lst); return dos;
=

// assume that the last date is to be included in the result

const const

dted oservtions& os, dte& lst) {

os;

};

C++ Code 4.5:

Subsets

17

Chapter 5

Security price history


The following class is used when we have a lot of historical data about securities. Given price observations, do various calculations and pulling of data, as well as printing various reports.

5.0.1 Security price history


When doing empirical work in nance, we always end up with the same basic problem. From a time series of price observations of a nancial security, we want to calculate any number of things: Returns at dierent frequencies, average returns, max, min returns, volatility,... We always return to the basic issue of storing data for the underlying prices. The class implemented in the following is an attempt to solve that problem once and for all. The purpose of the security_price_history class is to hold a price history for a security. The emphasis is on eciently storing this data. The general idea is to store the data in the following form: Security Name Date bid price trade price ask price 2 jan 1990 99 100 101 3 jan 1990 98 99 100 . . . . . . . . One assumption made here is that the data is not on a higher frequency than daily. If so need to change the date class to a date_time class that also stores time of day. Calculating returns etc will then be simply provided as functions that work on this data structure. This class is also useful as a base class. For example, a stock will need added functions for dividends, adjustments etc.

5.1 Header le


The header le denes the class interface.

18

#ifndef igs sgi rsy r #dene igs sgi rsy r #include "dated_obs.h"

class seurity private:

prie history

{ ;

public:

string seurity nme vetor<dte> dtes ; vetor<double> ids ; vetor<double> trdes ; vetor<double> sks ;

seurity prie history(); seurity prie history(const string&); seurity prie history(const seurity prie history&); seurity prie history operator=(const seurity prie history&); seurity prie history(); void ler(); void set seurity nme(const string&); void dd pries(const dte& d, const double& id, const double& trde,

// the most important function, all dates is added through calls to add prices

const double&

sk);

void void void

set id (const int& i, const double& id); // to set trde (const int& i, const double& trde); set sk (const int& i, const double& sk);

change current data.

void erse(const dte&); // delete on given dates void erse efore(const dte&); void erse etween(const dte&, const dte&); void erse fter(const dte&); bool ontins(const dte&) const; // check whether this date is present private: int index of dte(const dte&) const;// where in vector is this date? int index of lst dte efore(const dte&) const ; int index of (rst dte fter(const dte&) const ; public: bool empty() const; int size() const;// { return dates .size(); }; string seurity nme() const; vetor<dte> dtes() const; int int int int int int
no dtes() const; no pries() const; no ids() const; no trdes() const; no sks() const; no pries etween(const dte&, const dte&) const; dte dte t(const int&) const; double id(const int&) const; double id(const dte&) const; double trde(const int&) const; double trde(const dte&) const; double sk(const int&) const; double sk(const dte&) const; dte (rst dte() const; dte lst dte() const; double prie(const dte&) const; // price at given data double urrent prie(const dte&) const; // price at or before double prie(const int&) const; double uy prie(const int&) const; double sell prie(const int&) const;
};

given data

dted oservtions pries(const seurity prie history&); vetor<dte> dtes(const seurity prie history&); #endif

19

Header le 5.1:

security price history.h

5.2 Implementation

20

#include "security_price_history.h" seurity prie historyXX seurity prie history(){ ler();


}; // make sure empty

seurity prie historyXX seurity prie history(const string& nme){ ler(); seurity nme = nme;
};

seurity prie historyXX seurity prie history(){ ler();


// copy construction

};

seurity prie historyXX seurity prie history(const seurity prie history& sh) ler(); dtes = vetor<dte>(sh.size()); ids = vetor<double>(sh.size()); trdes = vetor<double>(sh.size()); sks = vetor<double>(sh.size()); for (unsigned i=0;i<sh.no dtes();++i){ dtes [i]=sh.dte t(i); ids [i]=sh.id(i); trdes [i]=sh.trde(i); sks [i]=sh.sk(i);
}; };

set seurity nme(sh.seurity nme()); seurity prie history seurity prie historyXX operator= ler(); dtes = vetor<dte>(sh.size()); ids = vetor<double>(sh.size()); trdes = vetor<double>(sh.size()); sks = vetor<double>(sh.size()); for (unsigned i=0;i<sh.no dtes();++i){ dtes [i]=sh.dte t(i); ids [i]=sh.id(i); trdes [i]=sh.trde(i); sks [i]=sh.sk(i);
}; (

const

seurity prie history& sh)

set seurity nme(sh.seurity nme());

return

(*

this);

};

void

seurity prie historyXXler() { dtes .erse(dtes .egin(),dtes .end()); ids .erse(ids .egin(),ids .end()); trdes .erse(trdes .egin(),trdes .end()); sks .erse(sks .egin(),sks .end()); seurity nme =string();
=

string seurity prie historyXXseurity nme() const { return seurity nme ; }; void seurity prie historyXXset seurity nme(const string& s) { seurity nme dte seurity prie historyXXdte t(const int& t) const { return dtes [t]; };

};

s;

};

bool seurity prie historyXXempty() const{ if ( (no dtes()<1) && (seurity nme().length()<1) ) return true; return false;
};

void void void

seurity prie historyXXset id (const int& i, const double& id) { if (i<no dtes()) ids [i]=id; }; seurity prie historyXXset trde (const int& i, const double& trde) { if (i<no dtes()) trdes [i]=trde; seurity prie historyXXset sk (const int& i, const double& sk) { if (i<no dtes()) sks [i]=sk; }; seurity prie historyXXid (const int& t) const { return ids [t]; }; seurity prie historyXXtrde(const int& t) const { return trdes [t]; seurity prie historyXXsk (const int& t) const { return sks [t]; };
};

};

double double double

C++ Code 5.1:

21 Implementing the class

#include "security_price_history.h"

int
};

return

seurity prie historyXXno dtes dtes .size();

()

const const

int

int n pries=0; for (int i=0;i<no dtes();++i){ if ( (id(i)>0) | | (trde(i)>0)


};

seurity prie historyXXno pries()

| | (sk(i)>0)

) { ++n

pries;

};

return
};

n pries; lst)

int

seurity prie historyXXno pries etween(const dte& (rst, const dte& int n pri etween=0; for (int i=0;i<no dtes();++i) { if ((dte t(i)>=(rst) && (dte t(i)<=lst)) { if ((id(i)>0)| |(trde(i)>0)| |(sk(i)>0)) {++n pri etween;};
}; };

const

return
};

n pri etween;
{

int

seurity prie historyXXno ids() const int n pries=0; for (int i=0;i<no dtes();++i){ if (id(i)>0) { ++n pries; };
};

return
};

n pries;

int

int n pries=0; for (int i=0;i<no dtes();++i){ if (trde(i)>0) { ++n pries;


};

seurity prie historyXXno trdes()

const
};

return
};

n pries;
{

int

seurity prie historyXXno sks() const int n pries=0; for (int i=0;i<no dtes();++i){ if (sk(i)>0) { ++n pries; };
};

return
};

n pries;

C++ Code 5.2:

Sizes

22

#include "security_price_history.h" const double wssxq yf=1; double seurity prie historyXXprie(const int& i) const{ if (i>=no dtes()) { return wssxq yf; }; if (trde(i)>0.0) { return trde(i); }; if ( (id(i)>0.0) && (sk(i)>0.0)) { return 0.5*(id(i)+sk(i)); if (id(i)>0.0) { return id(i); }; // to avoid big jumps, if (sk(i)>0.0) { return sk(i); }; // skip these return wssxq yf;
};

}; // return bid ask average

double seurity prie historyXXid(const dte& d) const { int i = index of dte(d); // return price on date, only if obs if (i>=0) return id(i); return wssxq yf;
};

on that date, else return missing

double seurity prie historyXXtrde(const int i = index of dte(d); if (i>=0) return trde(i); return wssxq yf;
};

dte& d)

const

double seurity prie historyXXsk(const int i = index of dte(d); if (i>=0) return sk(i); return wssxq yf;
};

dte& d)

const

double seurity prie historyXXprie(const int i = index of dte(d); if (i>=0) return prie(i); return wssxq yf;
};

dte& d)

const

double seurity prie historyXXurrent prie(const dte& d) const { // return price on given date. if (empty()) { return wssxq yf; }; if (d<(rst dte()) { return wssxq yf; }; // if before rst or after last, return missing if (d>lst dte()) { return wssxq yf; }; int i = index of dte(d); // If don't have that price, return the last one observed before the wanted if (i>=0) return prie(i);
i=index of lst dte efore(d); if (i>=0) return prie(i); return wssxq yf;
// otherwise use last previously observed price.

date

};

double seurity prie historyXXuy prie(const int& if (i>=no dtes()) { return wssxq yf; }; if (sk(i)>0.0) { return sk(i); }; if (trde(i)>0.0) { return trde(i); }; return wssxq yf;
};

i)

const{

double seurity prie historyXXsell prie(const int& if (i>=no dtes()) { return wssxq yf; }; if (id(i)>0.0) { return id(i); }; if (trde(i)>0.0) { return trde(i); }; return wssxq yf;
};

i)

const{

dted oservtions pries(const seurity prie history& sh dted oservtions pr; for (int i=0;i<sh.no pries();++i) { dte d=sh.dte t(i); double prie = sh.prie(i); if (prie>0) pr.insert(d,prie);
}; };

){

return

pr;

23

C++ Code 5.3:

Prices

#include "security_price_history.h"

void if if if

seurity prie historyXXdd pries(const dte& d,

(!d.vlid()) ( (no

( (id<0) && (trde<0) && (sk<0) )

return;

// don't add

const double& const double& const double& return;


) ) {

id, trde, sk) {

dtes()<1) | | (d>lst dte() dtes .push k(d); trdes .push k(trde); ids .push k(id); sks .push k(sk);

// don't bother about empty dates

return;

};

if

(d<(rst

dte()) { dtes .insert(dtes .egin(),d); ids .insert(ids .egin(),id); trdes .insert(trdes .egin(),trde); sks .insert(sks .egin(),sk);

return;

};

int i = index of dte(d); if (i>=0) { // found, replace


trdes [i]=trde; ids [i]=id; sks [i]=sk;

return; if
(dte

// evidently should be inserted somewhere in between other observations.

for

(i=0;i<no

dtes();++i){ t(i)>d) { dtes .insert(dtes .egin()+i,d); ids .insert(ids .egin()+i,id); trdes .insert(trdes .egin()+i,trde); sks .insert(sks .egin()+i,sk);

return;

}; }; };

int

seurity prie historyXXsize()

const

return

dtes .size();

};

dte seurity prie historyXX(rst dte() const { if (dtes .size()>0) { return dtes .front();}; return dte(); // else
};

dte seurity prie historyXXlst dte() const { if (dtes .size()>0) { return dtes .k();}; return dte();
};

vetor<dte> seurity prie historyXXdtes() return dtes ;


};

const

C++ Code 5.4:

Utilities

24

#include "security_price_history.h"

void seurity prie int i = index of


//

historyXXerse(const dte& d) dte(d);


<<
endl;  erasing

if

(i>=0) { // returns -1 if not there

cout

<<

 erasing

dtes .erse(dtes .egin()+i); trdes .erse(trdes .egin()+i); ids .erse(ids .egin()+i); sks .erse(sks .egin()+i);
}; };

//

cout

<<

<<

endl;

void

seurity prie historyXXerse etween(const dte& (rst, const dte& lst) int iI = index of (rst dte fter((rst); int iP = index of lst dte efore(lst); if ( (iI>=0) && (iP>=0) ) { // returns -1 if not there iP++; // the erase does not delete the last one. dtes .erse(dtes .egin()+iI,dtes .egin()+iP); trdes .erse(trdes .egin()+iI,trdes .egin()+iP); ids .erse(ids .egin()+iI,ids .egin()+iP); sks .erse(sks .egin()+iI,sks .egin()+iP);

}; };

void seurity prie historyXXerse efore(const int i = index of lst dte efore(d); if (i>=0) { // returns -1 if not there

dte& d)

i++;// the erase does not delete the last one, so dtes .erse(dtes .egin(),dtes .egin()+i); trdes .erse(trdes .egin(),trdes .egin()+i); ids .erse(ids .egin(),ids .egin()+i); sks .erse(sks .egin(),sks .egin()+i);

add one.

}; };

void seurity prie historyXXerse fter(const int i = index of (rst dte fter(d); if (i>=0) { // returns -1 if not there

dte& d)

dtes .erse(dtes .egin()+i,dtes .end()); trdes .erse(trdes .egin()+i,trdes .end()); ids .erse(ids .egin()+i,ids .end()); sks .erse(sks .egin()+i,sks .end());

}; };

C++ Code 5.5:

Erasing

25

#include "security_price_history.h"

bool seurity prie historyXXontins(const dte& d) const return inry serh(dtes .egin(),dtes .end(),d);
};

int

if (!ontins(d)) return 1; for (int i=0;i<dtes .size();++i){ if (dtes [i]==d) return i;


}; };

// this routine returns the index at which date d is, or -1 if not found.

seurity prie historyXXindex of dte(const dte& d)

const

return int

1;

if (!d.vlid()) return 1; if (d>=lst dte()) return 1; if (d<(rst dte()) return 0; for (int i=0;i<dtes .size();++i){ if (dtes [i]>d) return i;
};

seurity prie historyXXindex of (rst dte fter(const dte& d)

const

return
};

1;

int

if (!d.vlid()) return 1; if (d<=(rst dte()) return 1; if (d>lst dte()) return index of for (int i=0;i<dtes .size();++i){ if (dtes [i]>=d) return i1;
};

seurity prie historyXXindex of lst dte efore(const dte& d) dte(lst dte());

const

return
};

1;

C++ Code 5.6:

Searching

26

Chapter 6

Stock price history


The following class is used when we have a lot of historical data about stocks. Given price observations, do a lot of various calculations and pulling of various data, as well as printing various reports.

6.1 Stock history


The purpose of the stock_price_history class is to hold a price history for a stock, with a number of special functions for that purpose. The class is made by adding data and functions to the base class security_price_history. The reason the general security price history class is not enough, is the problem that dividends and other adjustments need to accounted for in returns calculations.

6.2 Header le


6.2.1 stock_price_history.h
Note that a lot of the functionality of the class is inherited from security_price_history

27

#ifndef ygu sgi rsy r #include "security_price_history.h" #include "dated_obs.h"

class stok private: public:

prie history X

public

seurity prie history


;

{ // most of the functionality is inherited from security price history

dted oservtions dividends ; dted oservtions djustments

stok prie history(); stok prie history(const stok prie history&); stok prie history operator = (const stok prie history&); stok prie history(){ ler(); }; void ler(); empty()

bool void void int


dte

///////////////////// dividends //////////////////////////

const;

double bool int double bool double void void int

dd dividend (const dte&, const double&); remove dividend (const dte&); no dividends() const; dividend dte(const int&) const; dividend(const int&) const; dividends etween(const dte&, const dte&) const; no dividends etween(const dte&, const dte&) const; totl dividends etween(const dte&, const dte&) const; dividend on(const dte&) const; dividend(const dte&) const;

///// adjustments ///////////////////////////////

dd djustment (const dte&, const double&); remove djustment (const dte&); no djustments() const; dte djustment dte(const int& i) const; double djustment(const int& i) const; bool djustments etween(const dte& dI, const dte& dP) const; int no djustments etween(const dte& dI, const dte& dP) const; double ggregted djustments etween(const dte& dI, const dte& dP) bool djustment on(const dte& d) const; double djustment(const dte& d) const; oservtions oservtions oservtions oservtions oservtions oservtions

const;

};

dted dted dted dted dted dted

dily pries (const stok prie history& st); dily pries (const stok prie history& st, const dte& from, const dte& to); dily trde pries (const stok prie history& st); dily trde pries (const stok prie history& st, const dte& from, const dte& to); monthly pries (const stok prie history& st); nnul pries (const stok prie history& st);

dted oservtions dividends(const stok prie history&); dted oservtions dividends(const stok prie history&, const dte& dI,

const

dte& dP); dte& dP);

dted oservtions djustments(const stok prie history&); dted oservtions djustments(const stok prie history&, const dte& dI, #dene ygu sgi rsy r #endif

const

Header le 6.1:

Dene all class elements

28

6.3 Implementation
#include "stock_price_history.h"

const double

wssxq yf

1;

// Assumption: Prices are positive. Negative prices are missing observations.


};

stok prie historyXXstok prie history(){;

stok prie historyXXstok prie history(const stok prie history& sh)X seurity prie history(sh){ dividends .ler(); for (unsigned i=0;i<sh.no dividends();++i) dd dividend(sh.dividend dte(i), sh.dividend(i)); djustments .ler(); for (unsigned i=0;i<sh.no djustments();++i) dd djustment(sh.djustment dte(i), sh.djustment(i));
};

stok prie history stok prie historyXX operator= (const stok prie history& sh) ler(); seurity prie historyXXopertor=(sh); for (unsigned i=0;i<sh.no dividends();++i) dd dividend(sh.dividend dte(i), sh.dividend(i)); for (unsigned i=0;i<sh.no djustments();++i) dd djustment(sh.djustment dte(i), sh.djustment(i));

return *this;

};

void

stok prie historyXXler() { seurity prie historyXXler(); dividends .ler(); djustments .ler();

};

bool stok prie historyXXempty() const { if (no dividends()>0) return false; if (no djustments()>0) return false; return seurity prie historyXXempty();
};

C++ Code 6.1:

Basic operations

29

#include "stock_price_history.h"

int stok prie historyXXno dividends() const { return dividends .size(); }; dte stok prie historyXXdividend dte(const int& i) const { return dividends .dte t(i); }; double stok prie historyXXdividend(const int& i) const { return dividends .element t(i); }; bool
stok prie historyXXdividend on(const dte& d) dte& d)

// querying

const const

{ {

return

dividends .ontins(d);

};

double stok prie historyXXdividend(const double div = dividends .element t(d); if (div>0) return div; return 0.0;
};

void
};

stok prie historyXXdd dividend(const dte& dividend dte, dividends .insert(dividend dte,dividend mount);

const double&

dividend mount)

void bool

stok prie historyXXremove dividend(const dte& dividend dte)

dividends .remove(dividend dte);};

return false;
};

stok prie historyXXdividends etween(const dte& dI, const dte& dP) dte (rst, lst; if (dI<dP) { (rst=dI; lst=dP; } else { (rst=dP; lst=dI; }; if ( dividends .no os etween((rst,lst)>0) return true;

const

int

stok prie historyXXno dividends etween(const dte& dI, const dte& dP) dte (rst, lst; if (dI<dP) { (rst=dI; lst=dP; } else { (rst=dP; lst=dI; }; return dividends .no os etween((rst,lst); dte& dI,

const

};

double stok prie historyXXtotl dividends etween(const if (!dividends etween(dI,dP)) return 0;

const

dte& dP)

const

dte (rst, lst; if (dI<dP) { (rst=dI; lst=dP; } else { (rst=dP; lst=dI; }; double tot dividend = 0.0; for (int i=0; i<dividends .size(); ++i){ if ( (dividends .dte t(i)>(rst) && (dividends .dte t(i)<=lst) tot dividend += dividends .element t(i);
};

) {

}; };

return

tot dividend;

dted oservtions dividends(const stok prie history& sphist, const dte& dI, dted oservtions dividends; for (int i=0;i<sphist.no dividends();++i){ dte d=sphist.dividend dte(i); if ( (d>=dI) && (d<=dP) && (sphist.dividend(i)>=0.0) ){ dividends.insert(d,sphist.dividend(i));
}; }; };

const

dte& dP){

return

dividends;

dted oservtions dividends(const stok prie history& sphist){ return dividends(sphist,sphist.(rst dte(),sphist.lst dte());
};

C++ Code 6.2:


30

Dividends

#include "stock_price_history.h"

int stok prie historyXXno djustments() const{ return djustments .size(); }; dte stok prie historyXXdjustment dte(const int& i) const{ return djustments .dte t(i); }; double stok prie historyXXdjustment(const int& i) const { return djustments .element t(i);}; bool stok prie historyXXdjustment on(const dte& d) const { for (int i=0; i<djustments .size(); ++i) { if (djustments .dte t(i)==d) return true;
}; };

return false; double stok prie historyXXdjustment(const dte& d) const { for (int i=0; i<djustments .size(); ++i){ if (djustments .dte return 0.0;
};

t(i)==d)

return

djustments .element t(i);

};

void stok prie historyXXdd djustment ( const if (djustments .ontins(djustment dte)) {


} };

dte& djustment dte,

const double&

dj ftor)

djustments .insert(djustment dte, djustments .element t(djustment dte)*dj ftor);


{

else void bool

djustments .insert(djustment dte,dj ftor);

};

stok prie historyXXremove djustment(const dte& djustment dte){ djustments .remove(djustment dte);

};

stok prie historyXXdjustments etween(const dte& dI, const dte& dP) dte (rst, lst; if (dI<dP) { (rst=dI; lst=dP; } else { (rst=dP; lst=dI; }; if (djustments .no os etween((rst,lst)>0) return true;

const{

return false;
};

int

stok prie historyXXno djustments etween(const dte& dI, dte (rst, lst; if (dI<dP) { (rst=dI; lst=dP; } else { (rst=dP; lst=dI; }; return djustments .no os etween((rst,lst);

const

dte& dP)

const

};

double

stok prie historyXXggregted djustments etween(const dte& dI, const dte& dP) dte (rst, lst; if (dI<dP) { (rst=dI; lst=dP; } else { (rst=dP; lst=dI; }; double tot djustments=1.0; for (int i=0; i<djustments .size(); ++i){ if ( (djustments .dte t(i)>(rst) && (djustments .dte t(i)<=lst) ) { tot djustments *= djustments .element t(i);
};

const

}; };

return

tot djustments;

dted oservtions djustments(const stok prie history& sphist, const dte& dI, dted oservtions djustments; for (int i=0;i<sphist.no djustments();++i){ dte d=sphist.djustment dte(i); if ( (d>=dI) && (d<=dP) && (sphist.djustment(i)>0) ){ djustments.insert(d,sphist.djustment(i));
}; }; };

const

dte& dP){

return

djustments;

dted oservtions djustments(const stok prie history& sphist){ return djustments(sphist,sphist.(rst dte(),sphist.lst dte());
};

C++ Code 6.3:


31

Adjustments

You might also like