Skip to main content

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)

StrataNet — PyTorch Neural Network (v2.5+)

STRATA-NET is a novel recurrent neural network architecture purpose-built for market trading — not a vanilla LSTM or GRU, but a new architecture where the hidden state directly encodes interpretable market concepts.

Hidden State Design

h = [bias, momentum, trap_risk, uncertainty]   ← 4 dimensions, always interpretable

bias        ∈ [-1, 1]   directional conviction (negative = bearish, positive = bullish)
momentum    ∈ [ 0, 1]   structural energy from breakouts
trap_risk   ∈ [ 0, 1]   adverse selection / liquidity trap pressure
uncertainty ∈ [ 0, 1]   volatility-driven ambiguity

Unlike LSTM/GRU hidden states (opaque vectors), these dimensions have enforced hard bounds and semantic meaning at every step of inference.

Architecture

Input: OHLCV window  (B, T, 5)
         │
         ▼
StrataEmbedding      learned OHLCV → semantic features  (replaces hand-crafted SENSE)
         │
         ▼
StrataCoreCell  ×T   custom GRU-like cell with 4 structured gates
         │             — update gate z, reset gate r (like GRU)
         │             — but projected back to 4-dim interpretable hidden state
         │             — bounds enforced per dimension every step
         ▼
StrataHead           hidden state → LONG/SHORT/HOLD + confidence + regime
         │
         ▼
Output: action logits (3) + confidence (1) + regime logits (4)

Quick Start

import torch
from strata import StrataNet, StrataNetConfig, StrataNetTrainer, StrataNetDataset

# ── Train from OHLCV candles (no manual labeling needed) ─────────────────
# Labels are auto-generated by the STRATA state machine (teacher-student)
dataset = StrataNetDataset.from_candles(my_candles, seq_len=30, asset="AAPL")
trainer = StrataNetTrainer(asset="AAPL")
model   = trainer.train(dataset, epochs=30)

# Save as .pt — standard PyTorch format
model.save("aapl_net.pt")

# ── Load and deploy ───────────────────────────────────────────────────────
model = StrataNet.load("aapl_net.pt")

# Predict from a (30, 5) tensor of normalised OHLCV features
result = model.predict_action(x_tensor)
# {
#   "action":     "LONG",          # LONG | SHORT | HOLD
#   "confidence": 0.71,
#   "regime":     "TRENDING",      # TRENDING | RANGING | TRANSITIONING | CHOPPY
#   "state": {
#       "bias":        0.89,       # interpretable — always in [-1, 1]
#       "momentum":    0.43,       # interpretable — always in [0, 1]
#       "trap_risk":   0.21,       # interpretable — always in [0, 1]
#       "uncertainty": 0.54,       # interpretable — always in [0, 1]
#   }
# }

Normalise your OHLCV before feeding to StrataNet

from strata.net_trainer import _normalise_window

window  = candles[-30:]   # last 30 candles
x       = torch.tensor(_normalise_window(window), dtype=torch.float32)  # (30, 5)
result  = model.predict_action(x)

Custom config

cfg = StrataNetConfig(
    asset        = "TSLA",
    seq_len      = 60,      # longer lookback for volatile assets
    embed_dim    = 64,      # larger embedding for more complex patterns
    core_expand  = 32,      # wider recurrent cell
    head_dim     = 32,
    dropout      = 0.15,
)
model = StrataNet(cfg)
print(model.summary())
# StrataNet v1.0
#   asset       : TSLA
#   seq_len     : 60
#   hidden_dim  : 4  [bias, momentum, trap_risk, uncertainty]
#   parameters  : ~18,000

Comparison: STRATA vs LSTM/GRU/Transformer

LSTM / GRU Transformer StrataNet
Domain General General Market trading only
Hidden state Opaque N-dim vector Attention weights 4-dim, fully interpretable
State bounds None None Hard bounds per dimension
Output Price / probability Token / probability LONG/SHORT/HOLD + regime
Label source Future price needed Manual labels Auto from STRATA teacher
Model file .pt .pt / .bin .pt
Parameters Millions Millions ~5,000 (default)

Architecture (State Machine — Classic API)

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

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

strata_market-2.6.0-py3-none-any.whl (39.7 kB view details)

Uploaded Python 3

File details

Details for the file strata_market-2.6.0-py3-none-any.whl.

File metadata

  • Download URL: strata_market-2.6.0-py3-none-any.whl
  • Upload date:
  • Size: 39.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for strata_market-2.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 df647ae62f055399b3f3fab1f0ee944b840b7663ddba5a27aebde00d0c8c5f73
MD5 f758703c9cb473d823fc0c4348c571d0
BLAKE2b-256 39322ef5ac389d90910350360c17ea9aef6ae6326c88552646d2431df1277371

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page