Joel Grunbaum
2022-01-10 6bdd28a09c589cf631fce948476d48e9375f72a0
commit | author | age
bb2353 1 #include "book.hpp"
16b655 2 #include <algorithm>
bb2353 3 #include <chrono>
127d5a 4 #include <cstddef>
bb2353 5 #include <iostream>
JG 6
16b655 7 namespace book
JG 8 {
9 Order::Order(double price, OrderSideEnum side, int volume, double timestamp,
10              std::string id)
2c515f 11     : price{price}, side{side}, remaining_volume{volume},
JG 12       filled_volume(0), timestamp{timestamp}, id{id}
16b655 13 {
JG 14 }
bb2353 15
16b655 16 Level::Level(Order& order)
2c515f 17     : price{order.price}, volume(order.remaining_volume), side{order.side},
JG 18       timestamp{order.timestamp}, id{order.id}
16b655 19 {
bb2353 20 }
JG 21
16b655 22 bool operator<(const Level& a, const Level& b)
JG 23 {
2c515f 24     if (a.price < b.price)
JG 25         return true;
26     else if (a.price == b.price && (a.timestamp > b.timestamp))
27         return true;
28     else
29         return false;
bb2353 30 }
JG 31
16b655 32 bool operator>(const Level& a, const Level& b)
JG 33 {
2c515f 34     if (a.price > b.price)
JG 35         return true;
36     else if (a.price == b.price && (a.timestamp > b.timestamp))
37         return true;
38     else
39         return false;
bb2353 40 }
JG 41
16b655 42 bool operator<=(const Level& a, const Level& b)
JG 43 {
2c515f 44     if (a.price <= b.price)
JG 45         return true;
46     else if (a.price == b.price && (a.timestamp >= b.timestamp))
47         return true;
48     else
49         return false;
bb2353 50 }
JG 51
16b655 52 bool operator>=(const Level& a, const Level& b)
JG 53 {
2c515f 54     if (a.price >= b.price)
JG 55         return true;
56     else if (a.price == b.price && (a.timestamp >= b.timestamp))
57         return true;
58     else
59         return false;
16b655 60 }
JG 61
62 bool operator==(const Level& a, const Level& b)
63 {
2c515f 64     if (a.price == b.price && (a.timestamp == b.timestamp))
JG 65         return true;
66     else
67         return false;
127d5a 68 }
JG 69
70 std::ostream& operator<<(std::ostream& out, const Level& a)
71 {
2c515f 72     return out << "Price: " << a.price << ", volume: " << a.volume
JG 73                << ", time: " << a.timestamp << ", id: " << a.id;
bb2353 74 }
JG 75
76 Book::Book()
2c515f 77     : bidSide(), askSide(), productType(TEST), product("a"), stationId(7),
JG 78       unit("c"), expiry(std::chrono::nanoseconds(0)), aggFee(1), pasFee(-1),
79       broFee(2)
16b655 80 {
JG 81 }
bb2353 82
2c515f 83 Book::Book(ProductTypeEnum productType, std::string product, int stationId,
JG 84            std::string unit, std::chrono::nanoseconds expiry, double aggFee,
85            double pasFee, double broFee)
86     : bidSide{}, askSide{}, productType{productType}, product(product),
87       stationId(stationId), unit(unit), expiry(expiry), aggFee(aggFee),
88       pasFee(pasFee), broFee(broFee)
16b655 89 {
JG 90 }
bb2353 91
16b655 92 void Book::ask(Order& order)
JG 93 {
2c515f 94     while (this->bidSide.size() && this->bidSide[0].price >= order.price) {
JG 95         if (this->bidSide[0].volume > order.remaining_volume) {
96             int temp = this->bidSide[0].volume;
97             order.filled_volume += temp;
98             this->bidSide.front().volume -= order.remaining_volume;
99             order.remaining_volume -= temp;
100             break;
101         } else {
102             order.remaining_volume -= this->bidSide[0].volume;
103             order.filled_volume += this->bidSide[0].volume;
104             this->bidSide.erase(this->bidSide.begin());
105             std::make_heap(this->bidSide.begin(), this->bidSide.end(),
106                            std::less<Level>());
107         }
16b655 108     }
2c515f 109     if (order.remaining_volume > 0) {
JG 110         this->askSide.emplace_back(order);
111         std::make_heap(this->askSide.begin(), this->askSide.end(),
112                        std::greater<Level>());
113     }
bb2353 114 }
JG 115
16b655 116 void Book::bid(Order& order)
JG 117 {
2c515f 118     while (this->askSide.size() && this->askSide[0].price <= order.price) {
JG 119         if (this->askSide[0].volume > order.remaining_volume) {
120             int temp = this->askSide.front().volume;
121             order.filled_volume += temp;
122             this->askSide.front().volume -= order.remaining_volume;
123             order.remaining_volume -= temp;
124             break;
125         } else {
126             order.remaining_volume -= this->askSide[0].volume;
127             order.filled_volume += this->askSide[0].volume;
128             this->askSide.erase(this->askSide.begin());
129             std::make_heap(this->askSide.begin(), this->askSide.end(),
130                            std::greater<Level>());
131         }
16b655 132     }
2c515f 133     if (order.remaining_volume > 0) {
JG 134         this->bidSide.emplace_back(order);
135         std::make_heap(this->bidSide.begin(), this->bidSide.end(),
136                        std::less<Level>());
137     }
bb2353 138 }
JG 139
16b655 140 void Book::printBook(std::size_t numOrders)
JG 141 {
2c515f 142     std::cout << "Sell side: " << this->askSide.size() << std::endl;
JG 143     std::vector<Level> askCopy(this->askSide);
144     std::size_t count = 0;
145     std::sort(askCopy.begin(), askCopy.end());
146     std::reverse(askCopy.begin(), askCopy.end());
147     double price = askCopy.front().price;
148     for (auto i : askCopy) {
149         std::cout << i << std::endl;
150         count++;
151         if (count > numOrders) break;
152     }
153     std::cout << "Buy side: " << this->bidSide.size() << std::endl;
154     std::vector<Level> bidCopy(this->bidSide);
155     count = 0;
156     std::sort(bidCopy.begin(), bidCopy.end());
157     std::reverse(bidCopy.begin(), bidCopy.end());
158     price = bidCopy.front().price;
159     for (auto i : bidCopy) {
160         std::cout << i << std::endl;
161         count++;
162         if (count > numOrders) break;
163     }
164 }
16b655 165
JG 166 Book testBook(int orders, bool printBook)
167 {
2c515f 168     Book b = Book();
JG 169     double time(1);
170     for (int i = 1; i < orders; i++) {
171         Order t(i, Buy, 10, time++, "a");
172         b.bid(t);
173     }
174     for (int i = orders + 1; i < 2 * orders; i++) {
175         Order t(i, Sell, 10, time++, "b");
176         b.ask(t);
177     }
178     if (printBook) b.printBook(orders - 1);
179     return b;
bb2353 180 }
16b655 181 } // namespace book