Stay up-to-date with everything C++!
Content directly fetched from the subreddit just for you.
Join our group for discussions : @programminginc
Powered by : @r_channels
Post #25141
16
I rewrote part of backtrader in C++23
I rewrote core parts of backtrader in C++23 because Python backtests were getting too slow for the iteration speed I wanted.
Called it StratForge. Header-only, Apache 2.0.
https://github.com/StratCraftsAI/StratForge
Most of the work went into validation. Every indicator is checked against JSON data from backtrader. Not "close enough", it has to match.
SMA(30) on bar 247 = 1847.2361? Same here or it's a bug. I kept adding test cases until I felt like most paths were covered.
548 test cases, 40k+ assertions.
Indicators use CRTP, so no virtual calls on the hot path. About 150+ indicators (trend, momentum, volatility, volume, candlesticks, etc).
SIMD: xsimd + runtime dispatch.
Performance (512-bar dataset, P50, GCC 14, Release):
- EMA(30): 16 ns/bar
- SMA(30): 29 ns/bar
- MACD(12,26,9): 22 ns/bar
- Bollinger(20,2): 45 ns/bar
- Ichimoku(9,26,52): 67 ns/bar
Allocations aren't perfect yet. No pmr or constexpr.
Ichimoku is fully pre-reserved. The rest… still work in progress.
I like header-only. Drop it into one file and compile. Makes FetchContent easy:
Includes a few example strategies (SMA crossover, RSI mean reversion). All tested, all produce trades.
Uses some C++23 stuff (std::expected, [likely], designated initializers). Not heavy, but not C++20. Is that a problem for people?
About 5K LOC in headers. Builds fine locally. If it kills your compile times in a big codebase, let me know.
https://redd.it/1t628vg
@r_cpp
I rewrote core parts of backtrader in C++23 because Python backtests were getting too slow for the iteration speed I wanted.
Called it StratForge. Header-only, Apache 2.0.
https://github.com/StratCraftsAI/StratForge
Most of the work went into validation. Every indicator is checked against JSON data from backtrader. Not "close enough", it has to match.
SMA(30) on bar 247 = 1847.2361? Same here or it's a bug. I kept adding test cases until I felt like most paths were covered.
548 test cases, 40k+ assertions.
Indicators use CRTP, so no virtual calls on the hot path. About 150+ indicators (trend, momentum, volatility, volume, candlesticks, etc).
SIMD: xsimd + runtime dispatch.
Performance (512-bar dataset, P50, GCC 14, Release):
- EMA(30): 16 ns/bar
- SMA(30): 29 ns/bar
- MACD(12,26,9): 22 ns/bar
- Bollinger(20,2): 45 ns/bar
- Ichimoku(9,26,52): 67 ns/bar
Allocations aren't perfect yet. No pmr or constexpr.
Ichimoku is fully pre-reserved. The rest… still work in progress.
I like header-only. Drop it into one file and compile. Makes FetchContent easy:
FetchContent_Declare(stratforge
GIT_REPOSITORY https://github.com/StratCraftsAI/StratForge.git
GIT_TAG v0.1.0)
FetchContent_MakeAvailable(stratforge)
target_link_libraries(your_app PRIVATE stratforge)
Includes a few example strategies (SMA crossover, RSI mean reversion). All tested, all produce trades.
Uses some C++23 stuff (std::expected, [likely], designated initializers). Not heavy, but not C++20. Is that a problem for people?
About 5K LOC in headers. Builds fine locally. If it kills your compile times in a big codebase, let me know.
https://redd.it/1t628vg
@r_cpp