Add Bot.h and Bot.cpp

This commit is contained in:
Lev
2021-06-13 17:11:24 -05:00
parent 312341dca6
commit fdfd01b0f3
14 changed files with 362 additions and 347 deletions

View File

@ -2,10 +2,8 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
CSVReader::CSVReader() CSVReader::CSVReader()
{ {
} }
std::vector<OrderBookEntry> CSVReader::readCSV(std::string csvFilename) std::vector<OrderBookEntry> CSVReader::readCSV(std::string csvFilename)
@ -16,38 +14,44 @@ std::vector<OrderBookEntry> CSVReader::readCSV(std::string csvFilename)
std::string line; std::string line;
if (csvFile.is_open()) if (csvFile.is_open())
{ {
while(std::getline(csvFile, line)) while (std::getline(csvFile, line))
{ {
try { try
{
OrderBookEntry obe = stringsToOBE(tokenise(line, ',')); OrderBookEntry obe = stringsToOBE(tokenise(line, ','));
entries.push_back(obe); entries.push_back(obe);
}catch(const std::exception& e)
{
std::cout << "CSVReader::readCSV bad data" << std::endl;
} }
}// end of while catch (const std::exception &e)
} {
std::cout << "CSVReader::readCSV bad data" << std::endl;
}
} // end of while
}
std::cout << "CSVReader::readCSV read " << entries.size() << " entries" << std::endl; std::cout << "CSVReader::readCSV read " << entries.size() << " entries" << std::endl;
return entries; return entries;
} }
std::vector<std::string> CSVReader::tokenise(std::string csvLine, char separator) std::vector<std::string> CSVReader::tokenise(std::string csvLine, char separator)
{ {
std::vector<std::string> tokens; std::vector<std::string> tokens;
signed int start, end; signed int start, end;
std::string token; std::string token;
start = csvLine.find_first_not_of(separator, 0); start = csvLine.find_first_not_of(separator, 0);
do{ do
{
end = csvLine.find_first_of(separator, start); end = csvLine.find_first_of(separator, start);
if (start == csvLine.length() || start == end) break; if (start == csvLine.length() || start == end)
if (end >= 0) token = csvLine.substr(start, end - start); break;
else token = csvLine.substr(start, csvLine.length() - start); if (end >= 0)
token = csvLine.substr(start, end - start);
else
token = csvLine.substr(start, csvLine.length() - start);
tokens.push_back(token); tokens.push_back(token);
start = end + 1; start = end + 1;
}while(end > 0); } while (end > 0);
return tokens; return tokens;
} }
OrderBookEntry CSVReader::stringsToOBE(std::vector<std::string> tokens) OrderBookEntry CSVReader::stringsToOBE(std::vector<std::string> tokens)
@ -60,46 +64,50 @@ OrderBookEntry CSVReader::stringsToOBE(std::vector<std::string> tokens)
throw std::exception{}; throw std::exception{};
} }
// we have 5 tokens // we have 5 tokens
try { try
price = std::stod(tokens[3]); {
amount = std::stod(tokens[4]); price = std::stod(tokens[3]);
}catch(const std::exception& e){ amount = std::stod(tokens[4]);
std::cout << "CSVReader::stringsToOBE Bad float! " << tokens[3]<< std::endl; }
std::cout << "CSVReader::stringsToOBE Bad float! " << tokens[4]<< std::endl; catch (const std::exception &e)
throw; {
std::cout << "CSVReader::stringsToOBE Bad float! " << tokens[3] << std::endl;
std::cout << "CSVReader::stringsToOBE Bad float! " << tokens[4] << std::endl;
throw;
} }
OrderBookEntry obe{price, OrderBookEntry obe{price,
amount, amount,
tokens[0], tokens[0],
tokens[1], tokens[1],
OrderBookEntry::stringToOrderBookType(tokens[2])}; OrderBookEntry::stringToOrderBookType(tokens[2])};
return obe;
}
OrderBookEntry CSVReader::stringsToOBE(std::string priceString,
std::string amountString,
std::string timestamp,
std::string product,
OrderBookType orderType)
{
double price, amount;
try
{
price = std::stod(priceString);
amount = std::stod(amountString);
}
catch (const std::exception &e)
{
std::cout << "CSVReader::stringsToOBE Bad float! " << priceString << std::endl;
std::cout << "CSVReader::stringsToOBE Bad float! " << amountString << std::endl;
throw;
}
OrderBookEntry obe{price,
amount,
timestamp,
product,
orderType};
return obe;
}
OrderBookEntry CSVReader::stringsToOBE(std::string priceString,
std::string amountString,
std::string timestamp,
std::string product,
OrderBookType orderType)
{
double price, amount;
try {
price = std::stod(priceString);
amount = std::stod(amountString);
}catch(const std::exception& e){
std::cout << "CSVReader::stringsToOBE Bad float! " << priceString<< std::endl;
std::cout << "CSVReader::stringsToOBE Bad float! " << amountString<< std::endl;
throw;
}
OrderBookEntry obe{price,
amount,
timestamp,
product,
orderType};
return obe; return obe;
} }

