Promotion is the process of taking a strategy that has been written, verified, and backtested in Python and compiling it into the C++20 core that powers the QuanuX spreader. The pipeline moves through three stages: Python prototype, Cython bridge, and native C++ execution logic. Each stage produces a verifiable artifact, and no stage can be skipped. This page explains how each stage works, what the Foundry generates at each step, and what you need to have in place before C++ promotion becomes available.
The three-stage pipeline
Python — Your strategy lives in server/strategies/ and inherits from the StrategyComponent base classes. This is the research layer. It has full access to pandas, numpy, and the broader Python data science ecosystem.
Cython — The Foundry generates a .pyx file with typed C++ declarations and a PyStrategyWrapper class that bridges Python calls into the C++ InjectionStub interface. The Cython extension compiles into a shared object that Crucible loads directly. This is the current stable promotion target.
C++ — The Foundry generates a native C++20 header and implementation conforming to the spreader’s InjectionStub contract. The compiled artifact runs inside the spreader’s Core 3 execution thread with no Python interpreter in the path. This target is in active development.
C++ generation via target_lang=cpp is in active development and not yet recommended for production use. Use target_lang=cython for stable, high-performance execution. Python and Cython targets are fully supported.
Anaconda environment management
QuanuX is the first quantitative trading platform to offer an official Conda channel. Anaconda is the recommended way to manage the boundary between Python research and C++ execution, because it lets you maintain separate, tightly controlled environments for each stage without dependency conflicts.
Install QuanuX into Conda:
conda config --add channels conda-forge
conda config --add channels QuanuX
conda install quanux
When you are iterating on strategy logic, work in a Conda environment that includes your full Python data science stack. When you are ready to compile a Cython extension or run Crucible, activate the QuanuX execution environment where the build toolchain and C++ headers are available. The Anaconda Synapse integration in QuanuX ensures the correct environment is selected automatically when you invoke quanuxctl.
Submitting a forge request targeting C++
The Foundry forge request is the same regardless of target_lang. The following example requests a C++ artifact for a spread strategy:
curl -X POST http://localhost:8080/api/foundry/forge \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"component_type": "strategy",
"name": "CLZ4_CLF5_Spread",
"target_lang": "cpp",
"target_version": "1.0.0",
"prompt": "Calendar spread: long CLZ4, short CLF5. Enter when spread exceeds entry_threshold. Exit when spread goes negative."
}'
{
"status": "accepted",
"job_id": "job_7d2f4b9a"
}
The Foundry generates a C++20 header conforming to the InjectionStub interface. The generated calculate method maps directly onto the CLZ4_CLF5_Spread.json logic gates:
CLZ4_CLF5_Spread_injected.hpp (generated)
namespace quanux::spreader::strategy {
struct StrategyState {
double entry_threshold = 0.05;
double current_spread = 0.0;
};
struct InjectionStub {
static void init(StrategyState& state) {
state.entry_threshold = 0.05;
state.current_spread = 0.0;
}
static bool calculate(StrategyState& state, const MarketTick& tick) noexcept {
state.current_spread = tick.price;
if (state.current_spread > state.entry_threshold) return true; // entry
if (state.current_spread < 0) return false; // exit
return false;
}
};
} // namespace quanux::spreader::strategy
The corresponding Cython wrapper in server/spreader-strategies/CLZ4_CLF5_Spread_wrapper.pyx exposes this to Python for Crucible backtesting:
CLZ4_CLF5_Spread_wrapper.pyx
# cython: language_level=3
# cython: cplus=True
cdef extern from "quanux/MarketTick.hpp" namespace "quanux":
cdef cppclass MarketTick:
double price
unsigned int instrument_id
cdef extern from "spreader/injected/CLZ4_CLF5_Spread_injected.hpp" \
namespace "quanux::spreader::strategy":
cdef cppclass StrategyState:
pass
cdef cppclass InjectionStub:
@staticmethod
void init(StrategyState& state)
@staticmethod
bint calculate(StrategyState& state, const MarketTick& tick) nogil
cdef class PyStrategyWrapper:
cdef StrategyState state
def __cinit__(self):
InjectionStub.init(self.state)
def calculate(self, double price, unsigned int instrument_id):
cdef MarketTick tick
tick.price = price
tick.instrument_id = instrument_id
return InjectionStub.calculate(self.state, tick)
Git-as-Governance requirement
Before any strategy can be loaded by the live spreader, the following conditions must all be true:
- The strategy artifact (
.hpp, .pyx, or .py) is committed to the repository.
- The commit is cryptographically signed (
git commit -S).
- The SHA-256 of the artifact on disk matches the hash recorded in the signed commit.
If any condition is not met, the spreader rejects the strategy at load time with a STATE_HALT signal. This is a hard rule enforced by the Ritchie FSM — it cannot be bypassed.
# Stage and sign the generated artifacts
git add server/spreader-strategies/CLZ4_CLF5_Spread_injected.hpp
git add server/spreader-strategies/CLZ4_CLF5_Spread_wrapper.pyx
git commit -S -m "feat(strategy): promote CLZ4_CLF5_Spread to cpp v1.0.0"
Never edit a generated artifact after committing it. Any modification changes the SHA-256 and will cause the spreader to halt. If the generated code needs changes, submit a new forge request and go through verification and backtesting again before committing.
Before promoting a strategy to the live spreader, confirm each of the following: