feat: add declarative SizingMethod types from upstream schema
Upstream added three new quantity sizing objects alongside DecimalString and Expr: - fixed_sum: buy N quote-currency worth at current price - percent_of_balance: buy N% of named asset's free balance - fixed_units: buy exactly N base units (semantic alias for decimal string) Update dsl-schema.json to include the three definitions and expand Action.quantity.oneOf to reference all five valid forms. Update prompts.rs Quantity section to present the declarative methods as the preferred approach — they're cleaner, more readable, and instrument-agnostic compared to raw Expr composition. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -66,14 +66,48 @@
|
||||
"properties": {
|
||||
"side": { "type": "string", "enum": ["buy", "sell"] },
|
||||
"quantity": {
|
||||
"description": "Per-order size in base asset units. Either a fixed decimal string (e.g. \"0.001\") or a dynamic Expr evaluated at candle close. When an Expr returns None the order is skipped; negative values are clamped to zero.",
|
||||
"description": "Per-order size in base asset units. Fixed decimal string (e.g. \"0.001\"), a declarative SizingMethod object, or a dynamic Expr object. When a method or Expr returns None the order is skipped; negative values are clamped to zero.",
|
||||
"oneOf": [
|
||||
{ "$ref": "#/definitions/DecimalString" },
|
||||
{ "$ref": "#/definitions/SizingFixedSum" },
|
||||
{ "$ref": "#/definitions/SizingPercentOfBalance" },
|
||||
{ "$ref": "#/definitions/SizingFixedUnits" },
|
||||
{ "$ref": "#/definitions/Expr" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"SizingFixedSum": {
|
||||
"description": "Buy `amount` worth of quote currency at the current price. qty = amount / current_price.",
|
||||
"type": "object",
|
||||
"required": ["method", "amount"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"method": { "const": "fixed_sum" },
|
||||
"amount": { "$ref": "#/definitions/DecimalString", "description": "Quote-currency amount, e.g. \"500\" means buy $500 worth." }
|
||||
}
|
||||
},
|
||||
"SizingPercentOfBalance": {
|
||||
"description": "Buy percent% of the named asset's free balance worth of base asset. qty = balance(asset) * percent/100 / current_price.",
|
||||
"type": "object",
|
||||
"required": ["method", "percent", "asset"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"method": { "const": "percent_of_balance" },
|
||||
"percent": { "$ref": "#/definitions/DecimalString", "description": "Percentage, e.g. \"2\" means 2% of the free balance." },
|
||||
"asset": { "type": "string", "description": "Asset name to look up, e.g. \"usdc\". Matched case-insensitively." }
|
||||
}
|
||||
},
|
||||
"SizingFixedUnits": {
|
||||
"description": "Buy exactly `units` of base asset. Semantic alias for a fixed decimal quantity.",
|
||||
"type": "object",
|
||||
"required": ["method", "units"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"method": { "const": "fixed_units" },
|
||||
"units": { "$ref": "#/definitions/DecimalString", "description": "Base asset quantity, e.g. \"0.01\" means 0.01 BTC." }
|
||||
}
|
||||
},
|
||||
"Rule": {
|
||||
"type": "object",
|
||||
"required": ["when", "then"],
|
||||
|
||||
@@ -74,36 +74,42 @@ bars_since_entry — complete bars elapsed since position was opened
|
||||
balance — free balance of a named asset (e.g. "usdt", "usdc")
|
||||
|
||||
### Quantity
|
||||
Action quantity is either a fixed decimal string **or** an Expr that evaluates to a number
|
||||
at candle close. If the Expr returns None the order is skipped; negative values are clamped
|
||||
to zero.
|
||||
Action quantity accepts four forms — pick the simplest one for your intent:
|
||||
|
||||
**Preferred: expression-based sizing** — instrument-agnostic, scales automatically:
|
||||
**1. Declarative sizing methods (preferred — instrument-agnostic, readable):**
|
||||
|
||||
Fixed fraction of quote balance (5% of USDC balance, converted to base units at current price):
|
||||
Spend a fixed quote amount (e.g. $500 worth of base at current price):
|
||||
```json
|
||||
{{"kind":"bin_op","op":"div",
|
||||
"left":{{"kind":"bin_op","op":"mul",
|
||||
"left":{{"kind":"balance","asset":"usdc"}},
|
||||
"right":{{"kind":"literal","value":"0.05"}}}},
|
||||
"right":{{"kind":"field","field":"close"}}}}
|
||||
{{"method":"fixed_sum","amount":"500"}}
|
||||
```
|
||||
|
||||
ATR-based risk sizing (risk $200 per trade, sized by volatility):
|
||||
Spend a percentage of free quote balance (e.g. 5% of USDC):
|
||||
```json
|
||||
{{"method":"percent_of_balance","percent":"5","asset":"usdc"}}
|
||||
```
|
||||
|
||||
Buy a fixed number of base units (semantic alias for a decimal string):
|
||||
```json
|
||||
{{"method":"fixed_units","units":"0.01"}}
|
||||
```
|
||||
|
||||
**2. Plain decimal string** — use only when you have a specific reason:
|
||||
`"0.01"` (0.01 BTC, 3.0 ETH, 50.0 SOL — instrument-specific, not portable)
|
||||
|
||||
**3. Expr** — for dynamic sizing not covered by the methods above, e.g. ATR-based:
|
||||
```json
|
||||
{{"kind":"bin_op","op":"div",
|
||||
"left":{{"kind":"literal","value":"200"}},
|
||||
"right":{{"kind":"func","name":"atr","period":14}}}}
|
||||
```
|
||||
|
||||
For exit rules, use `position_quantity` to close the exact open position:
|
||||
**4. Exit rules** — use `position_quantity` to close the exact open size:
|
||||
```json
|
||||
{{"kind":"position_quantity"}}
|
||||
```
|
||||
|
||||
**Fixed strings are also valid** when you want a specific size, e.g. `"0.01"`.
|
||||
NEVER use placeholder strings like `"ATR_SIZED"`, `"FULL_BALANCE"`, `"all"`, `"dynamic"` —
|
||||
these are rejected immediately. Use an Expr or a plain decimal string.
|
||||
these are rejected immediately.
|
||||
|
||||
### Multi-timeframe
|
||||
Any expression can reference a different timeframe via "timeframe" field.
|
||||
|
||||
Reference in New Issue
Block a user