#ifndef DECIDER_H_ #define DECIDER_H_ #include "helpers.h" #include "network.h" #include #include class decider { public: double start_money; unsigned start_stock; virtual int decide(double price, double money, unsigned stock) = 0; virtual void reset(double price) = 0; virtual ~decider() { } }; class macd_decider { private: std::size_t limit; protected: buffer prices; buffer macd; buffer signal; unsigned count = 0; public: double start_price; macd_decider(std::size_t limit = 1000); virtual void process(double price); virtual void reset(double price); }; template class neural_decider : public decider, macd_decider { public: using network_t = network; using self_t = neural_decider; network_t network; vector feedback; neural_decider() : network(), macd_decider() { } neural_decider(typename network_t::normalizer_t normalizer) : network(normalizer), macd_decider() { } virtual int decide(double price, double money, unsigned stock) { process(price); if (count < 35) return 0; auto input = prepare(money, stock); auto result = network.evaluate(input); double buy = result.get(0, 0); double sell = result.get(1, 0); double amount = buy - sell; amount -= sign(amount) * .5; for (int i = 0; i < r; i++) { feedback.set(i, 0, result.get(i + 2, 0)); } return abs(buy - sell) <= .5 ? 0 : amount * start_stock; } std::ostream& save(std::ostream& stream) { network.save(stream); return stream; } void load(std::istream& stream) { network.load(stream); } virtual void reset(double price) override { macd_decider::reset(price); } virtual ~neural_decider() { } self_t combine(self_t smth, typename network_t::combiner_t combiner = [](const double& a, const double& b) { return .35*a + .65*b; }) { self_t result; result.network = network.combine(smth.network, combiner); result.start_money = start_money; result.start_stock = start_stock; return result; } self_t mutate(typename network_t::normalizer_t mutator) { self_t result; result.network = network.mutate(mutator); result.start_money = start_money; result.start_stock = start_stock; return result; } private: typename network_t::input prepare(double money, unsigned stock) { vector state = { { (prices[0] * stock + money) / (start_money + start_stock * start_price) }, { (double)stock / this->start_stock } }; vector prices; vector tech; // prices are normalized as percent change value for (int j = 0; j < p; j++) { auto diff = this->prices[j] - this->prices[j+1]; prices.set(j, 0, diff / this->prices[j+1]); } int i = 0; for (int j = 0; j < m; j++, i++) { tech.set(i, 0, macd[j]); } for (int j = 0; j < s; j++, i++) { tech.set(i, 0, signal[j]); } // analytic data is normalized in its own domain tech = normalize(tech); return concat(concat(prices, tech), concat(feedback, state)); } }; #endif