Metadata-Version: 2.4
Name: strata-market
Version: 2.4.0
Summary: A layered, stateful framework for market regime estimation and decision support
License-Expression: MIT
Project-URL: Homepage, https://github.com/rafaelsistems/strata-market
Project-URL: Documentation, https://github.com/rafaelsistems/strata-market/blob/main/MANIFESTO.md
Project-URL: Issues, https://github.com/rafaelsistems/strata-market/issues
Keywords: trading,market,regime,quant,algorithmic trading,decision support
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# STRATA — Market State Framework

A trainable, stateful model architecture specialised for market trading —
analogous to LSTM/GRU but built for regime estimation and decision support,
not price prediction.

```bash
pip install strata-market
```

---

## Quick Start — High Level (v2.4+)

```python
from strata import StrataModel, StrataTrainer

# ── Use a pretrained model (zero setup) ──────────────────────────────────
model = StrataModel.from_pretrained("AAPL")   # also: TSLA, SPY, NVDA, QQQ
result = model.predict(candles)
# {"action": "LONG", "confidence": 0.71, "regime": "TRENDING",
#  "approved": True, "guard_reason": "", "state": {...}}

# ── Train your own model from OHLCV data ─────────────────────────────────
trainer = StrataTrainer(asset="MSFT")
windows = StrataTrainer.prepare_windows(my_candles)   # sliding windows
model   = trainer.train(windows, n_trials=100)
model.save("msft_model.json")

# ── Load and deploy anywhere ─────────────────────────────────────────────
model  = StrataModel.load("msft_model.json")
result = model.predict(latest_candles)
print(result["action"])   # "LONG" / "SHORT" / "HOLD"
```

---

## Quick Start — Low Level

```python
from strata import initial_state, update_state, decide, StrataGUARD, StrataMEMORY, sense

# 1. Initialize
state  = initial_state()
memory = StrataMEMORY()
guard  = StrataGUARD(asset="AAPL")   # optional: asset-aware guard thresholds

# 2. Per-bar update loop
candles = [...]  # list of OHLCV dicts, oldest → newest, minimum 3

inp        = sense(candles)           # raw OHLCV → semantic signals
mem_signal = memory.snapshot()        # pattern memory state
state      = update_state(state, inp, mem_signal)
decision   = decide(state)            # {"action": "LONG"|"SHORT"|"HOLD", "confidence": ..., "regime": ...}

approved, reason = guard.evaluate(state, decision, decision["confidence"])
final_action = decision["action"] if approved else "HOLD"

print(f"{final_action}  ({reason})")
```

---

## StrataModel — Trainable Model

### `StrataModel.from_pretrained(ticker)` — zero setup

```python
model = StrataModel.from_pretrained("AAPL")  # AAPL | TSLA | SPY | NVDA | QQQ
print(model.summary())
```

### `StrataTrainer` — train from your own data

```python
from strata import StrataModel, StrataTrainer

# Your candles: flat list of OHLCV dicts, oldest → newest
candles = [{"open": ..., "high": ..., "low": ..., "close": ..., "volume": ...}, ...]

# Prepare sliding windows (window_size=31 recommended)
windows = StrataTrainer.prepare_windows(candles, window_size=31)

# Train
trainer = StrataTrainer(asset="MSFT", verbose=True)
model   = trainer.train(windows, n_trials=100)

# Save — share with anyone who has strata-market installed
model.save("msft_model.json")
```

### `StrataModel.load()` — deploy anywhere

```python
model  = StrataModel.load("msft_model.json")
model.reset()   # start fresh session

# Per-bar prediction
result = model.predict(candles_window)
# {
#   "action":       "LONG",      # LONG | SHORT | HOLD
#   "confidence":   0.71,
#   "regime":       "TRENDING",  # TRENDING | RANGING | TRANSITIONING | CHOPPY
#   "risk":         "LOW",       # LOW | MEDIUM | HIGH
#   "approved":     True,        # False = GUARD blocked the action
#   "guard_reason": "",          # e.g. "TRAP_RISK_HIGH (0.67 > 0.60 [RANGING])"
#   "state":        {...},       # full internal state snapshot
# }

# Feed outcome to circuit breaker
model.record_outcome(was_loss=False)
```

---

## Architecture

