#include "engine.h"
typedef struct {
t_order order;
t_orderid id;
} t_order_in;
#define MYDATA t_order_in
#define MYDATAINIT {{'', '', 0, 0, 0}, 0}
#include "double_link_list.c"
list * bids;
list * asks;
t_orderid nextid;
node * find_node(t_orderid id, list * l) {
node * node_iter = l->head->next;
while (node_iter->data.id != id &&
node_iter != l->tail) {
node_iter = node_iter->next;
}
if (node_iter == l->tail) { return NULL; }
else { return node_iter; }
}
void send_exec(t_order * o1, t_order * o2) {
t_execution exec = (t_execution)(*o1);
exec.size = o1->size > o2->size ? o2->size : o1->size;
execution(exec);
int i;
for(i = 0; i < STRINGLEN; i++) {
exec.trader[i] = o2->trader[i];
}
exec.side = !exec.side;
execution(exec);
}
void trade(t_order * order_new,
node * node_old,
list * l) {
t_order * order_old = &node_old->data.order;
send_exec(order_new, order_old);
if (order_new->size >= order_old->size) {
order_new->size -= order_old->size;
remove_node(l, node_old);
}
else {
order_old->size -= order_new->size;
order_new->size = 0;
}
}
int hit_ask(t_price bid, t_price ask) { return bid >= ask; }
int hit_bid(t_price ask, t_price bid) { return ask <= bid; }
int cross(t_order * order) {
int isask = is_ask(order->side);
list * book = isask ? bids : asks;
int (*cross_test)(t_price, t_price) =
isask ? hit_bid : hit_ask;
node * book_iter = book->head->next;
while(book_iter != book->tail &&
cross_test(order->price,
book_iter->data.order.price)) {
trade(order, book_iter, book);
if (order->size == 0) {
return 1;
}
book_iter = book_iter->next;
}
return 0;
}
int priority_ask(t_price ask_new, t_price ask_old) { return ask_new < ask_old; }
int priority_bid(t_price bid_new, t_price bid_old) { return bid_new > bid_old; }
void queue(t_order * order) {
int isask = is_ask(order->side);
list * book = isask ? asks : bids;
int (*priority_test)(t_price, t_price) =
isask ? priority_ask : priority_bid;
node * book_iter = book->head->next;
while(book_iter != book->tail &&
!priority_test(order->price,
book_iter->data.order.price)) {
book_iter = book_iter->next;
}
t_order_in o;
o.order = *order;
o.id = nextid;
insert_before(book, book_iter, o);
}
void init() {
nextid = 1;
bids = new_list();
asks = new_list();
}
void destroy() {
delete_list(bids);
delete_list(asks);
}
t_orderid limit(t_order order) {
if (!cross(&order)) queue(&order);
return nextid++;
}
void cancel(t_orderid orderid) {
node * node = find_node(orderid, bids);
if (node) { remove_node(bids, node); }
else {
node = find_node(orderid, asks);
if (node) { remove_node(asks, node); }
}
}