Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ add_subdirectory(rnn)
add_subdirectory(rnn_tests)
add_subdirectory(rnn_examples)

add_subdirectory(strategic)

# add_subdirectory(opencl)

add_subdirectory(weights)
Expand Down
2 changes: 2 additions & 0 deletions strategic/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_executable(evaluate_strategy evaluate_strategy.cxx forecaster.cxx trivial_forecaster.cxx strategy.cxx simple_stock_strategy.cxx state.cxx portfolio.cxx oracle.cxx portfolio_oracle.cxx)
target_link_libraries(evaluate_strategy examm_strategy exact_common exact_time_series exact_weights examm_nn pthread)
99 changes: 99 additions & 0 deletions strategic/evaluate_strategy.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <map>
using std::map;

#include <string>
using std::string;

#include <vector>
using std::vector;

#include "common/arguments.hxx"
#include "common/log.hxx"
#include "rnn/rnn_genome.hxx"
#include "time_series/time_series_new.hxx"

#include "forecaster.hxx"
#include "oracle.hxx"
#include "state.hxx"
#include "strategy.hxx"


vector<string> arguments;

void print_values(string name, const map<string, double> &values) {
Log::debug("%s:\n", name.c_str());
for (auto const& [key, value] : values) {
Log::debug("\t%s = %lf\n", key.c_str(), value);
}
}



int main(int argc, char** argv) {
arguments = vector<string>(argv, argv + argc);

Log::initialize(arguments);
Log::set_id("main");

string output_directory;
get_argument(arguments, "--output_directory", true, output_directory);

int32_t time_offset = 1;
get_argument(arguments, "--time_offset", false, time_offset);

vector<string> input_parameter_names, output_parameter_names;
get_argument_vector(arguments, "--input_parameter_names", true, input_parameter_names);
get_argument_vector(arguments, "--output_parameter_names", true, output_parameter_names);

string time_series_filename;
get_argument(arguments, "--time_series_filename", true, time_series_filename);
TimeSeriesNew *time_series = new TimeSeriesNew(time_series_filename, input_parameter_names, output_parameter_names);

Forecaster* forecaster = Forecaster::initialize_from_arguments(arguments, time_series->get_input_parameter_names(), time_series->get_output_parameter_names());
Strategy* strategy = Strategy::initialize_from_arguments(arguments);
Oracle* oracle = Oracle::initialize_from_arguments(arguments);

if (argument_exists(arguments, "--normalize")) {
//Normalizer *normalizer = Normalizer::initialize_from_arguments(arguments);
//normalizer->normalize(time_series_new);
}

double current_reward = 0.0;
double reward = 0.0;

map<string, double> inputs;
map<string, double> next_inputs;

for (int32_t i = 0; i < time_series->get_number_rows() - time_offset; i++) {
time_series->get_inputs_at(i, inputs);
time_series->get_inputs_at(i + time_offset, next_inputs);

if (Log::at_level(Log::DEBUG)) print_values("inputs", inputs);

Log::info("getting forecast!\n");

map<string, double> forecast = forecaster->forecast(inputs);
if (Log::at_level(Log::DEBUG)) print_values("forecast", forecast);

strategy->make_move(inputs, forecast);

State *state = strategy->get_state();
current_reward = oracle->calculate_reward(state, next_inputs);
Log::info("reward for move is: %lf\n", current_reward);

//strategy->report_reward(current_reward);

//reward += current_reward;

delete state;
}

delete time_series;
delete forecaster;
delete strategy;
delete oracle;


Log::release_id("main");
return 0;
}
31 changes: 31 additions & 0 deletions strategic/forecaster.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "common/arguments.hxx"
#include "common/log.hxx"

#include "forecaster.hxx"
#include "trivial_forecaster.hxx"

Forecaster::Forecaster(const vector<string> &_input_parameter_names, const vector<string> &_output_parameter_names) : input_parameter_names(_input_parameter_names), output_parameter_names(_output_parameter_names) {
}

vector<string> Forecaster::get_output_parameter_names() const {
return output_parameter_names;
}

vector<string> Forecaster::get_input_parameter_names() const {
return input_parameter_names;
}

Forecaster* Forecaster::initialize_from_arguments(const vector<string> &arguments, const vector<string> &input_parameter_names, const vector<string> &output_parameter_names) {

string forecaster_type;
get_argument(arguments, "--forecaster_type", true, forecaster_type);

if (forecaster_type == "trivial") {
return new TrivialForecaster(arguments, input_parameter_names, output_parameter_names);

} else {
Log::fatal("unknown forecaster type '%s', cannot evaluate strategy.\n\n", forecaster_type.c_str());
exit(1);
}

}
71 changes: 71 additions & 0 deletions strategic/forecaster.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef FORECASTER_HXX
#define FORECASTER_HXX

#include <map>
using std::map;

#include <string>
using std::string;

#include <vector>
using std::vector;