```
Raw OHLCV
    │
    ▼
┌─────────┐
│  SENSE  │  OHLCV → {trend, vol, liquidity_above, break_structure}
└────┬────┘
     │
     ▼
┌─────────┐     ┌──────────┐
│  CORE   │◄────│  MEMORY  │  pattern bank (Short/Mid/Long layers)
└────┬────┘     └──────────┘
     │
     ▼
┌─────────┐
│ DECIDE  │  state → {action, confidence, risk, regime}
└────┬────┘
     │
     ▼
┌─────────┐
│  GUARD  │  hard-rule override (NOT learned — explicit, auditable)
└────┬────┘
     │
     ▼
  Final Action
     │
     ▼
┌─────────┐
│  LOOP   │  P&L feedback → weight adaptation (optional)
└─────────┘
```

---

## Modules

### `strata.sense(candles)` → signals

Converts a window of OHLCV candles into semantic signals.

| Signal | Range | Meaning |
|---|---|---|
| `trend` | [-1, 1] | Directional EMA crossover, ATR-normalized |
| `vol` | [0, 1] | Volatility intensity (ATR / median price) |
| `liquidity_above` | [0, 1] | Volume spike vs rolling average |
| `break_structure` | [0, 1] | Price closing beyond prior N-bar high/low |

```python
from strata import sense

candles = [
    {"open": 150.0, "high": 151.2, "low": 149.5, "close": 150.8, "volume": 1_200_000},
    # ... at least 3 candles, oldest → newest
]
signals = sense(candles)
# {"trend": 0.12, "vol": 0.03, "liquidity_above": 0.15, "break_structure": 0.0}
```

---

### `strata.update_state(state, inp, memory)` → state

Core state transition. Updates the internal state vector based on current signals and memory.

```python
from strata import initial_state, update_state

state = initial_state()   # {"bias": 0, "momentum": 0, "trap_risk": 0, "uncertainty": 0}
state = update_state(state, signals, memory_snapshot)
# {"bias": 0.08, "momentum": 0.04, "trap_risk": 0.12, "uncertainty": 0.02, "regime_score": 0.06}
```

**State dimensions:**

| Key | Range | Meaning |
|---|---|---|
| `bias` | [-1, 1] | Directional conviction. Positive = bullish, negative = bearish |
| `momentum` | [0, 1] | Structural energy from breakouts and volume |
| `trap_risk` | [0, 1] | Probability of adverse selection / liquidity trap |
| `uncertainty` | [0, 1] | Volatility-driven ambiguity in current conditions |

---

### `strata.decide(state)` → decision

Produces a structured action proposal from current state.

```python
from strata import decide

decision = decide(state)
# {"action": "LONG", "confidence": 0.62, "risk": "LOW", "regime": "TRENDING"}
```

Regimes: `TRENDING` | `RANGING` | `TRANSITIONING` | `CHOPPY`

---

### `strata.StrataGUARD`

Hard-rule risk gate. Blocks actions that violate explicit risk constraints. Rules are regime-aware and asset-aware.

```python
from strata import StrataGUARD

guard = StrataGUARD(asset="TSLA")   # HIGH vol: relaxed min_abs_bias
guard = StrataGUARD(asset="SPY")    # LOW vol ETF: relaxed max_trap_risk
guard = StrataGUARD()               # no asset profile — use regime defaults

approved, reason = guard.evaluate(state, decision, decision["confidence"])
# (True,  "OK")
# (False, "TRAP_RISK_HIGH (0.67 > 0.60 [RANGING])")

guard.record_outcome(was_loss=True)   # drives circuit breaker
```

**Guard rules (checked in order):**

| Rule | Fires when |
|---|---|
| `TRAP_RISK_HIGH` | `trap_risk > max_trap_risk` |
| `LOW_CONFIDENCE` | `confidence < min_confidence` |
| `CHAOS_REGIME` | `uncertainty > max_uncertainty` |
| `NO_CONVICTION` | `\|bias\| < min_abs_bias` |
| `CIRCUIT_BREAKER` | `consecutive_losses >= max` |

---

### `strata.StrataMEMORY`

Three-layer pattern memory (Short → Mid → Long). Patterns are promoted by consistency and frequency.

```python
from strata import StrataMEMORY

memory = StrataMEMORY()

# Feed observations each bar
memory.observe("fake_breakout", score=0.75)
memory.observe("trend_strength", score=0.60)
memory.step()   # advance time: promote, decay

# Use in state update
mem_signal = memory.snapshot()   # {"fake_breakout": 0.71, "trend_strength": 0.58}
state = update_state(state, signals, mem_signal)
```

---

### `strata.StrataLOOP`

Closed-loop weight adaptation based on P&L feedback. Optional — STRATA works without it.

