Orderbook Simulation
OrderbookSim is a C++ application simulating a financial market order book. It efficiently manages and matches buy and sell orders while calculating the Volume-Weighted Average Price (VWAP).
OrderbookSim

Overview

OrderbookSim is a C++ application that simulates an order book used in financial markets. It efficiently manages and matches buy and sell orders, and calculates the volume-weighted average price (VWAP). The project also includes a neural network built from scratch to predict sell prices, and now features GUIs for adding and viewing the order book in Python. This simulation helps users understand how order books work and how neural networks can be applied to financial data.

Running the program

In order to run the otherbook stimulation navigate to build

python .\OrderbookView.py # to view orders
python .\addOrder.py

Key Components

Orderbook

The main class representing the order book. It manages buy and sell orders, matches them based on price-time priority, maintains an order history, and calculates VWAP.

Order

Represents an individual order with attributes such as order type, side (buy/sell), price, and quantity.

Order Types

The project supports various order types including:

  • Good Till Cancel: The order remains active until filled, canceled, or it expires.
  • Fill and Kill: The order is filled as much as possible, and any remaining quantity is canceled immediately.
  • Market Order: Filled at the best available price.
  • Good For Day: Similar to Good Till Cancel, but automatically canceled at the end of the trading day.
  • Fill or Kill: Must be filled immediately and entirely or canceled.

Order Modify

Handles modifications to existing orders, such as price or quantity adjustments.

Trade

Represents a trade executed between a buy and sell order.

VWAP (Volume-Weighted Average Price)

Calculates the average price of orders based on their volume.

Neural Network for Price Prediction

A custom-built neural network designed to predict sell prices based on historical order data. This neural network provides a foundation for applying machine learning to financial market simulations.

GUI Integration

Python Bindings

OrderbookSim now includes Python bindings using Pybind11, allowing for integration with Python GUIs.

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "Orderbook.h"
namespace py = pybind11;
PYBIND11_MODULE(orderbook, handle) {
handle.doc() = "Orderbook"; // optional module docstring
py::class_<Orderbook>(handle, "Orderbook")
.def(py::init<>())
.def("addOrder", &Orderbook::addOrderViaPython)
.def("loadToJson", &Orderbook::saveToJson);
}
void addOrderViaPython(int type, int id, int side, int price, int qty)
Adds an order to the orderbook via Python interface.
Definition: Orderbook.cpp:398
void saveToJson(const std::string &buyfilename="BuyHistory.json", const std::string &sellfilename="SellHistory.json", const std::string &purchasefilename="PurchaseHistory.json", const std::string &buyLivefilename="BuyLiveHistory.json", const std::string &sellLivefilename="SellLiveHistory.json")
Saves orderbook data to JSON files.
Definition: Orderbook.cpp:558
PYBIND11_MODULE(orderbook, handle)
Defines the Pybind11 module for the Orderbook class.
Definition: orderbook_pybind.cpp:24

GUI for Viewing Orderbook

A Python GUI to view the order book using Tkinter:

import json
import tkinter as tk
from tkinter import ttk
def load_json(filename):
with open(filename, 'r') as file:
return json.load(file)
def create_table(frame, headers, data):
tree = ttk.Treeview(frame, columns=headers, show='headings')
for header in headers:
tree.heading(header, text=header)
tree.column(header, width=100)
for row in data:
tree.insert('', 'end', values=[row.get(header, '') for header in headers])
tree.pack(expand=True, fill='both')
return tree
def refresh_data():
global sell_orders, buy_orders, purchases, live_sell_orders, live_buy_orders
sell_orders = load_json('SellHistory.json')
buy_orders = load_json('BuyHistory.json')
purchases = load_json('PurchaseHistory.json')
live_sell_orders = load_json('SellLiveHistory.json')
live_buy_orders = load_json('BuyLiveHistory.json')
update_table(frame_sell_orders, sell_order_headers, sell_orders)
update_table(frame_buy_orders, buy_order_headers, buy_orders)
update_table(frame_purchases, purchase_headers, purchases)
update_table(frame_live_sell_orders, live_sell_order_headers, live_sell_orders)
update_table(frame_live_buy_orders, live_buy_order_headers, live_buy_orders)
root.after(10000, refresh_data) # Schedule the next refresh in 10 seconds
def update_table(frame, headers, data):
for widget in frame.winfo_children():
widget.destroy()
create_table(frame, headers, data)
root = tk.Tk()
root.title("Order Book")
root.geometry("1000x600")
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill="both")
frame_sell_orders = tk.Frame(notebook)
frame_buy_orders = tk.Frame(notebook)
frame_purchases = tk.Frame(notebook)
frame_live_sell_orders = tk.Frame(notebook)
frame_live_buy_orders = tk.Frame(notebook)
notebook.add(frame_sell_orders, text="Sell Orders")
notebook.add(frame_buy_orders, text="Buy Orders")
notebook.add(frame_purchases, text="Purchases")
notebook.add(frame_live_sell_orders, text="Live Sell Orders")
notebook.add(frame_live_buy_orders, text="Live Buy Orders")
sell_order_headers = ["order_id", "order_type", "price", "quantity", "side", "time"]
buy_order_headers = ["order_id", "order_type", "price", "quantity", "side", "time"]
purchase_headers = ["price", "quantity", "time"]
live_sell_order_headers = ["order_id", "order_type", "price", "quantity", "side", "time"]
live_buy_order_headers = ["order_id", "order_type", "price", "quantity", "side", "time"]
refresh_data()
root.mainloop()