View File

@ -4,22 +4,20 @@
#include <vector> #include <vector>
#include <string> #include <string>
class CSVReader class CSVReader
{ {
public: public:
CSVReader(); CSVReader();
static std::vector<OrderBookEntry> readCSV(std::string csvFile); static std::vector<OrderBookEntry> readCSV(std::string csvFile);
static std::vector<std::string> tokenise(std::string csvLine, char separator); static std::vector<std::string> tokenise(std::string csvLine, char separator);
static OrderBookEntry stringsToOBE(std::string price,
std::string amount,
std::string timestamp,
std::string product,
OrderBookType OrderBookType);
private: static OrderBookEntry stringsToOBE(std::string price,
static OrderBookEntry stringsToOBE(std::vector<std::string> strings); std::string amount,
std::string timestamp,
std::string product,
OrderBookType OrderBookType);
private:
static OrderBookEntry stringsToOBE(std::vector<std::string> strings);
}; };

View File

@ -6,7 +6,6 @@
MerkelMain::MerkelMain() MerkelMain::MerkelMain()
{ {
} }
void MerkelMain::init() void MerkelMain::init()
@ -16,7 +15,7 @@ void MerkelMain::init()
wallet.insertCurrency("BTC", 10); wallet.insertCurrency("BTC", 10);
while(true) while (true)
{ {
printMenu(); printMenu();
input = getUserOption(); input = getUserOption();
@ -24,7 +23,6 @@ void MerkelMain::init()
} }
} }
void MerkelMain::printMenu() void MerkelMain::printMenu()
{ {
// 1 print help // 1 print help
@ -33,11 +31,11 @@ void MerkelMain::printMenu()
std::cout << "2: Print exchange stats" << std::endl; std::cout << "2: Print exchange stats" << std::endl;
// 3 make an offer // 3 make an offer
std::cout << "3: Make an offer " << std::endl; std::cout << "3: Make an offer " << std::endl;
// 4 make a bid // 4 make a bid
std::cout << "4: Make a bid " << std::endl; std::cout << "4: Make a bid " << std::endl;
// 5 print wallet // 5 print wallet
std::cout << "5: Print wallet " << std::endl; std::cout << "5: Print wallet " << std::endl;
// 6 continue // 6 continue
std::cout << "6: Continue " << std::endl; std::cout << "6: Continue " << std::endl;
std::cout << "============== " << std::endl; std::cout << "============== " << std::endl;
@ -52,34 +50,15 @@ void MerkelMain::printHelp()
void MerkelMain::printMarketStats() void MerkelMain::printMarketStats()
{ {
for (std::string const& p : orderBook.getKnownProducts()) for (std::string const &p : orderBook.getKnownProducts())
{ {
std::cout << "Product: " << p << std::endl; std::cout << "Product: " << p << std::endl;
std::vector<OrderBookEntry> entries = orderBook.getOrders(OrderBookType::ask, std::vector<OrderBookEntry> entries = orderBook.getOrders(OrderBookType::ask,
p, currentTime); p, currentTime);
std::cout << "Asks seen: " << entries.size() << std::endl; std::cout << "Asks seen: " << entries.size() << std::endl;
std::cout << "Max ask: " << OrderBook::getHighPrice(entries) << std::endl; std::cout << "Max ask: " << OrderBook::getHighPrice(entries) << std::endl;
std::cout << "Min ask: " << OrderBook::getLowPrice(entries) << std::endl; std::cout << "Min ask: " << OrderBook::getLowPrice(entries) << std::endl;
} }
// std::cout << "OrderBook contains : " << orders.size() << " entries" << std::endl;
// unsigned int bids = 0;
// unsigned int asks = 0;
// for (OrderBookEntry& e : orders)
// {
// if (e.orderType == OrderBookType::ask)
// {
// asks ++;
// }
// if (e.orderType == OrderBookType::bid)
// {
// bids ++;
// }
// }
// std::cout << "OrderBook asks: " << asks << " bids:" << bids << std::endl;
} }
void MerkelMain::enterAsk() void MerkelMain::enterAsk()
@ -93,28 +72,31 @@ void MerkelMain::enterAsk()
{ {
std::cout << "MerkelMain::enterAsk Bad input! " << input << std::endl; std::cout << "MerkelMain::enterAsk Bad input! " << input << std::endl;
} }
else { else
try { {
try
{
OrderBookEntry obe = CSVReader::stringsToOBE( OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1], tokens[1],
tokens[2], tokens[2],
currentTime, currentTime,
tokens[0], tokens[0],
OrderBookType::ask OrderBookType::ask);
);
obe.username = "simuser"; obe.username = "simuser";
if (wallet.canFulfillOrder(obe)) if (wallet.canFulfillOrder(obe))
{ {
std::cout << "Wallet looks good. " << std::endl; std::cout << "Wallet looks good. " << std::endl;
orderBook.insertOrder(obe); orderBook.insertOrder(obe);
} }
else { else
{
std::cout << "Wallet has insufficient funds . " << std::endl; std::cout << "Wallet has insufficient funds . " << std::endl;
} }
}catch (const std::exception& e) }
catch (const std::exception &e)
{ {
std::cout << " MerkelMain::enterAsk Bad input " << std::endl; std::cout << " MerkelMain::enterAsk Bad input " << std::endl;
} }
} }
} }
@ -129,15 +111,16 @@ void MerkelMain::enterBid()
{ {
std::cout << "MerkelMain::enterBid Bad input! " << input << std::endl; std::cout << "MerkelMain::enterBid Bad input! " << input << std::endl;
} }
else { else
try { {
try
{
OrderBookEntry obe = CSVReader::stringsToOBE( OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1], tokens[1],
tokens[2], tokens[2],
currentTime, currentTime,
tokens[0], tokens[0],
OrderBookType::bid OrderBookType::bid);
);
obe.username = "simuser"; obe.username = "simuser";
if (wallet.canFulfillOrder(obe)) if (wallet.canFulfillOrder(obe))
@ -145,13 +128,15 @@ void MerkelMain::enterBid()
std::cout << "Wallet looks good. " << std::endl; std::cout << "Wallet looks good. " << std::endl;
orderBook.insertOrder(obe); orderBook.insertOrder(obe);
} }
else { else
{
std::cout << "Wallet has insufficient funds . " << std::endl; std::cout << "Wallet has insufficient funds . " << std::endl;
} }
}catch (const std::exception& e) }
catch (const std::exception &e)
{ {
std::cout << " MerkelMain::enterBid Bad input " << std::endl; std::cout << " MerkelMain::enterBid Bad input " << std::endl;
} }
} }
} }
@ -159,41 +144,42 @@ void MerkelMain::printWallet()
{ {
std::cout << wallet.toString() << std::endl; std::cout << wallet.toString() << std::endl;
} }
void MerkelMain::gotoNextTimeframe() void MerkelMain::gotoNextTimeframe()
{ {
std::cout << "Going to next time frame. " << std::endl; std::cout << "Going to next time frame. " << std::endl;
for (std::string p : orderBook.getKnownProducts()) for (std::string p : orderBook.getKnownProducts())
{ {
std::cout << "matching " << p << std::endl; std::cout << "matching " << p << std::endl;
std::vector<OrderBookEntry> sales = orderBook.matchAsksToBids(p, currentTime); std::vector<OrderBookEntry> sales = orderBook.matchAsksToBids(p, currentTime);
std::cout << "Sales: " << sales.size() << std::endl; std::cout << "Sales: " << sales.size() << std::endl;
for (OrderBookEntry& sale : sales) for (OrderBookEntry &sale : sales)
{ {
std::cout << "Sale price: " << sale.price << " amount " << sale.amount << std::endl; std::cout << "Sale price: " << sale.price << " amount " << sale.amount << std::endl;
if (sale.username == "simuser") if (sale.username == "simuser")
{ {
// update the wallet // update the wallet
wallet.processSale(sale); wallet.processSale(sale);
} }
} }
} }
currentTime = orderBook.getNextTime(currentTime); currentTime = orderBook.getNextTime(currentTime);
} }
int MerkelMain::getUserOption() int MerkelMain::getUserOption()
{ {
int userOption = 0; int userOption = 0;
std::string line; std::string line;
std::cout << "Type in 1-6" << std::endl; std::cout << "Type in 1-6" << std::endl;
std::getline(std::cin, line); std::getline(std::cin, line);
try{ try
userOption = std::stoi(line);
}catch(const std::exception& e)
{ {
// userOption = std::stoi(line);
}
catch (const std::exception &e)
{
//
} }
std::cout << "You chose: " << userOption << std::endl; std::cout << "You chose: " << userOption << std::endl;
return userOption; return userOption;
@ -205,28 +191,28 @@ void MerkelMain::processUserOption(int userOption)
{ {
std::cout << "Invalid choice. Choose 1-6" << std::endl; std::cout << "Invalid choice. Choose 1-6" << std::endl;
} }
if (userOption == 1) if (userOption == 1)
{ {
printHelp(); printHelp();
} }
if (userOption == 2) if (userOption == 2)
{ {
printMarketStats(); printMarketStats();
} }
if (userOption == 3) if (userOption == 3)
{ {
enterAsk(); enterAsk();
} }
if (userOption == 4) if (userOption == 4)
{ {
enterBid(); enterBid();
} }
if (userOption == 5) if (userOption == 5)
{ {
printWallet(); printWallet();
} }
if (userOption == 6) if (userOption == 6)
{ {
gotoNextTimeframe(); gotoNextTimeframe();
} }
} }