```python
from strata import StrataLOOP

loop = StrataLOOP()

# After each closed trade:
loop.record_outcome(state, decision["action"], pnl=+0.012)

# Get adapted weights for next update
weights = loop.weights
state = update_state(state, signals, mem_signal, weights=weights)

print(loop)
# STRATA-LOOP | updates=47 | recent_wr=61.70% | step=0.00476 | outcomes=47
```

---

## Supported Assets

STRATA ships with pre-calibrated volatility profiles for common assets:

| Class | Assets | Adjustment |
|---|---|---|
| HIGH vol | TSLA, NVDA, AMD, COIN, PLTR, MSTR | `min_abs_bias` relaxed by -0.010 |
| MED vol | AAPL, MSFT, GOOGL, META, AMZN, NFLX | No adjustment (baseline) |
| LOW vol ETF | SPY, QQQ, IWM, DIA, VTI, GLD, TLT | `max_trap_risk` relaxed by +0.10 |

Pass `asset="TICKER"` to `StrataGUARD` to activate profile. Unknown tickers default to MED.

---

## Installation

```bash
# No external dependencies beyond Python 3.9+
# Clone and run directly:
git clone <repo>
cd STRATA-FRAMEWORK-MARKET-TRADING
py -3.11 tests/test_harness.py   # verify installation
```

---

## Running Tests

```bash
# Core behavior (1000-step simulation)
py -3.11 tests/test_harness.py

# STRATA-LOOP weight adaptation
py -3.11 tests/test_loop.py

# Extreme scenario stress test (5 scenarios)
py -3.11 tests/test_stress.py
```

---

## Running Calibration

```bash
# Single asset calibration (requires parquet data in data/raw/)
py -3.11 replay/multi_year_calibration.py --ticker AAPL --save

# Cross-asset comparison report (requires all 5 calibrations)
py -3.11 replay/comparison_report.py

# Walk-forward IS/OOS test
py -3.11 replay/walk_forward_test.py --ticker AAPL
```

---

## Calibration Results (V2 Weights, 5-year data 2020–2024)

| Asset | Guard Rate | HOLD% | LONG% | SHORT% | Guard Spread |
|---|---|---|---|---|---|
| AAPL | 40.6% | 53.0% | 34.5% | 12.5% | — |
| TSLA | 37.8% | 52.9% | 36.1% | 11.0% | — |
| SPY | 39.9% | 50.6% | 36.2% | 13.2% | — |
| NVDA | 36.2% | 50.6% | 37.2% | 12.1% | — |
| QQQ | 39.3% | 49.7% | 37.4% | 12.8% | — |
| **Max-min spread** | | | | | **4.3% ✓** |

All assets: state drift STABLE, long memory formed, cross-year std < 2%.

---

## Stress Test Results

| Scenario | Guard Block | LONG% | Result |
|---|---|---|---|
| Crash | 100% | 0% | ✓ SANE |
| Fake Breakout | 11.5% | 38% | ✓ SANE |
| Sideways Chop | 100% | 0% | ✓ SANE |
| Strong Trend | 9.2% | 90% | ✓ SANE |
| Slow Grind | 0.3% | 99% | ✓ SANE |

---

## Design Philosophy

> STRATA is a cognitive layer, not a trading system. It answers one question: *"what kind of market are we in right now, and what constraints should that impose on action?"*

Key principles:
- **State, not prediction** — STRATA estimates regime, not price
- **Hard rules, not learned risk** — guard thresholds are explicit and auditable
- **Structural adaptation, not per-asset retraining** — one weight set, asset profiles for adjustment
- **Bounded learning** — LOOP weights stay within ±0.3 of calibrated seed values

See [`MANIFESTO.md`](MANIFESTO.md) for the full academic/theoretical treatment.

---

## Project Structure

```
strata/
├── __init__.py          public API
├── sense.py             OHLCV → semantic signals
├── core.py              state transition engine + weights
├── memory.py            3-layer pattern memory
├── decide.py            state → action proposal
├── guard.py             hard-rule risk gate (regime + asset aware)
└── loop.py              closed-loop weight adaptation

replay/
├── multi_year_calibration.py    5-year calibration runner
├── comparison_report.py         V1 vs V2 + cross-asset report
└── walk_forward_test.py         IS/OOS generalization test

tests/
├── test_harness.py      core behavior checks (1000 steps)
├── test_loop.py         STRATA-LOOP unit tests
└── test_stress.py       5 extreme scenario tests

data/
├── raw/                 parquet OHLCV files (not included)
└── results/             calibration CSV outputs
```
