The Signals API powers the transition from raw ML model predictions to actionable trading decisions. ADocumentation 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.
SignalLogic record stores a rule tree — a recursive JSON structure of conditions and combinators produced by the visual Signal Builder UI. At generation time, the platform fetches OHLCV market data, runs the feature pipeline, invokes the model, and passes the resulting prediction DataFrame through the rule tree to emit per-bar BUY, SELL, or HOLD labels. Alternatively, a registered plugin key can replace the rule tree for fully custom signal generation logic. Both synchronous and Celery-backed asynchronous generation are supported.
SignalLogic CRUD
Create Signal Logic
POST /api/v1/signals
Persists a new rule tree definition linked to an optional strategy. The rule_tree field must be a non-empty list of RuleGroup objects as produced by the Signal Builder UI. On success the record is immediately available for use in signal generation.
Request Body (SignalLogicCreate)
Human-readable name for the signal logic. Maximum 255 characters. Indexed for fast lookup.
Optional description explaining the signal hypothesis. Maximum 1000 characters.
Ordered list of
RuleGroup objects. The rule engine evaluates groups top-to-bottom and returns the action of the first matching group. Each group contains an action, a combinator, and a list of rules (leaf conditions or nested branch nodes).See the Rule Tree Structure section for the full schema.Controls how the rule engine emits signals.
"discrete"— emits string labels"BUY","SELL", or"HOLD"."numeric"— emits+1,-1, or0respectively.
Intended position-taking behaviour. Informational metadata consumed by the portfolio layer.
"long_only"— only BUY signals are acted on."long_short"— both BUY and SELL signals are acted on."portfolio"— signal weight is managed at portfolio construction level.
Optional UUID of the parent
Strategy. When provided, this signal logic is scoped to that strategy and can be filtered by strategy_id on the list endpoint.Response — 201 Created
Unique identifier of the created signal logic record.
Signal logic name.
Optional description.
The stored rule tree exactly as submitted.
"discrete" or "numeric"."long_only", "long_short", or "portfolio".Linked strategy UUID, if provided.
Optimistic-concurrency version counter. Starts at
1.ISO 8601 creation timestamp.
ISO 8601 last-update timestamp.
List Signal Logic
GET /api/v1/signals
Returns a paginated list of signal logic records. Optionally filter by strategy_id to retrieve only the rules associated with a particular strategy.
Query Parameters
When provided, returns only signal logic records linked to this strategy UUID. When omitted, all records are returned subject to
skip/limit.Number of records to skip for offset-based pagination.
Maximum records to return per page.
Response — 200 OK
Returns list[SignalLogicRead]. Each element has the same shape as the Create Signal Logic response.
Get Signal Logic
GET /api/v1/signals/{signal_id}
Retrieves a single signal logic record by its UUID.
Path Parameters
UUID of the signal logic record to retrieve.
Response
200 OK with SignalLogicRead. Returns 404 Not Found with {"detail": "SignalLogic not found"} when no record exists for the given ID.
Update Signal Logic
PATCH /api/v1/signals/{signal_id}
Partially updates a signal logic record. Only the fields present in the request body are modified.
Path Parameters
UUID of the signal logic record to update.
Request Body (SignalLogicUpdate — all fields optional)
Updated name.
Updated description.
Full replacement rule tree. The entire tree is replaced — partial updates within the tree are not supported.
"discrete" or "numeric"."long_only", "long_short", or "portfolio".Re-link or unlink the parent strategy.
Response — 200 OK
Returns the updated SignalLogicRead object. Returns 404 Not Found if the record does not exist.
Delete Signal Logic
DELETE /api/v1/signals/{signal_id}
Permanently removes a signal logic record.
Path Parameters
UUID of the signal logic record to delete.
Response
204 No Content on success. 404 Not Found if the record does not exist.
Rule Tree Validation
Validate Rule Tree
POST /api/v1/signals/validate-rule-tree
Dry-runs a rule tree against a synthetic single-row DataFrame to catch field name typos, unsupported operators, and structural errors before wiring the rule tree to a live model. No database writes occur. This endpoint is intended for use by the Signal Builder UI to provide instant feedback during rule authoring.
Request Body
The rule tree to validate. Must be a non-empty list. Returns
422 Unprocessable Entity if empty.List of field names that will be present in the real feature DataFrame at generation time. The validator builds a synthetic row with
0.0 for each field and exercises every branch. If a rule references a field not in sample_fields, validation will report a KeyError.Response — 200 OK
true when the rule tree evaluated against the synthetic sample without any errors.List of error messages encountered during evaluation. Empty when
valid is true. Contains KeyError messages for unknown fields and ValueError messages for unsupported operator/value combinations.Number of top-level rule groups in the submitted tree. Useful for confirming the parser read the structure correctly.
Rule Tree Structure
The rule engine supports a recursive tree of leaf conditions and branch combinators inside each top-levelRuleGroup.
RuleGroup (top-level)
Each entry in therule_tree array is a RuleGroup. The engine evaluates groups in declaration order and returns the action of the first group whose conditions are all satisfied. If no group matches, the bar receives a HOLD signal.
Signal to emit when this group matches. One of
"BUY", "SELL", "HOLD".How to combine the child
rules. "AND" requires all rules to pass; "OR" requires at least one.Ordered list of conditions. Each element is either a leaf condition or a nested branch node.
LeafRule (leaf condition)
Column name in the feature DataFrame (e.g.
"prediction", "rsi_14", "sentiment").Comparison operator. One of
">", "<", ">=", "<=", "==", "!=".Right-hand side of the comparison. Numeric for most feature fields; string for categorical columns.
BranchRule (nested combinator)
"AND" or "OR" — applied to the child rules list.Recursively nested conditions.
Signal Generation
Generate Signals (Synchronous)
POST /api/v1/signals/generate
Runs the full signal generation pipeline end-to-end and returns the results synchronously. The pipeline:
- Loads the specified
MLModelandFeaturerecords from the database. - Fetches OHLCV market data for the
symbol/timeframe/date range via the market data client. - Runs the
FeaturePipelineto compute and join all feature columns. - Invokes the model to produce a prediction series.
- Evaluates the rule tree (or plugin) against the predictions to produce per-bar signals.
- Returns a statistical summary and a 20-row preview.
You must supply either
signal_logic_id or plugin_key — not both, and not neither. Violating this constraint returns 422 Unprocessable Entity.Request Body (SignalGenerateRequest)
UUID of the trained
MLModel to use for generating predictions.List of
Feature UUIDs whose computed columns will form the model input DataFrame. All IDs must exist; a single missing ID returns 404.UUID of the
SignalLogic record whose rule tree converts predictions to signals. Mutually exclusive with plugin_key.Key of a registered signal generator plugin to use instead of a rule tree. Retrieve available keys from
GET /api/v1/signals/plugins/available. Mutually exclusive with signal_logic_id.Key-value parameters forwarded to the plugin at generation time. Ignored when
signal_logic_id is used.Ticker symbol to generate signals for (e.g.
"AAPL", "BTC-USD").Candle resolution. Must match the timeframe the features were designed for.
ISO 8601 start of the generation window (inclusive).
ISO 8601 end of the generation window (inclusive).
Forward-looking prediction horizon in bars. Passed to the Celery task for async generation; informational for synchronous calls.
Response — 200 OK (SignalGenerateResponse)
The
signal_logic_id echoed from the request. null when a plugin was used.The
plugin_key echoed from the request. null when a rule tree was used.UUID of the model that generated the predictions.
Ticker symbol echoed from the request.
Pipeline metadata returned by the signal engine (e.g. model version, feature pipeline hashes).
Aggregate signal statistics over the full date range.
First 20 rows of the joined prediction + signal DataFrame. Each record contains at minimum a timestamp, the model prediction value, and the resulting signal label.
Generate Signals (Asynchronous)
POST /api/v1/signals/generate/async
Dispatches signal generation as a Celery background task and immediately returns a task_id. Use the task ID to poll your Celery result backend for completion status. This endpoint accepts exactly the same request body as the synchronous POST /api/v1/signals/generate.
Request Body
Identical toSignalGenerateRequest — see the synchronous endpoint for full parameter documentation.
Response — 200 OK
Celery task ID. Poll your result backend (e.g. Redis) or a task-status endpoint to check completion.
Always
"PENDING" immediately after dispatch.List Signal Plugins
GET /api/v1/signals/plugins/available
Returns the keys of all registered signal generator plugins. Plugin keys can be passed as the plugin_key parameter in signal generation requests as an alternative to a persisted rule tree.
Response — 200 OK
Array of plugin key strings registered in the
signal_registry. Each key uniquely identifies a plugin class that implements the signal generation interface.Error Reference
| Status | Condition |
|---|---|
404 Not Found | SignalLogic, MLModel, or one or more Feature IDs do not exist. |
422 Unprocessable Entity | rule_tree is empty on validate; both or neither of signal_logic_id/plugin_key provided on generate; no OHLCV data returned for the requested range. |
204 No Content | Successful deletion — no response body. |