Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ set(BUILD_BENCHMARKS ${_SAVED_BUILD_BENCHMARKS})

# Subdirectories
add_subdirectory(src)
add_subdirectory(tools)

if(BUILD_TESTS)
add_subdirectory(tests)
Expand Down
6 changes: 5 additions & 1 deletion benchmarks/bench_matching_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ static void BM_OrderBook_MatchOnly(benchmark::State& state) {
std::vector<Order*> sells;
sells.reserve(100);

std::vector<Fill> fills;
fills.reserve(100);

for (int i = 0; i < 100; ++i) {
sells.push_back(make_order(pool, owned, i, OrderSide::SELL, 10000 + i, 100));
}
Expand All @@ -99,7 +102,8 @@ static void BM_OrderBook_MatchOnly(benchmark::State& state) {
reset_order(buy, 10000);
state.ResumeTiming();

book.match(buy);
fills.clear();
book.match(buy, fills);
benchmark::DoNotOptimize(book);
}
}
Expand Down
24 changes: 20 additions & 4 deletions benchmarks/bench_order_book.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ static void BM_OrderBook_MatchBuy(benchmark::State& state) {
// Resting sell orders — created once, reset each iteration
std::vector<Order*> sells;
sells.reserve(100);

std::vector<Fill> fills;
fills.reserve(100);

for (int i = 0; i < 100; ++i)
sells.push_back(make_order(pool, owned, i, OrderSide::SELL, 10000 - i, 100));

Expand All @@ -102,9 +106,10 @@ static void BM_OrderBook_MatchBuy(benchmark::State& state) {
book.add_order(s);
}
reset_order(buy, 10000);
state.ResumeTiming();
state.ResumeTiming();

auto remaining = book.match(buy);
fills.clear();
auto remaining = book.match(buy, fills);
benchmark::DoNotOptimize(remaining);
}
}
Expand All @@ -116,6 +121,10 @@ static void BM_OrderBook_MatchSell(benchmark::State& state) {

std::vector<Order*> buys;
buys.reserve(100);

std::vector<Fill> fills;
fills.reserve(100);

for (int i = 0; i < 100; ++i)
buys.push_back(make_order(pool, owned, i, OrderSide::BUY, 10000 + i, 100));

Expand All @@ -128,10 +137,12 @@ static void BM_OrderBook_MatchSell(benchmark::State& state) {
reset_order(b, 100);
book.add_order(b);
}

fills.clear();
reset_order(sell, 10000);
state.ResumeTiming();

auto remaining = book.match(sell);
auto remaining = book.match(sell, fills);
benchmark::DoNotOptimize(remaining);
}
}
Expand All @@ -143,6 +154,10 @@ static void BM_OrderBook_MarketOrder(benchmark::State& state) {

std::vector<Order*> sells;
sells.reserve(100);

std::vector<Fill> fills;
fills.reserve(100);

for (int i = 0; i < 100; ++i)
sells.push_back(make_order(pool, owned, i, OrderSide::SELL, 10000 + i * 10, 100));

Expand All @@ -158,7 +173,8 @@ static void BM_OrderBook_MarketOrder(benchmark::State& state) {
reset_order(buy, 10000);
state.ResumeTiming();

auto remaining = book.match(buy);
fills.clear();
auto remaining = book.match(buy, fills);
benchmark::DoNotOptimize(remaining);
}
}
Expand Down
6 changes: 5 additions & 1 deletion benchmarks/bench_price_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ BENCHMARK(BM_PriceLevel_RemoveOrder);
static void BM_PriceLevel_MatchOrder(State& state) {
ObjectPool<Order, 100000> pool;
PriceLevel level(10000);

std::vector<Fill> fills;
fills.reserve(100);

// Setup: add a buy order
auto buy = pool.acquire();
Expand All @@ -56,7 +59,8 @@ static void BM_PriceLevel_MatchOrder(State& state) {
sell->quantity = 60;
sell->remaining_quantity = 60;

auto remaining = level.match_order(sell.get());
fills.clear();
auto remaining = level.match_order(sell.get(), fills);
DoNotOptimize(remaining);

// Restore the buy order for next iteration
Expand Down
13 changes: 13 additions & 0 deletions include/velox/book/fill.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once
#include <cstdint>
#include "velox/matching/order.hpp"

namespace velox {

struct Fill {
Order* order;
uint32_t quantity;
int64_t price;
};

}
6 changes: 3 additions & 3 deletions include/velox/book/order_book.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <unordered_map>
#include "velox/matching/order.hpp"
#include "velox/book/price_level.hpp"
#include <iostream>

namespace velox {

Expand All @@ -16,7 +17,7 @@ class OrderBook {
// Core operations
bool add_order(Order* order);
bool cancel_order(uint64_t order_id);
Order* match(Order* incoming_order);
Order* match(Order* incoming_order, std::vector<Fill>& fills);
const std::vector<PriceLevel*>& get_bid_levels() const { return m_bid_levels; }
const std::vector<PriceLevel*>& get_ask_levels() const { return m_ask_levels; }

Expand All @@ -35,7 +36,6 @@ class OrderBook {
const char* symbol() const { return m_symbol; }

private:

// Stock ticker size
char m_symbol[8];

Expand All @@ -46,7 +46,7 @@ class OrderBook {
alignas(64) std::atomic<uint32_t> m_bid_depth{0};
alignas(64) std::atomic<uint32_t> m_ask_depth{0};

// Price levels (using simple vectors for now - can be optimized later)
// Price levels
std::vector<PriceLevel*> m_bid_levels; // Sorted high to low
std::vector<PriceLevel*> m_ask_levels; // Sorted low to high

Expand Down
4 changes: 3 additions & 1 deletion include/velox/book/price_level.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma once
#include <cstdint>
#include <array>
#include <vector>
#include "velox/matching/order.hpp"
#include "velox/book/fill.hpp"

namespace velox {

Expand All @@ -16,7 +18,7 @@ class PriceLevel {
// Core operations
void add_order(Order* order);
void remove_order(Order* order);
Order* match_order(Order* incoming);
Order* match_order(Order* incoming, std::vector<Fill>& fills);

// Getters
int64_t price() const { return m_price; }
Expand Down
50 changes: 50 additions & 0 deletions include/velox/core/symbol_engine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once
#include "velox/book/order_book.hpp"
#include "velox/matching/matching_engine.hpp"
#include "velox/feed/feed_handler.hpp"
#include "lockfree/spsc_queue.hpp"

namespace velox {

class SymbolEngine {
public:
SymbolEngine(const char* symbol,
RiskManager* risk_manager,
ExecutionGateway* gateway,
PositionManager* position_manager)
: m_book(symbol),
m_engine(symbol, risk_manager, gateway, position_manager) {}

// Called by Feed Handler thread to push an order from ITCH
void on_market_order(Order* order) {
m_engine.submit_order(order);
}

// Called by Matching Engine thread to run matching
void run_match_cycle() {
m_engine.run_match_cycle();
}

// Cancel order (via Order Book)
bool cancel_order(uint64_t order_id) {
return m_engine.cancel_order(order_id);
}

// Access to Order Book for snapshots
const OrderBook& order_book() const {
return m_book;
}

// Get stats from Matching Engine thread
MatchingEngine::Stats get_stats() { return m_engine.get_stats(); }

// Get symbol
const char* symbol() { return m_book.symbol(); }

private:
OrderBook m_book;
MatchingEngine m_engine;

};

}
14 changes: 9 additions & 5 deletions include/velox/matching/matching_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@ class MatchingEngine {

~MatchingEngine();

// Submit order (called by risk manager)
// Submit order (called by Risk Manager)
bool submit_order(Order* order);

// Cancel order (via Order Book)
bool cancel_order(uint64_t order_id) {
return m_order_book.cancel_order(order_id);
}

// Run matching cycle (called by matching thread)
// Run matching cycle (called by Matching Engine)
void run_match_cycle();

// Statistics
// Stats
struct Stats {
uint64_t orders_matched = 0;
uint64_t orders_rejected = 0;
Expand All @@ -36,9 +41,8 @@ class MatchingEngine {
};

Stats get_stats() const;

private:

private:
OrderBook m_order_book;
RiskManager* m_risk_manager;
ExecutionGateway* m_gateway;
Expand Down
12 changes: 11 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ add_library(velox_core STATIC

# Matching
matching/matching_engine.cpp
matching/order.cpp

# Risk
risk/risk_manager.cpp
Expand All @@ -28,4 +27,15 @@ target_link_libraries(velox_core
target_include_directories(velox_core PUBLIC
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/third_party/whirlpool/include
)

add_executable(velox_trading_engine main.cpp)

target_link_libraries(velox_trading_engine
velox_core
)

target_include_directories(velox_trading_engine PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/third_party/whirlpool/include
)
Loading
Loading