Skip to content

mccaffers/backtesting-engine-cpp

Repository files navigation

C++ Backtesting Engine

Active development!

Feel free to explore, but this code base is usuable at the moment.

About The Project

I'm developing a high-performance C++ backtesting engine designed to analyze financial data and evaluate multiple trading strategies at scale.

Build Bugs Code Smells Coverage

I'm extracting results and creating various graphs for trend analyses using SciPy for calculations and Plotly for visualization.

alt text

Read more results on https://mccaffers.com/quantitative_analysis/randomly_trading/

Setup

This backtesting engine can pull tick data from local files or from a Postgres database (I'm using QuestDB). Strategy execution is dispatched via a Redis list called strategy_queue, with each entry a Base64-encoded JSON payload, the load subcommand enqueues strategies (LPUSH) and the run subcommand dequeues and executes them (RPOP). The default workflow expects a local redis-server listening on 127.0.0.1:6379.

Clone with submodules

The project depends on two vendored libraries (libpqxx and boost-decimal) tracked as git submodules under external/. If you didn't clone with --recurse-submodules, run:

git submodule update --init --recursive

scripts/build_dep.sh does this for you on first run.

Install libpq (required by libpqxx)

For Ubuntu/Debian systems: sudo apt-get install libpq-dev
On Red Hat Linux (RHEL) systems: yum install postgresql-devel
For Mac Homebrew: brew install postgresql
For OpenSuse: zypper in postgresql-devel
For ArchLinux: pacman -S postgresql-libs

Install Boost, OpenSSL, and Redis

Boost.Redis is header-only but its single translation unit (compiled via <boost/redis/src.hpp> from source/redisRunner.cpp) pulls in Boost.Asio's SSL layer, so OpenSSL is a transitive requirement. A local redis-server on 127.0.0.1:6379 is also needed for the default load/run workflow.

For Mac Homebrew: brew install boost openssl redis
For Ubuntu/Debian systems: sudo apt-get install libboost-all-dev libssl-dev redis-server

The canonical CI prerequisite list lives in .github/workflows/scripts/brew.sh (postgresql, pkg-config, boost).

alt text

Build dependencies

libpqxx is built once via CMake. boost-decimal is header-only and pulled in via add_subdirectory from the top-level CMakeLists.txt, nothing to build. The script below handles the libpqxx build:

bash ./scripts/build_dep.sh

Xcode - Link Binary with Libraries (Source & Test)

./build/external/libpqxx/src/libpqxx-7.10.a

Xcode - Headers Path (for libpqxx and nlohmann/json)

"$(SRCROOT)/external/libpqxx/include/pqxx/internal"
"$(SRCROOT)/external/libpqxx/include/"
"$(SRCROOT)/external/"

Xcode - Library Path

"$(SRCROOT)/external/libpqxx/src"
"$(SRCROOT)/build/external/libpqxx/src"
"/opt/homebrew/Cellar/postgresql@14/14.15/lib/postgresql@14"

Build the project

bash ./scripts/build.sh

Run via terminal

bash ./scripts/run.sh builds the project, then, if redis-cli ping reaches a local Redis, enqueues an inline JSON strategy via load and executes it via run localhost. If Redis is unreachable the script prints a message and exits cleanly (see scripts/run.sh:22-25), so first-time users without Redis still get a clear signal.

The BacktestingEngine binary exposes a subcommand CLI:

BacktestingEngine load <path> [path...]
    Read each file as raw JSON, Base64-encode it, and LPUSH onto the Redis
    `strategy_queue` list.

BacktestingEngine run <questdb-host>
    RPOP one Base64-encoded strategy from `strategy_queue` and execute it
    against the supplied QuestDB host.

BacktestingEngine run <questdb-host> <base64-config>
    Decode the supplied Base64 strategy and execute it directly, bypassing
    Redis.

BacktestingEngine -h | --help
    Show usage.

Defaults are 127.0.0.1:6379 for the Redis endpoint and strategy_queue for the list key (see include/redisRunner.hpp and include/redisLoader.hpp).

Run tests via terminal

bash ./scripts/test.sh

Contributing

This is an active solo experiment, so I'm not accepting pull requests right now, but please fork freely and use GitHub Issues for bugs, questions, and ideas. See CONTRIBUTING.md for details.

License

MIT

About

Prototype of a high-performance C++ backtesting engine designed to analyse financial data and evaluate multiple trading strategies at scale.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors