A format specification for describing a trading strategy to coding agents and execution engines.
TRADE.md gives agents a persistent, structured understanding of a strategy's behaviour, risk profile, and lineage. It combines machine-readable tokens (YAML front matter) with human-readable rationale (markdown prose) in a single file -- just like DESIGN.md does for visual identity, but with one critical difference: the tokens are executable semantics. Compilers emit concrete strategy code directly from the file.
This is v0.2 alpha. Ships a freqtrade compiler, custom indicator support, and a strategy-as-directory layout.
Four problems this solves at once:
- Agents don't know what a strategy is. They can write
populate_entry_trendcode but they can't tell you whether the strategy is a pullback trader or a breakout trader, or when it should be disabled. TRADE.md makes the thesis and the runtime guardrails first-class. - Provenance is usually lost. Backtest results live in a notebook somewhere; separation scores live in a spreadsheet; kata lineage lives in commit messages. TRADE.md puts all three in the file itself.
- Handoff between human, agent, and runtime is lossy. Each layer re-interprets. TRADE.md becomes the single source of truth all three consume.
- Strategies are not portable across engines. Today a freqtrade strategy is bound to freqtrade forever. Engine-agnostic semantics means the same TRADE.md can target multiple runtimes.
One-per-strategy, not one-per-cell. A TRADE.md is a behavioural specification; cell assignment in the 560-grid is a portfolio-placement concern. Coupling them breaks portability and conflates two lifecycles. Cell preferences are expressible as soft hints (portfolio.preferred_cells), but placement is deployment-time metadata.
Engine-agnostic semantics, engine-specific compilers. The format talks about signals, risk, sizing, and gates in universal terms. v0.1 ships a freqtrade compiler only -- nothing in the spec leaks freqtrade conventions, so Hummingbot / Jesse / custom-runtime compilers can be added later without spec changes.
pip install trade-mdOr install from source for development:
git clone https://github.com/scaled-agents/TRADE-md.git
cd TRADE-md
pip install -e ".[dev]"Requires Python 3.11+. The only runtime dependency is PyYAML.
# validate a strategy against the spec
trade-md lint examples/heritage-rsi-ema/TRADE.md
# summarize a strategy for agent context
trade-md explain examples/heritage-rsi-ema/TRADE.md
# compile to a freqtrade IStrategy class
trade-md compile --target freqtrade \
examples/heritage-rsi-ema/TRADE.md \
-o HeritageRsiEma.py
# diff two versions for token + performance regressions
trade-md diff v0.3.0.TRADE.md v0.3.1.TRADE.md
# dump the linter rules as JSON (for agent context injection)
trade-md spec --rules-only --format json
# scaffold a new custom indicator module
trade-md new-indicator sep_score
# lint a standalone indicator module
trade-md lint-indicator indicators/sep_score.pyindicators:
trend_filter:
expr: "close > ema(200)"
vol_surge:
expr: "volume > volume.rolling(20).mean() * 1.5"
signals:
entry_long:
conditions:
- "rsi(14) < 30"
- "{trend_filter}"
- "close@1h > ema(50)@1h" # informative 1h timeframe
- "{vol_surge}"
tag: "rsi_oversold_uptrend"Compiles to:
dataframe['rsi_14'] = ta.RSI(dataframe, timeperiod=14)
dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)
dataframe['volume_roll_20_mean'] = dataframe['volume'].rolling(20).mean()
informative_1h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1h')
informative_1h['ema_50'] = ta.EMA(informative_1h, timeperiod=50)
dataframe = merge_informative_pair(dataframe, informative_1h, self.timeframe, '1h', ffill=True)
dataframe.loc[
((dataframe['rsi_14'] < 30)
& (dataframe['close'] > dataframe['ema_200'])
& (dataframe['close_1h'] > dataframe['ema_50_1h'])
& (dataframe['volume'] > dataframe['volume_roll_20_mean'] * 1.5)),
['enter_long', 'enter_tag']
] = (1, 'rsi_oversold_uptrend')See docs/DSL.md for the full DSL reference with more examples.
src/trade_md/
parser.py Front matter + prose section parsing
expr.py Condition DSL -> AST -> pandas mask
linter.py Rule-based validator (R001..R016)
explain.py Strategy summary for agent context
cli.py `trade-md` CLI entry point
indicator.py @indicator decorator and IndicatorMetadata
params.py Typed parameter descriptors (IntParam, etc.)
compilers/
freqtrade.py Emits freqtrade IStrategy Python or package
docs/
SPEC.md Format specification v0.2
DSL.md Condition DSL reference
WORKFLOW.md Canonical edit/lint/compile workflow
examples/
heritage-rsi-ema/ v0.1 reference example (single file)
heritage-rsi-ema-v02/ v0.2 reference example (strategy directory)
skills/
trade-md-workflow/SKILL.md Claude skill for strategy editing
tests/ 125 tests
The loop you already run becomes:
- Scout outputs a partial TRADE.md -- thesis + provisional tokens, no provenance yet
- Strategyzer fills in risk / sizing / gates, runs first backtest, writes back
provenance - Kata-harness iterates on TRADE.md (not on
.py); each kata loop = version bump +trade-md diffreport - Monitor reads
disable_whenas runtime guardrails, not just documentation - Portfolio orchestrator reads
portfolio.preferred_cellsas soft placement hints
Paired with a SKILL.md that says "for any freqtrade strategy task, edit TRADE.md then recompile -- never touch the .py directly," the .py files become build artifacts. Source of truth is the markdown.
skills/trade-md-workflow/SKILL.md is a Claude skill that operationalizes this discipline. Drop it into your user skills directory and any agent picking up a freqtrade task will:
- Run
trade-md explain TRADE.mdfirst to load strategy context - Edit the
.md(never the.py) - Lint and fix errors before recompiling
- Bump
versionandkata_iterationon behavioural changes - Run
trade-md diffto catch performance regressions - Write backtest results back into
provenance
See docs/WORKFLOW.md for the full workflow reference.
- Hummingbot / Jesse / custom-runtime compilers
trade-md simulate-- round-trip backtest + provenance write-backtrade-md migrate-- automatic v0.1 to v0.2 directory migration- Declarative FreqAI feature pipelines
- Signed provenance (reproducibility hashes)
MIT