# SPIDER (v2 supervised demo)

Spider is a **two-leg** strategy. The two legs are genuinely different theses on
separate wallets — not mirror images — so each is its own v2 recipe + supervised
`scan(inputs, ctx)`.

Ported from `senpi-skills/spider` (producer v5.1.1) to the runtime v2 supervised
external-scanner contract. The standalone producer daemon is gone; the runtime
supervises each leg's `scanners/scan.py` and calls `scan()` on the recipe's
`interval_seconds`.

## The two legs

| Leg     | Thesis                                      | Direction | Universe | Tick | minScore | Slots | DSL |
|---------|---------------------------------------------|-----------|----------|------|----------|-------|-----|
| `swing` | Tech & AI multi-day momentum                | LONG only | dynamic XYZ tech/AI pool + crypto alts | 300s | 5 | 3 @ marginPct 0.28 | wide, all time-cuts off, 7d hard timeout |
| `scalp` | Macro & majors fast mean-reversion          | LONG + SHORT | majors (BTC/ETH/SOL/HYPE) + energy (xyz:BRENTOIL/xyz:CL) | 60s | 4 | 4 @ marginPct 0.15 | tight, weak_peak + dead_weight on, 2h hard timeout |

- **swing** scores 4h/1h trend structure + 24h relative strength + RSI room +
  funding + smart-money consensus. Its universe is rebuilt each tick from the
  live instrument board (curated tech/AI/space include-set + auto-caught
  freshly-listed names, minus a commodity/FX/index exclude-set).
- **scalp** fades short-timeframe stretch (15m RSI extreme + stretch from a
  20-bar MA) with a 1h trend filter so it doesn't catch a falling knife.

Both recipes set `group: spider` — the agent-facing handle that ties the legs
together.

## Layout

```
spider/
├── README.md
├── swing/
│   ├── recipe.yaml
│   └── scanners/
│       ├── scan.py        # scan(inputs, ctx) entrypoint
│       └── scoring.py     # pure scoring functions (unit-tested)
└── scalp/
    ├── recipe.yaml
    └── scanners/
        ├── scan.py
        └── scoring.py
```

## Environment variables

| Variable               | Required | Purpose |
|------------------------|----------|---------|
| `SPIDER_SWING_WALLET`  | swing    | Swing-leg strategy wallet |
| `SPIDER_SCALP_WALLET`  | scalp    | Scalp-leg strategy wallet |
| `SENPI_API_KEY`        | yes      | MCP auth for `ctx.senpi_mcp` (injected into the scaffold child) |
| `SENPI_MCP_URL`        | yes      | MCP server URL |
| `TELEGRAM_CHAT_ID`     | optional | Notifications |

The two legs run as two separate strategies on two separate wallets. Fund both
wallets before enabling; the source's suggested split is swing 60% / scalp 40%
of the combined pool.

## Install / run

Run each leg as its own runtime instance, pointing at its recipe:

```bash
SPIDER_SWING_WALLET=0x... \
SENPI_API_KEY=... SENPI_MCP_URL=https://mcp.prod.senpi.ai/mcp \
  openclaw senpi run examples/strategies/spider/swing/recipe.yaml

SPIDER_SCALP_WALLET=0x... \
SENPI_API_KEY=... SENPI_MCP_URL=https://mcp.prod.senpi.ai/mcp \
  openclaw senpi run examples/strategies/spider/scalp/recipe.yaml
```

## Sizing note

The source producer computed `margin_usd = account_value * marginPct` and then
emitted at most `min(open_slots, affordable)` signals per tick, where
`affordable` was derived from free margin. In v2 the runtime owns slot count and
affordability (`strategy.slots` + the `risk.guard_rails`), so `scan()` emits
**every** candidate that clears `minScore` (after filtering held + recently
signaled assets) and carries `marginPct` (percent of withdrawable, 0–100) +
venue-clamped `leverage` on each signal's top level. The signal-gating
thresholds are unchanged; only the per-tick emission cap moved to the runtime.

## Action gate

The source's `OPEN_POSITION` action used `decision_mode: llm` with a
copy-verbatim pass-through prompt and a pinned confidence — i.e. a rule wearing
an LLM costume. The v2 recipes use `decision_mode: rule` directly.
