Skip to main content
Glama
keel-trade

Keel — Hyperliquid trading strategies

by keel-trade

Compose Strategy

keel_strategy_compose
Idempotent

Create 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

TableJSON Schema
NameRequiredDescriptionDefault
nameNoName for the new strategy (create mode).
sourceNoDSL source (raw text). Exactly one of `source` or `source_file` required.
dry_runNoOnly validate + compile, do not persist.
source_fileNoPath to a .py DSL file. Exactly one of `source` or `source_file` required.
strategy_idNoIf set, updates the named strategy; otherwise creates a new one.
parent_versionNoOptional commit/version ref this update is based on.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations (readOnlyHint=false, openWorldHint=true, idempotentHint=true, destructiveHint=false) carry only a general safety profile, and the description adds far beyond them: validation does NOT block the save (only parse/compile errors do), updates commit to server HEAD and write back into local working copies via workspace_sync unless there are uncommitted edits (never overwritten), and DSL constraints (no Python import statements; pipeline must end with a normalizer). This gives the agent accurate expectations for side effects and failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and dry_run guidance, which is good, but it is a long, dense wall of text with no visual structure. It is somewhat redundant — the no-fork/no-backtest exclusions and the pointer to keel_help(dsl_syntax) appear more than once, and the 'same knowledge chat-api keeps always-on' aside adds little. Most content is necessary given the tool's complexity, but tightening and sectioning would make it easier for an agent to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema covers return values and the tool is highly complex, the description is remarkably complete: it covers purpose, create/update modes, workflow prerequisites, defaulting behavior, server/local sync semantics, validation response shape (validation.errors/warnings), DSL constraints, and explicit routing to alternatives. Nothing an agent needs to call this correctly is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema fully documents all six parameters, giving a baseline of 3. The description adds meaning on top: the source/source_file exclusivity ('Pass exactly one'), the strategic use of dry_run ('use this first to iterate cheaply'), the create-vs-update semantics of strategy_id, and the default-universe behavior when name/asset scope is absent. This exceeds the baseline without duplicating the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first line states a specific operation and resource: 'Create or update a strategy from DSL source.' It distinguishes the two modes (create with empty strategy_id vs. update with strategy_id) and explicitly excludes sibling tools ('Do NOT use to fork an existing strategy — call keel_strategy_fork. Do NOT use to run a backtest — call keel_backtest_run'). An agent can immediately tell this apart from keel_strategy_fork, keel_strategy_get, and keel_backtest_run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Exceptional when-to-use guidance: it mandates a two-step discovery prerequisite (keel_components_search then keel_components_detail_batch), instructs first-time composers to invoke the strategy-creation MCP prompt, tells modifiers to use strategy-fork-and-iterate with minimal changes, and names exclusions (fork → keel_strategy_fork, backtest → keel_backtest_run). It even specifies the default universe when the user gives no asset scope, so the agent doesn't stall on an undecided parameter.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.