Commit 1c290c45 by Imanol Pérez Committed by GitHub

Upload files

parent c6339856
#include "Exception.hpp"
#include <iostream>
Exception::Exception(std::string sum, std::string prob)
{
problem = prob;
summary = sum;
std::cerr << "** Exception ("<<summary<<") **\n";
std::cerr << "Problem: " << problem << "\n\n";
}
#ifndef EXCEPTIONDEF
#define EXCEPTIONDEF
#include <string>
class Exception
{
public:
std::string problem, summary;
Exception(std::string sum, std::string problem);
void DebugPrint();
};
#endif
File added
#include <iostream>
#include "Organism.hpp"
#include <algorithm>
//////////////////////////////////////////////////////
// //
// Class for a single organism //
// //
// Imanol Perez //
// January 201 //
// //
//////////////////////////////////////////////////////
Organism::Organism() {
}
Organism::Organism(int i, int j)
{
/*
Constructor
*/
//Updates moving averages, which must be greater or equal to 0.
MA1=std::max(i, 0);
MA2=std::max(j, 0);
returns=0.0;
}
Organism::~Organism() { }
void Organism::DisposeObject() {
delete this;
}
bool Organism::isNull(void) {
/*
Checks if the organism is null.
An organism is considered null if both moving
averages are zero.
*/
return MA1==0 && MA2==0;
}
std::ostream& operator<<(std::ostream& output, Organism& org) {
/*
Allows to output an object of class Organism.
*/
if (org.returns!=0.0) output<<"Returns: "<<org.returns<<"\n";
output<<"First Moving Average: "<<org.MA1<<"\nSecond Moving Average: "<<org.MA2<<"\n";
return output;
}
#ifndef ORGANISMDEF
#define ORGANISMDEF
//////////////////////////////////////////////////////
// //
// Class for a single organism //
// //
// Imanol Perez //
// January 2017 //
// //
//////////////////////////////////////////////////////
#include <cmath>
#include "Exception.hpp"// This class throws errors using the class "error"
#include <algorithm>
class Organism;
class Organism
{
public:
int MA1; // first moving average
int MA2; // second moving average
double returns; // returns created by this organism
Organism(); // constructor
Organism(int, int); // constructor
~Organism();
void DisposeObject();
bool isNull(void); // checks if organism is null
//output
friend std::ostream& operator<<(std::ostream&, Organism&);
};
#endif
File added
#include <iostream>
#include "Quote.hpp"
#include "Stock.hpp"
#include "Organism.hpp"
#include "Population.hpp"
#include <algorithm>
#include "global.hpp"
#include <fstream>
//////////////////////////////////////////////////////
// //
// Class for the population //
// //
// Imanol Perez //
// January 2017 //
// //
//////////////////////////////////////////////////////
Population::Population() {
}
Population::Population(Stock S, int s, int ma)
{
/*
Constructor. Creates the object of class Population.
*/
size=s;
stock=S;
filled=0;
max_ma=ma;
organisms=new Organism[size];
// We fill in the population with null organisms.
for (int i=0; i<size; i++)
{
organisms[i] = Organism(0, 0); // Quotes with moving averages 0 are considered Null
}
}
void Population::addOrganism(Organism org) {
/*
We add the organism org to the population. If the population is full, throw exception.
*/
if (filled==size) throw Exception("Population limit reached", "There is no space to store more organisms");
organisms[filled]=org;
filled++;
}
double Population::fitness(Stock& s, int n, int start) {
/*
Fitness function that will work as the criteria to select the top 20% of organisms.
*/
if (n<0 or n>=filled) throw Exception("Index out of bounds", "The index is negative or too big");
double returns=1;
// Instead of calculating returns over all the interval available, it only
// runs through the interval specified in s, which was picked randomly.
// The objective is to have organisms that perform well in any random
// period of time.
for (int i=start; i<s.getFilled()-1; i++) {
// We run the algorithm: buy or sell S&P 500 depending on whether a mean average is larger
// or less than the other mean average.
if (s.sample(i-organisms[n].MA1+1, i).mean()>s.sample(i-organisms[n].MA2+1, i).mean()) {
returns*=s.getData(i+1).getPrice()/s.getData(i).getPrice();
} else {
returns*=s.getData(i).getPrice()/s.getData(i+1).getPrice();
}
}
return returns;
}
double Population::returns(int n) {
/*
Gives the overall returns of the organism n
*/
if (n<0 or n>=filled) throw Exception("Index out of bounds", "The index is negative or too big");
double returns=1;
for (int i=max_ma; i<stock.getFilled()-1; i++) {
if (stock.sample(i-organisms[n].MA1+1, i).mean()>stock.sample(i-organisms[n].MA2+1, i).mean()) {
returns*=stock.getData(i+1).getPrice()/stock.getData(i).getPrice();
} else {
returns*=stock.getData(i).getPrice()/stock.getData(i+1).getPrice();
}
}
return returns;
}
Population Population::top20(void) {
/*
It returns the top 20% of the organisms of the population
*/
// How many organisms form the 20% of the population?
int top20=floor(0.2*filled);
Population population=Population(stock, top20, max_ma);
{
// Select a random interval of length FITNESS_TIME_INTERVAL,
// and take a sample of S&P 500 for this interval.
// The objective is to obtain organisms that perform
// well in any random period of time.
int r=rand()%(stock.getFilled()-FITNESS_TIME_INTERVAL);
Stock S=stock.sample(std::max(0, r-max_ma), r+FITNESS_TIME_INTERVAL);
// We calculate fitness score of the organisms
for (int j=0; j<filled; j++) {
organisms[j].returns=fitness(S, j, max_ma);
}
}
// We store in the variable population the top 20% of the organisms
for (int i=0; i<top20; i++) {
for (int j=i+1; j<filled; j++) {
if (organisms[j].returns>organisms[i].returns) {
// Switch values between organisms[i] and organisms[j]
Organism temp=organisms[i];
organisms[i]=organisms[j];
organisms[j]=temp;
}
}
population.addOrganism(organisms[i]);
}
return population;
}
void Population::crossover(void) {
/*
Performs a crossover of the top 20% of the population to generate children.
*/
{
Population top= top20();
filled=0;
for (int i=0; i<top.size; i++) {
addOrganism(top.organisms[i]);
}
// We want to have a population of static size. Thus, while the population
// size is not the original one, create new children.
// To produce a children, pick two random and distinct parents. Take the
// first moving average of one of them, and the second moving average of
// the other one, and create a child.
while (filled!=size) {
int r1=rand()%top.size;
int r2=rand()%top.size;
if (r1==r2) continue;
if (rand()%2==0) {
addOrganism(Organism(top.organisms[r1].MA1, top.organisms[r2].MA2));
} else {
addOrganism(Organism(top.organisms[r2].MA1, top.organisms[r1].MA2));
}
}
}
}
void Population::mutation(void) {
/*
Mutates some of the children.
*/
int top20=floor(0.2*filled);
// We do not mutate the first 20% of the population, as these are the parents.
// We only want to mutate children.
for (int i=top20; i<filled; i++) {
// Not all children are mutated. A children will suffer from a mutation
// with probability MUTATION_PROBABILITY. In this case, we update
// the moving average of the children with a random value between 1
// and max_ma.
if ((double)rand()/(RAND_MAX)<=MUTATION_PROBABILITY) {
organisms[i].MA1=1+rand()%(max_ma+1);
}
if ((double)rand()/(RAND_MAX)<=MUTATION_PROBABILITY) {
organisms[i].MA2=1+rand()%(max_ma+1);
}
// Check if the organism i is in population, as we do not
// want to two identical children.
for (int j=0; j<i; j++) {
if (organisms[i].MA1==organisms[j].MA1 && organisms[i].MA2==organisms[j].MA2) {
// Prevent from moving to children i+1, in order
// to go to the mutation loop again with children i.
i-=1;
break;
}
}
}
}
std::ostream& operator<<(std::ostream& output, Population& population) {
/*
Allows to output an object of class Population.
*/
output<<"Population: "<<population.filled<<"\n";
output<<"Stock: "<<population.stock.getName()<<"\n\n";
for (int i=0; i<population.size; i++) {
if (population.organisms[i].isNull()) continue;
output<<"Organism no. "<<(i+1)<<":\n"<<population.organisms[i]<<"\n";
}
return output;
}
\ No newline at end of file
#ifndef POPULATIONDEF
#define POPULATIONDEF
//////////////////////////////////////////////////////
// //
// Class for the population //
// //
// Imanol Perez //
// December 2016 //
// //
//////////////////////////////////////////////////////
#include <cmath>
#include "Exception.hpp"// This class throws errors using the class "error"
#include "Quote.hpp"
#include "Stock.hpp"
#include "Organism.hpp"
#include <algorithm>
class Population;
class Population
{
public:
Population(); // constructor
Population(Stock, int, int); // constructor
void addOrganism(Organism); // Add organism
double fitness(Stock&, int, int); // fitness function: gives the returns of the organism in a random period of a specific length
double returns(int); // fitness function: gives the returns of the organism
Population top20(void); // returns the strongest 20% organisms
void crossover(void); // performs crossover
void mutation(void); // performs mutation of the new generation
Stock stock;
Organism* organisms;
int size, filled, max_ma;
//output
friend std::ostream& operator<<(std::ostream&, Population&);
};
#endif
File added
#include <iostream>
#include "Quote.hpp"
#include <ctime>
//////////////////////////////////////////////////////
// //
// Class that handles the quotes //
// of a certain stock in a certain date //
// //
// Imanol Perez //
// January 2017 //
// //
//////////////////////////////////////////////////////
Quote::Quote() {
}
Quote::Quote(std::string name, double price, std::string date)
{
// The price of the stock cannot be negative.
if (price<0) {
throw Exception("Negative price",
"The sprice of the stock must non negative");
}
// date must have the format YYYY/MM/DD
struct tm tm;
if (date!="0000/00/00" && !strptime(date.c_str(), "%Y/%m/%d", &tm)) {
throw Exception("Invalid date format", "Date format must be YYYY/MM/DD");
}
mPrice=price;
mName=name;
mDate=date;
}
std::string Quote::getName(void) {
return mName;
}
double Quote::getPrice(void) {
return mPrice;
}
void Quote::setPrice(double price) {
// The price of the stock cannot be negative.
if (price<0) {
throw Exception("Negative price",
"The sprice of the stock must non negative");
}
mPrice=price;
}
std::string Quote::getDate(void) {
/*
Returns the date of the quote
*/
return mDate;
}
void Quote::setDate(std::string date) {
/*
Updates the date of the stock
*/
// date must have format YYYY/MM/DD
struct tm tm;
if (date!="0000/00/00" && !strptime(date.c_str(), "%Y/%m/%d", &tm)) {
throw Exception("Invalid date format", "Date format must be YYYY/MM/DD");
}
mDate=date;
}
void Quote::increasePrice(double change) {
/*
Increases/decreases the price of the stock
*/
mPrice+=change;
}
void Quote::addReturn(double percentage) {
/*
We increase or decrease the price of the stock, by a determined percentage
*/
mPrice*=1+percentage;
}
bool Quote::isNull(void) {
/*
Checks if the quote is null
*/
return mDate=="0000/00/00";
}
std::ostream& operator<<(std::ostream& output, Quote& q) {
/*
Used to display a nice output of the class
*/
std::string name = q.getName();
double price = q.getPrice();
std::string date=q.getDate();
output<<"Name: "<<name<<"\nPrice: "<<price<<"\nDate: "<<date<<"\n";
return output;
}
#ifndef QUOTEDEF
#define QUOTEDEF
//////////////////////////////////////////////////////
// //
// Class that handles the quotes //
// of a certain stock in a certain date //
// //
// Imanol Perez //
// January 2017 //
// //
//////////////////////////////////////////////////////
#include <cmath>
#include "Exception.hpp"// This class throws errors using the class "error"
#include <ctime>
class Quote;
class Quote
{
private:
// member variables
double mPrice; // price of the stock
std::string mName; // name of the stock
std::string mDate; // date of the quote
public:
Quote(); // constructor
Quote(std::string, double, std::string); // constructor
std::string getName(void); // Get stock's name
double getPrice(void); // Get stock's price
void setPrice(double); // Set stock's price
std::string getDate(void); // Get stock's date
void setDate(std::string); // Set stock's date
void increasePrice(double); // Increase stock's price
void addReturn(double); // Add return (in percentage terms)
bool isNull(void); // Returns true if the quote is null
//output
friend std::ostream& operator<<(std::ostream&, Quote&);
};
#endif
File added
2006/12/18 1422.48
2006/12/19 1425.55
2006/12/20 1423.53
2006/12/21 1418.3
2006/12/22 1410.76
2006/12/26 1416.9
2006/12/27 1426.84
2006/12/28 1424.73
2006/12/29 1418.3
2007/01/03 1416.6
2007/01/04 1418.34
2007/01/05 1409.71
2007/01/08 1412.84
2007/01/09 1412.11
2007/01/10 1414.85
2007/01/11 1423.82
2007/01/12 1430.73
2007/01/16 1431.9
2007/01/17 1430.62
2007/01/18 1426.37
2007/01/19 1430.5
2007/01/22 1422.95
2007/01/23 1427.99
2007/01/24 1440.13
2007/01/25 1423.9
2007/01/26 1422.18
2007/01/29 1420.62
2007/01/30 1428.82
2007/01/31 1438.24
2007/02/01 1445.94
2007/02/02 1448.39
2007/02/05 1446.99
2007/02/06 1448
2007/02/07 1450.02
2007/02/08 1448.31
2007/02/09 1438.06
2007/02/12 1433.37
2007/02/13 1444.26
2007/02/14 1455.3
2007/02/15 1456.81
2007/02/16 1455.54
2007/02/20 1459.68
2007/02/21 1457.63
2007/02/22 1456.38
2007/02/23 1451.19
2007/02/26 1449.37
2007/02/27 1399.04
2007/02/28 1406.82
2007/03/01 1403.17
2007/03/02 1387.17
2007/03/05 1374.12
2007/03/06 1395.41
2007/03/07 1391.97
2007/03/08 1401.89
2007/03/09 1402.85
2007/03/12 1406.6
2007/03/13 1377.95
2007/03/14 1387.17
2007/03/15 1392.28
2007/03/16 1386.95
2007/03/19 1402.06
2007/03/20 1410.94
2007/03/21 1435.04
2007/03/22 1434.54
2007/03/23 1436.11
2007/03/26 1437.5
2007/03/27 1428.61
2007/03/28 1417.23
2007/03/29 1422.53
2007/03/30 1420.86
2007/04/02 1424.55
2007/04/03 1437.77
2007/04/04 1439.37
2007/04/05 1443.76
2007/04/09 1444.61
2007/04/10 1448.39
2007/04/11 1438.87
2007/04/12 1447.8
2007/04/13 1452.85
2007/04/16 1468.47
2007/04/17 1471.48
2007/04/18 1472.5
2007/04/19 1470.73
2007/04/20 1484.35
2007/04/23 1480.93
2007/04/24 1480.41
2007/04/25 1495.42
2007/04/26 1494.25
2007/04/27 1494.07
2007/04/30 1482.37
2007/05/01 1486.3
2007/05/02 1495.92
2007/05/03 1502.39
2007/05/04 1505.62
2007/05/07 1509.48
2007/05/08 1507.72
2007/05/09 1512.58
2007/05/10 1491.47
2007/05/11 1505.85
2007/05/14 1503.15
2007/05/15 1501.19
2007/05/16 1514.14
2007/05/17 1512.75
2007/05/18 1522.75
2007/05/21 1525.1
2007/05/22 1524.12
2007/05/23 1522.28
2007/05/24 1507.51
2007/05/25 1515.73
2007/05/29 1518.11
2007/05/30 1530.23
2007/05/31 1530.62
2007/06/01 1536.34
2007/06/04 1539.18
2007/06/05 1530.95
2007/06/06 1517.38
2007/06/07 1490.72
2007/06/08 1507.67
2007/06/11 1509.12
2007/06/12 1493
2007/06/13 1515.67
2007/06/14 1522.97
2007/06/15 1532.91
2007/06/18 1531.05
2007/06/19 1533.7
2007/06/20 1512.84
2007/06/21 1522.19
2007/06/22 1502.56
2007/06/25 1497.74
2007/06/26 1492.89
2007/06/27 1506.34
2007/06/28 1505.71
2007/06/29 1503.35
2007/07/02 1519.43
2007/07/03 1524.87
2007/07/05 1525.4
2007/07/06 1530.44
2007/07/09 1531.85
2007/07/10 1510.12
2007/07/11 1518.76