Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/strategy-library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ body:
- volatility
- volume
- risk
- event_volatility
- new category proposal
validations:
required: true
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ The [strategy library](nano/library/README.md) is Nano's community on-ramp: a sm

The same corpus is browsable at **[aethersystems.net/nano](https://aethersystems.net/nano)** — search and filter by category, cadence or signal, read the source and compiled IR side by side, and open any strategy directly in an editor. Nothing to install, no account needed.

| Momentum | Mean reversion | Trend | Volatility | Volume | Risk |
| --- | --- | --- | --- | --- | --- |
| 4 strategies | 3 strategies | 3 strategies | 2 strategies | 2 strategies | 1 strategy |
| Momentum | Mean reversion | Trend | Volatility | Volume | Risk | Event volatility |
| --- | --- | --- | --- | --- | --- | --- |
| 4 strategies | 3 strategies | 3 strategies | 2 strategies | 2 strategies | 1 strategy | 11 strategies |

The library is a conformance corpus, not a performance claim, live signal service, or trading recommendation.

Expand Down
108 changes: 108 additions & 0 deletions docs/event_signal_contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Macro-event signal contract

The `event_volatility/` library category consumes a **host event engine**: a deterministic runtime that owns the economic-release schedule, measures the post-release tape, and injects nonnegative bounded signal series into the Nano `MarketFrame`. Nano never fetches the release, never reads a clock, and never sees an order book — exactly as with every other host-provided signal.

This document is the contract those signals must satisfy. It is written from the strategy side: what each name means, what range the host must guarantee, and which measurements must be published as separate bull/bear pairs so baseline IR (which cannot carry negative literals) can express both directions.

## Design rules

1. **Nonnegative and bounded.** Every score is `0..1` (or `0/1` for flags, or a nonnegative ratio where noted). Signed quantities are forbidden; a signed surprise like `CORE_SURPRISE_Z = -1.4` must be published as the pair `CPI_COOL_SCORE = 0.86` / `CPI_HOT_SCORE = 0.0`.
2. **Bull/bear pairs are mutually exclusive by construction.** The host computes both sides from the same inputs and guarantees at most one side of a pair is above its qualification threshold at any tick.
3. **Missing is missing.** A signal the host cannot compute honestly (no release packet, not enough history, feed gap) is omitted from the frame. It is never filled with 0, a neutral constant, or a stale value. Nano's missing-signal semantics then make dependent conditions unknowable, and the strategy abstains.
4. **Versioned scales.** Any threshold or normalization constant (forecast-error scale, spread-stress baseline, whipsaw normalization) is versioned in the host. It is frozen during an event window and never silently retuned between events.
5. **The `(N)` annotation convention applies.** Event signals are bare names; the host owns every window and lookback.

## Reference points

- **Event anchor** — median executable mid from T-10s through T-1s relative to the scheduled release time.
- **Pre-event range** — high/low of a versioned T-5m window before the release.
- **First impulse** — maximum directional excursion from the event anchor during the initial observation window.

## Integrity and timing

| Signal | Range | Meaning |
| --- | --- | --- |
| `EVENT_READY` | 0/1 | A scheduled high-impact event window is armed and verified. |
| `ENTRY_WINDOW_OPEN` | 0/1 | Inside the host-enforced entry window (T+5s..T+180s in v1). |
| `RELEASE_CONFIRMED` | 0/1 | The release packet status is CONFIRMED from an execution-grade source. Calendar scrapes never set this. |
| `RELEASE_CONFLICT` | 0/1 | Any integrity failure: source conflict, CONFLICTED/LATE packet, schedule disagreement, failed payload hash. |
| `RELEASE_LATENCY_SCORE` | 0..1 | 1 = timely receipt relative to the provider publication timestamp. |
| `CALENDAR_INTEGRITY` | 0..1 | Agreement between the arming calendar and the release schedule source. |
| `SECONDS_SINCE_EVENT` | ≥0 | Whole seconds since the scheduled release. |

## Release interpretation (CPI family)

Computed deterministically from standardized forecast errors across headline and core fields; every component is preserved separately in the evidence packet.

| Signal | Range | Meaning |
| --- | --- | --- |
| `CPI_COOL_SCORE` | 0..1 | Cooler-than-consensus strength. Published beside `CPI_HOT_SCORE`; at most one is high. |
| `CPI_HOT_SCORE` | 0..1 | Hotter-than-consensus strength. |
| `CPI_HEADLINE_CORE_AGREEMENT` | 0..1 | Sign/magnitude agreement between headline and core surprises. |
| `CPI_REVISION_BULL_SCORE` | 0..1 | Bullish weight of prior-month revisions. |
| `CPI_REVISION_BEAR_SCORE` | 0..1 | Bearish weight of prior-month revisions. |
| `CPI_CONFLICT_SCORE` | 0..1 | Internal disagreement of the print (headline vs core vs revisions). |

## Price reaction

| Signal | Range | Meaning |
| --- | --- | --- |
| `UPSIDE_IMPULSE_ATR` | ≥0 | Max upward excursion from the event anchor divided by the pre-event 1m ATR. |
| `DOWNSIDE_IMPULSE_ATR` | ≥0 | Max downward excursion from the event anchor divided by the pre-event 1m ATR. |
| `IMPULSE_EFFICIENCY` | 0..1 | Net displacement divided by total path length. |
| `RETRACE_HOLD_SCORE` | 0..1 | `1 - retracement / impulse`, clamped. |
| `BREAK_FAILURE_SCORE` | 0..1 | Excursion outside the pre-event range followed by a deterministic close/reclaim back through the boundary. |
| `EVENT_ANCHOR_RECLAIM` | 0..1 | Strength of a reclaim of the event anchor from below. |
| `EVENT_ANCHOR_REJECT` | 0..1 | Strength of a rejection at the event anchor from above. |
| `SECOND_LEG_SCORE` | 0..1 | Raised only after impulse, controlled retrace, 30-90s compression, and a fresh break of the first-impulse extreme have occurred **in order**. |
| `OVERSHOOT_SCORE` | 0..1 | Excursion relative to the historical event-move distribution. |
| `VOLATILITY_COMPRESSION` | 0..1 | Contraction of realized range after the first impulse. |
| `PRE_EVENT_RANGE_BREAK_UP` | 0..1 | Upside break of the pre-event range. |
| `PRE_EVENT_RANGE_BREAK_DOWN` | 0..1 | Downside break of the pre-event range. |
| `WHIPSAW_SCORE` | 0..1 | Normalized event-anchor crossings and direction flips in the trailing observation window. 0 = one-way tape, 1 = pure churn. |

## Liquidity and flow

Consumed from the host's existing futures feature fabric; never rederived by the event engine.

| Signal | Range | Meaning |
| --- | --- | --- |
| `LIQUIDITY_OK` | 0/1 | Spread and depth renormalized against the pre-event baseline. |
| `SPREAD_STRESS` | ≥0 | Executable spread relative to pre-event baseline; 0 = normal, 1+ = severe. |
| `DEPTH_COLLAPSE_SCORE` | 0..1 | Loss of top-of-book depth vs baseline. |
| `BULL_FLOW_CONFIRM` | 0..1 | Bullish futures order-flow confirmation. |
| `BEAR_FLOW_CONFIRM` | 0..1 | Bearish futures order-flow confirmation. |
| `ABSORPTION_SCORE` | 0..1 | Passive absorption of aggressive flow. |
| `QUEUE_DEPLETION_SCORE` | 0..1 | Queue consumption rate at the touch. |
| `VOLUME_ACCELERATION` | ≥0 | Volume rate vs pre-event baseline. |
| `CANCEL_STRESS` | 0..1 | Cancellation intensity vs baseline. |

## Cross-market

Published only when the underlying markets are genuinely live and entitled; absent otherwise.

| Signal | Range | Meaning |
| --- | --- | --- |
| `BULL_CROSS_CONFIRM` | 0..1 | MES/MNQ and flow agreement on the upside. |
| `BEAR_CROSS_CONFIRM` | 0..1 | MES/MNQ and flow agreement on the downside. |
| `MES_MNQ_AGREEMENT` | 0..1 | Directional agreement between the two index futures. |
| `NQ_RELATIVE_STRENGTH` | 0..1 | NQ outperforming ES on the event path. |
| `NQ_RELATIVE_WEAKNESS` | 0..1 | NQ underperforming ES on the event path. |

## Options context

Grounding/weighting evidence only; options signals never independently create execution authority in v1.

| Signal | Range | Meaning |
| --- | --- | --- |
| `OPTIONS_FLOW_AVAILABLE` | 0/1 | A real options evidence plane is live. |
| `OPTIONS_UNUSUAL_SCORE` | 0..100 | Deterministic unusualness score. |
| `OPTIONS_BULL_SCORE` / `OPTIONS_BEAR_SCORE` | 0..1 | Directional options positioning. |
| `OPTIONS_IV_SHOCK` | ≥0 | Pre-release IV elevation. |
| `OPTIONS_IV_CRUSH` | 0..1 | Post-release IV collapse. |
| `GAMMA_POSITIVE_SCORE` / `GAMMA_NEGATIVE_SCORE` | 0..1 | Dealer gamma regime, only with provider-backed Greeks. |
| `CALL_WALL_DISTANCE_SCORE` / `PUT_WALL_DISTANCE_SCORE` | 0..1 | Proximity to major walls. |

## Control strategies

`event_liquidity_halt`, `event_release_integrity_halt`, and `event_whipsaw_halt` are published Nano strategies that emit `PAUSE`. They are auditable explanations, not the only safety mechanism: the host must enforce the same gates directly, and controls are never candidates for an execution slot.
28 changes: 27 additions & 1 deletion nano/library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Every entry has two files:

## Learn, compare, contribute

The current library contains 15 strategies across six familiar categories. Browse an entry to see the source, its expected IR, and the feed convention it assumes. When you are ready, a well-documented strategy pair is the most direct contribution to Nano.
The current library contains 26 strategies across seven familiar categories. Browse an entry to see the source, its expected IR, and the feed convention it assumes. When you are ready, a well-documented strategy pair is the most direct contribution to Nano.

[Add a strategy →](../../CONTRIBUTING.md#add-a-strategy) · [Open a strategy proposal →](https://github.com/DBarr3/Nano/issues/new?template=strategy-library.yml)

Expand All @@ -25,6 +25,7 @@ The current library contains 15 strategies across six familiar categories. Brows
| `volatility/` | `atr_volatility_halt`, `bb_squeeze_breakout` |
| `volume/` | `volume_spike_confirmation`, `obv_trend` |
| `risk/` | `max_drawdown_breaker` |
| `event_volatility/` | `event_impulse_pullback_long`, `event_impulse_pullback_short`, `cpi_impulse_pullback_long`, `cpi_impulse_pullback_short`, `event_false_first_move_long`, `event_false_first_move_short`, `event_second_leg_long`, `event_second_leg_short`, `event_liquidity_halt`, `event_release_integrity_halt`, `event_whipsaw_halt` |

## Signal conventions

Expand All @@ -49,6 +50,31 @@ Library entries compare **host-provided named signal series** with numeric liter
| OBV trend | `OBV_SLOPE(20)` | Linear-regression slope of OBV |
| equity drawdown | `DRAWDOWN` | Portfolio drawdown percentage |

### Macro-event signals (`event_volatility/`)

Event strategies consume a **host event engine** rather than bar indicators: the host arms a scheduled release window, measures the post-release tape deterministically, and publishes nonnegative bounded scores. Bull and bear terms are always separate series (never one signed value), which is what keeps twin-armed branches mutually exclusive and inside baseline IR. The full measurement definitions live in [`docs/event_signal_contract.md`](../../docs/event_signal_contract.md).

| Event measurement | Nano signal | Feed convention |
| --- | --- | --- |
| armed event window | `EVENT_READY` | 0 or 1; scheduled high-impact window verified |
| entry window | `ENTRY_WINDOW_OPEN` | 0 or 1; host-enforced T+5s..T+180s |
| confirmed release | `RELEASE_CONFIRMED` | 0 or 1; release packet status CONFIRMED only |
| release integrity | `RELEASE_CONFLICT` | 0 or 1; any source/hash/schedule conflict |
| cool CPI print | `CPI_COOL_SCORE` | 0..1 from standardized forecast errors |
| hot CPI print | `CPI_HOT_SCORE` | 0..1; published beside `CPI_COOL_SCORE` |
| upward impulse | `UPSIDE_IMPULSE_ATR` | max upward excursion from event anchor / pre-event 1m ATR |
| downward impulse | `DOWNSIDE_IMPULSE_ATR` | max downward excursion from event anchor / pre-event 1m ATR |
| retracement hold | `RETRACE_HOLD_SCORE` | 1 - retracement/impulse, clamped 0..1 |
| failed breakout | `BREAK_FAILURE_SCORE` | 0..1; range break then deterministic reclaim |
| range break up/down | `PRE_EVENT_RANGE_BREAK_UP` / `_DOWN` | 0..1 against the versioned T-5m range |
| anchor reclaim/reject | `EVENT_ANCHOR_RECLAIM` / `EVENT_ANCHOR_REJECT` | 0..1 at the T-10s..T-1s median mid anchor |
| second leg | `SECOND_LEG_SCORE` | 0..1; impulse, compression, then fresh extreme, in order |
| cross-market agreement | `BULL_CROSS_CONFIRM` / `BEAR_CROSS_CONFIRM` | 0..1 MES/MNQ + flow agreement |
| order-flow confirmation | `BULL_FLOW_CONFIRM` / `BEAR_FLOW_CONFIRM` | 0..1 from the host futures feature fabric |
| liquidity normalized | `LIQUIDITY_OK` | 0 or 1; spread and depth renormalized |
| spread stress | `SPREAD_STRESS` | 0 = baseline, 1+ = severely stressed |
| tape churn | `WHIPSAW_SCORE` | 0..1 normalized anchor crossings in the window |

Two v0.1 details matter:

1. Baseline IR cannot carry a negative literal. The v1.0 grammar supports unary minus, but a library entry using it would leave baseline IR — so signals with negative natural ranges are still shifted (`WILLR_POS`) or negated (`ZSCORE_NEG`) by the feed. Document the transform in a `//` comment.
Expand Down
43 changes: 43 additions & 0 deletions nano/library/event_volatility/cpi_impulse_pullback_long.nano
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Release-aware twin-armed continuation, bull branch. Armed before CPI next
// to cpi_impulse_pullback_short; neither may open exposure before the number
// and the host's release scores make at most one branch qualify.
// RELEASE_CONFIRMED = 1 only when the MacroReleasePacket status is CONFIRMED
// from the official/vendor release adapter - never from a scraped calendar.
// CPI_COOL_SCORE = bounded 0..1 cooler-than-consensus score computed
// deterministically from standardized forecast errors across headline and
// core fields; the matching CPI_HOT_SCORE is published separately so the
// branches stay mutually exclusive (both are never high together).
// UPSIDE_IMPULSE_ATR, RETRACE_HOLD_SCORE, BULL_CROSS_CONFIRM, LIQUIDITY_OK as
// in event_impulse_pullback_long.
// REGIME: CPI releases where the print is genuinely cool AND the tape agrees.
// Do NOT fire on a cool print alone - the impulse and retrace terms must
// confirm - and do NOT fire when the release packet is missing, provisional,
// or conflicted: RELEASE_CONFIRMED stays 0 and this branch honestly abstains.
// CONDITIONS: armed event, open entry window, confirmed release, cool CPI,
// upward impulse at least 0.8 pre-event ATRs, held retracement, cross-market
// agreement, normalized liquidity.
// INVALIDATION: host event risk model owns stop, hard flat, and the
// one-position-per-event lock.
// SHAPE: 5s cadence after the observe-only impulse window; cool print, leg
// up, shallow pullback that holds, continuation.
// NOT event_impulse_pullback_long: same tape shape, but this variant demands
// execution-grade release provenance and the fundamental sign to match the
// move. When both qualify, the proposal board still selects only one.
// CALIBRATED ON: MES around US CPI, 5s cadence. The 0.72 release threshold is
// a versioned fixed scale until enough forecast-error history exists; never
// silently retune it between events.
strategy CpiImpulsePullbackLong {

agent MacroEvent

every 5s {

if EVENT_READY > 0.5 and ENTRY_WINDOW_OPEN > 0.5 and RELEASE_CONFIRMED > 0.5 and CPI_COOL_SCORE > 0.72 and UPSIDE_IMPULSE_ATR > 0.8 and RETRACE_HOLD_SCORE > 0.6 and BULL_CROSS_CONFIRM > 0.55 and LIQUIDITY_OK > 0.5 {

buy(MES, 0.78)

}

}

}
19 changes: 19 additions & 0 deletions nano/library/event_volatility/cpi_impulse_pullback_long_ir.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"type": "Strategy",
"nanoIrVersion": "0.1.0",
"name": "CpiImpulsePullbackLong",
"effects": ["intent.emit", "log.append"],
"nodes": [
{ "type": "Schedule", "interval": "5s" },
{ "type": "Condition", "signal": "EVENT_READY", "operator": ">", "value": 0.5 },
{ "type": "Condition", "signal": "ENTRY_WINDOW_OPEN", "operator": ">", "value": 0.5 },
{ "type": "Condition", "signal": "RELEASE_CONFIRMED", "operator": ">", "value": 0.5 },
{ "type": "Condition", "signal": "CPI_COOL_SCORE", "operator": ">", "value": 0.72 },
{ "type": "Condition", "signal": "UPSIDE_IMPULSE_ATR", "operator": ">", "value": 0.8 },
{ "type": "Condition", "signal": "RETRACE_HOLD_SCORE", "operator": ">", "value": 0.6 },
{ "type": "Condition", "signal": "BULL_CROSS_CONFIRM", "operator": ">", "value": 0.55 },
{ "type": "Condition", "signal": "LIQUIDITY_OK", "operator": ">", "value": 0.5 },
{ "type": "Intent", "action": "BUY", "asset": "MES", "confidence": 0.78 },
{ "type": "Agent", "name": "MacroEvent" }
]
}
38 changes: 38 additions & 0 deletions nano/library/event_volatility/cpi_impulse_pullback_short.nano
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Release-aware twin-armed continuation, bear branch. Mirror of
// cpi_impulse_pullback_long. CPI_HOT_SCORE = bounded 0..1
// hotter-than-consensus score from the same standardized forecast errors
// that produce CPI_COOL_SCORE; the host publishes the pair so at most one
// branch can qualify on a given print. RELEASE_CONFIRMED = 1 only when the
// MacroReleasePacket status is CONFIRMED. DOWNSIDE_IMPULSE_ATR,
// RETRACE_HOLD_SCORE, BEAR_CROSS_CONFIRM, LIQUIDITY_OK as in
// event_impulse_pullback_short.
// REGIME: CPI releases where the print is genuinely hot AND the tape agrees.
// Do NOT fire on a hot print alone, and do NOT fire when the release packet
// is missing, provisional, or conflicted - this branch abstains.
// CONDITIONS: armed event, open entry window, confirmed release, hot CPI,
// downward impulse at least 0.8 pre-event ATRs, held retracement,
// cross-market agreement, normalized liquidity.
// INVALIDATION: host event risk model owns stop, hard flat, and the
// one-position-per-event lock.
// SHAPE: 5s cadence after the observe-only impulse window; hot print, leg
// down, weak bounce that fails, continuation.
// NOT event_impulse_pullback_short: same tape shape, but this variant demands
// execution-grade release provenance and the fundamental sign to match.
// CALIBRATED ON: MES around US CPI, 5s cadence. The 0.72 release threshold is
// a versioned fixed scale until enough forecast-error history exists; never
// silently retune it between events.
strategy CpiImpulsePullbackShort {

agent MacroEvent

every 5s {

if EVENT_READY > 0.5 and ENTRY_WINDOW_OPEN > 0.5 and RELEASE_CONFIRMED > 0.5 and CPI_HOT_SCORE > 0.72 and DOWNSIDE_IMPULSE_ATR > 0.8 and RETRACE_HOLD_SCORE > 0.6 and BEAR_CROSS_CONFIRM > 0.55 and LIQUIDITY_OK > 0.5 {

sell(MES, 0.78)

}

}

}
19 changes: 19 additions & 0 deletions nano/library/event_volatility/cpi_impulse_pullback_short_ir.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"type": "Strategy",
"nanoIrVersion": "0.1.0",
"name": "CpiImpulsePullbackShort",
"effects": ["intent.emit", "log.append"],
"nodes": [
{ "type": "Schedule", "interval": "5s" },
{ "type": "Condition", "signal": "EVENT_READY", "operator": ">", "value": 0.5 },
{ "type": "Condition", "signal": "ENTRY_WINDOW_OPEN", "operator": ">", "value": 0.5 },
{ "type": "Condition", "signal": "RELEASE_CONFIRMED", "operator": ">", "value": 0.5 },
{ "type": "Condition", "signal": "CPI_HOT_SCORE", "operator": ">", "value": 0.72 },
{ "type": "Condition", "signal": "DOWNSIDE_IMPULSE_ATR", "operator": ">", "value": 0.8 },
{ "type": "Condition", "signal": "RETRACE_HOLD_SCORE", "operator": ">", "value": 0.6 },
{ "type": "Condition", "signal": "BEAR_CROSS_CONFIRM", "operator": ">", "value": 0.55 },
{ "type": "Condition", "signal": "LIQUIDITY_OK", "operator": ">", "value": 0.5 },
{ "type": "Intent", "action": "SELL", "asset": "MES", "confidence": 0.78 },
{ "type": "Agent", "name": "MacroEvent" }
]
}
Loading
Loading