# Tape and Signals

## Scope

This document describes the **current** signal path used by the engine.
It replaces the old actionables-based runtime description.

## Data path

### Inputs
The engine consumes:
- normalized multi-venue BTC trades
- Bybit orderbook snapshots for range / execution context

### Bar model
Trades are aggregated into **10-second bars**.

Each bar stores:
- open / high / low / close
- buy volume / sell volume
- trade count
- exchange volume breakdown

### Signal windows
`computeSignal()` uses:
- **fast window:** last 5 bars = 50s
- **slow window:** last 60 bars = 10min

## Signal features

For each bar index the engine computes:

- `delta` — fast-window buy/sell imbalance
- `moveBps` — fast-window price move
- `score` — composite of delta and price move
- `surge` — fast-window volume vs recent average
- `topShare` — dominant exchange share in slow window
- `absorption` — delta opposes price with sufficient magnitude and surge

## Entry rules

Function: `shouldEnter()`

### Absorption entry
Enter when:
- `absorption = true`
- `|delta| > 0.30`
- `surge > 2.5`
- `fastVol > 80k`
- `topShare <= 0.65`

Direction:
- `delta > 0` → long
- `delta < 0` → short

### Momentum entry
Enter when:
- `|score| > 0.55`
- `|delta| > 0.40`
- `fastVol > 100k`
- `surge > 3`
- `delta * moveBps > 0`
- `topShare <= 0.65`

Direction:
- `score > 0` → long
- `score < 0` → short

## Risk / regime gates

Before an entry is emitted, the engine also checks:

- realized vol from **bar closes**
- average volume per bar
- current 5-minute orderbook range
- cooldowns / loss streaks / direction lock
- capital / margin / max risk per trade

### Current vol gate
- `rv >= 5`
- `rv <= 7`

### Current range gate
- `range >= 10bps`

## Targets and sizing

### Targets
`computeAdaptiveTargets()` derives:
- stop bps
- tp1 bps
- tp2 bps
- regime (`normal` / `volatile`)

from the current 5-minute Bybit orderbook range and fee budget.

### Sizing
`computePositionSize()` sizes as:
- base risk = `% of current capital`
- then scaled by conviction multiplier

`computeConvictionMultiplier()` uses:
- score magnitude
- regime
- absorption bonus
- win/loss streak state

## Exit rules

`checkExits()` emits exit intents for:
- trailing stop
- time exit
- force close
- tp1
- stop loss

The caller then fills those intents according to execution mode.

## Execution by mode

### Replay
Uses `emulateChaseEntry()` against recorded orderbook snapshots.

### Demo
Uses real `chaseLimitOrder()` via Bybit demo API.

### Live
Reserved for the same API behavior on mainnet.

## Important historical bug (resolved)

A major source of divergence was fixed:

- **old replay/backtest rv:** multi-venue bar closes
- **old live rv:** Bybit orderbook mid

That mismatch made the same numeric rv threshold mean different things.
Now both replay and live-facing runners use **bar-close rv**.

## Current honest replay result

With realistic chase fill emulation:
- **MAKER_OPT:** +$109.81
- **Trades:** 21
- **Win rate:** 85.7%
- **Max DD:** 1.88%

## Files

- `src/core/strategy.ts` — engine, signal logic, sizing, exits, chase emulation
- `src/runners/replay.ts` — replay runner
- `src/runners/demo-benchmark.ts` — demo execution runner
- `src/runners/dashboard.ts` — IPC dashboard consumer
