Compose Strategy
keel_strategy_composeCreate or update Hyperliquid trading strategies from DSL source, with dry-run validation before persisting. Automatically defaults to a top-volume perp universe when no asset scope is provided.
Instructions
Create or update a strategy from DSL source. With dry_run=true, validates + tries to compile without persisting — use this first to iterate cheaply. With strategy_id set, updates an existing strategy; otherwise creates a new one. Pass exactly one of source (DSL text) or source_file (path).
Compose only AFTER the required two-step discovery: keel_components_search each role and named concept, then keel_components_detail_batch the full set you'll wire — so the DSL is planned from real component types and slots, not memory. The pipeline MUST reach WeightSeries (end with a normalizer) or it's incomplete — never persist or backtest an incomplete pipeline; fix what's missing first.
FIRST-TIME COMPOSING in this session? Invoke the strategy-creation MCP prompt FIRST (see prompts/list). It auto-loads the full decompose → discover → reason → draft workflow plus ~7 knowledge files (reasoning_principles, composition_mechanics, dsl_syntax, mistakes, tool_usage, universe_selection, pipeline_system) — the same knowledge chat-api keeps always-on. Without it you're composing blind and will likely hit common mistakes the skill catalogs. For modifying an existing strategy, invoke strategy-fork-and-iterate instead, and iterate — don't rewrite: make the SMALLEST change that answers the request, one at a time; never rearchitect a working strategy or add unrequested signals without asking first.
DEFAULTS: if the user gave no asset scope, default the Universe to mode='top_volume', top_n=30, market='perp' and target_timeframe='1d' — do not ask them to choose a universe or timeframe first; state what you used.
Server HEAD is the source of truth: updates commit directly to the server. If the strategy is also checked out locally on this machine, the update is written back into the working copy in the same operation (workspace_sync in the response) unless the local file has uncommitted edits — those are never overwritten. Validation feedback (errors + warnings + type-flow) always surfaces in the response under validation.errors and validation.warnings. Validation does NOT block the save — matches the web app editor + chat-api policy where the user sees issues inline but compile is the actual gate. Only parse and compile errors block. DSL constraints: NO Python import statements (component names like ROC, PriceDataLoader, ForecastScaler are pre-resolved — use them directly). The pipeline must end with a normalizer (ForecastWeightNormalizer or equivalent). Call keel_help(topic='dsl_syntax') for the full DSL reference, or keel_components_search to discover available components. Do NOT use to fork an existing strategy — call keel_strategy_fork. Do NOT use to run a backtest — call keel_backtest_run.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Name for the new strategy (create mode). | |
| source | No | DSL source (raw text). Exactly one of `source` or `source_file` required. | |
| dry_run | No | Only validate + compile, do not persist. | |
| source_file | No | Path to a .py DSL file. Exactly one of `source` or `source_file` required. | |
| strategy_id | No | If set, updates the named strategy; otherwise creates a new one. | |
| parent_version | No | Optional commit/version ref this update is based on. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |