Raw model predictions — floating-point forward-return estimates — are not directly tradeable. The Signal Engine bridges that gap by applying a configurable rule tree or a signal generator plugin to turn predictions into discreteDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/najmulhossainnj/Hedge-fund-backend/llms.txt
Use this file to discover all available pages before exploring further.
BUY, SELL, or HOLD directives (or their numeric equivalents +1, 0, -1). Signal logic is stored as a versioned SignalLogic record, making every signal regime auditable and reproducible.
SignalLogic Entity
ASignalLogic row stores the complete rule tree together with output and position mode settings.
SignalLogic Fields
| Field | Type | Description |
|---|---|---|
rule_tree | RuleGroup[] | Ordered list of rule groups — first match wins |
output_mode | string | "discrete" (BUY/SELL/HOLD), "numeric" (+1/0/-1), or "score" (raw prediction pass-through) |
position_mode | string | "long_only", "long_short", or "portfolio" |
strategy_id | UUID | null | Optional back-reference to the owning strategy |
Two Signal Generation Modes
Rule-Tree Mode
A JSON condition tree is evaluated bar-by-bar against the prediction and feature columns. The rule tree is serialised in
SignalLogic.rule_tree and can be built by the Signal Builder UI or posted as raw JSON. No code required.Plugin Mode
A
BaseSignalGenerator subclass is resolved from the signal plugin registry via plugin_key. Plugins have access to the full predictions DataFrame and can implement arbitrarily complex logic (ranking, portfolio construction, etc.).signal_logic_id or a plugin_key — the two modes are mutually exclusive:
Rule Tree Structure
The rule tree is a JSON array ofRuleGroup objects. Each group combines a set of leaf conditions with a combinator and maps the outcome to an action:
HOLD / 0 signal.
Leaf Rule Operators
| Operator | Meaning |
|---|---|
> | Strictly greater than |
< | Strictly less than |
>= | Greater than or equal |
<= | Less than or equal |
== | Equal (useful for categorical flags) |
!= | Not equal |
Branch Rules (Nested Combinators)
Rules within a group can themselves beBranchRule objects, enabling nested AND/OR logic:
All
field references in leaf rules must match column names present in the predictions DataFrame produced by the model. Use POST /api/signals/validate-rule-tree to dry-run your rule tree before saving it.Available Signal Plugins
| Plugin Key | Description |
|---|---|
signal.threshold | Applies fixed upper/lower thresholds to the raw prediction score |
signal.long_short | Maps positive predictions to BUY, negative to SELL, near-zero to HOLD |
signal.ranking | Ranks predictions across a universe and signals top-N long, bottom-N short |
signal.portfolio | Converts predictions to continuous position weights for portfolio construction |
Validating a Rule Tree
Before wiring a rule tree to a strategy you can perform a dry run:Signal Output
Discrete Mode (output_mode: "discrete")
Output is a signal column containing the strings "BUY", "SELL", or "HOLD".
Numeric Mode (output_mode: "numeric")
Output is a signal column containing +1 (long), -1 (short), or 0 (flat). This mode is required when feeding signals directly to portfolio optimisers or to the vectorbt backtest engine’s signal-weight sizing mode.
Score Mode (output_mode: "score")
Output is a signal column containing the raw floating-point prediction value with no thresholding applied. Useful when passing signals to downstream portfolio construction layers that perform their own ranking or weight optimisation.
Signal Summary
Every generation response includes a summary of the produced signal series:signal_rate is the fraction of bars with a non-HOLD signal — a useful sanity check before backtesting. Very low signal rates (< 0.05) or very high rates (> 0.95) typically indicate misconfigured thresholds.
Async Generation
For large date ranges or multi-symbol universes, passasync_mode: true in the generation request. The engine dispatches the computation to a Celery worker and immediately returns a task_id. Poll GET /api/signals/tasks/{task_id} to check status and retrieve results when complete.