Joel Grunbaum
2022-01-09 b4cf0a2e71ad2c204925b33f9600dc720e25b827
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)
bb2353 11     : price{price}, side{side}, remaining_volume{volume},
16b655 12       filled_volume(0), timestamp{timestamp}, id{id}
JG 13 {
14 }
bb2353 15
16b655 16 Level::Level(Order& order)
bb2353 17     : price{order.price}, volume(order.remaining_volume), side{order.side},
16b655 18       timestamp{order.timestamp}, id{order.id}
JG 19 {
bb2353 20 }
JG 21
16b655 22 bool operator<(const Level& a, const Level& b)
JG 23 {
24     if (a.price < b.price)
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 {
34     if (a.price > b.price)
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 {
44     if (a.price <= b.price)
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 {
54     if (a.price >= b.price)
55     return true;
56     else if (a.price == b.price && (a.timestamp >= b.timestamp))
57     return true;
58     else
59     return false;
60 }
61
62 bool operator==(const Level& a, const Level& b)
63 {
64     if (a.price == b.price && (a.timestamp == b.timestamp))
65     return true;
66     else
67     return false;
127d5a 68 }
JG 69
70 std::ostream& operator<<(std::ostream& out, const Level& a)
71 {
16b655 72     return out << "Price: " << a.price << ", volume: " << a.volume
JG 73                << ", time: " << a.timestamp << ", id: " << a.id;
bb2353 74 }
JG 75
76 Book::Book()
b4cf0a 77     : bidSide(), askSide(), productType(TEST), product("a"), stationId(7),
bb2353 78       unit("c"), expiry(std::chrono::nanoseconds(0)), aggFee(1), pasFee(-1),
16b655 79       broFee(2)
JG 80 {
81 }
bb2353 82
JG 83 Book::Book(ProductTypeEnum productType, std::string product,
b4cf0a 84            int stationId, std::string unit,
bb2353 85            std::chrono::nanoseconds expiry, double aggFee, double pasFee,
JG 86            double broFee)
87     : bidSide{}, askSide{}, productType{productType}, product(product),
88       stationId(stationId), unit(unit), expiry(expiry), aggFee(aggFee),
16b655 89       pasFee(pasFee), broFee(broFee)
JG 90 {
91 }
bb2353 92
16b655 93 void Book::ask(Order& order)
JG 94 {
95     while (this->bidSide.size() && this->bidSide[0].price >= order.price) {
96     if (this->bidSide[0].volume > order.remaining_volume) {
97         int temp = this->bidSide[0].volume;
98         order.filled_volume += temp;
99         this->bidSide.front().volume -= order.remaining_volume;
100         order.remaining_volume -= temp;
101         break;
102     } else {
103         order.remaining_volume -= this->bidSide[0].volume;
104         order.filled_volume += this->bidSide[0].volume;
105         this->bidSide.erase(this->bidSide.begin());
106         std::make_heap(this->bidSide.begin(), this->bidSide.end(),
107                        std::less<Level>());
108     }
bb2353 109     }
16b655 110     if (order.remaining_volume > 0) {
JG 111     this->askSide.emplace(this->askSide.begin(), order);
112     std::make_heap(this->askSide.begin(), this->askSide.end(),
113                    std::greater<Level>());
bb2353 114     }
JG 115 }
116
16b655 117 void Book::bid(Order& order)
JG 118 {
119     while (this->askSide.size() && this->askSide[0].price <= order.price) {
120     if (this->askSide[0].volume > order.remaining_volume) {
121         int temp = this->askSide.front().volume;
122         order.filled_volume += temp;
123         this->askSide.front().volume -= order.remaining_volume;
124         order.remaining_volume -= temp;
125         break;
126     } else {
127         order.remaining_volume -= this->askSide[0].volume;
128         order.filled_volume += this->askSide[0].volume;
129         this->askSide.erase(this->askSide.begin());
130         std::make_heap(this->askSide.begin(), this->askSide.end(),
131                        std::greater<Level>());
132     }
133     }
134     if (order.remaining_volume > 0) {
135     this->bidSide.emplace(this->bidSide.begin(), order);
136     std::make_heap(this->bidSide.begin(), this->bidSide.end(),
137                    std::less<Level>());
138     }
bb2353 139 }
JG 140
16b655 141 void Book::printBook(std::size_t numOrders)
JG 142 {
143     std::cout << "Sell side: " << this->askSide.size() << std::endl;
144     std::vector<Level> askCopy(this->askSide);
6926be 145     std::size_t count = 0;
16b655 146     std::sort(askCopy.begin(), askCopy.end());
JG 147     for (auto i = askCopy.rbegin(); i != askCopy.rend() && count < numOrders; i++, count++) {
148         std::cout << *i << std::endl;
149     }
150     std::cout << "Buy side: " << this->bidSide.size() << std::endl;
151     std::vector<Level> bidCopy(this->bidSide);
152     count = 0;
153     std::sort(bidCopy.begin(), bidCopy.end());
154     for (auto i = bidCopy.rbegin(); i != bidCopy.rend() && count < numOrders; i++, count++) {
155         std::cout << *i << std::endl;
156     }
157     }
158
159 Book testBook(int orders, bool printBook)
160 {
161     Book b = Book();
162     double time(1);
163     for (int i = 1; i < orders; i++) {
164     Order t(i, Buy, 10, time++, "a");
165     b.bid(t);
166     }
167     for (int i = orders + 1; i < 2 * orders; i++) {
168     Order t(i, Sell, 10, time++, "b");
169     b.ask(t);
170     }
171     if (printBook) b.printBook(orders - 1);
172     return b;
bb2353 173 }
16b655 174 } // namespace book