diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/.gitignore b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/.gitignore index 3110669..de9e9ac 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/.gitignore +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/.gitignore @@ -1 +1,5 @@ -a.exe \ No newline at end of file +a.exe +asks.txt +assets.txt +bids.txt +user-sales.txt \ No newline at end of file diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.cpp b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.cpp index 63c7e69..6253858 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.cpp +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.cpp @@ -7,6 +7,10 @@ MerkelMain::MerkelMain() { currentTime = orderBook.getEarliestTime(); + wallet.insertCurrency("BTC", 10); + wallet.insertCurrency("ETC", 10); + wallet.insertCurrency("DOGE", 10); + wallet.insertCurrency("USDT", 10); } std::string MerkelMain::getCurrentTime() @@ -86,6 +90,7 @@ void MerkelMain::printMarketStats() // std::cout << "OrderBook asks: " << asks << " bids:" << bids << std::endl; } +// Enter a new ask void MerkelMain::enterAsk() { std::cout << "Make an ask - enter the amount: product,price, amount, eg ETH/BTC,200,0.5" << std::endl; @@ -125,6 +130,7 @@ void MerkelMain::enterAsk() } } +// Enter a new bid void MerkelMain::enterBid() { std::cout << "Make an bid - enter the amount: product,price, amount, eg ETH/BTC,200,0.5" << std::endl; @@ -165,23 +171,32 @@ void MerkelMain::enterBid() } } +// Withdraw an order +void MerkelMain::withdrawOrder(OrderBookEntry order) +{ + orderBook.removeOrder(order); +} + void MerkelMain::printWallet() { std::cout << wallet.toString() << std::endl; } -void MerkelMain::gotoNextTimeframe(bool silent) +std::vector MerkelMain::gotoNextTimeframe(bool silent) { - if(!silent) + // Sales vector to return + std::vector sales; + if (!silent) std::cout << "Going to next time frame. " << std::endl; + // Match ask to bids product by product for (std::string p : orderBook.getKnownProducts()) { - std::cout << "matching " << p << std::endl; - std::vector sales = orderBook.matchAsksToBids(p, currentTime); - std::cout << "Sales: " << sales.size() << std::endl; + std::cout << "Matching.. " << p << std::endl; + std::vector productSales = orderBook.matchAsksToBids(p, currentTime); + std::cout << "Number of sales for " << p << ": " << productSales.size() << std::endl; for (OrderBookEntry &sale : sales) { - if(!silent) + if (!silent) std::cout << "Sale price: " << sale.price << " amount " << sale.amount << std::endl; if (sale.username == "simuser") { @@ -189,9 +204,34 @@ void MerkelMain::gotoNextTimeframe(bool silent) wallet.processSale(sale); } } + // Add this product sales to the complete sales list + sales.insert(sales.end(), productSales.begin(), productSales.end()); } currentTime = orderBook.getNextTime(currentTime); + return sales; +} + +// Enter an ask at the current time +void MerkelMain::enterAsk(double price, double amount, std::string product) +{ + OrderBookEntry order = {price, amount, currentTime, product, OrderBookType::ask, "simuser"}; + // check if the wallet can afford it + if (wallet.canFulfillOrder(order)) + { + orderBook.insertOrder(order); + } +} + +// Enter a bid at the current time +void MerkelMain::enterBid(double price, double amount, std::string product) +{ + OrderBookEntry order = {price, amount, currentTime, product, OrderBookType::bid, "simuser"}; + // check if the wallet can afford it + if (wallet.canFulfillOrder(order)) + { + orderBook.insertOrder(order); + } } int MerkelMain::getUserOption() @@ -265,3 +305,8 @@ std::vector MerkelMain::getCurrentBids() } return currentBids; } + +std::string MerkelMain::returnWallet() +{ + return wallet.toString(); +} \ No newline at end of file diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.h b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.h index 437d160..1cb2614 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.h +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/MerkelMain.h @@ -22,10 +22,21 @@ public: /** returns a vector of all bids orders for the current time */ std::vector getCurrentBids(); - /** matches bids and asks, proceeds to the next time frame */ - void gotoNextTimeframe(bool silent); - void enterAsk(OrderBookEntry newAsk); - void enterBid(OrderBookEntry newBid); + /** Matches bids and asks, returns the sales and proceeds to the next time frame */ + std::vector gotoNextTimeframe(bool silent); + + /** Enter a new ask */ + void enterAsk(double price, double amount, std::string product); + + /** Enter as new bid */ + void enterBid(double price, double amount, std::string product); + + /** Withdraw an order */ + void withdrawOrder(OrderBookEntry order); + + /** Return the wallet information */ + std::string returnWallet(); + private: void printMenu(); void printHelp(); @@ -40,8 +51,8 @@ private: std::string currentTime; - OrderBook orderBook{"../../../../111.csv"}; - //OrderBook orderBook{"20200317.csv"}; + //OrderBook orderBook{"../../../../111.csv"}; + OrderBook orderBook{"20200317.csv"}; //OrderBook orderBook{"20200601.csv"}; Wallet wallet; }; diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.cpp b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.cpp index c324a8e..761d49b 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.cpp +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.cpp @@ -86,6 +86,11 @@ std::string OrderBook::getNextTime(std::string timestamp) { next_timestamp = orders[0].timestamp; } + // break the loop by comparing the argument timestamp with the timestamp found + if (timestamp > next_timestamp) + { + return "END"; + } return next_timestamp; } @@ -95,6 +100,26 @@ void OrderBook::insertOrder(OrderBookEntry &order) std::sort(orders.begin(), orders.end(), OrderBookEntry::compareByTimestamp); } +// Remove order from the order book +void OrderBook::removeOrder(OrderBookEntry &order) +{ + for(int i=0; i OrderBook::matchAsksToBids(std::string product, std::string timestamp) { // asks = orderbook.asks @@ -201,4 +226,4 @@ std::vector OrderBook::matchAsksToBids(std::string product, std: } } return sales; -} +} \ No newline at end of file diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.h b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.h index 9201658..e202187 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.h +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/OrderBook.h @@ -22,7 +22,10 @@ public: * */ std::string getNextTime(std::string timestamp); - void insertOrder(OrderBookEntry &order); + void insertOrder(OrderBookEntry& order); + + // Remove order from the order book + void removeOrder(OrderBookEntry& order); std::vector matchAsksToBids(std::string product, std::string timestamp); diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.cpp b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.cpp index 5c528f3..b6724ea 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.cpp +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.cpp @@ -3,6 +3,11 @@ TradingBot::TradingBot(MerkelMain *merkel) { this->merkel = merkel; + products = merkel->getKnownProducts(); + // We create the log files + logAssets(merkel->returnWallet(), merkel->getCurrentTime(), "start"); + logBidsAsks(OrderBookEntry{1.0, 1.0, "", "", OrderBookType::ask, "simuser"}, "start"); + logUserSales(lastSales, "start"); } void TradingBot::startBot() @@ -26,21 +31,15 @@ void TradingBot::printMenu() // 1 print help std::cout << "1: Retrieve current orders" << std::endl; std::cout << "2: Predict ask and bid rates" << std::endl; - std::cout << "3: Print predictions" << std::endl;; + std::cout << "3: Print predictions" << std::endl; + std::cout << "4: Make automatic bids and asks for the current time" << std::endl; + std::cout << "5: Process bids and asks and go to next time slot" << std::endl; + std::cout << "6: Fully automate this time slot" << std::endl; + std::cout << "7: Fully automate all remaining time slots" << std::endl; std::cout << "8: Exit bot" << std::endl; std::cout << spacer << std::endl; std::cout << "Enter an option: "; return; - // 2 print exchange stats - std::cout << "2: Print exchange stats" << std::endl; - // 3 make an offer - std::cout << "3: Make an offer " << std::endl; - // 4 make a bid - std::cout << "4: Make a bid " << std::endl; - // 5 print wallet - std::cout << "5: Print wallet " << std::endl; - // 6 continue - std::cout << "6: Continue " << std::endl; } int TradingBot::getUserOption() @@ -63,12 +62,14 @@ void TradingBot::processUserOption(int userOption) { if (userOption == 0) return; + // Retrieve bids and asks for current time slot if (userOption == 1) { retrieveOrders(); if (bookAsks.size() > 0 && bookBids.size() > 0) std::cout << "Bids and Asks loaded successfully for the current time." << std::endl; } + // User linear regression to predict future rates if (userOption == 2) { predictRates(); @@ -77,25 +78,77 @@ void TradingBot::processUserOption(int userOption) std::cout << "New predicitons have been created" << std::endl; } } + // Create new bids or asks if they are predicted to make a profit if (userOption == 3) { + if(predictedAsks.size() == 0 || predictedBids.size() == 0) + { + std::cout << "No predictions to print" << std::endl; + return; + } printPredictions(); } + // Based on predicted rates, make new bids or asks + if (userOption == 4) + { + makeAutoBids(); + makeAutoAsks(); + } + // Have Merkel process bids, asks and go to the new time slot + if (userOption == 5) + { + processBidsAsks(); + } + // Automate by pulling orders, predicting rates, making new asks/bids, withdrawing bids/asks + if (userOption == 6) + { + retrieveOrders(); + predictRates(); + makeAutoBids(); + makeAutoAsks(); + processBidsAsks(); + } + // Automate all remaining time slots if (userOption == 7) { - testFunc(); + do + { + retrieveOrders(); + predictRates(); + makeAutoBids(); + makeAutoAsks(); + processBidsAsks(); + } + while (merkel->getCurrentTime() != "END"); + std::cout << "Finished all time slots and made " << salesHistory.size() << " sales" << std::endl; } } +// R1A +// Retrieve orders for the current time slot void TradingBot::retrieveOrders() { bookAsks.clear(); bookAsks = merkel->getCurrentAsks(); bookBids.clear(); bookBids = merkel->getCurrentBids(); + // We'll go through all products and get the mean + // Get the mean ask and bid price and store in history + std::map askMap; + std::map bidMap; + for (const std::string &product : products) + { + askMap[product] = getMean(bookAsks, product); + bidMap[product] = getMean(bookBids, product); + } + askHistory.push_back(askMap); + bidHistory.push_back(bidMap); + return; } +// R1B // Predict the next rates for all products +// Also calculates the mean ask and bid prices per product and saves them to history void TradingBot::predictRates() { if (bookAsks.size() == 0 || bookBids.size() == 0) @@ -104,41 +157,249 @@ void TradingBot::predictRates() return; } - // We'll go through all products and get the mean - std::vector products = merkel->getKnownProducts(); - - // Get all asks and store the mean - std::map askMap; - for (const std::string &product : products) - { - askMap[product] = getMean(bookAsks, product); - std::cout << askMap[product] << std::endl; - } - askHistory.push_back(askMap); - - // Get all bids and store the mean - std::map bidMap; - for (const std::string &product : products) - { - bidMap[product] = getMean(bookBids, product); - } - bidHistory.push_back(bidMap); - // If the history vectors only have 1 element, then we're at the first time slot - // Our prediction will be half way between the mean ask and bid - if (bidHistory.size() == 1) + // We can only predict a future price thorugh regression when there are at least 2 entries in the history vectors + if (bidHistory.size() >= 2 && askHistory.size() >= 2) { - for (std::string &product : products) + for (const std::string &product : products) { - predictedAsks[product] = (bidHistory[0][product] + askHistory[0][product]) / 2; - predictedBids[product] = predictedAsks[product]; + // We want to find an equation of type Y = a + bX where + // Y is the predicted value + // X is the point in time index + // We need to calculate a and b + // The regression needs to be calculated every time slot because it may change due to the new data + + // ASKS // + std::vector askRegression = regressionFromHistory(askHistory, product); + double &askIntercept = askRegression[0]; + double &askSlope = askRegression[1]; + // We calculate the current askRegression value (1-indexed) + // The formula is Y = Y-intercept + Slope * X or regressionValue = askntercept + askSlope * timeIndex + + + currentAsks[product] = askIntercept + askSlope * bidHistory.size(); + predictedAsks[product] = askIntercept + askSlope * (bidHistory.size() + 1); + + // BIDS // + std::vector bidRegression = regressionFromHistory(bidHistory, product); + double &bidIntercept = bidRegression[0]; + double &bidSlope = bidRegression[1]; + // We calculate the current bidRegression value (1-indexed) + // The formula is Y = Y-intercept + Slope * X or regressionValue = bidIntercept + bidSlope * timeIndex + currentBids[product] = bidIntercept + bidSlope * bidHistory.size(); + predictedBids[product] = bidIntercept + bidSlope * (bidHistory.size() + 1); } } + return; +} - //std::map> provMap; +// R2A +// R2B +// R2D +// Make bids automatically +void TradingBot::makeAutoBids() +{ + // The bid history has one or no entries, auto bids are skipped + if (bidHistory.size() < 2) + return; - //askHistory.push_back(getMean(bookAsks)); - //bidHistory.push_back(getMean(bookBids)); + // We use the regression values to determine if we should make bids for the different products + for (std::string &product : products) + { + // We'll make a bid (buy) the product if the predicted price is higher than the current mean stored in bidHistory + if (bidHistory.back()[product] < predictedBids[product]) + { + // The price we'll offer to buy will be half way between the current and predicted regression values + double price = (currentBids[product] + predictedBids[product]) / 2.0; + // To determine how much to offer to buy, we'll use the last saved list of sales to get an idea of the traded volume + double amount = 0.0; + if (lastSales.size() > 0) + { + for(int i=0; i price) + { + merkel->withdrawOrder(bid); + } + } + + // We now make a bid + // R2B + merkel->enterBid(price, amount, product); + // We log the bid + // R4B + logBidsAsks(OrderBookEntry{price, amount, merkel->getCurrentTime(), product, OrderBookType::bid, "simuser"}, "append"); + } + } +} + +// R3A +// R3B +// R3D +// Make asks automatically +void TradingBot::makeAutoAsks() +{ + // The ask history has one or no entries, auto asks are skipped + if (askHistory.size() < 2) + return; + + // We use the regression values to determine if we should make asks for the different products + for (std::string &product : products) + { + // We'll make an ask (sell) the product if the predicted price is lower than the current mean stored in askHistory + if (askHistory.back()[product] > predictedAsks[product]) + { + // The price we'll offer to sell will be half way between the current and predicted regression values + double price = (currentAsks[product] + predictedAsks[product]) / 2.0; + // To determine how much to offer to sell, we'll use the last saved list of sales to get an idea of the traded volume + double amount = 0.0; + if (lastSales.size() > 0) + { + for(int i=0; iwithdrawOrder(ask); + } + } + + // We now make an ask + // R3B + merkel->enterAsk(price, amount, product); + // We log the ask + // R4B + logBidsAsks(OrderBookEntry{price, amount, merkel->getCurrentTime(), product, OrderBookType::ask, "simuser"}, "append"); + } + } +} + +// R2C & R3C +// Ask Merkel to process all bids and asks for the current time slot +void TradingBot::processBidsAsks() +{ + lastSales.clear(); + // R2C & R3C + lastSales = merkel->gotoNextTimeframe(true); + salesHistory.insert(salesHistory.end(), lastSales.begin(), lastSales.end()); + logAssets(merkel->returnWallet(), merkel->getCurrentTime(), "append"); + logUserSales(lastSales, "append"); + return; +} + +// Calculate and Return the Y intercept and slope from a vector of map objects +std::vector TradingBot::regressionFromHistory(std::vector> history, std::string product) +{ + // Check if enough data points are present + if (history.size() < 2) + return std::vector{0.0, 0.0}; + // number of history entries + int hisSize = history.size(); + // Build a vector of history prices for this product + std::vector priceHistory; + for (const std::map &historyEntry : history) + { + priceHistory.push_back(historyEntry.at(product)); + } + // Find the mean of the independent variables + // 1-indexed sum + double sumX = (hisSize * (hisSize + 1)) / 2; + double meanX = sumX / ((double)hisSize); + // Find the mean of the dependent variables + double sumY = 0.0; + double meanY = 0.0; + for (const double &price : priceHistory) + { + sumY += price; + } + meanY = sumY / ((double)hisSize); + // We calculate the distances to the mean lines + // X distances + std::vector distanceX; + for (int i = 1; i <= hisSize; ++i) + { + distanceX.push_back(((double)i) - meanX); + } + // Y distances + std::vector distanceY; + for (const double &price : priceHistory) + { + distanceY.push_back(price - meanY); + } + // We square X distances + std::vector distanceSquareX; + for (int i = 0; i < distanceX.size(); ++i) + { + distanceSquareX.push_back(distanceX[i] * distanceX[i]); + } + // We find the product of the distances + std::vector distanceProducts; + for (int i = 0; i < distanceX.size(); ++i) + { + distanceProducts.push_back(distanceX[i] * distanceY[i]); + } + // We add up the X distance squares + double squareSum = 0.0; + for (const double &square : distanceSquareX) + { + squareSum += square; + } + // We add up the distance products + double productSum = 0.0; + for (const double &distanceP : distanceProducts) + { + productSum += distanceP; + } + // We calculate the slope of the regression line + double slope = productSum / squareSum; + + // We calculate interception with the Y axis + // We know the regression line will go through the (meanX, meanY) point + // We have: meanY = yIntercept + slope * meanX + // So we solve for Y + double yIntercept = meanY - slope * meanX; + return std::vector{yIntercept, slope}; } // return the mean price from the vector @@ -154,7 +415,8 @@ double TradingBot::getMean(std::vector orders, std::string produ ++count; } } - if (count == 0) return 0.0; + if (count == 0) + return 0.0; return sum / count; } @@ -179,73 +441,116 @@ void TradingBot::printPredictions() } } -void TradingBot::testFunc() +// R4A +// Print assets from wallet +void TradingBot::logAssets(std::string Wallet, std::string timestamp, std::string mode) { - std::cout << "Asks" << std::endl; - for (int i = 0; i < bookAsks.size(); ++i) - { - std::cout << "Entry: " << bookAsks[i].timestamp << " - " - << bookAsks[i].product << " - " - << OrderBookEntry::OrderBookTypeToString(bookAsks[i].orderType) << " - " - << std::fixed << bookAsks[i].price << " - " - << std::fixed << bookAsks[i].amount << " - " - << bookAsks[i].username << std::endl; - } - - std::cout << "Bids" << std::endl; - for (int i = 0; i < bookBids.size(); ++i) - { - std::cout << "Entry: " << bookBids[i].timestamp << " - " - << bookBids[i].product << " - " - << OrderBookEntry::OrderBookTypeToString(bookBids[i].orderType) << " - " - << std::fixed << bookBids[i].price << " - " - << std::fixed << bookBids[i].amount << " - " - << bookBids[i].username << std::endl; - } - - return; - std::cout << "Asks" << std::endl; - for (auto const &ask : predictedAsks) - { - std::cout << ask.first << " - " << ask.second << std::endl; - } - - std::cout << "Bids" << std::endl; - for (auto const &bid : predictedBids) - { - std::cout << bid.first << " - " << bid.second << std::endl; - } - - //std::cout << "Ask: " << askHistory[0] << std::endl; - return; - - std::vector currentAsks = merkel->getCurrentAsks(); - std::cout.precision(8); - for (int i = 0; i < currentAsks.size(); ++i) - { - //std::cout << merkel->getCurrentTime() << std::endl; - if (currentAsks[i].product == "DOGE/BTC") + std::fstream assetStream; + if(mode == "start") + assetStream.open("assets.txt", std::ios::out); + else + assetStream.open("assets.txt", std::ios_base::app); + + // Check the file was created properly + if(!assetStream) { - //std::cout.precision(14); - std::cout << "Entry: " << currentAsks[i].timestamp << " - " - << currentAsks[i].product << " - " - << OrderBookEntry::OrderBookTypeToString(currentAsks[i].orderType) << " - " - << std::fixed << currentAsks[i].price << " - " - << std::fixed << currentAsks[i].amount << " - " - << currentAsks[i].username << std::endl; + // We couldn't open/create the file + return; + } + else + { + assetStream << "Time: " << timestamp << std::endl; + assetStream << Wallet << std::endl; + assetStream.close(); + } +} + +// R4B +// Print bids and offers that have been created +void TradingBot::logBidsAsks(OrderBookEntry order, std::string mode) +{ + std::fstream askStream; + std::fstream bidStream; + if(mode == "start") + { + // create the files overwriting anything there + askStream.open("asks.txt", std::ios::out); + bidStream.open("bids.txt", std::ios::out); + askStream.close(); + bidStream.close(); + return; + } + else if(order.orderType == OrderBookType::ask) + { + askStream.open("asks.txt", std::ios_base::app); + // Check the file was created properly + if(!askStream) + { + // We couldn't open/create the file + return; + } + else + { + askStream << order.timestamp << "," + << order.product << "," + << OrderBookEntry::OrderBookTypeToString(order.orderType) << "," + << order.price << "," + << order.amount << std::endl; + askStream.close(); } } - - return; - - std::vector prods = merkel->getKnownProducts(); - for (int i = 0; i < prods.size(); ++i) + else if(order.orderType == OrderBookType::bid) { - std::cout << prods[i] << std::endl; + bidStream.open("bids.txt", std::ios_base::app); + // Check the file was created properly + if(!bidStream) + { + // We couldn't open/create the file + return; + } + else + { + bidStream << order.timestamp << "," + << order.product << "," + << OrderBookEntry::OrderBookTypeToString(order.orderType) << "," + << order.price << "," + << order.amount << std::endl; + bidStream.close(); + } } - return; +} - std::string test1 = OrderBookEntry::OrderBookTypeToString(OrderBookType::bid); - std::cout << test1 << std::endl; - return; +// R4C +// Print successful asks and bids +void TradingBot::logUserSales(std::vector sales, std::string mode) +{ + std::fstream saleStream; + if(mode == "start") + saleStream.open("user-sales.txt", std::ios::out); + else + saleStream.open("user-sales.txt", std::ios_base::app); + + // Check the file was created properly + if(!saleStream) + { + // We couldn't open/create the file + return; + } + else + { + // We loop though the sales vector and check the type username + for(const OrderBookEntry &sale : sales) + { + // this means the sale was created from a user ask or sale. + if(sale.username == "simuser") + { + saleStream << sale.timestamp << "," + << sale.product << "," + << OrderBookEntry::OrderBookTypeToString(sale.orderType) << "," + << sale.price << "," + << sale.amount << std::endl; + } + } + saleStream.close(); + } } \ No newline at end of file diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.h b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.h index f1ee128..f98e389 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.h +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/TradingBot.h @@ -6,6 +6,7 @@ #include #include #include +#include class TradingBot { @@ -13,7 +14,6 @@ public: TradingBot(MerkelMain *merkel); /** start the Trading Bot interface */ void startBot(); - void testFunc(); private: // ===== Functions ===== @@ -22,17 +22,29 @@ private: int getUserOption(); void processUserOption(int userOption); void printPredictions(); - // Exchange functions - void retrieveOrders(); // Retrieves current orders from Merkel and stores them in bookBids and BookAsks + // ==== Exchange functions ==== + void retrieveOrders(); void predictRates(); - // Helper functions + void makeAutoBids(); + void makeAutoAsks(); + void processBidsAsks(); + // ==== Helper functions ==== + static std::vector regressionFromHistory(std::vector> history, std::string product); static double getMean(std::vector orders, std::string product); + static void logAssets(std::string wallet, std::string timestamp, std::string mode); + static void logBidsAsks(OrderBookEntry order, std::string mode); + static void logUserSales(std::vector sales, std::string mode); // ===== Variables ===== MerkelMain *merkel; + std::vector products; std::vector bookBids; std::vector bookAsks; + std::vector lastSales; std::vector> bidHistory; std::vector> askHistory; + std::vector salesHistory; std::map predictedBids; std::map predictedAsks; + std::map currentBids; + std::map currentAsks; }; \ No newline at end of file diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/Wallet.cpp b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/Wallet.cpp index 2079dcd..43b0de0 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/Wallet.cpp +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/Wallet.cpp @@ -78,7 +78,7 @@ bool Wallet::canFulfillOrder(OrderBookEntry order) { double amount = order.amount; std::string currency = currs[0]; - std::cout << "Wallet::canFulfillOrder " << currency << " : " << amount << std::endl; + //std::cout << "Wallet::canFulfillOrder " << currency << " : " << amount << std::endl; return containsCurrency(currency, amount); } @@ -87,7 +87,7 @@ bool Wallet::canFulfillOrder(OrderBookEntry order) { double amount = order.amount * order.price; std::string currency = currs[1]; - std::cout << "Wallet::canFulfillOrder " << currency << " : " << amount << std::endl; + //std::cout << "Wallet::canFulfillOrder " << currency << " : " << amount << std::endl; return containsCurrency(currency, amount); } diff --git a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/main.cpp b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/main.cpp index 7ca1048..c948dca 100644 --- a/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/main.cpp +++ b/CM2005 Object Oriented Programming/Midterm/Merkelrex-TradingBot/main.cpp @@ -7,5 +7,5 @@ int main() { MerkelMain app{}; TradingBot bot{&app}; - app.init(); + bot.startBot(); }