1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
{
orders = CSVReader::readCSV(filename);
}
/** return vector of all known products in the dataset*/
std::vector<std::string> OrderBook::getKnownProducts()
{
std::vector<std::string> products;
std::map<std::string,bool> prodMap;
for (OrderBookEntry& e : orders)
{
prodMap[e.product] = true;
}
// now flatten the map to a vector of strings
for (auto const& e : prodMap)
{
products.push_back(e.first);
}
return products;
}
/** return vector of Orders according to the sent filters*/
std::vector<OrderBookEntry> OrderBook::getOrders(OrderBookType type,
std::string product,
std::string timestamp)
{
std::vector<OrderBookEntry> orders_sub;
for (OrderBookEntry& e : orders)
{
if (e.orderType == type &&
e.product == product &&
e.timestamp == timestamp )
{
orders_sub.push_back(e);
}
}
return orders_sub;
}
void OrderBook::insertOrder(OrderBookEntry& order)
{
orders.push_back(order);
std::sort(orders.begin(), orders.end(), OrderBookEntry::compareByTimestamp);
}
/* R2D: Using the live order book from the exchange, decide if it should withdraw its bids at any point in time */
/* R3D: Using the live order book from the exchange, decide if it should withdraw its offers at any point in time */
void OrderBook::withdrawOrder(std::string time)
{
for (std::size_t i = orders.size() - 1; i < orders.size(); --i)
{
if(orders[i].timestamp == time && orders[i].username == "simuser")
{
orders.erase(orders.begin() + i);
}
}
}
std::vector<OrderBookEntry> OrderBook::matchAsksToBids(std::string product, std::string timestamp)
{
// asks = orderbook.asks
std::vector<OrderBookEntry> asks = getOrders(OrderBookType::ask,
product,
timestamp);
// bids = orderbook.bids
std::vector<OrderBookEntry> bids = getOrders(OrderBookType::bid,
product,
timestamp);
// sales = []
std::vector<OrderBookEntry> sales;
// I put in a little check to ensure we have bids and asks
// to process.
if (asks.size() == 0 || bids.size() == 0)
{
std::cout << " OrderBook::matchAsksToBids no bids or asks" << std::endl;
return sales;
}
// sort asks lowest first
std::sort(asks.begin(), asks.end(), OrderBookEntry::compareByPriceAsc);
// sort bids highest first
std::sort(bids.begin(), bids.end(), OrderBookEntry::compareByPriceDesc);
// for ask in asks:
std::cout << "max ask " << asks[asks.size()-1].price << std::endl;
std::cout << "min ask " << asks[0].price << std::endl;
std::cout << "max bid " << bids[0].price << std::endl;
std::cout << "min bid " << bids[bids.size()-1].price << std::endl;
for (OrderBookEntry& ask : asks)
{
// for bid in bids:
for (OrderBookEntry& bid : bids)
{
// if bid.price >= ask.price # we have a match
if (bid.price >= ask.price)
{
// sale = new order()
// sale.price = ask.price
OrderBookEntry sale{ask.price, 0, timestamp,
product,
OrderBookType::asksale};
if (bid.username == "simuser")
{
sale.username = "simuser";
sale.orderType = OrderBookType::bidsale;
}
if (ask.username == "simuser")
{
sale.username = "simuser";
sale.orderType = OrderBookType::asksale;
}
// # now work out how much was sold and
// # create new bids and asks covering
// # anything that was not sold
// if bid.amount == ask.amount: # bid completely clears ask
if (bid.amount == ask.amount)
{
// sale.amount = ask.amount
sale.amount = ask.amount;
// sales.append(sale)
sales.push_back(sale);
// bid.amount = 0 # make sure the bid is not processed again
bid.amount = 0;
// # can do no more with this ask
// # go onto the next ask
// break
break;
}
// if bid.amount > ask.amount: # ask is completely gone slice the bid
if (bid.amount > ask.amount)
{
// sale.amount = ask.amount
sale.amount = ask.amount;
// sales.append(sale)
sales.push_back(sale);
// # we adjust the bid in place
// # so it can be used to process the next ask
// bid.amount = bid.amount - ask.amount
bid.amount = bid.amount - ask.amount;
// # ask is completely gone, so go to next ask
// break
break;
}
// if bid.amount < ask.amount # bid is completely gone, slice the ask
if (bid.amount < ask.amount &&
bid.amount > 0)
{
// sale.amount = bid.amount
sale.amount = bid.amount;
// sales.append(sale)
sales.push_back(sale);
// # update the ask
// # and allow further bids to process the remaining 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;
// # some ask remains so go to the next bid
// continue
continue;
}
}
}
}
return sales;
}/
|