Repository navigation
Expand file tree
/
Copy pathorder_book.cpp
More file actions
127 lines (100 loc) · 4.07 KB
/
Copy pathorder_book.cpp
File metadata and controls
127 lines (100 loc) · 4.07 KB
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
#include "order_book.h"
#include <iomanip>
#include <iostream>
OrderBook:: OrderBook(): num_bids_(0), num_asks_(0){
for(size_t i=0; i<MAX_ORDERS; i++){
orders_[i].active = false;
}
}
void OrderBook::add_order(uint64_t ref_num, char side, uint32_t shares, uint32_t price, uint16_t locate) {
size_t idx = (ref_num * 11400714819323198485ULL) & (MAX_ORDERS - 1);
while (orders_[idx].active && orders_[idx].order_ref_num != ref_num) {
idx = (idx + 1) & (MAX_ORDERS - 1);
}
orders_[idx] = Order{ref_num, side, shares, price, locate, true};
if (side == 'B') {
add_bid_volume(price, shares);
} else if (side == 'S') {
add_ask_volume(price, shares);
}
}
void OrderBook::execute_order(uint64_t ref_num, uint32_t exec_shares) {
size_t idx = (ref_num * 11400714819323198485ULL) & (MAX_ORDERS - 1);
while (orders_[idx].active && orders_[idx].order_ref_num != ref_num) {
idx = (idx + 1) & (MAX_ORDERS - 1);
}
Order& order = orders_[idx];
if(!order.active || order.order_ref_num != ref_num) return;
if(order.side == 'B'){
remove_bid_volume(order.price, exec_shares);
} else if(order.side == 'S'){
remove_ask_volume(order.price, exec_shares);
}
if (order.shares <= exec_shares) {
order.active = false;
} else {
order.shares -= exec_shares; // Order partially filled
}
}
void OrderBook::cancel_order(uint64_t ref_num, uint32_t cancel_shares) {
// Identical volume-reduction logic to execution
execute_order(ref_num, cancel_shares);
}
void OrderBook::delete_order(uint64_t ref_num) {
size_t idx = (ref_num * 11400714819323198485ULL) & (MAX_ORDERS - 1);
while (orders_[idx].active && orders_[idx].order_ref_num != ref_num) {
idx = (idx + 1) & (MAX_ORDERS - 1);
}
Order& order = orders_[idx];
if(!order.active || order.order_ref_num != ref_num) return;
if(order.side == 'B'){
remove_bid_volume(order.price, order.shares);
} else if(order.side == 'S'){
remove_ask_volume(order.price, order.shares);
}
order.active = false;
}
void OrderBook::replace_order(uint64_t orig_ref_num, uint64_t new_ref_num, uint32_t new_shares, uint32_t new_price) {
size_t idx = (orig_ref_num * 11400714819323198485ULL) & (MAX_ORDERS - 1);
while (orders_[idx].active && orders_[idx].order_ref_num != orig_ref_num) {
idx = (idx + 1) & (MAX_ORDERS - 1);
}
if(!orders_[idx].active || orders_[idx].order_ref_num != orig_ref_num) return;
char side = orders_[idx].side;
uint16_t locate = orders_[idx].stock_locate;
delete_order(orig_ref_num); // Remove original order
add_order(new_ref_num, side, new_shares, new_price, locate); // Add updated order
}
uint32_t OrderBook::get_best_bid() const {
return (num_bids_ > 0) ? bids_[0].price : 0; // Highest price in bids
}
uint32_t OrderBook::get_best_ask() const {
return (num_asks_ > 0) ? asks_[0].price : 0; // Lowest price in asks
}
void OrderBook::print_bbo() const {
if (num_bids_ == 0 && num_asks_ == 0) {
std::cout << "[BBO] Empty Book\n";
return;
}
std::cout << "[BBO] ";
if (num_bids_ > 0) {
double bid_px = bids_[0].price / 10000.0;
uint32_t bid_vol = bids_[0].volume;
std::cout << "Bid: $" << std::fixed << std::setprecision(2) << bid_px << " (" << bid_vol << " sh)";
} else {
std::cout << "Bid: N/A";
}
std::cout << " | ";
if (num_asks_ > 0) {
double ask_px = asks_[0].price / 10000.0;
uint32_t ask_vol = asks_[0].volume;
std::cout << "Ask: $" << std::fixed << std::setprecision(2) << ask_px << " (" << ask_vol << " sh)";
} else {
std::cout << "Ask: N/A";
}
if (num_bids_ > 0 && num_asks_ > 0) {
double spread = (static_cast<double>(asks_[0].price) - static_cast<double>(bids_[0].price)) / 10000.0;
std::cout << " | Spread: $" << std::fixed << std::setprecision(2) << spread;
}
std::cout << "\n";
}