class Forecaster {
protected:
vector<string> input_parameter_names;
vector<string> output_parameter_names;

public:
/**
* Initializes the abstract class of forecaster by setting its input and output parameter names
* \param input_parameter_names are the input columns to use by the forecaster
* \param output_parameter names are the columns forecasted by the forecaster
*/
Forecaster(const vector<string> &_input_parameter_names, const vector<string> &_output_parameter_names);

/**
* Provide a virtual destructor for this virtual class
*/
virtual ~Forecaster() = default;

/**
* \return the input parameter names for the forecaster
*/
vector<string> get_input_parameter_names() const;

/**
* \return the output parameter names for the forecaster
*/
vector<string> get_output_parameter_names() const;

/**
* Creates one of any of the potential sublcasses of the Forecaster class given
* command line arguments.
*
* \param arguments is the vector of command line arguments
* \param input_parameter_names are the input parameter names to be used (the ones in the arguments
* may be regular expressions so we use the ones from the time series object).
* \param output_parameter_names are the output parameter names to be used (the ones in the arguments
* may be regular expressions so we use the ones from the time series object).
*
* \return a pointer to a Forecaster object
*/
static Forecaster* initialize_from_arguments(const vector<string> &arguments, const vector<string> &input_parameter_names, const vector<string> &output_parameter_names);

/**
* Given the current context of the system, provide a forecast of what the next
* context is expected to be.
*
* \param context is a representation of the current context of the problem being worked
* on, e.g., the current time series values (used to predict the next or other future
* time series values).
*
* \return the forecasted vector of values
*/
virtual map<string, double> forecast(const map<string, double> &context) = 0;

};

#endif
20 changes: 20 additions & 0 deletions strategic/oracle.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "common/arguments.hxx"
#include "common/log.hxx"

#include "oracle.hxx"
#include "portfolio_oracle.hxx"

Oracle* Oracle::initialize_from_arguments(const vector<string> &arguments) {

string oracle_type;
get_argument(arguments, "--oracle_type", true, oracle_type);

if (oracle_type == "portfolio") {
return new PortfolioOracle(arguments);

} else {
Log::fatal("unknown oracle type '%s', cannot evaluate oracle.\n\n", oracle_type.c_str());
exit(1);
}

}
48 changes: 48 additions & 0 deletions strategic/oracle.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef STRATEGY_ORACLE_HXX
#define STRATEGY_ORACLE_HXX

#include <map>
using std::map;

#include <string>
using std::string;

#include <vector>
using std::vector;

#include "state.hxx"

class Oracle {
public:
/**
* Creates one of any of the potential sublcasses of the Oracle class given
* command line arguments.
*
* \param arguments is the vector of command line arguments
*
* \return a pointer to an Oracle object
*/
static Oracle* initialize_from_arguments(const vector<string> &arguments);


/**
* A default destructor for this virtual class.
*/
virtual ~Oracle() = default;

/**
* Calculates the reward given the state of a strategy and the current state (context) of
* the system.
*
* \param state is some subclass of the State class, representing the state of the strategy
* needed to calculate a reward.
* \param context is the context of the system for the next time step after it made its
* last move.
*
* \return a reward value representing how good the strategy's current state is compared
* to its previous state.
*/
virtual double calculate_reward(State *state, const map<string, double> &context) = 0;
};

#endif
25 changes: 25 additions & 0 deletions strategic/portfolio.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "common/log.hxx"

#include "portfolio.hxx"


Portfolio::Portfolio(double _current_money_pool, string _price_suffix) : current_money_pool(_current_money_pool), price_suffix(_price_suffix) {
}

void Portfolio::add_stock(string stock, double purchased_shares) {
shares[stock] = purchased_shares;
}

double Portfolio::calculate_value(const map<string, double> &context) {
double value = current_money_pool;

for (auto const& [stock, purchased_shares] : shares) {
Log::info("getting price for %s with %lf purchased shares.\n", stock.c_str(), purchased_shares);

double price = context.at(stock + price_suffix);

value += price * purchased_shares;
}

return value;
}
53 changes: 53 additions & 0 deletions strategic/portfolio.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef STOCK_PORTFOLIO_HXX
#define STOCK_PORTFOLIO_HXX

#include <map>
using std::map;

#include <string>
using std::string;

#include "state.hxx"


class Portfolio : public State {
private:
//The strategy's current money pool
double current_money_pool;

//The suffix for price column names determined by the stock strategy.
string price_suffix;

//A map of stock names to how many shares are owned.
map<string, double> shares;

public:
/**
* Initialize the portfolio with how much money is available.
*
* \param _current_money_pool is how much unspent money the portfolio has.
* \param price_suffix is the suffix for column names for stock prices.
*/
Portfolio(double _current_money_pool, string price_suffix);

/**
* Used to specify how much of each stock has been purchased (if any).
*
* \param stock is the stock ticker name to add
* \param purchased shares is how many shares are owned of the stock
*/
void add_stock(string stock, double purchased_shares);

/**
* Calculate how much money we have available in our money pool plus the
* values of all our stocks.
*
* \param context is the current state which has all the current stock ticker
* prices.
*
* \return the total worth of our stocks and current money pool
*/
double calculate_value(const map<string, double> &context);
};

#endif
Loading