6.7 KiB
6.7 KiB
Task: Unified Market Data Service + Redis Message Log
Priority: HIGH
Assigned: Glitch (after trader-dashboard-controls completes)
Status: Queued
Date: 2026-03-01
Depends on: trader-dashboard-controls (in progress)
Problem
Two services independently fetch the same OHLCV data from Binance.us:
- Dashboard scanner (
lib/server/scanner.ts) — 29 coins × 1h × every 30s - TA Service (
ta_service.py) — 29 coins × 3 timeframes (5m/1h/4h) × own cycle
This doubles API calls, wastes bandwidth, and increases rate limit risk.
Solution
New Service: coinex-market-data
A single long-running service that:
- Fetches ALL OHLCV data from
api.binance.us(29 coins × 3 timeframes) - Caches everything in Redis with TTLs
- Publishes updates to Redis pub/sub channels on each refresh
- Exposes a health endpoint
No other service should hit Binance directly after this.
Redis Schema
# Cached OHLCV candle data
market:ohlcv:{symbol}:{timeframe} → JSON array of candles (TTL: varies by timeframe)
- 5m: TTL 120s (refresh every 60s)
- 1h: TTL 300s (refresh every 120s)
- 4h: TTL 600s (refresh every 300s)
# Latest price/ticker for quick reads
market:price:{symbol} → JSON { price, change24h, volume, timestamp } (TTL: 60s)
# Pub/sub channels for real-time consumers
channel: market:update:{timeframe} → published after each timeframe refresh cycle
channel: market:update:all → published after complete scan cycle
# Message log (see below)
market:log → Redis Stream (XADD) of all messages passing through Redis
Refresh Cycle
Every 30s: Fetch 5m candles for all 29 coins → cache → publish market:update:5m
Every 120s: Fetch 1h candles for all 29 coins → cache → publish market:update:1h
Every 300s: Fetch 4h candles for all 29 coins → cache → publish market:update:4h
Consumer Changes
Dashboard scanner (scanner.ts):
- Remove ALL direct Binance API calls
- Read from
market:ohlcv:{symbol}:1hRedis keys instead - Subscribe to
market:update:1hchannel to trigger recalculation - Calculate RSI/VWAP/BB from cached candles (same logic, different data source)
TA Service (ta_service.py):
- Remove ALL direct Binance API calls
- Read from
market:ohlcv:{symbol}:{timeframe}Redis keys - Subscribe to
market:update:{timeframe}channels to trigger indicator calculation - Keep all indicator logic (EMA ribbons, TTM Squeeze, Stoch RSI) unchanged
Redis Message Log
Use Redis Streams (XADD/XRANGE/XLEN) to log ALL messages passing through Redis:
# Every publish, cache write, and signal gets logged
Stream key: redis:message_log
Fields per entry:
- type: "publish" | "cache_write" | "cache_read" | "signal" | "trade" | "error"
- channel: the pub/sub channel or key involved
- source: "market-data" | "ta-service" | "dashboard" | "trader-bot"
- summary: human-readable one-liner
- payload_size: bytes
- timestamp: ISO string
The market data service wraps Redis operations to auto-log:
- Every
PUBLISH→ logged with channel + payload size - Every
SETEX(cache write) → logged with key + TTL - Every signal published by TA service → logged
- Every trade action by trader bot → logged
Dashboard API:
GET /api/redis/log?limit=100&type=signal&source=ta-service— filterable log viewer- Displayed in the Status page under a new "Redis Activity" section
Stream is capped at 10,000 entries (XADD ... MAXLEN ~ 10000) to prevent unbounded growth.
Architecture
┌─────────────────────┐
│ Binance.us API │
└─────────┬───────────┘
│ (ONLY connection)
┌─────────▼───────────┐
│ Market Data Service │ ← NEW (Python, systemd)
│ Port 8895 /health │
└─────────┬───────────┘
│ SETEX + PUBLISH + XADD
┌─────────▼───────────┐
│ Redis │
│ OHLCV cache │
│ Pub/sub channels │
│ Message stream log │
└──┬──────┬────────┬──┘
│ │ │
┌────────▼┐ ┌───▼─────┐ ┌▼──────────┐
│Dashboard │ │TA Svc │ │Trader Bot │
│Scanner │ │(signals)│ │(trades) │
│(scores) │ │ │ │ │
└──────────┘ └─────────┘ └───────────┘
Tech Stack
- Python (asyncio + aiohttp + redis-py)
- FastAPI health endpoint on port 8895
- Systemd user service:
coinex-market-data.service - Redis Streams for message logging
Files
- New service:
~/.openclaw/workspace/projects/coinex-market-data/ - Dashboard scanner:
~/.openclaw/workspace/projects/coinex-dashboard/lib/server/scanner.ts - TA service:
~/.openclaw/workspace-glitch/projects/coinex-ta-service/ta_service.py - Redis: 127.0.0.1:6379
Git Repository
- Create private Gitea repo FIRST:
https://git.letsgetnashty.com/case/coinex-market-data - Git credentials:
case:Gh0st%21nTh3Mach1n3(URL-encoded in remote URL) - Git config: user
Case, emailcase-lgn@protonmail.com - Push initial commit before starting development
- Commit frequently throughout build
Constraints
api.binance.usONLY (not api.binance.com — 451 geo-block)- Respect Binance rate limits (1200 req/min)
- All existing indicator/scoring logic untouched
- Dashboard must work identically from user perspective
- Include unit tests
- Context7 mandatory for library docs
Definition of Done
- Market data service running, fetching all 29 coins × 3 timeframes
- All OHLCV data cached in Redis with appropriate TTLs
- Dashboard scanner reads from Redis (zero Binance calls)
- TA service reads from Redis (zero Binance calls)
- Redis message log capturing all pub/sub + cache activity
/api/redis/logendpoint on dashboard with filtering- Redis Activity section on Status page
- Health endpoint at :8895/health
- Systemd service created and running
- Gitea repo created and pushed
- Unit tests passing
- All 3 services confirmed working together end-to-end