docs(prompts): add DSL expression kind reference and three working examples
Shows correct usage of rsi/bollinger/ema_trend condition shortcuts, entry_price and bars_since_entry ExprKind values, and func/cross_over/bin_op expressions. Also calls out common model mistakes (rsi as ExprKind, bars_since_entry as FuncName, expr_field) and adds a note that spot strategies are long-only. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
183
src/prompts.rs
183
src/prompts.rs
@@ -119,6 +119,188 @@ When I share results from previous iterations, use them to guide your next strat
|
|||||||
- **Condition audit shows one condition always true/false**: That condition is
|
- **Condition audit shows one condition always true/false**: That condition is
|
||||||
redundant or broken. Remove it or adjust its parameters.
|
redundant or broken. Remove it or adjust its parameters.
|
||||||
|
|
||||||
|
## Critical: expression kinds (common mistakes)
|
||||||
|
|
||||||
|
These are the ONLY valid values for `"kind"` inside an `Expr` object:
|
||||||
|
`literal`, `field`, `func`, `bin_op`, `apply_func`, `unary_op`, `bars_since`,
|
||||||
|
`entry_price`, `position_quantity`, `unrealised_pnl`, `bars_since_entry`, `balance`
|
||||||
|
|
||||||
|
Common mistakes to NEVER make:
|
||||||
|
- `"kind": "rsi"` inside an Expr is WRONG. `rsi` is a *Condition* kind, not an Expr.
|
||||||
|
To use RSI value in a `compare` expression use: `{{"kind":"func","name":"rsi","period":14}}`
|
||||||
|
- `"kind": "bars_since_entry"` is a valid standalone Expr (no extra fields needed).
|
||||||
|
Do NOT put `"bars_since_entry"` as a `"name"` inside `{{"kind":"func",...}}` — that is WRONG.
|
||||||
|
- `"kind": "expr_field"` does NOT exist. Use `{{"kind":"field","field":"close"}}`.
|
||||||
|
- `rsi`, `adx`, `supertrend` are NOT valid inside `apply_func`. Use only `apply_func`
|
||||||
|
with `ApplyFuncName` values: `highest`, `lowest`, `sma`, `ema`, `wma`, `std_dev`, `sum`,
|
||||||
|
`bollinger_upper`, `bollinger_lower`.
|
||||||
|
|
||||||
|
## Working examples
|
||||||
|
|
||||||
|
### Example 1 — EMA crossover with trend filter and position exits
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{
|
||||||
|
"type": "rule_based",
|
||||||
|
"candle_interval": "1h",
|
||||||
|
"rules": [
|
||||||
|
{{
|
||||||
|
"comment": "Buy: EMA9 crosses above EMA21 while price is above EMA50",
|
||||||
|
"when": {{
|
||||||
|
"kind": "all_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "position", "state": "flat"}},
|
||||||
|
{{"kind": "ema_crossover", "fast_period": 9, "slow_period": 21, "direction": "above"}},
|
||||||
|
{{"kind": "ema_trend", "period": 50, "direction": "above"}}
|
||||||
|
]
|
||||||
|
}},
|
||||||
|
"then": {{"side": "buy", "quantity": "0.001"}}
|
||||||
|
}},
|
||||||
|
{{
|
||||||
|
"comment": "Sell: EMA9 crosses below EMA21, OR 2% stop-loss, OR 72-bar time exit",
|
||||||
|
"when": {{
|
||||||
|
"kind": "all_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "position", "state": "long"}},
|
||||||
|
{{
|
||||||
|
"kind": "any_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "ema_crossover", "fast_period": 9, "slow_period": 21, "direction": "below"}},
|
||||||
|
{{
|
||||||
|
"kind": "compare",
|
||||||
|
"left": {{"kind": "field", "field": "close"}},
|
||||||
|
"op": "<",
|
||||||
|
"right": {{"kind": "bin_op", "op": "mul", "left": {{"kind": "entry_price"}}, "right": {{"kind": "literal", "value": "0.98"}}}}
|
||||||
|
}},
|
||||||
|
{{
|
||||||
|
"kind": "compare",
|
||||||
|
"left": {{"kind": "bars_since_entry"}},
|
||||||
|
"op": ">=",
|
||||||
|
"right": {{"kind": "literal", "value": "72"}}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}},
|
||||||
|
"then": {{"side": "sell", "quantity": "0.001"}}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2 — RSI mean-reversion with Bollinger band confirmation
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{
|
||||||
|
"type": "rule_based",
|
||||||
|
"candle_interval": "4h",
|
||||||
|
"rules": [
|
||||||
|
{{
|
||||||
|
"comment": "Buy: RSI below 35 AND price below lower Bollinger band",
|
||||||
|
"when": {{
|
||||||
|
"kind": "all_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "position", "state": "flat"}},
|
||||||
|
{{"kind": "rsi", "period": 14, "threshold": "35", "comparison": "below"}},
|
||||||
|
{{"kind": "bollinger", "period": 20, "band": "below_lower"}}
|
||||||
|
]
|
||||||
|
}},
|
||||||
|
"then": {{"side": "buy", "quantity": "0.001"}}
|
||||||
|
}},
|
||||||
|
{{
|
||||||
|
"comment": "Sell: RSI recovers above 55, OR 3% stop-loss, OR 48-bar time exit",
|
||||||
|
"when": {{
|
||||||
|
"kind": "all_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "position", "state": "long"}},
|
||||||
|
{{
|
||||||
|
"kind": "any_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "rsi", "period": 14, "threshold": "55", "comparison": "above"}},
|
||||||
|
{{
|
||||||
|
"kind": "compare",
|
||||||
|
"left": {{"kind": "field", "field": "close"}},
|
||||||
|
"op": "<",
|
||||||
|
"right": {{"kind": "bin_op", "op": "mul", "left": {{"kind": "entry_price"}}, "right": {{"kind": "literal", "value": "0.97"}}}}
|
||||||
|
}},
|
||||||
|
{{
|
||||||
|
"kind": "compare",
|
||||||
|
"left": {{"kind": "bars_since_entry"}},
|
||||||
|
"op": ">=",
|
||||||
|
"right": {{"kind": "literal", "value": "48"}}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}},
|
||||||
|
"then": {{"side": "sell", "quantity": "0.001"}}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3 — ATR breakout with ATR-based stop-loss
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{
|
||||||
|
"type": "rule_based",
|
||||||
|
"candle_interval": "1h",
|
||||||
|
"rules": [
|
||||||
|
{{
|
||||||
|
"comment": "Buy: close crosses above 20-bar high while EMA50 confirms uptrend",
|
||||||
|
"when": {{
|
||||||
|
"kind": "all_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "position", "state": "flat"}},
|
||||||
|
{{"kind": "ema_trend", "period": 50, "direction": "above"}},
|
||||||
|
{{
|
||||||
|
"kind": "cross_over",
|
||||||
|
"left": {{"kind": "field", "field": "close"}},
|
||||||
|
"right": {{"kind": "func", "name": "highest", "field": "high", "period": 20, "offset": 1}}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}},
|
||||||
|
"then": {{"side": "buy", "quantity": "0.001"}}
|
||||||
|
}},
|
||||||
|
{{
|
||||||
|
"comment": "Sell: 2-ATR stop-loss below entry price, OR 48-bar time exit",
|
||||||
|
"when": {{
|
||||||
|
"kind": "all_of",
|
||||||
|
"conditions": [
|
||||||
|
{{"kind": "position", "state": "long"}},
|
||||||
|
{{
|
||||||
|
"kind": "any_of",
|
||||||
|
"conditions": [
|
||||||
|
{{
|
||||||
|
"kind": "compare",
|
||||||
|
"left": {{"kind": "field", "field": "close"}},
|
||||||
|
"op": "<",
|
||||||
|
"right": {{
|
||||||
|
"kind": "bin_op", "op": "sub",
|
||||||
|
"left": {{"kind": "entry_price"}},
|
||||||
|
"right": {{
|
||||||
|
"kind": "bin_op", "op": "mul",
|
||||||
|
"left": {{"kind": "func", "name": "atr", "period": 14}},
|
||||||
|
"right": {{"kind": "literal", "value": "2.0"}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}},
|
||||||
|
{{
|
||||||
|
"kind": "compare",
|
||||||
|
"left": {{"kind": "bars_since_entry"}},
|
||||||
|
"op": ">=",
|
||||||
|
"right": {{"kind": "literal", "value": "48"}}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}},
|
||||||
|
"then": {{"side": "sell", "quantity": "0.001"}}
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
```
|
||||||
|
|
||||||
## Anti-patterns to avoid
|
## Anti-patterns to avoid
|
||||||
|
|
||||||
- Don't use the same indicator for both entry and exit (circular logic)
|
- Don't use the same indicator for both entry and exit (circular logic)
|
||||||
@@ -128,6 +310,7 @@ When I share results from previous iterations, use them to guide your next strat
|
|||||||
- Don't create strategies with more than 5-6 conditions — overfitting risk
|
- Don't create strategies with more than 5-6 conditions — overfitting risk
|
||||||
- Don't ignore fees — a strategy needs to overcome 0.1% per round trip
|
- Don't ignore fees — a strategy needs to overcome 0.1% per round trip
|
||||||
- Always gate buy rules with position state "flat" and sell rules with "long"
|
- Always gate buy rules with position state "flat" and sell rules with "long"
|
||||||
|
- Never add a short-entry (sell when flat) rule — spot markets are long-only
|
||||||
"##
|
"##
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user