Skip to content

Latest commit

 

History

History
66 lines (51 loc) · 3 KB

File metadata and controls

66 lines (51 loc) · 3 KB

Contributing to QuantBot

This is a research codebase where correctness is non-negotiable: a silent accounting bug or a strategy that looks good only in-sample is worse than no change at all. Two rules below are hard gates.

Build requirement: PowerShell, not Bash

Build through the PowerShell terminal using _build.bat (which loads vcvars64.bat, then runs cmake --build build). The Git Bash / MSYS layer on Windows silently mangles cmd /c — it rewrites /c into a path, so cmd opens interactively and the build no-ops while appearing to succeed. Every build and every verification command in this file assumes PowerShell.

cmake -S . -B build -G Ninja          # once, or after editing CMakeLists.txt
cmd /c _build.bat                      # build all targets

Run the full verification suite before every PR

All four must pass. Run them from PowerShell after building:

.\build\indverify.exe          # incremental-indicator parity (must say ALL PARITY CHECKS PASSED)
.\build\parttest.exe           # partial-trim P&L accounting (must say ALL CHECKS PASSED)
.\build\shorttest.exe          # short / cover / flip accounting (must say ALL CHECKS PASSED)
.\build\backtest.exe config.json --data data | Select-String "Final equity|Trades "

The regression gate is a hard merge blocker

The last command above must print exactly:

 Final equity    471874.87
 Trades          328

If your change moves these numbers while the feature you added is disabled (the default), that is a bug, not a feature — it means a "no-op" change altered existing behavior. Do not merge until the gate is bit-exact again. (The 100-name rotation gate, 490,511,624,146.48 / 1,257 trades via --universe data_cache/universe_100.txt, has the same status.) New behavior must live behind a config flag that is off by default, so the gate run sees the original code path unchanged.

Research hygiene: out-of-sample or it didn't happen

Any new strategy feature must demonstrate improvement in walk-forward out-of-sample results, not just in-sample. A full-history backtest that looks better proves nothing — it is trivial to curve-fit. The bar is: run the walk-forward (--walkforward 5 1), and if you tuned parameters, reserve a holdout the tuner never touches and report performance there. Five extensions have already been built, looked great in-sample, and been rejected on clean out-of-sample data (RESEARCH_LOG.md). Rejecting a hypothesis with honest data is a successful contribution; shipping an in-sample mirage is not. State the OOS numbers in your PR description.

Scope discipline

  • Don't modify the fill model in src/Backtest.cpp without adding/extending a unit proof (parttest / shorttest) that pins the new behavior to the penny.
  • Don't commit credentials. Keys come from APCA_API_KEY_ID / APCA_API_SECRET_KEY environment variables; config.json holds placeholders.
  • Keep quantbot (live bot) free of test-only or research-only code paths.