diff --git a/CMakeLists.txt b/CMakeLists.txt index c279293..a201aa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD 14) add_subdirectory(external/curl) add_subdirectory(external/jsoncpp) -add_executable(TradeSim main.cpp src/Market.cpp src/Market.h src/Exchange.cpp src/Exchange.h src/Trader.h src/TradeTracker.cpp src/TradeTracker.h src/Binance.cpp src/Binance.h src/Wallet.cpp src/Wallet.h src/Transaction.cpp src/Transaction.h src/WebAPI.cpp src/WebAPI.h) +add_executable(TradeSim main.cpp src/Market.cpp src/Market.h src/Exchange.cpp src/Exchange.h src/Trader.h src/TradeTracker.cpp src/TradeTracker.h src/Binance.cpp src/Binance.h src/Wallet.cpp src/Wallet.h src/Transaction.cpp src/Transaction.h src/WebAPI.cpp src/WebAPI.h src/BasicTrader.cpp src/BasicTrader.h src/Trader.cpp) target_link_libraries(TradeSim libcurl) target_link_libraries(TradeSim jsoncpp_lib) include_directories(${CURL_INCLUDE_DIR}) diff --git a/main.cpp b/main.cpp index 5395cd2..93564f1 100644 --- a/main.cpp +++ b/main.cpp @@ -1,10 +1,29 @@ #include +#include #include "src/Binance.h" +#include "src/TradeTracker.h" +#include "src/BasicTrader.h" int main(void) { + using namespace std::chrono_literals; + Binance b; - std::cout << b.getMarket("BTCBUSD")->getExchangeRate() << std::endl; + TradeTracker ttr; + ttr.addExchange(&b); + + BasicTrader btr(&ttr); + ttr.addTrader(&btr); + + bool running = true; + int roundsRemaining = 1000; + + while (roundsRemaining != 0) { + ttr.round(); + std::this_thread::sleep_for(10000ms); + --roundsRemaining; + } + return 0; } \ No newline at end of file diff --git a/src/BasicTrader.cpp b/src/BasicTrader.cpp new file mode 100644 index 0000000..4d63f6e --- /dev/null +++ b/src/BasicTrader.cpp @@ -0,0 +1,46 @@ +#include "BasicTrader.h" +#include + +BasicTrader::BasicTrader(TradeTracker *tradeTracker) : tradeTracker(tradeTracker) {} + +void BasicTrader::step() { + Market *market = tradeTracker->getExchange("Binance")->getMarket("ETHBUSD"); + calcualteEMA(); + double price = market->getExchangeRate(); + if(ema > 0) { + if (!own && price * 1.001 <= ema) { + market->buy(&wallet, wallet.getBalance("BUSD") * 0.9 / market->getExchangeRate()); + std::cout << "ETH bought @" << market->getExchangeRate() << " because EMA(" << queue_size << ") is down by " + << (1 - (ema / prev_ema)) * 100 << "%" << std::endl; + own = true; + price_bougth = price; + } + if (own && price * 0.999 >= ema && price > price_bougth) { + market->sell(&wallet, wallet.getBalance("ETH")); + std::cout << "ETH sold @" << market->getExchangeRate() << " because EMA(" << queue_size << ") is up by " + << (1 - (ema / prev_ema)) * 100 << "%" << std::endl; + own = false; + } + std::cout << "EMA(" <getExchange("Binance")->getMarket("ETHBUSD"); + double price = market->getExchangeRate(); + prices.push_back(price); + if (prices.size() <= queue_size) { + std::cout << "Gathering Data " << (double) prices.size() / queue_size * 100 << "%" << std::endl; + } else { + double moving_avrage = 0; + prices.pop_front(); + for (int i = 0; i < queue_size; ++i) { + moving_avrage += prices[i]; + } + moving_avrage /= queue_size; + prev_ema = (prev_ema == 0) ? moving_avrage : prev_ema; + double k = 2 / ((double) queue_size + 1); + ema = (price - prev_ema) * k + prev_ema; + } +} diff --git a/src/BasicTrader.h b/src/BasicTrader.h new file mode 100644 index 0000000..61613d4 --- /dev/null +++ b/src/BasicTrader.h @@ -0,0 +1,22 @@ +#ifndef TRADESIM_BASICTRADER_H +#define TRADESIM_BASICTRADER_H +#include + +#include "TradeTracker.h" +#include "Trader.h" + +class BasicTrader : public Trader{ + TradeTracker* tradeTracker; + size_t queue_size = 54; + std::deque prices; + double prev_ema = 0,ema = 0; + void calcualteEMA(); + bool own = false; + double price_bougth = 0; +public: + BasicTrader(TradeTracker *tradeTracker); + void step(); +}; + + +#endif //TRADESIM_BASICTRADER_H diff --git a/src/Binance.cpp b/src/Binance.cpp index ec677e7..abda9fa 100644 --- a/src/Binance.cpp +++ b/src/Binance.cpp @@ -4,8 +4,8 @@ Binance::Binance() :Exchange("Binance",0.1){ // TODO: Ezt lehetne configból is (pl. jsoncpp-vel) - markets["BTCBUSD"] = Market("BTC/BUSD"); - markets["ETHBUSD"] = Market("ETH/BUSD"); + markets["BTCBUSD"] = Market("BTC/BUSD", this); + markets["ETHBUSD"] = Market("ETH/BUSD", this); updateAllMarkets(); } diff --git a/src/Exchange.cpp b/src/Exchange.cpp index 4055b9d..770a11b 100644 --- a/src/Exchange.cpp +++ b/src/Exchange.cpp @@ -5,7 +5,7 @@ const std::string &Exchange::getName() const { return name; } -const Market *Exchange::getMarket(std::string name) { +Market *Exchange::getMarket(std::string name) { try { return &markets.at(name); }catch (std::out_of_range e) { @@ -22,4 +22,4 @@ double Exchange::getFee() const { return fee; } -Exchange::Exchange(const std::string &name, double fee) : name(name), fee(fee) {} +Exchange::Exchange(const std::string &name, double fee) : name(name), fee(fee) {} \ No newline at end of file diff --git a/src/Exchange.h b/src/Exchange.h index d063a79..5790dfe 100644 --- a/src/Exchange.h +++ b/src/Exchange.h @@ -13,11 +13,10 @@ protected: double fee; public: Exchange(const std::string &name, double fee); - const std::string &getName() const; virtual void updateAllMarkets() = 0; virtual void updateMarket(std::string name) = 0; - const Market *getMarket(std::string name); + Market *getMarket(std::string name); void addMarket(Market m); double getFee() const; diff --git a/src/Market.cpp b/src/Market.cpp index 84c493b..d378f1c 100644 --- a/src/Market.cpp +++ b/src/Market.cpp @@ -13,15 +13,15 @@ void Market::setExchangeRate(double exchangeRate) { exchange_rate = exchangeRate; } -Market::Market(const std::string& name): name(name) {} +Market::Market(const std::string &name, Exchange *ex) : name(name),exchange(ex) {} void Market::buy(Wallet* w, double amount) { - w->acceptTransaction(Transaction(getLHSCurrency(),getRHSCurrency(),amount-amount*(exchange->getFee()/100),exchange_rate*amount)); + w->acceptTransaction(Transaction(getRHSCurrency(),getLHSCurrency(),amount-amount*(exchange->getFee()/100),exchange_rate*amount)); } void Market::sell(Wallet* w, double amount) { - w->acceptTransaction(Transaction(getRHSCurrency(),getLHSCurrency(), - amount-amount*(exchange->getFee()/100),exchange_rate*amount)); + w->acceptTransaction(Transaction(getLHSCurrency(),getRHSCurrency(), + exchange_rate*amount,amount-amount*(exchange->getFee()/100))); } std::string Market::getLHSCurrency() { diff --git a/src/Market.h b/src/Market.h index 672a86b..bdbe601 100644 --- a/src/Market.h +++ b/src/Market.h @@ -13,7 +13,7 @@ class Market { Exchange* exchange; public: Market(); - Market(const std::string& name); + Market(const std::string &name, Exchange *ex); const std::string &getName() const; double getExchangeRate() const; void setExchangeRate(double exchangeRate); diff --git a/src/TradeTracker.cpp b/src/TradeTracker.cpp index b5f8db9..83cf3af 100644 --- a/src/TradeTracker.cpp +++ b/src/TradeTracker.cpp @@ -16,3 +16,11 @@ Exchange *TradeTracker::getExchange(const std::string& name) { } return nullptr; } + +void TradeTracker::addExchange(Exchange* exchange) { + exchanges.push_back(exchange); +} + +void TradeTracker::addTrader(Trader *t) { + traders.push_back(t); +} diff --git a/src/TradeTracker.h b/src/TradeTracker.h index 5a6850b..3cdffa0 100644 --- a/src/TradeTracker.h +++ b/src/TradeTracker.h @@ -9,9 +9,11 @@ class TradeTracker { std::vector exchanges; std::vector traders; - void round(); public: Exchange* getExchange(const std::string& name); + void addTrader(Trader* t); + void addExchange(Exchange* exchange); + void round(); }; #endif //TRADESIM_TRADETRACKER_H diff --git a/src/Trader.cpp b/src/Trader.cpp new file mode 100644 index 0000000..5e9915a --- /dev/null +++ b/src/Trader.cpp @@ -0,0 +1,5 @@ +#include "Trader.h" + +Trader::Trader(): wallet(std::initializer_list {"BUSD","ETH","BTC"}) { + wallet.acceptTransaction(Transaction("BTC","BUSD",100,0)); +} \ No newline at end of file diff --git a/src/Trader.h b/src/Trader.h index 1bdc015..5970f5c 100644 --- a/src/Trader.h +++ b/src/Trader.h @@ -1,12 +1,16 @@ #ifndef TRADESIM_TRADER_H #define TRADESIM_TRADER_H +#include "Wallet.h" + class TradeTracker; class Trader { public: + Trader(); virtual void step() = 0; protected: TradeTracker* tracker; + Wallet wallet; }; diff --git a/src/Wallet.cpp b/src/Wallet.cpp index f4a592d..aba7df5 100644 --- a/src/Wallet.cpp +++ b/src/Wallet.cpp @@ -7,9 +7,26 @@ Wallet::Wallet(std::string* symbols, int size) { } } +Wallet::Wallet(std::initializer_list init_list) { + for (auto i = init_list.begin();i != init_list.end();++i) { + balances[i->c_str()] = 0.0; + } +} + void Wallet::acceptTransaction(Transaction transaction) { if(balances.at(transaction.getCurrencyLhs()) >= transaction.getPrice()){ balances[transaction.getCurrencyLhs()] -= transaction.getPrice(); balances[transaction.getCurrencyRhs()] += transaction.getAmount(); }else throw "Invalid Transaction: too low balance"; } + +double Wallet::getBalance(std::string currency) { + try{ + double bal = balances.at(currency); + return bal; + }catch(std::out_of_range e) { + return 0; + } +} + + diff --git a/src/Wallet.h b/src/Wallet.h index 4235997..6427d2f 100644 --- a/src/Wallet.h +++ b/src/Wallet.h @@ -9,7 +9,9 @@ class Wallet { std::map balances; public: Wallet(std::string* symbols, int size); + Wallet(std::initializer_list init_list); void acceptTransaction(Transaction transaction); + double getBalance(std::string); };