WTF
This commit is contained in:
		
							parent
							
								
									3d83bb3f8f
								
							
						
					
					
						commit
						72fb76e8c2
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -38,3 +38,6 @@
 | 
			
		||||
*.ilg
 | 
			
		||||
*.ind
 | 
			
		||||
*.ist
 | 
			
		||||
 | 
			
		||||
/net/
 | 
			
		||||
*.net
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								common.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								common.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										4
									
								
								common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								common.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
#include "network.h"
 | 
			
		||||
#include "decider.h"
 | 
			
		||||
 | 
			
		||||
using current_decider = neural_decider<24, 16, 16, 32, 16>;
 | 
			
		||||
							
								
								
									
										13
									
								
								decider.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								decider.h
									
									
									
									
									
								
							@ -42,9 +42,6 @@ public:
 | 
			
		||||
 | 
			
		||||
    network_t network;
 | 
			
		||||
 | 
			
		||||
    double   start_money;
 | 
			
		||||
    unsigned start_stock;
 | 
			
		||||
 | 
			
		||||
    neural_decider() : network(), macd_decider() { }
 | 
			
		||||
    neural_decider(typename network_t::normalizer_t normalizer) 
 | 
			
		||||
        : network(normalizer), macd_decider()  { }
 | 
			
		||||
