MarketPulse is a Go microservice that tracks intraday stock movements and generates real-time RSI alerts. It maintains per-symbol RSI state across requests and restarts, providing accurate technical analysis with oversold/overbought notifications for professional trading workflows.
| Feature | Description |
|---|---|
| Stateful RSI Tracking | Maintains per-symbol RSI state across requests/restarts using Wilderβs Smoothing with SMA seeding. |
| Hybrid State Storage | Redis persistence + in-memory fallback with eviction (configurable max symbols). |
| Cache Stampede Protection | Singleflight pattern prevents thundering herd during fallback initialization. |
| Incremental Data Fetch | Fetches only candles newer than last update timestamp to minimize bandwidth. |
| Smart Warmup Flow | 3-phase RSI warmup: Processing (<14), Warming (14β50), Stable (β₯50). |
| Real-time Alerts | Oversold/Overbought detection with configurable thresholds. |
| Rate Limiting | Upstream API protection via ticker-based request pacing. |
| JWT Authentication | Secure token-based access control for production environments. |
| Middleware | CORS, structured logging (Zap), panic recovery, and request tracing. |
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Frontend β β MarketPulse β β Upstream API β
β (Static SPA) βββββΊβ (Go Microsvc) βββββΊβ (AlphaVantage+) β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β
ββββββββββββββββββββ
β Redis β β Compact RSI State
β (symbol:*.compact)|
ββββββββββββββββββββ
StateRepository abstracts Redis/memory storage logicmain.goPOST /login
curl -X POST http://localhost:8080/login \
-H "Content-Type: application/json" \
-d '{"username":"demo","password":"demo"}'
Response
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user_id": "demo_user_1"
}
GET /market/intraday/{symbol}
curl "http://localhost:8080/market/intraday/IBM?tail=20&rsi_low=25&rsi_high=75" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
| Param | Type | Default | Description |
|---|---|---|---|
tail |
int | nil | Max recent candles to return |
rsi_low |
float64 | 30.0 | Oversold threshold |
rsi_high |
float64 | 70.0 | Overbought threshold |
Sample Response
{
"symbol": "IBM",
"rsi": 42.56,
"change_pct": 1.25,
"alert": "",
"is_valid_rsi": true,
"warmup_status": "stable",
"seeded_candles": 200,
"rsi_count": 127,
"last_fetch": "2026-01-16T10:30:00Z",
"candles": [
{
"ts": "2026-01-16T10:25:00Z",
"o": 145.20,
"h": 145.80,
"l": 145.10,
"c": 145.65,
"v": 123456
}
]
}
1. LOAD STATE ββ
ββ [Redis UP] βββ symbol:IBM:compact βββ
ββ [Redis DOWN] ββ Memory Fallback βββββ€
β
2. WARMUP/UPDATE βββββββββββββββββββββββββββββββββββββββ€
- If Count=0: Seed from full history (SMA 14-period) β
- Fetch incremental candles (> LastTs) β
- Wilder smoothing: (Prev*13 + Current)/14 β
β
3. ALERT β RESPONSE ββββββββββββββββββββββββββββββββββββ
| State | Count | Description |
|---|---|---|
| processing | < 14 | Initial SMA calculation period |
| warming | 14β49 | Wilder smoothing warmup; usable but lower confidence |
| stable | β₯ 50 | Production-ready accuracy |
| insufficient | β | No loss data detected (prevents division by zero) |
| Component | Technology | Purpose |
|---|---|---|
| Web Framework | Chi Router | Lightweight, composable routing |
| State Store | Redis + In-memory | Hybrid persistence + fallback |
| HTTP Client | Resty | Upstream API calls |
| Auth | JWT (HS256) | Token-based security |
| Logging | Zap | Structured logging |
git clone <repository> marketpulse
cd marketpulse
cp .env.example .env
# Required
REDIS_ADDR=redis:6379
UPSTREAM_URL=http://localhost:8000/query
JWT_SECRET=your-super-secret-key-min-32-chars
HTTP_PORT=:8080
# Optional
MAX_SYMBOLS_MEMORY=1000
JWT_EXPIRY=24h
LOG_LEVEL=info
docker-compose up --build
marketpulse/
βββ cmd/
β βββ main.go
βββ internal/
β βββ api/
β βββ domain/
β βββ infra/
βββ pkg/
βββ rsi/
| Operation | p50 | p95 | Notes |
|---|---|---|---|
| Cold RSI (seed) | 180ms | 320ms | Full history fetch + SMA |
| Warm RSI | 45ms | 120ms | Incremental + cache hit |
| Redis Fallback | 2ms | 8ms | Pure memory path |
| Memory Pressure | 15ms | 45ms | LRU eviction overhead |
This project is licensed under the MIT License.