View File

@ -5,28 +5,27 @@
#include "OrderBook.h" #include "OrderBook.h"
#include "Wallet.h" #include "Wallet.h"
class MerkelMain class MerkelMain
{ {
public: public:
MerkelMain(); MerkelMain();
/** Call this to start the sim */ /** Call this to start the sim */
void init(); void init();
private:
void printMenu();
void printHelp();
void printMarketStats();
void enterAsk();
void enterBid();
void printWallet();
void gotoNextTimeframe();
int getUserOption();
void processUserOption(int userOption);
std::string currentTime; private:
void printMenu();
void printHelp();
void printMarketStats();
void enterAsk();
void enterBid();
void printWallet();
void gotoNextTimeframe();
int getUserOption();
void processUserOption(int userOption);
// OrderBook orderBook{"20200317.csv"}; std::string currentTime;
OrderBook orderBook{"20200601.csv"};
Wallet wallet;
// OrderBook orderBook{"20200317.csv"};
OrderBook orderBook{"20200601.csv"};
Wallet wallet;
}; };

View File

@ -4,7 +4,6 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
/** construct, reading a csv data file */ /** construct, reading a csv data file */
OrderBook::OrderBook(std::string filename) OrderBook::OrderBook(std::string filename)
{ {
@ -16,15 +15,15 @@ std::vector<std::string> OrderBook::getKnownProducts()
{ {
std::vector<std::string> products; std::vector<std::string> products;
std::map<std::string,bool> prodMap; std::map<std::string, bool> prodMap;
for (OrderBookEntry& e : orders) for (OrderBookEntry &e : orders)
{ {
prodMap[e.product] = true; prodMap[e.product] = true;
} }
// now flatten the map to a vector of strings // now flatten the map to a vector of strings
for (auto const& e : prodMap) for (auto const &e : prodMap)
{ {
products.push_back(e.first); products.push_back(e.first);
} }
@ -32,41 +31,41 @@ std::vector<std::string> OrderBook::getKnownProducts()
return products; return products;
} }
/** return vector of Orders according to the sent filters*/ /** return vector of Orders according to the sent filters*/
std::vector<OrderBookEntry> OrderBook::getOrders(OrderBookType type, std::vector<OrderBookEntry> OrderBook::getOrders(OrderBookType type,
std::string product, std::string product,
std::string timestamp) std::string timestamp)
{ {
std::vector<OrderBookEntry> orders_sub; std::vector<OrderBookEntry> orders_sub;
for (OrderBookEntry& e : orders) for (OrderBookEntry &e : orders)
{ {
if (e.orderType == type && if (e.orderType == type &&
e.product == product && e.product == product &&
e.timestamp == timestamp ) e.timestamp == timestamp)
{ {
orders_sub.push_back(e); orders_sub.push_back(e);
} }
} }
return orders_sub; return orders_sub;
} }
double OrderBook::getHighPrice(std::vector<OrderBookEntry> &orders)
double OrderBook::getHighPrice(std::vector<OrderBookEntry>& orders)
{ {
double max = orders[0].price; double max = orders[0].price;
for (OrderBookEntry& e : orders) for (OrderBookEntry &e : orders)
{ {
if (e.price > max)max = e.price; if (e.price > max)
max = e.price;
} }
return max; return max;
} }
double OrderBook::getLowPrice(std::vector<OrderBookEntry> &orders)
double OrderBook::getLowPrice(std::vector<OrderBookEntry>& orders)
{ {
double min = orders[0].price; double min = orders[0].price;
for (OrderBookEntry& e : orders) for (OrderBookEntry &e : orders)
{ {
if (e.price < min)min = e.price; if (e.price < min)
min = e.price;
} }
return min; return min;
} }
@ -79,9 +78,9 @@ std::string OrderBook::getEarliestTime()
std::string OrderBook::getNextTime(std::string timestamp) std::string OrderBook::getNextTime(std::string timestamp)
{ {
std::string next_timestamp = ""; std::string next_timestamp = "";
for (OrderBookEntry& e : orders) for (OrderBookEntry &e : orders)
{ {
if (e.timestamp > timestamp) if (e.timestamp > timestamp)
{ {
next_timestamp = e.timestamp; next_timestamp = e.timestamp;
break; break;
@ -94,7 +93,7 @@ std::string OrderBook::getNextTime(std::string timestamp)
return next_timestamp; return next_timestamp;
} }
void OrderBook::insertOrder(OrderBookEntry& order) void OrderBook::insertOrder(OrderBookEntry &order)
{ {
orders.push_back(order); orders.push_back(order);
std::sort(orders.begin(), orders.end(), OrderBookEntry::compareByTimestamp); std::sort(orders.begin(), orders.end(), OrderBookEntry::compareByTimestamp);
@ -102,17 +101,17 @@ void OrderBook::insertOrder(OrderBookEntry& order)
std::vector<OrderBookEntry> OrderBook::matchAsksToBids(std::string product, std::string timestamp) std::vector<OrderBookEntry> OrderBook::matchAsksToBids(std::string product, std::string timestamp)
{ {
// asks = orderbook.asks // asks = orderbook.asks
std::vector<OrderBookEntry> asks = getOrders(OrderBookType::ask, std::vector<OrderBookEntry> asks = getOrders(OrderBookType::ask,
product, product,
timestamp);
// bids = orderbook.bids
std::vector<OrderBookEntry> bids = getOrders(OrderBookType::bid,
product,
timestamp); timestamp);
// bids = orderbook.bids
std::vector<OrderBookEntry> bids = getOrders(OrderBookType::bid,
product,
timestamp);
// sales = [] // sales = []
std::vector<OrderBookEntry> sales; std::vector<OrderBookEntry> sales;
// I put in a little check to ensure we have bids and asks // I put in a little check to ensure we have bids and asks
// to process. // to process.
@ -127,24 +126,24 @@ std::vector<OrderBookEntry> OrderBook::matchAsksToBids(std::string product, std:
// sort bids highest first // sort bids highest first
std::sort(bids.begin(), bids.end(), OrderBookEntry::compareByPriceDesc); std::sort(bids.begin(), bids.end(), OrderBookEntry::compareByPriceDesc);
// for ask in asks: // for ask in asks:
std::cout << "max ask " << asks[asks.size()-1].price << std::endl; std::cout << "max ask " << asks[asks.size() - 1].price << std::endl;
std::cout << "min ask " << asks[0].price << std::endl; std::cout << "min ask " << asks[0].price << std::endl;
std::cout << "max bid " << bids[0].price << std::endl; std::cout << "max bid " << bids[0].price << std::endl;
std::cout << "min bid " << bids[bids.size()-1].price << std::endl; std::cout << "min bid " << bids[bids.size() - 1].price << std::endl;
for (OrderBookEntry& ask : asks) for (OrderBookEntry &ask : asks)
{ {
// for bid in bids: // for bid in bids:
for (OrderBookEntry& bid : bids) for (OrderBookEntry &bid : bids)
{ {
// if bid.price >= ask.price # we have a match // if bid.price >= ask.price # we have a match
if (bid.price >= ask.price) if (bid.price >= ask.price)
{ {
// sale = new order() // sale = new order()
// sale.price = ask.price // sale.price = ask.price
OrderBookEntry sale{ask.price, 0, timestamp, OrderBookEntry sale{ask.price, 0, timestamp,
product, product,
OrderBookType::asksale}; OrderBookType::asksale};
if (bid.username == "simuser") if (bid.username == "simuser")
{ {
@ -154,63 +153,62 @@ std::vector<OrderBookEntry> OrderBook::matchAsksToBids(std::string product, std:
if (ask.username == "simuser") if (ask.username == "simuser")
{ {
sale.username = "simuser"; sale.username = "simuser";
sale.orderType = OrderBookType::asksale; sale.orderType = OrderBookType::asksale;
} }
// # now work out how much was sold and // # now work out how much was sold and
// # create new bids and asks covering // # create new bids and asks covering
// # anything that was not sold // # anything that was not sold
// if bid.amount == ask.amount: # bid completely clears ask // if bid.amount == ask.amount: # bid completely clears ask
if (bid.amount == ask.amount) if (bid.amount == ask.amount)
{ {
// sale.amount = ask.amount // sale.amount = ask.amount
sale.amount = ask.amount; sale.amount = ask.amount;
// sales.append(sale) // sales.append(sale)
sales.push_back(sale); sales.push_back(sale);
// bid.amount = 0 # make sure the bid is not processed again // bid.amount = 0 # make sure the bid is not processed again
bid.amount = 0; bid.amount = 0;
// # can do no more with this ask // # can do no more with this ask
// # go onto the next ask // # go onto the next ask
// break // break
break; break;
} }
// if bid.amount > ask.amount: # ask is completely gone slice the bid // if bid.amount > ask.amount: # ask is completely gone slice the bid
if (bid.amount > ask.amount) if (bid.amount > ask.amount)
{ {
// sale.amount = ask.amount // sale.amount = ask.amount
sale.amount = ask.amount; sale.amount = ask.amount;
// sales.append(sale) // sales.append(sale)
sales.push_back(sale); sales.push_back(sale);
// # we adjust the bid in place // # we adjust the bid in place
// # so it can be used to process the next ask // # so it can be used to process the next ask
// bid.amount = bid.amount - ask.amount // bid.amount = bid.amount - ask.amount
bid.amount = bid.amount - ask.amount; bid.amount = bid.amount - ask.amount;
// # ask is completely gone, so go to next ask // # ask is completely gone, so go to next ask
// break // break
break; break;
} }
// if bid.amount < ask.amount # bid is completely gone, slice the ask
// if bid.amount < ask.amount # bid is completely gone, slice the ask if (bid.amount < ask.amount &&
if (bid.amount < ask.amount && bid.amount > 0)
bid.amount > 0)
{ {
// sale.amount = bid.amount // sale.amount = bid.amount
sale.amount = bid.amount; sale.amount = bid.amount;
// sales.append(sale) // sales.append(sale)
sales.push_back(sale); sales.push_back(sale);
// # update the ask // # update the ask
// # and allow further bids to process the remaining amount // # and allow further bids to process the remaining amount
// ask.amount = ask.amount - bid.amount // ask.amount = ask.amount - bid.amount
ask.amount = ask.amount - bid.amount; ask.amount = ask.amount - bid.amount;
// bid.amount = 0 # make sure the bid is not processed again // bid.amount = 0 # make sure the bid is not processed again
bid.amount = 0; bid.amount = 0;
// # some ask remains so go to the next bid // # some ask remains so go to the next bid
// continue // continue
continue; continue;
} }
} }
} }
} }
return sales; return sales;
} }

View File

@ -6,33 +6,31 @@
class OrderBook class OrderBook
{ {
public: public:
/** construct, reading a csv data file */ /** construct, reading a csv data file */
OrderBook(std::string filename); OrderBook(std::string filename);
/** return vector of all know products in the dataset*/ /** return vector of all know products in the dataset*/
std::vector<std::string> getKnownProducts(); std::vector<std::string> getKnownProducts();
/** return vector of Orders according to the sent filters*/ /** return vector of Orders according to the sent filters*/
std::vector<OrderBookEntry> getOrders(OrderBookType type, std::vector<OrderBookEntry> getOrders(OrderBookType type,
std::string product, std::string product,
std::string timestamp); std::string timestamp);
/** returns the earliest time in the orderbook*/ /** returns the earliest time in the orderbook*/
std::string getEarliestTime(); std::string getEarliestTime();
/** returns the next time after the /** returns the next time after the
* sent time in the orderbook * sent time in the orderbook
* If there is no next timestamp, wraps around to the start * If there is no next timestamp, wraps around to the start
* */ * */
std::string getNextTime(std::string timestamp); std::string getNextTime(std::string timestamp);
void insertOrder(OrderBookEntry& order); void insertOrder(OrderBookEntry &order);
std::vector<OrderBookEntry> matchAsksToBids(std::string product, std::string timestamp); std::vector<OrderBookEntry> matchAsksToBids(std::string product, std::string timestamp);
static double getHighPrice(std::vector<OrderBookEntry>& orders);
static double getLowPrice(std::vector<OrderBookEntry>& orders);
private:
std::vector<OrderBookEntry> orders;
static double getHighPrice(std::vector<OrderBookEntry> &orders);
static double getLowPrice(std::vector<OrderBookEntry> &orders);
private:
std::vector<OrderBookEntry> orders;
}; };

View File

@ -1,20 +1,20 @@
#include "OrderBookEntry.h" #include "OrderBookEntry.h"
OrderBookEntry::OrderBookEntry( double _price, OrderBookEntry::OrderBookEntry(
double _amount, double _price,
std::string _timestamp, double _amount,
std::string _product, std::string _timestamp,
OrderBookType _orderType, std::string _product,
std::string _username) OrderBookType _orderType,
: price(_price), std::string _username)
amount(_amount), :
timestamp(_timestamp), price(_price),
product(_product), amount(_amount),
orderType(_orderType), timestamp(_timestamp),
username(_username) product(_product),
orderType(_orderType),
username(_username)
{ {
} }
OrderBookType OrderBookEntry::stringToOrderBookType(std::string s) OrderBookType OrderBookEntry::stringToOrderBookType(std::string s)

View File

@ -2,39 +2,44 @@
#include <string> #include <string>
enum class OrderBookType{bid, ask, unknown, asksale, bidsale}; enum class OrderBookType
{
bid,
ask,
unknown,
asksale,
bidsale
};
class OrderBookEntry class OrderBookEntry
{ {
public: public:
OrderBookEntry(double _price,
double _amount,
std::string _timestamp,
std::string _product,
OrderBookType _orderType,
std::string username = "dataset");
OrderBookEntry( double _price, static OrderBookType stringToOrderBookType(std::string s);
double _amount,
std::string _timestamp,
std::string _product,
OrderBookType _orderType,
std::string username = "dataset");
static OrderBookType stringToOrderBookType(std::string s); static bool compareByTimestamp(OrderBookEntry &e1, OrderBookEntry &e2)
{
return e1.timestamp < e2.timestamp;
}
static bool compareByPriceAsc(OrderBookEntry &e1, OrderBookEntry &e2)
{
return e1.price < e2.price;
}
static bool compareByPriceDesc(OrderBookEntry &e1, OrderBookEntry &e2)
{
return e1.price > e2.price;
}
static bool compareByTimestamp(OrderBookEntry& e1, OrderBookEntry& e2) double price;
{ double amount;
return e1.timestamp < e2.timestamp; std::string timestamp;
} std::string product;
static bool compareByPriceAsc(OrderBookEntry& e1, OrderBookEntry& e2) OrderBookType orderType;
{ std::string username;
return e1.price < e2.price;
}
static bool compareByPriceDesc(OrderBookEntry& e1, OrderBookEntry& e2)
{
return e1.price > e2.price;
}
double price;
double amount;
std::string timestamp;
std::string product;
OrderBookType orderType;
std::string username;
}; };

View File

@ -0,0 +1,20 @@
#include "TradingBot.h"
#include <iostream>
Bot::Bot(std::string filename)
{
orders = CSVReader::readCSV(filename);
Print(20);
}
void Bot::Print(int intLimit)
{
int i = 0;
for (OrderBookEntry &entry : orders)
{
std::cout << entry.product << " " << entry.price << " " << entry.amount << std::endl;
i++;
if (i == intLimit)
break;
}
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "OrderBook.h"
#include <vector>
//#include "CSVReader.h"
class Bot
{
public:
Bot(std::string filename);
void Print(int intLimit);
private:
std::vector<OrderBookEntry> orders;
};

View File

@ -4,8 +4,6 @@
Wallet::Wallet() Wallet::Wallet()
{ {
} }
void Wallet::insertCurrency(std::string type, double amount) void Wallet::insertCurrency(std::string type, double amount)
@ -19,33 +17,35 @@ void Wallet::insertCurrency(std::string type, double amount)
{ {
balance = 0; balance = 0;
} }
else { // is there else
{ // is there
balance = currencies[type]; balance = currencies[type];
} }
balance += amount; balance += amount;
currencies[type] = balance; currencies[type] = balance;
} }
bool Wallet::removeCurrency(std::string type, double amount) bool Wallet::removeCurrency(std::string type, double amount)
{ {
if (amount < 0) if (amount < 0)
{ {
return false; return false;
} }
if (currencies.count(type) == 0) // not there yet if (currencies.count(type) == 0) // not there yet
{ {
//std::cout << "No currency for " << type << std::endl; //std::cout << "No currency for " << type << std::endl;
return false; return false;
} }
else { // is there - do we have enough else
if (containsCurrency(type, amount))// we have enough { // is there - do we have enough
if (containsCurrency(type, amount)) // we have enough
{ {
//std::cout << "Removing " << type << ": " << amount << std::endl; //std::cout << "Removing " << type << ": " << amount << std::endl;
currencies[type] -= amount; currencies[type] -= amount;
return true; return true;
} }
else // they have it but not enough. else // they have it but not enough.
return false; return false;
} }
} }
@ -53,15 +53,14 @@ bool Wallet::containsCurrency(std::string type, double amount)
{ {
if (currencies.count(type) == 0) // not there yet if (currencies.count(type) == 0) // not there yet
return false; return false;
else else
return currencies[type] >= amount; return currencies[type] >= amount;
} }
std::string Wallet::toString() std::string Wallet::toString()
{ {
std::string s; std::string s;
for (std::pair<std::string,double> pair : currencies) for (std::pair<std::string, double> pair : currencies)
{ {
std::string currency = pair.first; std::string currency = pair.first;
double amount = pair.second; double amount = pair.second;
@ -91,12 +90,10 @@ bool Wallet::canFulfillOrder(OrderBookEntry order)
return containsCurrency(currency, amount); return containsCurrency(currency, amount);
} }
return false;
return false;
} }
void Wallet::processSale(OrderBookEntry& sale) void Wallet::processSale(OrderBookEntry &sale)
{ {
std::vector<std::string> currs = CSVReader::tokenise(sale.product, '/'); std::vector<std::string> currs = CSVReader::tokenise(sale.product, '/');
// ask // ask
@ -109,7 +106,6 @@ void Wallet::processSale(OrderBookEntry& sale)
currencies[incomingCurrency] += incomingAmount; currencies[incomingCurrency] += incomingAmount;
currencies[outgoingCurrency] -= outgoingAmount; currencies[outgoingCurrency] -= outgoingAmount;
} }
// bid // bid
if (sale.orderType == OrderBookType::bidsale) if (sale.orderType == OrderBookType::bidsale)
@ -123,9 +119,8 @@ void Wallet::processSale(OrderBookEntry& sale)
currencies[outgoingCurrency] -= outgoingAmount; currencies[outgoingCurrency] -= outgoingAmount;
} }
} }
std::ostream& operator<<(std::ostream& os, Wallet& wallet) std::ostream &operator<<(std::ostream &os, Wallet &wallet)
{ {
os << wallet.toString(); os << wallet.toString();
return os; return os;
} }

View File

@ -5,36 +5,28 @@
#include "OrderBookEntry.h" #include "OrderBookEntry.h"
#include <iostream> #include <iostream>
class Wallet class Wallet
{ {
public: public:
Wallet(); Wallet();
/** insert currency to the wallet */ /** insert currency to the wallet */
void insertCurrency(std::string type, double amount); void insertCurrency(std::string type, double amount);
/** remove currency from the wallet */ /** remove currency from the wallet */
bool removeCurrency(std::string type, double amount); bool removeCurrency(std::string type, double amount);
/** check if the wallet contains this much currency or more */ /** check if the wallet contains this much currency or more */
bool containsCurrency(std::string type, double amount); bool containsCurrency(std::string type, double amount);
/** checks if the wallet can cope with this ask or bid.*/ /** checks if the wallet can cope with this ask or bid.*/
bool canFulfillOrder(OrderBookEntry order); bool canFulfillOrder(OrderBookEntry order);
/** update the contents of the wallet /** update the contents of the wallet
* assumes the order was made by the owner of the wallet * assumes the order was made by the owner of the wallet
*/ */
void processSale(OrderBookEntry& sale); void processSale(OrderBookEntry &sale);
/** generate a string representation of the wallet */
std::string toString();
friend std::ostream &operator<<(std::ostream &os, Wallet &wallet);
/** generate a string representation of the wallet */ private:
std::string toString(); std::map<std::string, double> currencies;
friend std::ostream& operator<<(std::ostream& os, Wallet& wallet);
private:
std::map<std::string,double> currencies;
}; };

View File

@ -1,10 +1,11 @@
#include "Wallet.h" #include "Wallet.h"
#include <iostream> #include <iostream>
#include "MerkelMain.h" #include "MerkelMain.h"
#include "TradingBot.h"
int main() int main()
{ {
MerkelMain app{}; MerkelMain app{};
app.init(); Bot myBot("20200317.csv");
//app.init();
} }