GUI for Adding Orders

A Python GUI to add orders to the order book using Tkinter:

import tkinter as tk
from tkinter import messagebox
import orderbook # Made via pybind
class OrderEntryGUI:
def __init__(self, master):
self.master = master
self.orderbook = orderbook.Orderbook()
self.order_id_counter = 0
self.order_type_mapping = {
'GoodTillCancel': 1,
'FillAndKill': 2,
'Market': 3,
'GoodForDay': 4,
'FillOrKill': 5
}
self.type_var = tk.StringVar(master)
self.side_var = tk.StringVar(master)
self.price_entry = tk.Entry(master)
self.qty_entry = tk.Entry(master)
self.create_widgets()
def create_widgets(self):
tk.Label(self.master, text="Type").grid(row=0, column=0)
tk.Label(self.master, text="Side").grid(row=1, column=0)
tk.Label(self.master, text="Price").grid(row=2, column=0)
tk.Label(self.master, text="Quantity").grid(row=3, column=0)
types = ['GoodTillCancel', 'FillAndKill', 'Market', 'GoodForDay', 'FillOrKill']
tk.OptionMenu(self.master, self.type_var, *types).grid(row=0, column=1)
sides = ['Buy', 'Sell']
tk.OptionMenu(self.master, self.side_var, *sides).grid(row=1, column=1)
self.price_entry.grid(row=2, column=1)
self.qty_entry.grid(row=3, column=1)
tk.Button(self.master, text="Add Order", command=self.add_order).grid(row=4, column=0, columnspan=2)
tk.Button(self.master, text="Reset", command=self.reset).grid(row=5, column=0, columnspan=2)
def add_order(self):
order_type_str = self.type_var.get()
order_type = self.order_type_mapping.get(order_type_str)
side = self.side_var.get()
try:
price = int(self.price_entry.get())
qty = int(self.qty_entry.get())
except ValueError:
messagebox.showerror("Error", "Price and quantity must be numbers.")
return
order_id = self.order_id_counter
self.order_id_counter += 1
self.orderbook.addOrder(order_type, order_id, 1 if side == 'Buy' else 2, price, qty)
print("Order added:", order_type_str, order_id, side, price, qty)
messagebox.showinfo("Order Added", "Order added successfully.")
self.type_var.set('')
self.side_var.set('')
self.price_entry.delete(0, tk.END)
self.qty_entry.delete(0, tk.END)
def reset(self):
self.type_var.set('')
self.side_var.set('')
self.price_entry.delete(0, tk.END)
self.qty_entry.delete(0, tk.END)
if __name__ == "__main__":
root = tk.Tk()
root.title("Order Entry")
app = OrderEntryGUI(root)
root.mainloop()

Usage

Example

Here's a simple example of how to use the order book:

#include "Orderbook.h"
int main() {
Orderbook orderbook;
const OrderId orderId = 1;
orderbook.addOrder(std::make_shared<Order>(OrderType::GoodTillCancel, orderId, Side::Buy, 100, 10));
std::cout << "Orderbook size: " << orderbook.Size() << std::endl;
orderbook.CancelOrder(orderId);
std::cout << "Orderbook size after cancellation: " << orderbook.Size() << std::endl;
return 0;
}
int main(int argc, char *argv[])
Definition: CMakeCCompilerId.c:868
std::uint64_t OrderId
Represents a unique identifier for an order.
Definition: Usings.hpp:37
Manages and matches orders in a trading environment.
Definition: Orderbook.hpp:36
void CancelOrder(OrderId orderId)
Cancels an order by its ID.
Definition: Orderbook.cpp:464
Trades addOrder(OrderPtr order)
Adds an order to the orderbook.
Definition: Orderbook.cpp:412
std::size_t Size() const
Retrieves the number of orders in the orderbook.
Definition: Orderbook.cpp:494

Simulation

The OrderbookSim.cpp file contains the main function and a simulation function randomOrderSimulation to generate random orders:

#include <iostream>
#include "Orderbook.h"
#include <random>
void randomOrderSimulation(const int n);
int main() {
const int n = 1000;
return 0;
}
void randomOrderSimulation(const int n) {
Orderbook orderbook;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> type(1, 5);
std::uniform_int_distribution<> side(1, 100);
std::uniform_int_distribution<> price(1, 500);
std::uniform_int_distribution<> quantity(1, 500);
for (int i = 0; i < n; i++) {
orderbook.addOrder(intToOrderType(type(gen)), i, side(gen) == 1 ? Side::Buy : Side::Sell, price(gen), quantity(gen));
}
orderbook.printAllOrders();
std::cout << "OrderBook Size: " << orderbook.Size() << std::endl;
}
void randomOrderSimulation(const int n)
Simulates random order entries in the orderbook.
Definition: OrderbookSim.cpp:46
void printAllOrders()
Prints all orders and orderbook details.
Definition: Orderbook.cpp:530

Neural Network Price Prediction

To use the neural network for predicting sell prices, you need to provide training data and configure the network parameters. The neural network implementation is integrated into the project to enhance the simulation's predictive capabilities.

Dependencies

The project relies on standard C++ libraries and includes the Google Test framework for testing purposes.

Testing

The project includes comprehensive unit tests implemented using the Google Test framework to ensure correctness and reliability. To run the tests, use the following file:

Contributing

Contributions are welcome! Feel free to open issues or pull requests for any improvements or bug fixes.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contact

For any inquiries or feedback, please contact [JideO.nosp@m.yela.nosp@m.yo1@G.nosp@m.mail.nosp@m..com].