Documentation Index
Fetch the complete documentation index at: https://mintlify.com/deskiziarecords/QUIMERIA-HYPERION/llms.txt
Use this file to discover all available pages before exploring further.
The /ws/stream endpoint delivers the full SMK step() result for each bar over a persistent WebSocket connection. The frontend uses this to drive the TradingView chart, sensor panels, and execution panel in real time during backtest replay.
Endpoint
ws://localhost:8000/ws/stream
Load data first with POST /api/load/csv (or another data endpoint) before connecting. The pipeline must have bars loaded; otherwise run will complete immediately with a done message.
Commands
The client sends JSON commands to control playback. The server processes each command and streams bar results back.
run
Start streaming bars at a fixed interval.
{"action": "run", "speed": 100}
Milliseconds to wait between bars. Use 0 or 1 for maximum speed. Common values: 100 (fast), 500 (slow), 1000 (one per second).
step
Process a single bar and return its result. The stream does not continue automatically.
stop
Pause streaming. The cursor position is preserved. Send run again to resume.
reset
Reset the pipeline cursor to bar 0 without reloading data. Useful for re-running a backtest from the beginning.
Server messages
The server sends one JSON message per bar during run or step, plus control messages.
bar message
{
"type": "bar",
"data": { /* full SMK step() result dict */ }
}
The data field contains the complete result from SMKPipeline.step(). See SMK step() result schema for the full field reference.
done message
Sent when the last bar has been processed.
stopped message
Sent immediately in response to a stop command.
error message
Sent if the pipeline raises an unhandled exception on a bar.
{"type": "error", "message": "description of what went wrong"}
Example: per-bar payload shape
{
"type": "bar",
"data": {
"bar": {"time": 1715000000, "open": 1.09100, "high": 1.09250, "low": 1.09050, "close": 1.09200, "volume": 1250},
"bar_index": 42,
"total_bars": 300,
"veto": {"decision": "Proceed", "reasons": [], "trade_allowed": true},
"amd": {"state": "Manipulation", "prev": "Accumulation", "changed": true, "R_MASTER": false},
"fusion": {"p_fused": 0.74, "confidence": 0.81, "veto_active": false, "regime": "TRENDING"},
"mandra": {"open": true, "delta_e": 0.048, "size": 0.012, "regime_stable": true},
"sensors": [
{"id": "s01", "name": "VolatilityDecay", "score": 0.82, "active": true, "layer": "L3", "status": "ENTRAPPED"},
{"id": "p01", "name": "MarketRhythm", "score": 0.67, "active": true, "layer": "L3-ext", "status": "BEAT:4"}
],
"execution": {
"action": "LONG",
"reason": "IPDA_DELIVER",
"is_armed": true,
"stop_loss_price": 1.09020,
"take_profit_price": 1.09450,
"lot_size": 0.05,
"kelly_size": 0.022,
"rr_ratio": 2.1,
"delta_e": 0.048
}
}
}
Client examples
const ws = new WebSocket("ws://localhost:8000/ws/stream");
ws.onopen = () => {
// Start streaming at 200ms per bar
ws.send(JSON.stringify({ action: "run", speed: 200 }));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "bar") {
const { bar, sensors, veto, execution } = msg.data;
console.log(`Bar ${msg.data.bar_index}: trade_allowed=${veto.trade_allowed}`);
// Update chart, sensor bars, execution panel...
}
if (msg.type === "done") {
console.log("Backtest complete");
ws.close();
}
};
ws.onerror = (err) => console.error("WebSocket error", err);
Stepping through bars manually
import asyncio, json, websockets
async def manual_step():
async with websockets.connect("ws://localhost:8000/ws/stream") as ws:
for _ in range(5):
await ws.send(json.dumps({"action": "step"}))
msg = json.loads(await ws.recv())
if msg["type"] == "bar":
print(json.dumps(msg["data"]["veto"], indent=2))
asyncio.run(manual_step())
Use {"action": "step"} combined with the /api/status endpoint to build a debugger-style replay: step one bar, inspect the full result, then decide whether to continue.