Strategy Development
Build, test, and deploy JSON-defined trading strategies
A strategy is a named, versioned set of trading rules stored as a JSON definition. The platform evaluates your conditions against real-time indicator values and generates orders automatically — no code required to run a strategy.
What Strategies Are
Every strategy is a JSON document that describes:
- Which pairs to trade — one or more USDT pairs (e.g.
BTCUSDT,ETHUSDT) - What timeframe — the candle interval used to compute indicators
- Entry conditions — rules that must ALL be true before entering a position
- Exit conditions — rules where ANY one triggers a position close
- Position sizing — how much equity to allocate per position
- Position limit — how many positions to hold simultaneously
The platform's StrategyExecutor evaluates these rules against live indicator values computed by the IndicatorEngine (pure numpy — no external TA-Lib dependency). When entry conditions align, it places buy orders. When any exit condition fires, it places sell orders and updates trailing stop levels.
Strategy Lifecycle
draft → testing → validated → deployed → archived
↓
undeploy → validated
| Status | Meaning |
|---|---|
draft | Just created — not yet tested |
testing | A test run is in progress |
validated | At least one test run has completed |
deployed | Actively evaluating conditions and placing orders |
archived | Soft-deleted — no longer active |
A strategy moves from draft to testing automatically when you start a test run. After the test completes it becomes validated. You can only deploy from validated. To archive a deployed strategy, undeploy it first.
Strategy versions are immutable. You never overwrite a version — you always create a new one. This means you always have a full audit trail.
Strategy Definition Schema
{
"pairs": ["BTCUSDT", "ETHUSDT"],
"timeframe": "1h",
"entry_conditions": {
"rsi_below": 30,
"macd_cross_above": true,
"adx_above": 25
},
"exit_conditions": {
"stop_loss_pct": 3,
"take_profit_pct": 8,
"trailing_stop_pct": 2,
"max_hold_candles": 48
},
"position_size_pct": 10,
"max_positions": 3
}
| Field | Type | Required | Description |
|---|---|---|---|
pairs | string[] | Yes | One or more USDT trading pair symbols |
timeframe | string | Yes | Candle interval: 1m, 5m, 15m, 1h, 4h, or 1d |
entry_conditions | object | Yes | All non-null conditions must be true to enter |
exit_conditions | object | Yes | Any condition triggers exit |
position_size_pct | number | Yes | Percent of equity to allocate per position (1–100) |
max_positions | number | Yes | Maximum simultaneous open positions (1–50) |
A Complete Example
This strategy buys BTC and ETH when RSI is oversold, the MACD has just turned bullish, and the trend is strong. It exits via a stop-loss, take-profit, or if the position stagnates for more than 48 candles.
{
"pairs": ["BTCUSDT", "ETHUSDT"],
"timeframe": "1h",
"entry_conditions": {
"rsi_below": 30,
"macd_cross_above": true,
"adx_above": 25,
"volume_above_ma": 1.3
},
"exit_conditions": {
"stop_loss_pct": 3,
"take_profit_pct": 8,
"trailing_stop_pct": 2,
"max_hold_candles": 48
},
"position_size_pct": 10,
"max_positions": 3
}
Create this via REST:
curl -X POST http://localhost:8000/api/v1/strategies \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "RSI Oversold + MACD",
"description": "Buy oversold dips with trend confirmation",
"definition": { ... }
}'
Response:
{
"strategy_id": "strat_abc123",
"name": "RSI Oversold + MACD",
"status": "draft",
"current_version": 1,
"created_at": "2026-03-01T10:00:00Z"
}
Entry Conditions — AND Logic
All 12 entry condition keys use AND logic. Every non-null condition must evaluate to true for the entry signal to fire. Set a key to null (or omit it) to ignore it.
See the Indicators page for a detailed breakdown of each condition, what it measures, and example values.
Exit Conditions — OR Logic
Any single exit condition firing closes the position immediately. The priority order when multiple conditions trigger on the same candle is:
stop_loss → take_profit → trailing_stop → max_hold_candles → indicator exits
This means a stop-loss always takes priority over a take-profit if both conditions are met on the same candle (this should not happen in practice but defines the tiebreak).
See the Indicators page for all 7 exit condition keys.
Versioning
Each PUT to /strategies/{id}/versions creates a new immutable version:
from agentexchange import AgentExchangeClient
client = AgentExchangeClient(api_key="ak_live_...")
v2 = client.create_version(
strategy_id="strat_abc123",
definition={
"pairs": ["BTCUSDT", "ETHUSDT"],
"timeframe": "1h",
"entry_conditions": {"rsi_below": 25, "macd_cross_above": True, "adx_above": 28},
"exit_conditions": {"stop_loss_pct": 2, "take_profit_pct": 6, "trailing_stop_pct": 1.5},
"position_size_pct": 8,
"max_positions": 3
},
change_notes="Tightened RSI threshold and stop-loss based on test results"
)
# v2["version"] == 2
Versions are never deleted. The current_version field on the strategy points to the latest version, but you can deploy any version by number.
REST API Reference
| Method | Path | Description |
|---|---|---|
POST | /api/v1/strategies | Create a strategy |
GET | /api/v1/strategies | List strategies (paginated) |
GET | /api/v1/strategies/{id} | Get detail, definition, and latest test results |
PUT | /api/v1/strategies/{id} | Update name or description |
DELETE | /api/v1/strategies/{id} | Archive (soft-delete) |
POST | /api/v1/strategies/{id}/versions | Create a new version |
GET | /api/v1/strategies/{id}/versions | List all versions |
GET | /api/v1/strategies/{id}/versions/{v} | Get a specific version |
POST | /api/v1/strategies/{id}/deploy | Deploy a version to live |
POST | /api/v1/strategies/{id}/undeploy | Stop live execution |
All endpoints require Authorization: Bearer {jwt} or X-API-Key.
Next Steps
- Built-in Indicators — all 7 indicators, conditions, and example values
- Strategy Testing — multi-episode testing and the recommendation engine
- Deploying Strategies — versioning, monitoring, and rematches