Skip to content
moremedsPublic

About

Streaming technical-analysis signal service — computes indicators, rule-engine signals, and market regime from bars and live ticks; serves them over REST/WebSocket.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

784 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

APEX — streaming technical-analysis signal service

APEX reads market bars and live ticks, computes technical-analysis indicators + rule-engine signals + market regime, and serves signal payloads over WebSocket/REST.

It is one of four decoupled systems:

livewire ──bars──▶  APEX  ──signals (WS/REST)──▶  argon
(parquet           (TA brain)                     (stateless UI)
 data lake)            ▲
                       └──live ticks── xenon (WebSocket)
  • livewire — the bar warehouse (Hive-partitioned Parquet "bronze" lake, read on demand via DuckDB).
  • xenon — the live tick feed (WebSocket).
  • APEX — this repo: indicators (TA-Lib), a rule engine, regime detection. Stateless compute; persists fired signals to Postgres.
  • argon — a stateless UI that pulls everything from APEX on demand (stores nothing).

Project status (2026-06): APEX was pivoted from a risk-monitoring + backtesting monolith into this streaming service. The streaming path (bars-in → subscription → signals-out → live-in) and the chart read surface are implemented and merged. A Phase 6 strip-down of the legacy backtest/risk code is still pending, so some of that code is still present under src/backtest/ and src/domain/backtest/. Pre-pivot documentation has moved to docs/legacy/.


Run it

APEX is a FastAPI app served by uvicorn on port 8322 (override with APEX_API_PORT).

# 1. point APEX at its data sources via .env (gitignored)
cat > .env <<'EOF'
APEX_LIVEWIRE_ROOT=/absolute/path/to/livewire/data-lake/bronze
APEX_PG_URL=postgresql://apex_app:apex@127.0.0.1:5432/apex_signals
EOF

# 2. launch (the script loads .env, runs preflight checks, then execs the server)
scripts/serve.sh
#   …or directly, loading the env file yourself:
uv run --env-file .env python -m src.api.server

Health check: curl -s http://127.0.0.1:8322/health → {"status":"ok", "pg_connected":…}.

Configuration (environment variables)

APEX's data sources are env-gated — it boots regardless, and each unset source just makes its endpoints return 503 (degrades, never crashes).

Variable Default Enables
APEX_LIVEWIRE_ROOT unset /bars, /indicators, and the streaming warmup seed
APEX_LIVEWIRE_SILVER_ROOT unset Silver revision watcher and adjusted daily/factor artifacts
APEX_LIVEWIRE_PRICE_MODE raw Bar reads: raw Bronze or adjusted Silver/factor-joined Bronze
APEX_LIVEWIRE_REVISION_POLL_SECONDS 30 Poll interval for atomically published Silver revisions
APEX_PG_URL unset /signals snapshot/backfill, /confluence, and signal persistence
APEX_PG_READ_URLS unset /v1/db/* catalog/table reads + /v1/uw/* curated joins (comma-separated DSNs; each DSN's database name is the {database} segment)
APEX_PG_READ_TOKEN unset Bearer credential required by every /v1/db/* and /v1/uw/* route
APEX_XENON_WS_URL ws://127.0.0.1:8765 live ticks → live WS signal frames
APEX_XENON_API_KEY unset Service credential for the xenon tick feed: sent as X-API-Key (with no Origin header) on the WS upgrade. Required once xenon's relay enforces upgrade auth; unset keeps the no-auth path. Secret — .env only
APEX_TIMEFRAMES 1d timeframes the streaming pipeline subscribes/warms
APEX_API_PORT 8322 listen port

API surface

Method · Path Purpose
GET /health liveness + pg_connected
WS /ws/signals subscribe to a ticker → ack + PG snapshot + live signal frames
GET /signals/{ticker} signal backfill (load / reconnect / ?since=)
GET /bars/{ticker} OHLCV candles from livewire
GET /indicators/{ticker}?indicator= per-bar indicator series (compute-on-read)
GET /confluence/{ticker} multi-timeframe confluence

Full reference and payload shapes: docs/argon-apex-api.md.

PostgreSQL read surface (env-gated)

With APEX_PG_READ_URLS and APEX_PG_READ_TOKEN set, the API serves read-only PostgreSQL access — GET /v1/db/* generic catalog/table reads and GET /v1/uw/* curated uw_scan joins — under Bearer auth on dedicated read-only pools. Full route/grammar/error contract: docs/argon-apex-api.md §3b.

Lifecycle: APEX is idle at rest. A WS subscribe triggers a one-time warmup seed (preloads history into the indicator buffer) and attaches the live feed; signals fire per closed bar, ref-counted across subscribers. The REST chart surface (/bars, /indicators, /confluence) is independent and compute-on-read.

When APEX_LIVEWIRE_SILVER_ROOT is configured, the long-running service polls revisions/current.json. A newer valid revision reseeds only affected active subscriptions, buffers that symbol's Xenon ticks during replacement, atomically swaps all configured timeframe histories, and replays buffered ticks. Leave the price mode at its default raw during shadow validation. Setting APEX_LIVEWIRE_PRICE_MODE=adjusted makes daily reads use materialized Silver and intraday reads apply Silver factor intervals to Bronze. Missing or incomplete Silver data fails explicitly; Apex never silently falls back to raw bars.


Documentation


Development

make install                                   # install deps (uv)
uv run python -m pytest tests/unit --no-cov    # unit tests
uv run mypy src/ --ignore-missing-imports      # type check
make format                                    # black + isort

Signal persistence schema: migrations/005_ta_signals.sql (ta_signals / indicator_values / confluence_scores).

About

Streaming technical-analysis signal service — computes indicators, rule-engine signals, and market regime from bars and live ticks; serves them over REST/WebSocket.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages