A layered, stateful framework for market regime estimation and decision support
Project description
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.
pip install strata-market
Quick Start — High Level (v2.4+)
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
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
model = StrataModel.from_pretrained("AAPL") # AAPL | TSLA | SPY | NVDA | QQQ
print(model.summary())
StrataTrainer — train from your own data
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
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 |
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.
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.
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.
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.
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.
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
# 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
# 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
# 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 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
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file strata_market-2.5.0-py3-none-any.whl.
File metadata
- Download URL: strata_market-2.5.0-py3-none-any.whl
- Upload date:
- Size: 36.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e466453fd26f416d31d6731612be0e3448f39978a2685bf5d1c29f28747d219d
|
|
| MD5 |
da4824da642316f2505a1deae7186a4a
|
|
| BLAKE2b-256 |
d92082387f21fcba599f72f33e1968c801b4e177fca39dcf778b49f6829e7418
|