@ -64,6 +61,16 @@ public:
 | 
			
		||||
        return abs(buy - sell) <= .5 ? 0 : amount * start_stock / 10;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::ostream& save(std::ostream& stream) {
 | 
			
		||||
        network.save(stream);
 | 
			
		||||
 | 
			
		||||
        return stream;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void load(std::istream& stream) {
 | 
			
		||||
        network.load(stream);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void reset() override
 | 
			
		||||
    {
 | 
			
		||||
        macd_decider::reset();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								macd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								macd.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
#include "argh.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, const char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    argh::parser args;
 | 
			
		||||
    args.add_params({ "l", "low" });
 | 
			
		||||
    args.add_params({ "h", "high" });
 | 
			
		||||
    args.add_params({ "s", "signal" });
 | 
			
		||||
 | 
			
		||||
    args.parse(argc, argv);
 | 
			
		||||
 | 
			
		||||
    unsigned low, high, s;
 | 
			
		||||
 | 
			
		||||
    args({"l", "low"}, 12)   >> low;
 | 
			
		||||
    args({"h", "high"}, 26)  >> high;
 | 
			
		||||
    args({"s", "signal"}, 9) >> s;
 | 
			
		||||
 | 
			
		||||
    unsigned max = std::max({ low, high, s });
 | 
			
		||||
    buffer<double> prices(max);
 | 
			
		||||
    buffer<double> macd(max);
 | 
			
		||||
    buffer<double> signal(max);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    double price;
 | 
			
		||||
    std::cout << "no,price,macd,signal,delta" << std::endl;
 | 
			
		||||
    for (int i = 0; std::cin >> price; i++) {
 | 
			
		||||
        prices.add(price);
 | 
			
		||||
        double value = ema<double>(prices.begin(), prices.begin() + low) - ema<double>(prices.begin(), prices.begin() + high);
 | 
			
		||||
        macd.add(value);
 | 
			
		||||
        signal.add(ema<double>(macd.begin(), macd.begin() + s));
 | 
			
		||||
 | 
			
		||||
        std::cout << i << "," << prices[0] << "," << macd[0] << "," << signal[0] << "," << prices[1] - prices[0] << std::endl; 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										57
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								main.cpp
									
									
									
									
									
								
							@ -1,57 +0,0 @@
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
double expavg(const std::vector<double> &values, int start, int n) 
 | 
			
		||||
{
 | 
			
		||||
    double a = 1 - 2./(n + 1);
 | 
			
		||||
 | 
			
		||||
    double nominator = 0., denominator = 0.;
 | 
			
		||||
    double b = 1.;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < n; i++) {
 | 
			
		||||
        nominator += b*values[start - i];
 | 
			
		||||
        denominator += b;
 | 
			
		||||
 | 
			
		||||
        b *= a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return nominator / denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    int low = 12, high = 26, s = 9;
 | 
			
		||||
 | 
			
		||||
    if (argc >= 2) 
 | 
			
		||||
        low = std::atoi(argv[2]);
 | 
			
		||||
 | 
			
		||||
    if (argc >= 3) 
 | 
			
		||||
        high = std::atoi(argv[4]);
 | 
			
		||||
 | 
			
		||||
    if (argc >= 4) 
 | 
			
		||||
        s = std::atoi(argv[3]);
 | 
			
		||||
 | 
			
		||||
    std::vector<double> prices;
 | 
			
		||||
    double price;
 | 
			
		||||
 | 
			
		||||
    while (std::cin >> price) {
 | 
			
		||||
        prices.push_back(price);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<double> macd(prices.size());
 | 
			
		||||
    std::vector<double> signal(prices.size());
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < prices.size(); ++i) {
 | 
			
		||||
        macd[i]   = expavg(prices, i, std::min(i, low)) - expavg(prices, i, std::min(i, high));
 | 
			
		||||
        signal[i] = expavg(macd, i, std::min(i, s));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::cout << "price,macd,signal,delta" << std::endl;
 | 
			
		||||
    for (int i = 1; i < prices.size(); ++i) {
 | 
			
		||||
        std::cout << prices[i] << "," << macd[i] << "," << signal[i] << "," << prices[i] - prices[i-1] << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								matrix.h
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								matrix.h
									
									
									
									
									
								
							@ -159,6 +159,30 @@ class matrix
 | 
			
		||||
 | 
			
		||||
            return stream;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::ostream& save(std::ostream& stream)
 | 
			
		||||
        {
 | 
			
		||||
            T temp;
 | 
			
		||||
            for (int i = 0; i < m; ++i) {
 | 
			
		||||
                for (int j = 0; j < n; j++) {
 | 
			
		||||
                    temp = get(i, j);
 | 
			
		||||
                    stream.write(reinterpret_cast<char*>(&temp), sizeof(T));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return stream;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void load(std::istream& stream)
 | 
			
		||||
        {
 | 
			
		||||
            T temp;
 | 
			
		||||
            for (int i = 0; i < m; ++i) {
 | 
			
		||||
                for (int j = 0; j < n; j++) {
 | 
			
		||||
                    stream.read(reinterpret_cast<char*>(&temp), sizeof(T));
 | 
			
		||||
                    set(i, j, temp);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, int m, int n> matrix<T, m, n> operator*(const T& lhs, const matrix<T, m, n>& rhs) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								network.h
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								network.h
									
									
									
									
									
								
							@ -3,6 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#include "matrix.h"
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
template <typename T, int in, int out>
 | 
			
		||||
struct layer {
 | 
			
		||||
@ -43,6 +44,19 @@ struct layer {
 | 
			
		||||
    {
 | 
			
		||||
        return combine(rhs, combiner, combiner);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::ostream& save(std::ostream& stream) {
 | 
			
		||||
        weights.save(stream);
 | 
			
		||||
        bias.save(stream);
 | 
			
		||||
 | 
			
		||||
        return stream;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void load(std::istream& stream) 
 | 
			
		||||
    {
 | 
			
		||||
        weights.load(stream);
 | 
			
		||||
        bias.load(stream);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <std::size_t N, typename T, int ...inputs> struct layer_types;
 | 
			
		||||
@ -111,6 +125,18 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        return combine(rhs, combiner, combiner);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::ostream& save(std::ostream& stream) 
 | 
			
		||||
    {
 | 
			
		||||
        current.save(stream);
 | 
			
		||||
        
 | 
			
		||||
        return stream;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void load(std::istream& stream)
 | 
			
		||||
    {
 | 
			
		||||
        current.load(stream);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, int in, int out, int ...layers> 
 | 
			
		||||
@ -171,6 +197,20 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        return combine(rhs, combiner, combiner);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::ostream& save(std::ostream& stream)
 | 
			
		||||
    {
 | 
			
		||||
        base::save(stream);
 | 
			
		||||
        subnetwork.save(stream);
 | 
			
		||||
        
 | 
			
		||||
        return stream;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void load(std::istream& stream)
 | 
			
		||||
    {
 | 
			
		||||
        base::load(stream);
 | 
			
		||||
        subnetwork.load(stream);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								tester.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								tester.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
#include "argh.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, const char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    argh::parser args;
 | 
			
		||||
    args.add_params({ "s", "stock" });
 | 
			
		||||
    args.add_params({ "m", "money" });
 | 
			
		||||
 | 
			
		||||
    args.parse(argc, argv);
 | 
			
		||||
 | 
			
		||||
    std::string network, input;
 | 
			
		||||
    
 | 
			
		||||
    args(1) >> network;
 | 
			
		||||
    args(2) >> input;
 | 
			
		||||
 | 
			
		||||
    double   money;
 | 
			
		||||
    unsigned stock;
 | 
			
		||||
 | 
			
		||||
    args({"s", "stock"}, 1000) >> stock;
 | 
			
		||||
    args({"m", "money"}, 1000.) >> money;
 | 
			
		||||
 | 
			
		||||
    std::function<double(const double&)> normalizer = [](const double& result) -> double { return erf(result); };
 | 
			
		||||
    current_decider decider(normalizer);
 | 
			
		||||
    
 | 
			
		||||
    std::ifstream network_file(network, std::ios::in | std::ios::binary);
 | 
			
		||||
    std::ifstream input_file(input);
 | 
			
		||||
 | 
			
		||||
    decider.load(network_file);
 | 
			
		||||
 | 
			
		||||
    double price;
 | 
			
		||||
    decider.start_money = money;
 | 
			
		||||
    decider.start_stock = stock;
 | 
			
		||||
    std::cout << "x,price,decsion,money,stock" << std::endl;
 | 
			
		||||
    for (int i = 0; input_file >> price; i++) {
 | 
			
		||||
        auto decision   = decider.decide(price, money, stock);
 | 
			
		||||
        auto current    = price * stock + money;
 | 
			
		||||
        auto max_credit = std::max(current * 0.05, -1e4);
 | 
			
		||||
 | 
			
		||||
        if (decision < 0) {
 | 
			
		||||
            decision = std::max<int>(decision, -stock); // cannot sell more than we actually have
 | 
			
		||||
        } else if (decision > 0) {
 | 
			
		||||
            decision = std::min<int>(floor((money + max_credit) / price), decision);   
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        money -= price * decision;
 | 
			
		||||
        stock += decision;
 | 
			
		||||
 | 
			
		||||
        /* std::cout */ 
 | 
			
		||||
        /*     << i << "," */ 
 | 
			
		||||
        /*     << price << "," */ 
 | 
			
		||||
        /*     << decision << "," */ 
 | 
			
		||||
        /*     << money << "," */
 | 
			
		||||
        /*     << stock */
 | 
			
		||||
        /*     << std::endl; */
 | 
			
		||||
    }
 | 
			
		||||
    std::cout << "Koniec: " << money + stock*price;
 | 
			
		||||
    /* decider.network.save(std::cout); */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										215
									
								
								trainer.h
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								trainer.h
									
									
									
									
									
								
							@ -5,22 +5,15 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct trained {
 | 
			
		||||
    unsigned int id;
 | 
			
		||||
    T decider;
 | 
			
		||||
    
 | 
			
		||||
    double   monies;
 | 
			
		||||
    unsigned stock;
 | 
			
		||||
    double   wealth;
 | 
			
		||||
   
 | 
			
		||||
    void recalculate(double price)
 | 
			
		||||
    {
 | 
			
		||||
        wealth = monies + stock*price;
 | 
			
		||||
    }
 | 
			
		||||
    unsigned id;
 | 
			
		||||
    unsigned position;
 | 
			
		||||
 | 
			
		||||
    double score;
 | 
			
		||||
    T      decider;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
@ -34,14 +27,20 @@ class trainer {
 | 
			
		||||
    std::size_t n;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    using dataset = std::vector<double>;
 | 
			
		||||
 | 
			
		||||
    double money;
 | 
			
		||||
    unsigned stock;
 | 
			
		||||
    unsigned int generation;
 | 
			
		||||
 | 
			
		||||
    std::function<double(std::shared_ptr<trained<T>> x)> q;
 | 
			
		||||
    std::function<double(std::shared_ptr<trained<T>>, const dataset&, double, unsigned)> q;
 | 
			
		||||
 | 
			
		||||
    trainer(double money, unsigned stock, std::size_t n, std::function<T()> factory) 
 | 
			
		||||
        : factory(factory), id(0), money(money), stock(stock), n(n),
 | 
			
		||||
        q([](std::shared_ptr<trained<T>> x){ return x->wealth; }), random_engine(std::time(0))
 | 
			
		||||
        : factory(factory), id(0), generation(1), money(money), stock(stock), n(n),
 | 
			
		||||
        q([](std::shared_ptr<trained<T>> x, const dataset& input, double money, unsigned stock) { 
 | 
			
		||||
            return money + input.back() * stock; 
 | 
			
		||||
        }), 
 | 
			
		||||
        random_engine(std::time(0)) 
 | 
			
		||||
    {
 | 
			
		||||
        add(n);
 | 
			
		||||
    }
 | 
			
		||||
@ -67,105 +66,109 @@ public:
 | 
			
		||||
        trainees.push_back(trainee);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int train(std::shared_ptr<trained<T>> trainee, double price)
 | 
			
		||||
    void evolve()
 | 
			
		||||
    {
 | 
			
		||||
        auto decision   = trainee->decider.decide(price, trainee->monies, trainee->stock);
 | 
			
		||||
        auto current    = price*trainee->stock + trainee->monies;
 | 
			
		||||
        auto max_credit = std::max(current * 0.05, -1e4);
 | 
			
		||||
 | 
			
		||||
        /* std::cout << "D: " << decision << " C: " << current << " P: " << price << " MC: " << max_credit << std::endl; */ 
 | 
			
		||||
        if (decision > 0 && trainee->monies - decision*price < -max_credit) {
 | 
			
		||||
            decision = floor((trainee->monies + max_credit) / price);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (decision < 0 && -decision > trainee->stock) {
 | 
			
		||||
            decision = -trainee->stock;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        trainee->stock  += decision;
 | 
			
		||||
        trainee->monies -= price*decision;
 | 
			
		||||
        trainee->recalculate(price);
 | 
			
		||||
 | 
			
		||||
        return decision;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void test(std::istream& input)
 | 
			
		||||
    {
 | 
			
		||||
        for (auto trainee : trainees) {
 | 
			
		||||
            trainee->monies = money;
 | 
			
		||||
            trainee->stock  = stock;
 | 
			
		||||
 | 
			
		||||
            trainee->decider.start_money = money;
 | 
			
		||||
            trainee->decider.start_stock = stock;
 | 
			
		||||
            trainee->decider.reset();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        double price, start;
 | 
			
		||||
        input >> price;
 | 
			
		||||
        start = price*stock + money;
 | 
			
		||||
 | 
			
		||||
        do {
 | 
			
		||||
            for (auto trainee : trainees) {
 | 
			
		||||
                train(trainee, price);
 | 
			
		||||
            }
 | 
			
		||||
        } while (input >> price);
 | 
			
		||||
 | 
			
		||||
        auto hodl = price * stock + money;
 | 
			
		||||
        std::cout << "Zakonczono testy " << trainees.size() << " przypadkow." << std::endl;
 | 
			
		||||
        std::cout << "HODL: " << hodl << " START: " << start << std::endl;
 | 
			
		||||
        std::cout << "-----------------------" << std::endl;
 | 
			
		||||
 | 
			
		||||
        normalize();
 | 
			
		||||
 | 
			
		||||
        for (auto trainee : trainees) {
 | 
			
		||||
            std::cout 
 | 
			
		||||
                << "#" << trainee->id << ": " << trainee->wealth 
 | 
			
		||||
                << " [" << trainee->wealth - hodl << "] (" << trainee->score << ") "
 | 
			
		||||
                << trainee->stock << " akcji, " 
 | 
			
		||||
                << trainee->monies << " gelda w banku. " << std::endl; 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sort();
 | 
			
		||||
        filter();
 | 
			
		||||
        breed();
 | 
			
		||||
 | 
			
		||||
        // cleanup before next training sessions
 | 
			
		||||
        for (auto t : trainees) {
 | 
			
		||||
            t->score = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void normalize()
 | 
			
		||||
    void train(const dataset& input, std::shared_ptr<trained<T>> trainee) 
 | 
			
		||||
    {
 | 
			
		||||
        trainee->decider.start_money = money;
 | 
			
		||||
        trainee->decider.start_stock = stock;
 | 
			
		||||
        trainee->decider.reset();
 | 
			
		||||
 | 
			
		||||
        double   money = this->money;
 | 
			
		||||
        unsigned stock = this->stock;
 | 
			
		||||
 | 
			
		||||
        for (double price : input) {
 | 
			
		||||
            auto decision   = trainee->decider.decide(price, money, stock);
 | 
			
		||||
            auto current    = price * stock + money;
 | 
			
		||||
            auto max_credit = std::max(current * 0.05, -1e4);
 | 
			
		||||
 | 
			
		||||
            if (decision < 0) {
 | 
			
		||||
                decision = std::max<int>(decision, -stock); // cannot sell more than we actually have
 | 
			
		||||
            } else if (decision > 0) {
 | 
			
		||||
                decision = std::min<int>(floor((money + max_credit) / price), decision);   
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            money -= price * decision;
 | 
			
		||||
            stock += decision;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        trainee->score += q(trainee, input, money, stock);
 | 
			
		||||
 | 
			
		||||
        auto last   = input.back();
 | 
			
		||||
        auto first  = input.front();
 | 
			
		||||
        auto wealth = money + stock * last;
 | 
			
		||||
 | 
			
		||||
        auto hodl   = this->money + this->stock * last;
 | 
			
		||||
        auto start  = this->money + this->stock * first;
 | 
			
		||||
 | 
			
		||||
        std::cout 
 | 
			
		||||
            << "#" << trainee->id << ": " << wealth 
 | 
			
		||||
            
 | 
			
		||||
            << std::showpos
 | 
			
		||||
            << " H: " << wealth - hodl << " (" << (wealth - hodl) / hodl * 100 << "%)" 
 | 
			
		||||
            << " S: " << wealth - start << " (" << (wealth - start) / start * 100 << "%) "
 | 
			
		||||
            << std::noshowpos
 | 
			
		||||
 | 
			
		||||
            << stock << " akcji, " 
 | 
			
		||||
            << money << " gelda w banku. " 
 | 
			
		||||
            << std::endl; 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void train(const dataset& input, const std::string& name)
 | 
			
		||||
    {
 | 
			
		||||
        std::cout << "Zestaw " << name
 | 
			
		||||
            << " GEN #" << this->generation 
 | 
			
		||||
            << " start: " << money + input.front() * stock
 | 
			
		||||
            << " HODL: " << money + input.back() * stock
 | 
			
		||||
            << std::endl;
 | 
			
		||||
 | 
			
		||||
        for (auto trainee : trainees) {
 | 
			
		||||
            train(input, trainee);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void sort()
 | 
			
		||||
    {
 | 
			
		||||
        std::sort(trainees.begin(), trainees.end(), [=](std::shared_ptr<trained<T>> a, std::shared_ptr<trained<T>> b){
 | 
			
		||||
            return q(a) > q(b);
 | 
			
		||||
            return a->score > b->score;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        auto high = q(*trainees.begin());
 | 
			
		||||
        auto low  = q(*(trainees.end() - 1));
 | 
			
		||||
 | 
			
		||||
        // best = 1, worst = 0
 | 
			
		||||
        unsigned i = 0;
 | 
			
		||||
        for (auto t : trainees) {
 | 
			
		||||
            t->score = (q(t) - low) / (high - low);
 | 
			
		||||
        };
 | 
			
		||||
            t->position = i++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void filter()
 | 
			
		||||
    {
 | 
			
		||||
        /* static std::exponential_distribution<double> distribution(0.50); */
 | 
			
		||||
        static std::uniform_real_distribution<double> distribution(0.0, 1.0);
 | 
			
		||||
        auto random = [=](){ return distribution(random_engine); };
 | 
			
		||||
        
 | 
			
		||||
        auto iterator = std::remove_if(trainees.begin(), trainees.end(), [&](std::shared_ptr<trained<T>> t) {
 | 
			
		||||
            return random() < (double)t->position / n;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        /* auto random = [=](){ return 1. - std::clamp(0., distribution(random_engine), 2.)/2.1; }; */
 | 
			
		||||
        /* auto iterator = std::remove_if(trainees.begin(), trainees.end(), [=](std::shared_ptr<trained<T>> t) { */
 | 
			
		||||
        /*     return random() > t->score; */
 | 
			
		||||
        /* }); */
 | 
			
		||||
 | 
			
		||||
        trainees.erase(trainees.begin() + 49, trainees.end());
 | 
			
		||||
        trainees.erase(iterator, std::end(trainees));
 | 
			
		||||
 | 
			
		||||
        std::cout << "Przy życiu pozostają: ";
 | 
			
		||||
        for (auto trainee : trainees) {
 | 
			
		||||
            std::cout << "#" << trainee->id << " ";
 | 
			
		||||
            std::cout << "#" << trainee->id << " (" << trainee->position << ") ";
 | 
			
		||||
        }
 | 
			
		||||
        std::cout << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void breed()
 | 
			
		||||
    {   
 | 
			
		||||
        std::size_t diff = n - trainees.size();
 | 
			
		||||
        std::cout << "---------------------------------------" << std::endl;
 | 
			
		||||
        std::cout << "W populacji brakuje " << diff << " sieci, aktualnie " << trainees.size() << "." << std::endl;
 | 
			
		||||
 | 
			
		||||
        std::vector<double> probability;
 | 
			
		||||
@ -173,44 +176,38 @@ public:
 | 
			
		||||
            probability.push_back(t->score);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::discrete_distribution<unsigned> distribution(probability.begin(), probability.end());
 | 
			
		||||
        std::exponential_distribution<double> exponential(1.5);
 | 
			
		||||
        
 | 
			
		||||
        std::discrete_distribution<unsigned>   distribution(probability.begin(), probability.end());
 | 
			
		||||
        std::exponential_distribution<double>  exponential(1.5);
 | 
			
		||||
        std::uniform_real_distribution<double> ratio(0.0, 1.0);
 | 
			
		||||
 | 
			
		||||
        auto combiner = [=](const double& a, const double& b){
 | 
			
		||||
            auto mutation = (rand() % 2 ? -1 : 1) * exponential(random_engine);
 | 
			
		||||
 | 
			
		||||
            if (exponential(random_engine) < 1) {
 | 
			
		||||
                return .6 * a + .4 * b + mutation; 
 | 
			
		||||
                auto r = ratio(random_engine);
 | 
			
		||||
                return r * a + (1 - r) * b + mutation; 
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (rand() % 2 ? a : b) + mutation;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        unsigned first, second;
 | 
			
		||||
        for (int i = 0; i < diff; i++) {
 | 
			
		||||
        for (int i = 0; i < diff - 4; i++) {
 | 
			
		||||
            first = distribution(random_engine);
 | 
			
		||||
            do { second = distribution(random_engine); } while (first == second);
 | 
			
		||||
 | 
			
		||||
            auto combined = trainees[first]->decider.combine(trainees[second]->decider, combiner);
 | 
			
		||||
            std::cout << "Łączenie #" << trainees[first]->id << " z #" << trainees[second]->id << " dało #" << (id+1) << std::endl;
 | 
			
		||||
 | 
			
		||||
            add(combined);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        add(4); // some random things
 | 
			
		||||
 | 
			
		||||
        generation++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void see_best(std::istream& stream)
 | 
			
		||||
    {
 | 
			
		||||
        std::shared_ptr<trained<T>> trainee = this->trainees[0];
 | 
			
		||||
 | 
			
		||||
        std::cout << "price,decision" << std::endl;
 | 
			
		||||
        double price;
 | 
			
		||||
        
 | 
			
		||||
        trainee->monies = money;
 | 
			
		||||
        trainee->stock  = stock;
 | 
			
		||||
 | 
			
		||||
        trainee->decider.reset();
 | 
			
		||||
        while (stream >> price) {
 | 
			
		||||
            int decision = train(trainee, price);
 | 
			
		||||
            std::cout << price << "," << decision << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
    std::vector<std::shared_ptr<trained<T>>> population() {
 | 
			
		||||
        return trainees;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								wtf.cpp
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								wtf.cpp
									
									
									
									
									
								
							@ -7,6 +7,7 @@
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include "argh.h"
 | 
			
		||||
#include "matrix.h"
 | 
			
		||||
@ -14,7 +15,7 @@
 | 
			
		||||
#include "decider.h"
 | 
			
		||||
#include "trainer.h"
 | 
			
		||||
 | 
			
		||||
using current_decider = neural_decider<24, 12, 12, 32, 16>;
 | 
			
		||||
using current_decider = neural_decider<24, 16, 16, 32, 16>;
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
@ -23,27 +24,24 @@ int main(int argc, char* argv[])
 | 
			
		||||
    args.add_params({"-s", "--stock"});
 | 
			
		||||
    args.add_params({"-p", "--population"});
 | 
			
		||||
    args.add_params({"-n", "--iterations"});
 | 
			
		||||
    args.add_params({"-o", "--output-dir"});
 | 
			
		||||
 | 
			
		||||
    args.parse(argc, argv);
 | 
			
		||||
 | 
			
		||||
    double   money;
 | 
			
		||||
    unsigned stock, population, iterations;
 | 
			
		||||
    std::string input_file;
 | 
			
		||||
    std::string input_file, output_dir;
 | 
			
		||||
 | 
			
		||||
    args({ "m", "money" }, 1000.)   >> money;
 | 
			
		||||
    args({ "s", "stock" }, 1000)    >> stock;
 | 
			
		||||
    args({ "p", "population" }, 25) >> population;
 | 
			
		||||
    args({ "n", "iterations" }, 4)  >> iterations;
 | 
			
		||||
    args(1) >> input_file;
 | 
			
		||||
    args({ "o", "output-dir" }, "") >> output_dir;
 | 
			
		||||
 | 
			
		||||
    std::uniform_real_distribution<double> distribution(-2.0, 2.0);
 | 
			
		||||
    std::uniform_real_distribution<double> bias_distribution(-16.0, 16.0);
 | 
			
		||||
 | 
			
		||||
    std::random_device rd;
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Engines 
 | 
			
		||||
    //
 | 
			
		||||
    std::mt19937 random_engine(rd());
 | 
			
		||||
 | 
			
		||||
    std::function<double(const int&, const int&)> randomizer = [&](const int&, const int&) -> double {
 | 
			
		||||
@ -64,19 +62,47 @@ int main(int argc, char* argv[])
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    trainer<current_decider> train(money, stock, population, factory);
 | 
			
		||||
 
 | 
			
		||||
    std::fstream input;
 | 
			
		||||
    input.open(input_file);
 | 
			
		||||
    std::map<std::string, trainer<current_decider>::dataset> datasets;
 | 
			
		||||
    for (auto it = args.begin() + 1; it != args.end(); it++) {
 | 
			
		||||
        std::string filename = *it;
 | 
			
		||||
        std::ifstream file;
 | 
			
		||||
        file.open(filename);
 | 
			
		||||
        if (!file.is_open()) continue;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < iterations; i++) {
 | 
			
		||||
        input.clear();
 | 
			
		||||
        input.seekg(0);
 | 
			
		||||
        trainer<current_decider>::dataset set;
 | 
			
		||||
        double price;
 | 
			
		||||
        while (file >> price) set.push_back(price);
 | 
			
		||||
 | 
			
		||||
        train.test(input);
 | 
			
		||||
        datasets[filename] = set;
 | 
			
		||||
 | 
			
		||||
        file.close();
 | 
			
		||||
        std::cout << "Zaladowano zestaw testowy " << filename << " z " << set.size() << " wartosciami." << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    input.clear();
 | 
			
		||||
    input.seekg(0);
 | 
			
		||||
    if (datasets.size() == 0) {
 | 
			
		||||
        std::cout << "Brak poprawnie zaladowanych zestawow testowych." << std::endl;
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    train.see_best(input);
 | 
			
		||||
    while (train.generation <= iterations) {
 | 
			
		||||
        for (auto pair : datasets) {
 | 
			
		||||
            train.train(pair.second, pair.first);
 | 
			
		||||
        }
 | 
			
		||||
        train.evolve();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!output_dir.empty()) {
 | 
			
		||||
        for (auto trained : train.population()) {
 | 
			
		||||
        std::stringstream stream;
 | 
			
		||||
            stream << output_dir << trained->id << ".net";
 | 
			
		||||
            std::string filename = stream.str();
 | 
			
		||||
 | 
			
		||||
            std::cout << "Zapisuje siec #" << trained->id << " do pliku " << filename << std::endl;
 | 
			
		||||
 | 
			
		||||
            std::ofstream file(filename, std::ios::out | std::ios::binary);
 | 
			
		||||
            trained->decider.save(file);
 | 
			
		||||
            file.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user