Formerly Upbit Alpha Desk. Full-stack intelligence console for KRW market structure, listings, and market data operations.
Upbit Alpha Desk is a full-stack trading-intel console for the KRW market.
It blends Upbit day-candles, cached tickers, saved trading-value files, and Bybit-based listing strategies into one React frontend backed by an Express + Redis API layer.
- Backend: Node.js, Express, TypeScript, Redis (market-data cache), Axios schedulers
- Frontend: React (Vite + TypeScript), React Query, Chart.js, date-fns
- Scheduling: Listing calendar & listing strategy analyzers (3h), ticker cache persistence, saved_data parsing, midnight candle refresh
- Package Manager: pnpm
src/ # Express server + schedulers
βββ server.ts # API & static serving entry
βββ config.ts # CORS / API key / rate-limit config
βββ clients/
β βββ redisClient.ts # Lazy Redis connector
β βββ bybitClient.ts # Bybit hourly candle fetcher
βββ services/ # DataManager + schedulers
frontend/ # React/Vite SPA (served as static build)
βββ src/components/... # Sidebar, analytics, listing lab, insights
βββ src/api/ # Typed API client + DTOs
public/ # Legacy static assets (still served)
cache/ # JSON snapshots for schedulers & ticker cache
saved_data/ # Trading-value JSON files parsed into Redis
- Backend
pnpm install pnpm dev # tsx + nodemon - Frontend
cd frontend pnpm install pnpm dev # http://localhost:5173 (uses VITE_API_BASE_URL)
- Production build
The Express server automatically serves
pnpm build # compiles backend + frontend pnpm start # serves /api and the built SPA
frontend/dist(setSERVE_FRONTEND=falseto disable). - Tests
pnpm test # vitest unit tests (rate limiter, etc.)
Copy .env.example (backend root):
CORS_ORIGINS=https://app.your-domain.com
API_KEY=optional-x-api-key
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX=120
REDIS_URL=redis://default:password@host:11219
SERVE_FRONTEND=true
PORT=3000For the React dev server, copy frontend/.env.example and adjust:
VITE_API_BASE_URL=http://localhost:3000| Route | Description |
|---|---|
GET /api/coins |
Supported KRW markets (volume sorted). |
GET /api/data/:coin/latest?days=30 |
Latest day-candle slice. |
GET /api/data/:coin/range?start=YYYY-MM-DD&end=YYYY-MM-DD |
Day-candle slice for a date range (start required, end defaults to today). |
GET /api/data/:coin/statistics |
Min/Max/Range per coin. |
GET /api/market-data/:coin |
Redis-backed trading-value overlay (falls back to saved files). |
GET /api/coins/listing-dates |
Cached listing calendar snapshot (3h cadence). |
GET /api/coins/listing-strategies |
Cached Bybit short-scenario lab (3h cadence). |
GET /api/ticker / GET /api/ticker/:coins |
1-minute cached Upbit tickers (API-key protected if set). |
- Ticker cache: 60s TTL + persisted JSON (restored on restart).
- Day candles: Loaded on-demand and updated daily at 00:05 KST.
- Market data overlay: Parsed once per
saved_datamtime, then cached in Redis for 6h per coin. - Listing calendar & lab: Every 3 hours; results saved to
cache/and, after restart, to Redis for warm responses.
Upbit Alpha Deskλ KRW λ§μΌμ© 리μ‘νΈ κΈ°λ° λμ보λμ
λλ€.
Upbit μΌλ΄, 1λΆ μΊμ ν°μ»€, saved_data κ±°λλκΈ, Bybit μμ₯ μ μ λ΅ ν΅κ³λ₯Ό Redisκ° λ·λ¨μμ μΊμ±νκ³ Express APIλ‘ μ 곡ν©λλ€.
- λ°±μλ: Node.js, Express, TypeScript, Redis μΊμ, Axios μ€μΌμ€λ¬
- νλ°νΈμλ: React (Vite), React Query, Chart.js, date-fns
- μ€μΌμ€λ¬: μμ₯ μΊλ¦°λ / μμ₯ μ λ΅(3μκ°), ν°μ»€ μΊμ, saved_data νμ, μμ λ°μ΄ν° κ°±μ
src/ # Express API + μ€μΌμ€λ¬
frontend/ # React/Vite SPA
public/ # κΈ°μ‘΄ μ μ μμ
cache/, saved_data/ # μ΄μ μΊμ/λ°μ΄ν°
- 루νΈμμ
pnpm install,pnpm dev(API μλ²). frontend/μμpnpm install,pnpm dev(Vite)..envμVITE_API_BASE_URLμ λ°±μλ μ£Όμλ‘ μ§μ .- λ°°ν¬ μ
pnpm build(λ°±/νλ°νΈ λμ λΉλ) νpnpm startμ€ν β Expressκ°frontend/dist(SPA)μ/api/*λ₯Ό ν¨κ» μλΉμ€ν©λλ€. pnpm testλͺ λ ΉμΌλ‘ κΈ°λ³Έ μ λ ν μ€νΈ(λ μ΄νΈ 리미ν°)λ₯Ό λ릴 μ μμ΅λλ€.
CORS_ORIGINS=https://app.example.com
API_KEY=μ νμ μΈμ¦ ν€
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX=120
REDIS_URL=redis://default:password@host:11219
SERVE_FRONTEND=trueνλ°νΈλ frontend/.env μμ VITE_API_BASE_URLμ μ€μ νμΈμ.
| κ²½λ‘ | μ€λͺ |
|---|---|
/api/coins |
μ§μ KRW λ§μΌ λͺ©λ‘ |
/api/data/:coin/latest?days=N |
μ΅κ·Ό NμΌ μΌλ΄ λ°μ΄ν° |
/api/data/:coin/range?start=YYYY-MM-DD&end=YYYY-MM-DD |
κΈ°κ°λ³ μΌλ΄ λ°μ΄ν° (start νμ, end λ―Έμ§μ μ μ€λ) |
/api/data/:coin/statistics |
ν΅κ³ (μ΅κ³ /μ΅μ λ±) |
/api/market-data/:coin |
Redis μΊμλ κ±°λλκΈ/κ±°λλ |
/api/coins/listing-dates |
3μκ°λ§λ€ κ°±μ λλ μμ₯ μΊλ¦°λ |
/api/coins/listing-strategies |
3μκ°λ§λ€ κ³μ°λλ μμ₯ μ μ λ΅ λ³΄κ³ μ |
/api/ticker / /api/ticker/:coins |
1λΆ μΊμ Upbit ν°μ»€ |
- ν°μ»€: 1λΆ TTL + λμ€ν¬ λ°±μ
- μΌλ΄ λ°μ΄ν°: μμ (00:05) μλ μ λ°μ΄νΈ
- κ±°λλκΈ:
saved_dataνμΌ λ³κ²½ μ μ¬νμ± β Redis 6μκ° μΊμ - μμ₯ μΊλ¦°λ/μ λ΅: 3μκ°λ§λ€ μ¬κ³μ° + λμ€ν¬/Redis μ€λ μ·
μμ΄/νκ΅μ΄ μ€λͺ μ ν¨κ» μ 곡νλ νλ«νΌν μμ μ μ°Έκ³ νμΈμ.