@battlegrid/mcp-server 31.2.5 → 31.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -16
- package/SKILL.md +48 -60
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/skills/EXPORT.json +17 -0
- package/skills/battlegrid-agent-management/SKILL.md +173 -0
- package/skills/battlegrid-arena-play/SKILL.md +132 -0
- package/skills/battlegrid-market-analysis/SKILL.md +76 -0
- package/skills/battlegrid-radar-deployment/SKILL.md +180 -0
- package/skills/battlegrid-strategy-authoring/SKILL.md +305 -0
- package/skills/battlegrid-strategy-doctor/SKILL.md +142 -0
- package/skills/battlegrid-strategy-examples/SKILL.md +270 -0
- package/skills/battlegrid-strategy-examples/references/playbooks.md +110 -0
- package/skills/battlegrid-strategy-examples/references/recipes.md +118 -0
- package/skills/battlegrid-strategy-examples/references/tradingview-ports.md +83 -0
- package/skills/battlegrid-trade-analysis/SKILL.md +74 -0
- package/skills/battlegrid-strategy-studio/SKILL.md +0 -254
- package/skills/battlegrid-strategy-studio/references/playbooks.md +0 -370
- package/skills/battlegrid-strategy-studio/references/recipes.md +0 -173
- package/skills/battlegrid-strategy-studio/references/tradingview-ports.md +0 -250
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: battlegrid-strategy-examples
|
|
3
|
+
description: Full-surface composition patterns for the strategy studio — validated desk-grade examples of custom report sections, benchmark sections, condition trees with verdicts and enforcement gates, tiered signal weights, routing gates, ATR trade levels, and position management. Activate beside strategy-authoring whenever a strategy is being composed or upgraded beyond a basic template.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Strategy Studio — full-power composition patterns
|
|
7
|
+
|
|
8
|
+
`strategy-authoring` owns the flow (evidence → locked spec → discover → compile → review →
|
|
9
|
+
apply). This skill owns **what to compose**: a default build — a few platform sections, no
|
|
10
|
+
conditions, untouched weights — wastes the studio. The playbooks below are compiled in CI, so their
|
|
11
|
+
shapes are binding in the sense that matters — they are checked, not merely asserted. Loose tokens
|
|
12
|
+
elsewhere in this file are not covered by that gate, and vocabulary moves with deploys, so discovery
|
|
13
|
+
in the conversation stays the authority — prefer what `list_strategy_vocabulary`,
|
|
14
|
+
`get_strategy_column_contract`, and `get_strategy_signal_definition` return over anything
|
|
15
|
+
printed here, and read exact headers from a preview's `conditionColumns` before conditioning on
|
|
16
|
+
them.
|
|
17
|
+
|
|
18
|
+
## The full-power checklist
|
|
19
|
+
|
|
20
|
+
Before compiling a CREATE, every "no" here is a decision to state, not an omission:
|
|
21
|
+
|
|
22
|
+
1. At least one **custom section** whose columns encode the thesis — not only platform modules.
|
|
23
|
+
2. **Conditions** encode the entry logic: building blocks (`verdict: null`) + verdict carriers,
|
|
24
|
+
and at least one `required: true` condition vetoing obvious disqualifiers **before any
|
|
25
|
+
billing or LLM call**.
|
|
26
|
+
3. **Every signal meant to score is named in `rules`** with a deliberate tier — unnamed signals
|
|
27
|
+
keep server defaults (typically Off). Verify in the compiled scorecard, never assume.
|
|
28
|
+
4. **Gates** (`minAggregateScore`, `minRequiredCount`, `minAtrPct`) are computed against the
|
|
29
|
+
chosen weight budget, not guessed.
|
|
30
|
+
5. **Trade levels + position management** match the setup's geometry and holding period.
|
|
31
|
+
6. `marketReadText` states standing orders with `{...}` markers so live values render inline.
|
|
32
|
+
|
|
33
|
+
## Header grammar (system-generated — never named by the author)
|
|
34
|
+
|
|
35
|
+
| Transform | Header | Validated example |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `value` | `<code>` | `bbWidthPct`, `RVOL`, `rate` |
|
|
38
|
+
| `trajectory` w4 | `<code>_t3…_t1`, `_now`, `_trend` (rising/falling/flat) | `RSI14_now`, `RSI14_trend` |
|
|
39
|
+
| `distance` | `dist_<code>` (signed % from price) | `dist_SMA50` |
|
|
40
|
+
| `spread` | `<base>_<operand>_spread` | `mark_oracle_spread` |
|
|
41
|
+
| `aggregate` wN | `<code>_mean<N>` | `rate_mean24` |
|
|
42
|
+
| `rank` | `<code>_rank_<hi\|lo\|far\|near>` — ordinal, `lte N` = top-N | `bbWidthPct_rank_lo` |
|
|
43
|
+
| `efficiency` wN | `<code>_er` (1 straight, ~0 chop) | `close_ltf_er` |
|
|
44
|
+
| `maxShare` wN | `<code>_maxShare` | `volBase_ltf_maxShare` |
|
|
45
|
+
| `classifyZone` / `classifyState` | `<code>_zone` / `<code>_state` | `RSI14_zone`, `ADX_state` |
|
|
46
|
+
|
|
47
|
+
Non-anchor rungs affix `_ltf` (lower) / `_htf` (regime): `MAalign_htf`,
|
|
48
|
+
`zones_htf_support_dist`. Chains are bounded at two: inner `distance`/`spread` → outer
|
|
49
|
+
`trajectory`/`aggregate`/`efficiency`/`maxShare`/`rank` (`EMA5 spread EMA13 × trajectory` →
|
|
50
|
+
`EMA5_EMA13_spread_now` + `_trend`).
|
|
51
|
+
|
|
52
|
+
**Timeframe references are two families.** *Relative* (`anchor`/`lower`/`regime`) re-resolve
|
|
53
|
+
when the strategy timeframe changes — `regime` is the anchor's ladder successor (1d for a 4h
|
|
54
|
+
anchor). *Pinned* (`{abs: "<tf>"}`) is fixed, ignores anchor retunes, suffixes the literal
|
|
55
|
+
(`RSI14_1d`, `dist_SMA200_1d`, `MAalign_1d` — validated), and binds to discovery's
|
|
56
|
+
`rankedTimeframes`, a **superset** of the authorable anchor set — `{abs: "1d"}` is valid while
|
|
57
|
+
`1d` is not an anchor. `offset: 1` on a pinned `value` column reads the last **closed** bar of
|
|
58
|
+
that timeframe (`RSI14[t - 1]`) — the deterministic daily-close read; offset 0 reads the
|
|
59
|
+
forming bar (provisional), and offset does not change the header, so one offset per
|
|
60
|
+
`metric × timeframe` per section. **Daily-strategy pattern:** anchor 4h, pinned-1d thesis
|
|
61
|
+
columns at `offset: 1`, `required: true` daily conditions gating every carrier, anchor-rung
|
|
62
|
+
columns only for entry timing and risk — daily inputs then move once per daily close while
|
|
63
|
+
stops and time decay keep managing intraday. **Benchmark sections** (`benchmarkTicker: "BTC"`,
|
|
64
|
+
required-nullable on every custom section) read the benchmark's values on every row — the
|
|
65
|
+
standard market-leader regime gate. Platform `sectionKey`s are their literal keys
|
|
66
|
+
(`includeMtfConfluence`). Custom `sectionKey`s are the **server's** to issue, and which of the two
|
|
67
|
+
things you do depends on the operation: on a **CREATE, omit `sectionKey` entirely** — supplying one
|
|
68
|
+
is refused, since a new strategy owns no custom sections yet; on an **UPDATE or RESTORE, send back
|
|
69
|
+
the keys `get_strategy` returned** for the sections you are keeping. Either way you never invent
|
|
70
|
+
one. To section-qualify a duplicated header, read the key from a preview's `conditionColumns` or
|
|
71
|
+
from the qualified candidates a `CONDITION_COLUMN_AMBIGUOUS` refusal offers.
|
|
72
|
+
|
|
73
|
+
**Event columns print only on their event.** `MACD_cross` and `EMA5_13` (Bullish/Bearish) carry a
|
|
74
|
+
value on the crossing bar and are null on every other one, which reads as UNRESOLVED. Use an event
|
|
75
|
+
column as a TRIGGER inside a carrier, and pair it with a persistent state — a spread sign,
|
|
76
|
+
`MAalign` — for regime. A condition that treats an event column as a standing state is unresolved on
|
|
77
|
+
nearly every bar, which is a gate that never gates.
|
|
78
|
+
|
|
79
|
+
**`PDH` and `PDL` are anchored to `1d`.** They are catalogued price levels, so `dist_PDH gte 0`
|
|
80
|
+
composes directly — but bind them `{abs: '1d'}`, which is the only reference the save path accepts on
|
|
81
|
+
them, and read them from any anchor that way. (`distance` still rejects an `offset`, and a clause
|
|
82
|
+
still compares a column against a literal; neither of those shapes is what a previous-day level
|
|
83
|
+
needed.)
|
|
84
|
+
|
|
85
|
+
## Conditions
|
|
86
|
+
|
|
87
|
+
`{ conditionKey, name, definition, verdict, required, exit, clock, closes }` — all eight
|
|
88
|
+
required, no defaults. Clauses: numeric/rank headers take `lt|lte|gte|gt|between`;
|
|
89
|
+
classification/direction headers take `is|in` with the served vocabulary. Groups:
|
|
90
|
+
`ALL | ANY | NOT | N_OF` (with `n`), depth ≤ 2. `conditionRef` composes named conditions (no
|
|
91
|
+
cycles; forward refs legal). `sectionKey: null` is sugar for a report-unique header only.
|
|
92
|
+
Verdicts: first TRUE carrier **in declaration order** decides UP/DOWN/NEITHER — order carriers
|
|
93
|
+
most-specific first; building blocks carry `null`. `required: true` = FALSE blocks compose-trade
|
|
94
|
+
before billing. Evaluation is three-valued: UNRESOLVED never collapses to FALSE; forming-bar
|
|
95
|
+
reads are provisional.
|
|
96
|
+
|
|
97
|
+
**The evidence clock.** `clock: "LIVE"` reads the forming bar; `clock: "CLOSE"` reads settled
|
|
98
|
+
bars, and `closes` is how many consecutive closed bars must read TRUE (1–5) — always `1` under
|
|
99
|
+
LIVE, which has exactly one frame. A CLOSE clock is legal **only** over a header resolved from
|
|
100
|
+
this coin's own candle series at offset 0. Frame-inert operands are refused
|
|
101
|
+
(`CONDITION_CLOCK_OPERAND_ILLEGAL`): perp-payload scalars, published rolling changes, ranks, zone
|
|
102
|
+
entities, MDS regime labels, enrichment metrics, session scalars, and any clause authored at a
|
|
103
|
+
non-zero offset. A closed frame cannot move them, so "held for N closes" would describe reads
|
|
104
|
+
that never happened. The remedy is a split, not a re-clock: move that clause into its own LIVE
|
|
105
|
+
condition and `conditionRef` it. **Worked liquidity floor:** `LIQUID_FLOOR` is LIVE because
|
|
106
|
+
`vol24hUsd` is a bundle scalar; the carrier that refs it may be CLOSE over its own candle-series
|
|
107
|
+
clauses.
|
|
108
|
+
|
|
109
|
+
**The lane a strategy is deployed to.** Report-level scalars split by LANE, and the split is not a
|
|
110
|
+
quality of the header — it is which reader runs. Market breadth and the reference pairs are ordinary
|
|
111
|
+
market-wide reads with no session dimension, so they resolve everywhere. The five **session-field**
|
|
112
|
+
scalars (`fieldPlayers`, `fieldUpBias`, `fieldBiasDir`, `captConc`, `picksSpread`) describe a game
|
|
113
|
+
session the agent is playing in, and **radar runs outside one** — so a radar deployment whose
|
|
114
|
+
strategy reads one is refused outright (`CONDITION_OPERAND_UNSERVED_IN_LANE`), naming the scalars it
|
|
115
|
+
can read instead. The refusal lands at DEPLOY rather than at save, because a strategy carries no lane
|
|
116
|
+
of its own: the same strategy is legal, and reads those scalars correctly, on an arena agent.
|
|
117
|
+
|
|
118
|
+
**The exit role.** `exit: true` makes a settled TRUE reading close open positions its verdict
|
|
119
|
+
opposes — UP exits SHORTs, DOWN exits LONGs, a NEITHER or `null` verdict exits both. Legal only
|
|
120
|
+
under `clock: "CLOSE"`: a LIVE reading is the forming bar, and an exit fired on one is an
|
|
121
|
+
intrabar exit. Orthogonal to `required` — the two act on disjoint lifecycles, pre-entry versus
|
|
122
|
+
open — so a condition may carry both, either, or neither.
|
|
123
|
+
|
|
124
|
+
**A state column is not a flip event.** `ST_DIR` reads the same on every bar of a trend, so
|
|
125
|
+
`ST_DIR is "bullish"` is a regime filter and never an entry signal. The flip needs an event column
|
|
126
|
+
beside it — an `EMA5_13` cross, or a `ST_DIR` trajectory whose `_trend` changes. The same distinction
|
|
127
|
+
applies to every persisting classification: `MAalign`, `ADX_state`, `zone`.
|
|
128
|
+
|
|
129
|
+
**Name the anchor when a metric is calibrated for one.** `KC_SQUEEZE is "on"` reads *on* about 57% of
|
|
130
|
+
1h crypto bars even at canonical parameters — Bollinger σ is close-to-close while ATR captures
|
|
131
|
+
intrabar range, so σ/ATR runs low here — against about 19% at 15m. It is a selective filter at 15m and
|
|
132
|
+
below and close to useless at 1h. A metric whose selectivity depends on the anchor is stated with the
|
|
133
|
+
anchor, or the author gates on something that admits most bars.
|
|
134
|
+
|
|
135
|
+
## Entry
|
|
136
|
+
|
|
137
|
+
`{ trigger, confirmTf, closes, bandAtrMultiple, levelSource, levelOffsetAtrMultiple,
|
|
138
|
+
validForBars }` — all seven required on every CREATE, no defaults. This axis is replaced WHOLE
|
|
139
|
+
on save, so an omitted key would silently revert an author's discipline rather than be refused.
|
|
140
|
+
|
|
141
|
+
**The trigger decides WHEN, and for two of them WHERE, an entry is taken.**
|
|
142
|
+
|
|
143
|
+
- `AT_SIGNAL` — fire the moment the radar observes the qualification flip, at whatever bar is on
|
|
144
|
+
the tape, keeping the platform's flat wall-clock entry window. Today's behaviour.
|
|
145
|
+
- `ON_CANDLE_CLOSE` — the flip ARMS the pair; the entry is taken only after a close on
|
|
146
|
+
`confirmTf` that still reads the conditions true and has not displaced beyond the band.
|
|
147
|
+
- `STOP_THROUGH_LEVEL` — a TRIGGER order rests at the authored level ± offset and the exchange
|
|
148
|
+
book is the watcher; the entry is taken when price trades through, not when the platform
|
|
149
|
+
notices.
|
|
150
|
+
- `ON_RETEST` — a LIMIT order rests at the broken level, waiting for a return to it. Not filling
|
|
151
|
+
is a correct outcome, not a failure.
|
|
152
|
+
|
|
153
|
+
`confirmTf` is the bar whose close confirms. Exactly two values are legal: the strategy's own
|
|
154
|
+
timeframe and the rung below it — one only, when the strategy sits on the ladder floor. It is
|
|
155
|
+
NOT the authorable main-candle set; a rung further down names a bar nothing else in the strategy
|
|
156
|
+
observes and makes the radar sweep on every one of its closes.
|
|
157
|
+
|
|
158
|
+
`closes` (1–5) is how many consecutive confirming closes are required, and `bandAtrMultiple` is
|
|
159
|
+
the veto width: the entry is VOIDED when the confirming close has moved at or beyond that many
|
|
160
|
+
ATR against the armed verdict. Strictly greater than zero — zero is not "no filter" but a filter
|
|
161
|
+
that voids on any adverse move — and at or below the platform's own entry-deviation gate, since
|
|
162
|
+
a wider band cannot refuse anything the platform will not refuse anyway.
|
|
163
|
+
|
|
164
|
+
`levelSource` is one of `SWING_HIGH`, `SWING_LOW`, `BOLLINGER_UPPER`, `BOLLINGER_LOWER`,
|
|
165
|
+
resolved once at decision time. `levelOffsetAtrMultiple` (0–2) is an UNSIGNED magnitude — the
|
|
166
|
+
direction is implied by the trigger and the verdict, so a signed value would invert the
|
|
167
|
+
trigger's meaning. `validForBars` (1–24) denominates validity in the strategy's OWN bars rather
|
|
168
|
+
than minutes, because a 1h setup waiting for a retest has not failed after fifteen minutes.
|
|
169
|
+
|
|
170
|
+
**The legality matrix runs one way.** All seven keys are always present, so the question is
|
|
171
|
+
never "is it set" but "is it set to something that MEANS anything under this trigger".
|
|
172
|
+
`closes` ≠ 1 is refused under any trigger but `ON_CANDLE_CLOSE`; `levelOffsetAtrMultiple` ≠ 0 is
|
|
173
|
+
refused under a non-level trigger. Leave a dial at its inert value rather than setting one the
|
|
174
|
+
platform will ignore.
|
|
175
|
+
|
|
176
|
+
## Report sections
|
|
177
|
+
|
|
178
|
+
`{ kind, sectionKey, title, benchmarkTicker, notes, columns }` — the custom section shape. A
|
|
179
|
+
section carries no `timeframe`: its relative columns resolve against the strategy timeframe, and a
|
|
180
|
+
column reaches any other timeframe by pinning it (`timeframe: { abs: '4h' }`). `benchmarkTicker` and `notes` are **required-nullable**: send an explicit `null` rather
|
|
181
|
+
than omitting them, because the section is rebuilt whole on save and an omitted key clears the
|
|
182
|
+
author's value silently. On a CREATE, omit `sectionKey` — it is derived from the section itself.
|
|
183
|
+
|
|
184
|
+
## Signal rules
|
|
185
|
+
|
|
186
|
+
`{ signalId, allocation, required, params }` — one entry per signal you want scoring.
|
|
187
|
+
`allocation` is the tier (0–3) and `params` replaces canonical defaults only when present.
|
|
188
|
+
|
|
189
|
+
## Signal weights and gate math
|
|
190
|
+
|
|
191
|
+
Tiers: 0 Off · 1 Normal · 2 Important · 3 Critical.
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
aggregateScore = Σ(score × allocation) / Σ(allocation) over triggered signals
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Weights are relative — build a pyramid: 1–2 Critical (thesis, usually `required`), 2–4
|
|
198
|
+
Important (independent confirmation, different modules), 1–3 Normal (context), rest Off so
|
|
199
|
+
noise cannot dilute the average. Gate check: with 3/2/2/1 weights, Critical + one Important at
|
|
200
|
+
score 1.0 → (3+2)/8 = 0.625, so a 0.6 gate means "thesis plus one confirmation".
|
|
201
|
+
`simulate_aggregate_score` does this arithmetic from compiled values at review time.
|
|
202
|
+
`required: true` counts the signal toward `minRequiredCount` when triggered; at
|
|
203
|
+
`allocation: 0` it is rejected (contract 34). `params` replace canonical defaults only when
|
|
204
|
+
present — read `get_strategy_signal_definition({ signalId, timeframe })` before tuning (e.g.
|
|
205
|
+
`rsi_overbought {"threshold": 65}` for a fade book; `volume_surge {"multiplier": 1.5}`).
|
|
206
|
+
`derive_strategy_rule_view` shows which signals a draft report feeds — weighting a signal the
|
|
207
|
+
report never feeds is dead weight.
|
|
208
|
+
|
|
209
|
+
## Routing gates
|
|
210
|
+
|
|
211
|
+
`{ minAggregateScore, minRequiredCount, minAtrPct }` — whether a scored setup may route to a
|
|
212
|
+
trade at all. `minAggregateScore` 0–1 · `minRequiredCount` 0–20 · `minAtrPct` is the dead-market
|
|
213
|
+
floor, with bounds from `get_trading_config_catalog`.
|
|
214
|
+
|
|
215
|
+
## Trade levels
|
|
216
|
+
|
|
217
|
+
`{ minStopLossAtrMultiple, maxStopLossAtrMultiple, minRiskRewardRatio }` — where stops and
|
|
218
|
+
targets may sit. `minStopLossAtrMultiple < maxStopLossAtrMultiple` (≤ the 3×ATR structural cap),
|
|
219
|
+
`minRiskRewardRatio` within the served range. Sizing is risk-budget based — a wider stop means a
|
|
220
|
+
smaller position, never more risk.
|
|
221
|
+
|
|
222
|
+
## Position management
|
|
223
|
+
|
|
224
|
+
`{ breakEvenEnabled, breakEvenTriggerR, trailingEnabled, trailingTriggerR, trailingGivebackPct,
|
|
225
|
+
trailingBufferPct, timeDecayEnabled, timeDecayGracePeriodMinutes, timeDecayIntervalMinutes,
|
|
226
|
+
timeDecayTightenPct, timeDecayMaxTightenPct, timeDecayStaleThresholdTpProgressPct,
|
|
227
|
+
decisionInvalidationExitEnabled }` — how the stop moves after entry, and when a position is
|
|
228
|
+
closed for reasons other than its stop.
|
|
229
|
+
|
|
230
|
+
Validated bounds: break-even trigger 0.5–2R; trailing trigger 0–2R step 0.01 (0 = trail from
|
|
231
|
+
entry), giveback 25–55%, buffer 0.01–1%; timeDecay grace ≥ interval, tighten 0.1–50% to max
|
|
232
|
+
1–100%, stale threshold 0–100% of TP progress. Per-mechanism flags; no umbrella switch.
|
|
233
|
+
|
|
234
|
+
`decisionInvalidationExitEnabled` is the post-fill invalidation exit: a **closed**
|
|
235
|
+
strategy-timeframe candle beyond the decision's invalidation level closes the position
|
|
236
|
+
reduce-only. Bar-close only — the protective stop still owns intrabar moves.
|
|
237
|
+
|
|
238
|
+
Persona presets: scalper (5m/15m) stops 0.5–1.2 ATR, RR 1.5, BE 0.7R, trail 0.9R/giveback 30,
|
|
239
|
+
timeDecay ON (45/15, tighten 15→60, stale 30) · intraday mean-revert (1h) 1.0–2.5 ATR, RR 1.5,
|
|
240
|
+
BE 0.8R, no trail, timeDecay ON (120/60, 10→40, stale 25) · swing breakout (4h) 0.75–1.75 ATR,
|
|
241
|
+
RR 2, BE 1R, trail 1.2R/giveback 35 · swing trend (4h) 1.0–2.5 ATR, RR 2, BE 1R, trail
|
|
242
|
+
1.5R/giveback 45–55, no timeDecay.
|
|
243
|
+
|
|
244
|
+
## Not expressible — the catalog keys this needs
|
|
245
|
+
|
|
246
|
+
The one place a claim that the catalog LACKS something may live, and every row names the key it
|
|
247
|
+
denies so the claim can be checked. A claim about the grammar's shape (a clause compares one
|
|
248
|
+
column against a literal; `distance` rejects an `offset`) belongs in prose above — those are
|
|
249
|
+
permanent. A claim that a metric is absent belongs here, or nowhere.
|
|
250
|
+
|
|
251
|
+
| Script / primitive | Key the catalog would need | Nearest expressible neighbour |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| 100-period SMA | `SMA100` | the shipped 50- or 200-period simple average, whichever the thesis leans on |
|
|
254
|
+
|
|
255
|
+
## Where the worked material lives
|
|
256
|
+
|
|
257
|
+
This skill's body is the contract — the axes, the header grammar, how conditions and weights behave,
|
|
258
|
+
and the absence section above. The worked material is disclosed on demand, so it costs nothing until
|
|
259
|
+
you ask for it. Read a reference with `read_skill_reference` when you reach the work it covers:
|
|
260
|
+
|
|
261
|
+
- **`references/recipes.md`** — copy-adaptable column objects and condition fragments: cross
|
|
262
|
+
detection, board-relative ranks, cross-venue basis, crowd positioning, coin selection, and the
|
|
263
|
+
discovery fields worth reading before you compose.
|
|
264
|
+
- **`references/playbooks.md`** — five validated desk-grade compositions end to end, and how to
|
|
265
|
+
adapt one rather than copy it.
|
|
266
|
+
- **`references/tradingview-ports.md`** — per-script port recipes for the popular TradingView
|
|
267
|
+
strategies, each naming its substitutions where the catalog lacks a primitive.
|
|
268
|
+
|
|
269
|
+
Every rule about how a column *behaves* is in this body, not in a reference. If a reference seems to
|
|
270
|
+
state one, the body is the authority.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Playbooks — validated desk-grade compositions
|
|
2
|
+
|
|
3
|
+
Worked compositions for the strategy studio, each validated against the live grammar. Shapes are
|
|
4
|
+
binding; the tokens are illustrations and stay live-discovered.
|
|
5
|
+
|
|
6
|
+
**Contents**
|
|
7
|
+
- Playbooks (validated compositions)
|
|
8
|
+
- Using a playbook
|
|
9
|
+
|
|
10
|
+
Read `## Header grammar` and `## Conditions` in the skill body first — the rules about how columns
|
|
11
|
+
behave live there, not here.
|
|
12
|
+
|
|
13
|
+
## Playbooks (validated compositions)
|
|
14
|
+
|
|
15
|
+
*Validated* is a gate, not a claim: every playbook below is compiled against the live catalog by
|
|
16
|
+
`strategy-playbooks.compile.test.ts`, which fails the build if one stops assembling or if a header
|
|
17
|
+
its conditions name stops resolving. Edit a playbook and the gate re-checks it; move the grammar
|
|
18
|
+
underneath one and the gate catches that too.
|
|
19
|
+
|
|
20
|
+
### 1 · Volatility Compression Breakout — 4h swing
|
|
21
|
+
|
|
22
|
+
Custom `Squeeze Scan` (no `sectionKey` — this is a CREATE): `BB_WIDTH_PCT value` + `rank lo`, `ADX value`,
|
|
23
|
+
`RVOL value`, `BB_PCT_B value`, `CLOSE_CHANGE value`, `NOTIONAL_VOLUME_1D value`; plus platform
|
|
24
|
+
`includeStructureZones`. (No `includeBollingerBands`: it renders `bbWidthPct` and
|
|
25
|
+
`bbWidthPct_rank_lo` a second time, which makes both of `SQUEEZE_ON`'s clauses ambiguous, and the
|
|
26
|
+
custom section already carries them.) Conditions: `LIQUID_FLOOR` (required —
|
|
27
|
+
`vol24hUsd gte 25000000`); `SQUEEZE_ON` building block (`bbWidthPct_rank_lo lte 10` AND
|
|
28
|
+
`ADX lt 20`); `BREAK_UP` verdict UP (ref SQUEEZE_ON + `closeChg gt 0` + `RVOL gte 1.5` +
|
|
29
|
+
`pctB gte 0.85`); `BREAK_DOWN` verdict DOWN (mirror with `pctB lte 0.15`). Rules:
|
|
30
|
+
`bollinger_squeeze` 3 required · `volume_surge` 2 required `{"multiplier":1.5}` ·
|
|
31
|
+
`volatility_atr_expanding` 2 · `sr_resistance_break` 2 · `sr_support_break` 2 ·
|
|
32
|
+
`bollinger_upper_touch` 1 · `bollinger_lower_touch` 1 · `trend_adx_ranging` 1. Gates
|
|
33
|
+
0.55 / 2 / 0.8. Levels 0.75–1.75 ATR, RR 2. PM: BE 1R; trail 1.2R giveback 35 buffer 0.3.
|
|
34
|
+
Market Read: "Trade only expansions out of compression: {SQUEEZE_ON} must read TRUE… skip
|
|
35
|
+
anything failing {LIQUID_FLOOR}."
|
|
36
|
+
|
|
37
|
+
### 2 · Crowded-Positioning Fade — 1h intraday
|
|
38
|
+
|
|
39
|
+
Custom `Positioning`: `FUNDING_RATE value`→`rate`, `aggregate w24`→`rate_mean24`,
|
|
40
|
+
`FUNDING_ANN value`→`ann`, `OI_CHG value`→`oiChg`, `OI_PX_REGIME value`→`oiRegime` (vocab:
|
|
41
|
+
new longs / new shorts / short covering / long liquidation), `MARK spread ORACLE`→
|
|
42
|
+
`mark_oracle_spread`, `RSI14 value`, `CHG_24H value`→`chg24h`; plus `includeCvd`. Conditions:
|
|
43
|
+
`NO_LIQUIDATION_TAPE` required NOT-veto (`NOT [oiRegime is "long liquidation"]`);
|
|
44
|
+
`CROWDED_LONGS` building block (`ann gte 25` + `oiChg gte 3` + `oiRegime is "new longs"`);
|
|
45
|
+
`FADE_SHORT` verdict DOWN (ref + `RSI14 gte 65` + `chg24h gte 5`); mirrored `SQUEEZED_SHORTS`
|
|
46
|
+
/ `SQUEEZE_LONG` verdict UP. Rules: `funding_extreme_positive`/`_negative` 3 required
|
|
47
|
+
`{"thresholdPct":0.001}` · `oi_surge` 2 `{"thresholdPct":0.03}` · `rsi_overbought` 2
|
|
48
|
+
`{"threshold":65}` · `rsi_oversold` 2 `{"threshold":35}` · `cvd_bear_divergence` 2 ·
|
|
49
|
+
`cvd_bull_divergence` 2 · `mfi_overbought` 1 · `mfi_oversold` 1. Gates 0.6 / 1 / 0.5. Levels
|
|
50
|
+
1.0–2.5 ATR, RR 1.5. PM: BE 0.8R, no trail, timeDecay ON (120/60, 10→40, stale 25).
|
|
51
|
+
|
|
52
|
+
### 3 · Relative-Strength Rotation with a Benchmark Gate — 4h cross-sectional
|
|
53
|
+
|
|
54
|
+
Custom `Leadership`: `ROC12 rank hi` + `rank lo`, `RVOL rank hi`,
|
|
55
|
+
`EMA5 spread EMA13 × trajectory w4`, `NOTIONAL_VOLUME_1D value`. **Rank `ROC12`, not
|
|
56
|
+
`CLOSE_CHANGE`:** `closeChg` is the one magnitude-only rankable code, so `hi`/`lo` on it are
|
|
57
|
+
refused, and its legal `far` ordering sorts by |change| — which would put the session's biggest
|
|
58
|
+
losers in a "leaders" cohort. Custom `BTC Regime` with
|
|
59
|
+
`"benchmarkTicker": "BTC"`: `MA_ALIGN value`→`MAalign`, `ADX value`, `REGIME_TREND value` —
|
|
60
|
+
every row reads BTC. Conditions: `BTC_RISK_ON` building block (`MAalign is "bullish"` +
|
|
61
|
+
`ADX gte 20` — both read bare, since only this section renders them); `BTC_RISK_OFF`
|
|
62
|
+
(`MAalign is "bearish"`); `LEADER` (`roc12_rank_hi lte 5` + `RVOL_rank_hi lte 10` +
|
|
63
|
+
`vol24hUsd gte 100000000`); `ROTATE_IN` verdict UP (`ALL[ref BTC_RISK_ON, ref LEADER]`);
|
|
64
|
+
`ROTATE_OUT` verdict DOWN (`ALL[ref BTC_RISK_OFF, roc12_rank_lo lte 5]`). Rules:
|
|
65
|
+
`comparison_sector_momentum` 3 · `rel_roc_positive`/`_negative` 2 · `ma_ema_aligned_bull`/
|
|
66
|
+
`_bear` 2 required · `rel_ppo_bull_cross`/`_bear_cross` 1 · `volume_surge` 1. Gates
|
|
67
|
+
0.5 / 1 / 0.6. Levels 1–2 ATR, RR 1.8. PM: BE 1R; trail 1R giveback 45. Ranked cohort ≥ 40 —
|
|
68
|
+
rank conditions need a cohort wider than their thresholds.
|
|
69
|
+
|
|
70
|
+
### 4 · HTF Trend Pullback — 1h, multi-timeframe confluence
|
|
71
|
+
|
|
72
|
+
Platform `includeMtfConfluence` (`MAalign_ltf/…/_htf`, `RSI14_*_zone`, `ADX_*_state` vocab
|
|
73
|
+
weak/developing/trending/extreme), `includeMovingAverages` (`dist_EMA20`, …), `includeRsi`
|
|
74
|
+
(`RSI14_now`, `RSI14_zone`). These three render `MAalign` and `RSI14_zone` twice between them, so
|
|
75
|
+
every condition below reads a suffixed form — never bare `MAalign` or bare `RSI14_zone`, which
|
|
76
|
+
would be ambiguous. Conditions: `HTF_UP` building block (`MAalign_htf is "bullish"` +
|
|
77
|
+
`ADX_htf_state in ["trending","extreme"]`); `HTF_DOWN` mirror; `TREND_PRESENT` **required**
|
|
78
|
+
`ANY[ref HTF_UP, ref HTF_DOWN]` — chop blocks compose-trade entirely, before billing;
|
|
79
|
+
`PULLBACK_LONG` verdict UP (ref HTF_UP + `RSI14_now between 35 55` +
|
|
80
|
+
`dist_EMA20 between -3 0.5`); `PULLBACK_SHORT` verdict DOWN (mirror, 45–65 / −0.5–3). Rules:
|
|
81
|
+
`mtf_pullback_long`/`_short` 3 required · `htf_ma_aligned_bull`/`_bear` 2 required ·
|
|
82
|
+
`htf_trend_adx_trending` 2 · `ma_ema_aligned_bull`/`_bear` 1 · `rsi_oversold` 1
|
|
83
|
+
`{"threshold":40}`. Gates 0.6 / 2 / 0.7 (a pullback signal AND an HTF alignment). Levels
|
|
84
|
+
1–2.5 ATR, RR 2. PM: BE 1R; trail 1.5R giveback 30 buffer 0.3.
|
|
85
|
+
|
|
86
|
+
### 5 · Perp/Spot Flow Divergence at Structure — 15m scalp
|
|
87
|
+
|
|
88
|
+
Platform `includePerpSpotFlow` (`perpSpotFlow` vocab: confirmed_bull / confirmed_bear /
|
|
89
|
+
perp_led_fragile / spot_led_accumulation / neutral), `includeStructureZones`
|
|
90
|
+
(`zones_htf_support_dist` signed %, support below price is negative; `_age_h`), custom `Tape`
|
|
91
|
+
(`BUY_PRESSURE value`→`buyPres` 0–1, `RVOL value`, `CLOSE_CHANGE value`). Conditions:
|
|
92
|
+
`SPOT_ACCUM` (`perpSpotFlow is "spot_led_accumulation"`); `NEAR_SUPPORT`
|
|
93
|
+
(`zones_htf_support_dist between -2 0` + `zones_htf_support_age_h gte 12`); `DIP_BID` verdict
|
|
94
|
+
UP — refs plus an `N_OF(2)` quorum over `buyPres gte 0.55` / `RVOL gte 1.2` / `closeChg gt 0`
|
|
95
|
+
(quorum beats a brittle ALL); `FRAGILE_POP` verdict DOWN (`perp_led_fragile` +
|
|
96
|
+
`zones_htf_resist_dist between 0 2` + `RVOL gte 1.3`). Rules:
|
|
97
|
+
`flow_perp_spot_bull_divergence`/`_bear_divergence` 3 required · `cvd_bull_divergence`/
|
|
98
|
+
`_bear_divergence` 2 · `sr_at_support`/`_at_resistance` 2 · `structure_ob_approach` 1 ·
|
|
99
|
+
`volume_surge` 1. Gates 0.55 / 1 / 0.4. Levels 0.5–1.2 ATR, RR 1.5. PM: BE 0.7R; trail 0.9R
|
|
100
|
+
giveback 30 buffer 0.15; timeDecay ON aggressive (45/15, 15→60, stale 30).
|
|
101
|
+
|
|
102
|
+
## Using a playbook
|
|
103
|
+
|
|
104
|
+
Discover → confirm headers (`get_strategy_column_contract`, or one `preview_strategy_report`
|
|
105
|
+
whose `conditionColumns` lists every addressable header with operators and vocabulary) →
|
|
106
|
+
calibrate literals against the previewed live values → compile once → review the compiled
|
|
107
|
+
scorecard, condition outcomes, verdict tally, and `marketReadMarkers` (fix `unknown` /
|
|
108
|
+
`ambiguous` markers) → apply per the strategy-authoring flow. Coin selection is call context,
|
|
109
|
+
not strategy state: explicit tickers for focused work, `ranked` (with an optional category) for
|
|
110
|
+
scanning books.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Recipes — copy-adaptable fragments
|
|
2
|
+
|
|
3
|
+
Column objects for a custom section's `columns[]`, condition fragments for `conditions[]`, and the
|
|
4
|
+
coin-selection and discovery shapes an author reaches for while writing a payload.
|
|
5
|
+
|
|
6
|
+
**Shapes are binding. Tokens are illustrations** — re-discover every metric, transform and parameter
|
|
7
|
+
against the live tools (`list_strategy_categories`, `list_strategy_vocabulary`,
|
|
8
|
+
`get_metric_construction_hints`, `get_strategy_column_contract`) before compiling. A recipe is a
|
|
9
|
+
worked shape, never a substitute for discovery.
|
|
10
|
+
|
|
11
|
+
Read `## Header grammar` and `## Conditions` in the skill body first: how a column's header is
|
|
12
|
+
generated, how event columns resolve, what `{abs: …}` binds, and which classifications are states
|
|
13
|
+
rather than events all live there. This document assumes them.
|
|
14
|
+
|
|
15
|
+
**Contents**
|
|
16
|
+
- Column recipes
|
|
17
|
+
- Cross detection
|
|
18
|
+
- Board-relative rank recipes
|
|
19
|
+
- Cross-venue and perp/spot basis
|
|
20
|
+
- Crowd positioning
|
|
21
|
+
- Coin selection
|
|
22
|
+
- Discovery fields worth reading
|
|
23
|
+
|
|
24
|
+
## Column recipes
|
|
25
|
+
|
|
26
|
+
| Intent | Column | Header it generates |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Live traded price | `{ "metric": "LAST", "transformId": "value", "timeframe": { "rel": "anchor" } }` | `last` |
|
|
29
|
+
| Momentum build-up | `{ "metric": "RSI14", "transformId": "trajectory", "timeframe": { "rel": "anchor" }, "window": 4 }` | `RSI14_t3…_now`, `RSI14_trend` |
|
|
30
|
+
| Closed-bar-only trajectory | add `"bars": "closed"` to any trajectory | same, drawn from closed bars |
|
|
31
|
+
| Extension from trend | `{ "metric": "SMA50", "transformId": "distance", "timeframe": { "rel": "anchor" } }` | `dist_SMA50` (signed %) |
|
|
32
|
+
| Funding paid over a day | `{ "metric": "FUNDING_RATE", "transformId": "aggregate", "timeframe": { "rel": "anchor" }, "window": 24 }` | `rate_mean24` |
|
|
33
|
+
| Chop filter on the entry rung | `{ "metric": "CLOSE", "transformId": "efficiency", "timeframe": { "rel": "lower" }, "window": 5, "bars": "closed" }` | `close_ltf_er` (≥0.6 directional) |
|
|
34
|
+
| One-bar volume concentration | `{ "metric": "VOLUME", "transformId": "maxShare", "timeframe": { "rel": "lower" }, "window": 4, "bars": "closed" }` | `volBase_ltf_maxShare` |
|
|
35
|
+
| Room to structure | `{ "metric": "STRUCT_ZONES", "transformId": "nearestZoneDist", "timeframe": { "rel": "regime" }, "side": "resistance" }` | `zones_htf_resist_dist` |
|
|
36
|
+
| Last **closed** daily read | `{ "metric": "RSI14", "transformId": "value", "timeframe": { "abs": "1d" }, "offset": 1 }` | `RSI14_1d` — `RSI14[t - 1]` |
|
|
37
|
+
|
|
38
|
+
## Cross detection
|
|
39
|
+
|
|
40
|
+
`crossDetect` is the transform that turns a pair into an EVENT column — it prints on the crossing bar
|
|
41
|
+
and is null otherwise:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{ "metric": "MACD", "transformId": "crossDetect", "timeframe": { "rel": "anchor" } }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
An event column is a trigger inside a carrier, never a standing state; pair it with a persistent
|
|
48
|
+
state for regime. The skill body's `## Header grammar` states that rule and is the authority on it —
|
|
49
|
+
a condition that reads a `crossDetect` column as a state is UNRESOLVED on nearly every bar.
|
|
50
|
+
|
|
51
|
+
## Board-relative rank recipes
|
|
52
|
+
|
|
53
|
+
`rank` turns any column into an ordinal across the scanned board. Ordering semantics: `hi` most
|
|
54
|
+
positive, `lo` most negative, `far`/`near` by magnitude (offered only where sign matters), and
|
|
55
|
+
`lte N` reads as "top N".
|
|
56
|
+
|
|
57
|
+
| Intent | Column | Header |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| Most volatile on the board | `{ "metric": "ATR_PCT", "transformId": "rank", "timeframe": { "rel": "anchor" }, "ordering": "hi" }` | `atrPct_rank_hi` (1 = most volatile) |
|
|
60
|
+
| Biggest movers, sign-agnostic | `{ "metric": "CLOSE_CHANGE", "transformId": "rank", "timeframe": { "rel": "anchor" }, "ordering": "far" }` | `closeChg_rank_far` |
|
|
61
|
+
| Most extended from VWAP | `{ "metric": "VWAP", "transformId": "distance", "chainedTransformId": "rank", "timeframe": { "rel": "anchor" }, "ordering": "far" }` | `dist_VWAP_rank_far` |
|
|
62
|
+
|
|
63
|
+
Confirm every rank ordering against `get_metric_construction_hints({ metric }).rankOrderings` — it is
|
|
64
|
+
present only where rank is composable on that metric, and is already range-gated server-side. Read
|
|
65
|
+
the offered set; never derive one from the metric's native output.
|
|
66
|
+
|
|
67
|
+
## Cross-venue and perp/spot basis
|
|
68
|
+
|
|
69
|
+
| Intent | Column | Header |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| Perp premium to oracle | `{ "metric": "MARK", "transformId": "spread", "timeframe": { "rel": "anchor" }, "inputs": [{ "metric": "ORACLE" }] }` | `mark_oracle_spread` |
|
|
72
|
+
| Basis to Binance spot | `{ "metric": "MARK", "transformId": "spread", "timeframe": { "rel": "anchor" }, "inputs": [{ "metric": "SPOT_CLOSE_BN" }] }` | `mark_bnClose_spread` |
|
|
73
|
+
| Basis to Coinbase spot | same with `{ "metric": "SPOT_CLOSE_CB" }` | `mark_cbClose_spread` |
|
|
74
|
+
|
|
75
|
+
A positive basis that is widening while price stalls is perp-led; the flow playbooks use it as the
|
|
76
|
+
fragility read.
|
|
77
|
+
|
|
78
|
+
## Crowd positioning
|
|
79
|
+
|
|
80
|
+
`CROWD_UPBIAS` is the platform's own crowd read — the share of recent settled sessions predicting UP,
|
|
81
|
+
as a percentage:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{ "metric": "CROWD_UPBIAS", "transformId": "value", "timeframe": { "rel": "anchor" } }
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Header `upBias`. It is a fade input, not a trend input: it says what the board expects, which is the
|
|
88
|
+
thing a crowded-positioning playbook trades against.
|
|
89
|
+
|
|
90
|
+
## Coin selection
|
|
91
|
+
|
|
92
|
+
`coinSelection` is required on every compile and is discriminated on `mode`:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{ "mode": "ranked", "limit": 25, "category": "DEFI" }
|
|
96
|
+
{ "mode": "explicit", "tickers": ["BTC", "ETH", "SOL"] }
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`ranked` is top-N by 24h volume with an optional sector filter; `explicit` names a ticker set
|
|
100
|
+
validated against the active universe. The sector vocabulary is
|
|
101
|
+
`ALL` / `CRYPTO` / `L1` / `MEMES` / `DEFI` / `TRADFI` / `STOCKS` / `INDICES` / `COMMODITIES` —
|
|
102
|
+
discover the live set rather than assuming this list has not moved. An explicit set is capped; the
|
|
103
|
+
refusal names the cap.
|
|
104
|
+
|
|
105
|
+
## Discovery fields worth reading
|
|
106
|
+
|
|
107
|
+
Two answers are frequently fetched and then left unread, and each has cost a refusal that a
|
|
108
|
+
single already-served field would have prevented:
|
|
109
|
+
|
|
110
|
+
- `get_strategy_column_contract({ column }).outputs[].conditionOperators` — an empty array means that
|
|
111
|
+
rendered header has no comparison semantics and **cannot appear in a condition clause at all**.
|
|
112
|
+
Legality is per rendered header, not per column: a trajectory's slot header and its `_trend` header
|
|
113
|
+
answer differently.
|
|
114
|
+
- `get_metric_construction_hints({ metric }).rankOrderings` and `.qualifiedForms` — the composable
|
|
115
|
+
rank orderings, and the section-qualified forms available when a header is duplicated report-wide.
|
|
116
|
+
- `get_trading_config_catalog()` carries the platform defaults an omitted dial inherits, including
|
|
117
|
+
`defaultMaxEntryDeviationAtrMultiple` — the band an entry is still admitted within. Read it before
|
|
118
|
+
authoring an entry band, rather than restating a number the platform already owns.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# TradingView ports — familiar processes in studio vocabulary
|
|
2
|
+
|
|
3
|
+
Per-script port recipes. Each ports the PROCESS (regime filter -> setup state -> trigger -> stop
|
|
4
|
+
engine) and names its substitutions where the catalog lacks a primitive.
|
|
5
|
+
|
|
6
|
+
**Contents**
|
|
7
|
+
- Squeeze Momentum [LazyBear] / TTM Squeeze
|
|
8
|
+
- Supertrend / UT Bot / Chandelier Exit
|
|
9
|
+
- MACD + 200 MA filter
|
|
10
|
+
- Golden / Death Cross
|
|
11
|
+
- RSI-2 (Connors)
|
|
12
|
+
- VWAP reversion
|
|
13
|
+
- Donchian / Turtle breakout
|
|
14
|
+
- ICT / SMC (FVG + order blocks)
|
|
15
|
+
- Now native, formerly substituted
|
|
16
|
+
|
|
17
|
+
## TradingView ports — familiar processes, studio vocabulary
|
|
18
|
+
|
|
19
|
+
Players often ask for strategies by the name of a popular TradingView script. Port the
|
|
20
|
+
**process** (regime filter → setup state → trigger → stop engine), and where the catalog lacks
|
|
21
|
+
the primitive, name the substitution in the spec-lock question — never present a substitute as
|
|
22
|
+
the thing itself. Most TV strategies run on the daily chart: carry that with the
|
|
23
|
+
daily-strategy pattern above (pinned-1d thesis at `offset: 1` on an intraday anchor), which
|
|
24
|
+
binds decisions to daily closes while the studio keeps managing risk intraday.
|
|
25
|
+
|
|
26
|
+
Event-column behaviour, state-vs-event, `PDH`/`PDL` binding and the squeeze's anchor calibration are
|
|
27
|
+
rules about the columns themselves, not about porting — they live in the skill body's
|
|
28
|
+
`## Header grammar` and `## Conditions`. Read those first; this document is the per-script recipes.
|
|
29
|
+
|
|
30
|
+
- **Squeeze Momentum [LazyBear] / TTM Squeeze** → `KC_SQUEEZE is "on"` is the native one-condition
|
|
31
|
+
read: the Bollinger pair sitting inside the Keltner channel, at the script's own multiplier.
|
|
32
|
+
The four boundaries stay addressable, so `BB_UPPER spread KC_UPPER` and
|
|
33
|
+
`BB_LOWER spread KC_LOWER` still express the same reading at a threshold you choose. Release
|
|
34
|
+
direction from the MACD trajectory, `bollinger_squeeze` Critical-required.
|
|
35
|
+
Its selectivity is anchor-dependent — see `## Conditions` in the skill body before gating on it.
|
|
36
|
+
(`bbWidthPct_rank_lo` + `ADX lt 20` remains a serviceable board-relative compression proxy, but it
|
|
37
|
+
is no longer the only option.)
|
|
38
|
+
- **Supertrend / UT Bot / Chandelier Exit** → `ST_LINE` and `ST_DIR` are native, so the regime
|
|
39
|
+
half is a direct port: `ST_DIR is "bullish"` as the persistent state, `dist_ST_LINE` for
|
|
40
|
+
distance to the plotted stop. The plotted trailing line is still best executed by the studio's
|
|
41
|
+
own stop engine — `trailingTriggerR: 0` (trail from entry), giveback ~30–40 (tight factor) or
|
|
42
|
+
45–55 (loose/chandelier) — because a trailing stop is a position-management mechanism, not a
|
|
43
|
+
column. `ST_DIR` is a persisting state and not a flip event — see `## Conditions` in the
|
|
44
|
+
skill body — so the FLIP needs an event column beside it. Name that as a substitution.
|
|
45
|
+
- **MACD + 200 MA filter** → `ABOVE_200` building block (`dist_SMA200 gt 0`) referenced by a
|
|
46
|
+
carrier with `MACD_cross is "Bullish"`; rules `macd_bull/bear_cross` 3 required +
|
|
47
|
+
`ma_sma200_above/below` 2 required; swing-trend geometry.
|
|
48
|
+
- **Golden / Death Cross** → `SMA50 spread SMA200 × trajectory` gives state and freshness:
|
|
49
|
+
`SMA50_SMA200_spread_now gt 0` AND `_trend is "rising"`; optional breadth gate on
|
|
50
|
+
`mktBreadth_crypto gte 0` — every published scope resolves, not only `all`, because the leg reads
|
|
51
|
+
the `(timeframe, scope)` pairs a condition names; position-persona geometry. `SMA50 × SMA200` is
|
|
52
|
+
the canonical definition and stays the default port; `EMA50` is available as the crypto variant
|
|
53
|
+
when a player asks for it by name.
|
|
54
|
+
- **RSI-2 (Connors)** → `RSI2` is native, so this ports exactly: `RSI2 lte 10` gated by required
|
|
55
|
+
`ABOVE_200`; the source's fast exit is time — timeDecay ON (180/60, 15→50, stale 20);
|
|
56
|
+
`rsi_oversold` 3 required with a tuned threshold. Keep the literal `lte 10` as the GATE:
|
|
57
|
+
`RSI2 × classifyZone` exists and reads on the same Connors bands, but a zone label is a fixed
|
|
58
|
+
reading while the literal is a threshold the author can see and tune. Use the zone as a report
|
|
59
|
+
column, never as the substitute for the gate.
|
|
60
|
+
- **VWAP reversion** → `dist_VWAP` band + `dist_VWAP_rank_far lte 5` for board-relative
|
|
61
|
+
stretch; required `NOT [ADX_state in ["trending","extreme"]]` veto; scalp geometry +
|
|
62
|
+
aggressive timeDecay (VWAP anchors daily at 00:00 UTC).
|
|
63
|
+
- **Donchian / Turtle breakout** → `zone is "breakout high"` + `dist_swingHi gte 0` +
|
|
64
|
+
`RVOL gte 1.5`; `sr_resistance_break` 3 required; turtle exits = trend preset (trail from
|
|
65
|
+
1R, giveback 50). Mirror with `"breakdown low"`. **Daily-breakout variant on any anchor:**
|
|
66
|
+
pin the structure at 1d — `zone_1d is "breakout high"`, `dist_swingHi_1d gte 0` (validated).
|
|
67
|
+
**Literal previous-day levels are native**: `dist_PDH gte 0` composes directly. Their `{abs: '1d'}`
|
|
68
|
+
binding is stated in `## Header grammar` in the skill body.
|
|
69
|
+
- **ICT / SMC (FVG + order blocks)** → `STRUCT_ZONES` is the native zone engine:
|
|
70
|
+
`zones_htf_support_type` (`bullish FVG`/`bullish order block`), `zones_htf_support_dist
|
|
71
|
+
between -1.5 0`, `_age_h gte 12`, HTF bias required via `MAalign_htf`; rules
|
|
72
|
+
`structure_fvg_approach`/`structure_ob_approach` required (their `proximityPct` is the
|
|
73
|
+
in-zone dial). Liquidity sweeps, displacement, killzones and event *sequencing* are shapes the
|
|
74
|
+
grammar does not have — a clause compares one column against a literal, so an ordered sequence
|
|
75
|
+
of events cannot be stated at all. That is a grammar limit, not a missing metric; name it as
|
|
76
|
+
one.
|
|
77
|
+
- **Now native, formerly substituted** — WaveTrend (`WT1`/`WT2`), QQE (`QQE_RSI_MA`/`QQE_STOP`),
|
|
78
|
+
Hull (`HMA20`), Ichimoku (`ICHI_CONV`/`ICHI_BASE`/`ICHI_SPAN_A`/`ICHI_SPAN_B`/`ICHI_LAG`),
|
|
79
|
+
Parabolic SAR (`PSAR`), Keltner (`KC_UPPER`/`KC_MID`/`KC_LOWER`), daily pivots
|
|
80
|
+
(`PIVOT_P`/`PIVOT_R1`–`R3`/`PIVOT_S1`–`S3`), Williams %R (`WILLR14`), Stochastic RSI
|
|
81
|
+
(`STOCH_RSI14`), the TTM squeeze (`KC_SQUEEZE`), Connors RSI-2 (`RSI2`), the 9/21/50 EMAs
|
|
82
|
+
(`EMA9`/`EMA21`/`EMA50`), and literal previous-day levels (`PDH`/`PDL`). Port these directly —
|
|
83
|
+
do not offer a substitute for a primitive the catalog serves.
|