Skip to content

Commit

Permalink
since OrderId cannot be shared, efficiently create a copy
Browse files Browse the repository at this point in the history
  • Loading branch information
robaho committed Dec 17, 2024
1 parent ee7eed7 commit bdcb043
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 10 deletions.
6 changes: 3 additions & 3 deletions exchange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int Exchange::cancel(long exchangeId) {
return book->cancelOrder(order);
}

long Exchange::insertOrder(std::string instrument,F price,int quantity,Side side,std::string orderId) {
long Exchange::insertOrder(const std::string& instrument,F price,int quantity,Side side,const std::string& orderId) {
OrderBook *book = books.getOrCreate(instrument,*this);
auto bookGuard = book->lock();
long id = nextID();
Expand All @@ -52,11 +52,11 @@ long Exchange::insertOrder(std::string instrument,F price,int quantity,Side side
return id;
}

long Exchange::buy(std::string instrument,F price,int quantity,std::string orderId) {
long Exchange::buy(const std::string& instrument,F price,int quantity,const std::string& orderId) {
return insertOrder(instrument,price,quantity,BUY,orderId);
}

long Exchange::sell(std::string instrument,F price,int quantity,std::string orderId) {
long Exchange::sell(const std::string& instrument,F price,int quantity,const std::string& orderId) {
return insertOrder(instrument,price,quantity,SELL,orderId);
}

Expand Down
10 changes: 5 additions & 5 deletions exchange.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ class Exchange : OrderBookListener {
Exchange();
Exchange(ExchangeListener& listener);
/** submit limit buy order. returns exchange order id */
long buy(std::string instrument,F price,int quantity,std::string orderId);
long buy(const std::string& instrument,F price,int quantity,const std::string& orderId);
/** submit market buy order. returns exchange order id. If the order cannot be filled, the rest is cancelled */
long marketBuy(std::string instrument,int quantity,std::string orderId) {
long marketBuy(const std::string& instrument,int quantity,const std::string& orderId) {
return buy(instrument,DBL_MAX,quantity,orderId);
}
/** submit limit sell order. returns exchange order id */
long sell(std::string instrument,F price,int quantity,std::string orderId);
long sell(const std::string& instrument,F price,int quantity,const std::string& orderId);
/** submit market sell order. returns exchange order id. If the order cannot be filled, the rest is cancelled */
long marketSell(std::string instrument,int quantity,std::string orderId) {
long marketSell(const std::string& instrument,int quantity,const std::string& orderId) {
return sell(instrument,-DBL_MAX,quantity,orderId);
}
int cancel(long exchangeId);
Expand All @@ -49,6 +49,6 @@ class Exchange : OrderBookListener {
OrderMap allOrders;
SpinLock mu;
long nextID();
long insertOrder(std::string instrument,F price,int quantity,Side side,std::string orderId);
long insertOrder(const std::string& instrument,F price,int quantity,Side side,const std::string& orderId);
ExchangeListener& listener;
};
18 changes: 16 additions & 2 deletions order.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ friend struct Order;
Order *order=nullptr;
};

struct OrderId {
// used to avoid dynamic memory in std::string, even though SSO (small string optimization) usually avoids it
private:
char buffer[64];
public:
OrderId(const std::string& oid) {
auto len = oid.copy(buffer, 64);
buffer[len]=0;
}
operator const char *() const { return buffer; }
};

struct Order {
friend class OrderBook;
friend class OrderList;
Expand All @@ -43,15 +55,17 @@ friend class Exchange;

int remaining;
int filled=0;
OrderId _orderId;

void fill(int quantity) { remaining -= quantity; filled += quantity; }
void cancel() { remaining = 0; }
bool isMarket() { return price == DBL_MAX || price == -DBL_MAX; } // could add "type" property, but not necessary for only limit and market orders
protected:
// protected to allow testcase
Order(const std::string &orderId,const std::string &instrument,F price,int quantity,Side side,long exchangeId) : timeSubmitted(epoch()), remaining(quantity), orderId(orderId), instrument(instrument), exchangeId(exchangeId) , price(price), quantity(quantity), side(side) {}
Order(const std::string &orderId,const std::string &instrument,F price,int quantity,Side side,long exchangeId) : timeSubmitted(epoch()), remaining(quantity),
_orderId(orderId), orderId(_orderId), instrument(instrument), exchangeId(exchangeId) , price(price), quantity(quantity), side(side) {}
public:
const std::string orderId;
const char * const orderId;
const std::string &instrument;
const long exchangeId;
const F price;
Expand Down
12 changes: 12 additions & 0 deletions order_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#define BOOST_TEST_MODULE orderbook
#include <boost/test/included/unit_test.hpp>

#include "order.h"
#include "test.h"

BOOST_AUTO_TEST_CASE( order_basic ) {
auto order = TestOrder("myorder",1,100,10,BUY);
BOOST_TEST(order.orderId == "myorder");
auto order2 = TestOrder("myorder2",1,100,10,BUY);
BOOST_TEST(order2.orderId == "myorder2");
}
3 changes: 3 additions & 0 deletions pricelevels.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "order.h"
#include "orderlist.h"

// The purpose of PriceLevels is to allow a compile time indirection to test implementation using different data structures

struct price_compare {
explicit price_compare(bool ascending) : ascending(ascending) {}
template<class T, class U>
Expand Down Expand Up @@ -237,4 +239,5 @@ typedef StructPriceLevels<std::vector<OrderList>> VectorPriceLevels;
typedef MapPriceLevels<std::map<F,OrderList,fixed_compare>> StdMapPriceLevels;
typedef MapPtrPriceLevels<std::map<F,OrderList*,fixed_compare>> StdMapPtrPriceLevels;

// define the PriceLevels implementation to use
typedef VectorPriceLevels PriceLevels;
1 change: 1 addition & 0 deletions test.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ static const std::string dummy_oid = "";
class TestOrder : public Order {
public:
TestOrder(long id,F price,int quantity,Side side) : Order(dummy_oid,dummy_instrument,price,quantity,side,id) {}
TestOrder(std::string orderId,long id,F price,int quantity,Side side) : Order(orderId,dummy_instrument,price,quantity,side,id) {}
};

0 comments on commit bdcb043

Please sign in to comment.