A professional-grade cryptocurrency trading terminal with real-time market data, AI-powered analysis, and advanced trading tools.
- Real-time Market Data - Live Binance WebSocket streaming
- Advanced Charting - Candlestick charts with technical indicators
- AI Trading Analyst - Claude-powered market analysis
- Risk Management - ATR-based stop loss, position sizing, trailing stops
- Paper & Live Trading - Test strategies or trade with real funds
- Multi-Asset Tracking - Watchlist, correlations, funding rates
- Price Alerts - Browser notifications + Telegram integration
- Backtesting - Test strategies on historical data
Simply open nexus-pro.html or nexus-pro-enhanced.html in your browser:
# Or serve with a local server
cd nexus-pro-html
npx serve .Features available:
- Simulated market data
- Paper trading
- Local storage persistence
- All UI components
cd backend
# Install dependencies
npm install
# Copy environment file
cp .env.example .env
# Edit .env with your API keys (optional)
nano .env
# Start the server
npm start
# or for development with hot reload
npm run devServer runs at http://localhost:3001
Update the frontend to connect to your backend:
In nexus-pro-enhanced.html, modify the API calls to point to your backend:
const API_BASE = 'http://localhost:3001';GET /health
GET /api/binance/klines?symbol=BTCUSDT&interval=1h&limit=500
GET /api/binance/ticker/BTCUSDT
GET /api/binance/tickers
GET /api/binance/depth/BTCUSDT?limit=100
GET /api/binance/funding
POST /api/binance/order (requires API key)
GET /api/trades (requires Bearer auth)
POST /api/trades/paper (requires Bearer auth)
POST /api/trades/paper/close/:id (requires Bearer auth)
POST /api/trades/risk/size (requires Bearer auth)
GET /api/trades/performance/rolling?window=50 (requires Bearer auth)
GET /api/trades/performance/tuning?window=200 (requires Bearer auth)
GET /api/trades/performance/setup-controls (requires Bearer auth)
GET /api/trades/performance/setup-controls/history?limit=100 (requires Bearer auth)
POST /api/trades/performance/setup-controls/clear (requires Bearer auth)
POST /api/trades/performance/purge (requires Bearer auth)
GET /api/trades/positions/open (requires Bearer auth)
GET /api/trades/stats/summary (requires Bearer auth)
// /api/trades/performance/rolling returns block-rate, blocked reasons,
// rolling expected-value trend (edge decay), and recent expectancy metrics.
// /api/trades/performance/tuning returns telemetry-based threshold recommendations,
// out-of-sample validation summary, and promotion gate status.
// /api/trades/performance/setup-controls returns active auto-disabled setup states.
// /api/trades/performance/setup-controls/history returns setup control audit events.
// /api/trades/performance/purge trims telemetry outside retention policy.
Use these backend scripts before enabling live mode and during production tuning cycles:
cd backend
# 1) Validate Supabase/Binance credentials and required tables
npm run validate:live
# 2) Get telemetry-driven threshold recommendations for a user
# (requires backend running and a valid user bearer token)
OPS_BEARER_TOKEN=your_jwt npm run tune:thresholds
# 2b) Weekly ops cycle (KPI packet + tuning gate + optional apply)
OPS_BEARER_TOKEN=your_jwt npm run tune:weekly
# Optional flags:
# API_BASE=http://localhost:3001
# TUNING_WINDOW=200
# APPLY_DOTENV=true # writes recommended threshold values into backend/.env
# FORCE_APPLY_DOTENV=true # bypasses OOS promotion gate checksThe tuning script calls GET /api/trades/performance/tuning and emits recommended updates for:
TRADE_MIN_CONFIDENCE, TRADE_MAX_SPREAD_BPS, TRADE_MAX_SLIPPAGE_BPS, TRADE_MIN_LIQUIDITY_USD, TRADE_MAX_PORTFOLIO_NOTIONAL_USD, and TRADE_MAX_SYMBOL_EXPOSURE_USD.
When APPLY_DOTENV=true, both tuning scripts enforce promotion gating from out-of-sample checks before applying threshold changes. To override for emergency/manual operations, set FORCE_APPLY_DOTENV=true.
The weekly KPI packet (GET /api/trades/performance/weekly-kpis) now also includes setup-control status:
setupControls.enabledsetupControls.activeDisabledSetupssetupControls.active
To persist setup-level segmentation and execution quality KPIs in Supabase-backed mode:
cd backend
# 1) Run SQL in Supabase SQL Editor:
# scripts/sql/2026-04-06-add-setup-and-execution-columns.sql
# scripts/sql/2026-04-06-add-setup-control-events-table.sql
# 2) Verify the new columns are queryable through PostgREST
npm run verify:telemetry-schema
# 2a) Verify setup control events table specifically
npm run verify:setup-control-readiness
# 2a-ci) Emit compact readiness artifact for CI pipelines
npm run verify:setup-control-readiness:ci
# 2d) Verify full telemetry readiness bundle (Supabase schema + server recheck)
OPS_ADMIN_TOKEN=your_admin_token npm run verify:telemetry-readiness-bundle
# 2d-ci) Emit full readiness artifact for CI pipelines
OPS_ADMIN_TOKEN=your_admin_token npm run verify:telemetry-readiness-bundle:ci
# 2e) Validate readiness artifact schema contract + readiness values
npm run validate:readiness:artifacts
# GitHub Actions (workflow_dispatch)
# .github/workflows/backend-check.yml -> job: telemetry-readiness-artifacts
# validates JSON schema contract + readiness fields before job success
# uploads artifact bundle with run-scoped name and 30-day retention:
# telemetry-readiness-artifacts-<run_number>-<run_attempt>
# artifacts include:
# backend/artifacts/setup-control-readiness.json
# backend/artifacts/telemetry-readiness-bundle.json
# Nightly telemetry readiness workflow
# .github/workflows/telemetry-readiness-nightly.yml
# schedule: daily at 03:00 UTC + manual workflow_dispatch
# validates JSON schema contract + readiness fields before job success
# uploads run-scoped artifact bundle (90-day retention) and failure logs (30-day retention):
# telemetry-readiness-nightly-<run_number>-<run_attempt>
# telemetry-readiness-nightly-server-log-<run_number>-<run_attempt> (on failure)
# optional webhook notification secret for both workflows:
# READINESS_NOTIFY_WEBHOOK
# 2b) Force server-side diagnostics cache refresh after migration
OPS_ADMIN_TOKEN=your_admin_token npm run recheck:telemetry-schema
# 2c) One-command readiness gate (fails unless both checks are ready)
OPS_ADMIN_TOKEN=your_admin_token npm run ops:telemetry-ready
# Optional: auto-enable persistence flags in backend/.env when ready
OPS_ADMIN_TOKEN=your_admin_token APPLY_DOTENV=true npm run ops:telemetry-ready
# Roll back quickly (disables all telemetry persistence flags in backend/.env)
npm run disable:telemetry-persistence
# 3) Enable persistence flags in backend/.env
# SUPABASE_PERSIST_SETUP_TAG=true
# SUPABASE_PERSIST_EXECUTION_METRICS=true
# SUPABASE_PERSIST_SETUP_CONTROL_EVENTS=true
# 4) Post-enable smoke check (backend must be running on localhost:3001)
# requires ADMIN token (OPS_ADMIN_TOKEN or ADMIN_DIAGNOSTICS_TOKEN)
# and a JWT for authenticated endpoints (OPS_BEARER_TOKEN)
OPS_BEARER_TOKEN=your_jwt OPS_ADMIN_TOKEN=your_admin_token npm run smoke:persistence-ready
# Optional: include a tiny write probe (open + close one paper trade)
OPS_BEARER_TOKEN=your_jwt OPS_ADMIN_TOKEN=your_admin_token npm run smoke:persistence-ready:writeKeep all persistence flags set to false until step (2) passes.
Detailed runbook: backend/scripts/sql/TELEMETRY-OPS-PLAYBOOK.md
For .github/workflows/backend-check.yml and .github/workflows/telemetry-readiness-nightly.yml, configure these repository secrets:
BYBIT_API_KEYBYBIT_API_SECRETSUPABASE_URLSUPABASE_ANON_KEYSUPABASE_SERVICE_KEYJWT_SECRETADMIN_DIAGNOSTICS_TOKENOPS_ADMIN_TOKENOPS_BEARER_TOKEN(optional; enables post-enable persistence smoke in workflows)READINESS_NOTIFY_WEBHOOK(optional; Slack/Teams/custom webhook)
Minimum secrets for readiness artifact generation only:
SUPABASE_URLSUPABASE_ANON_KEYorSUPABASE_SERVICE_KEYADMIN_DIAGNOSTICS_TOKENorOPS_ADMIN_TOKEN
Optional secret for authenticated persistence smoke checks in CI:
OPS_BEARER_TOKEN
Troubleshooting workflow failures:
- If health check fails, inspect the uploaded
telemetry-readiness-nightly-server-log-<run_number>-<run_attempt>artifact for that run. - If readiness scripts fail with schema errors, rerun SQL migrations from
backend/scripts/sql/before re-dispatching workflow. - If admin schema recheck fails with unauthorized, verify
OPS_ADMIN_TOKENandADMIN_DIAGNOSTICS_TOKENare valid and not expired.
Use this sequence after schema migrations or environment changes:
- Run migration SQL in Supabase:
backend/scripts/sql/2026-04-06-add-setup-and-execution-columns.sqlbackend/scripts/sql/2026-04-06-add-setup-control-events-table.sql
- In GitHub Actions, manually run
Backend Checkand wait fortelemetry-readiness-artifactsjob completion. - Open the run artifacts bundle (
telemetry-readiness-artifacts-<run_number>-<run_attempt>) and inspect:
setup-control-readiness.jsontelemetry-readiness-bundle.json
- Confirm
ready: truein bundle artifact before enabling persistence flags. - Optionally run
Telemetry Readiness Nightlymanually once to verify scheduled-path behavior. - If any artifact reports
ready: false, keep persistence flags disabled and follow troubleshooting notes above.
POST /api/ai/analyze
POST /api/ai/signal
POST /api/ai/backtest
GET /api/ai/status
// /api/ai/signal now includes regime, winProbability, expectedValue, and actionable flag
GET /api/alerts (requires Bearer auth)
POST /api/alerts (requires Bearer auth)
PUT /api/alerts/:id (requires Bearer auth)
DELETE /api/alerts/:id (requires Bearer auth)
POST /api/alerts/:id/check (requires Bearer auth)
POST /api/alerts/check-batch (requires Bearer auth)
POST /api/alerts/telegram/send (requires Bearer auth + server Telegram env config)
ws://localhost:3001/ws
// Subscribe to symbols
{"type": "subscribe", "symbols": ["BTCUSDT", "ETHUSDT"], "channels": ["kline_1m", "ticker"]}
// Execute trade
{"type": "execute_trade", "symbol": "BTCUSDT", "side": "BUY", "quantity": 0.001}
Create a .env file in the backend directory:
# Server
PORT=3001
FRONTEND_URL=http://localhost:3000
# Binance (optional - for live trading)
BINANCE_API_KEY=your_key
BINANCE_API_SECRET=your_secret
# Supabase (optional - for database)
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_ANON_KEY=your_key
SUPABASE_SERVICE_KEY=your_service_role_key
# Claude AI (optional - for AI analysis)
ANTHROPIC_API_KEY=your_key
# Telegram (optional - for alerts)
TELEGRAM_BOT_TOKEN=your_token
TELEGRAM_CHAT_ID=your_chat_id
# Security
JWT_SECRET=change-this-secret
REQUIRE_LIVE_CREDENTIALS=false
SESSION_IDLE_TIMEOUT_MS=86400000
SESSION_ABSOLUTE_TIMEOUT_MS=604800000
ADMIN_DIAGNOSTICS_TOKEN=replace-with-random-long-token
# Week 4 tuning + setup control policy knobs
TRADE_TUNING_OOS_MIN_DECISIONS=20
TRADE_TUNING_OOS_MIN_EDGE_PCT=0
TRADE_TUNING_OOS_MIN_EXPECTANCY_USD=0
TRADE_TUNING_OOS_MAX_BLOCK_RATE_PCT=80
TRADE_TUNING_OOS_MAX_EDGE_DECAY_PCT=0.12
TRADE_SETUP_AUTO_DISABLE_ENABLED=true
TRADE_SETUP_DISABLE_MIN_TRADES=12
TRADE_SETUP_DISABLE_EXPECTANCY_USD=0
TRADE_SETUP_DISABLE_LOOKBACK_TRADES=200
TRADE_SETUP_DISABLE_COOLDOWN_HOURS=24
TRADE_SETUP_HISTORY_MAX_ENTRIES=500
SUPABASE_PERSIST_SETUP_CONTROL_EVENTS=falseWhen NODE_ENV=production, startup now validates required production secrets.
If you want production to hard-require real Binance/Supabase credentials, set REQUIRE_LIVE_CREDENTIALS=true.
Binance:
- Go to https://www.binance.com
- Account → API Management
- Create new API key
- Enable futures trading if needed
Claude API:
- Go to https://console.anthropic.com
- Create account or sign in
- Generate API key
Telegram Bot:
- Open @BotFather on Telegram
- Send
/newbot - Follow instructions
- Copy the bot token
Supabase:
- Go to https://supabase.com
- Create new project
- Project Settings → API
- Copy URL and anon key
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3001
CMD ["npm", "start"]For backend/server usage, prefer SUPABASE_SERVICE_KEY (the server falls back to SUPABASE_ANON_KEY only when service key is missing).
For frontend/browser usage, use SUPABASE_ANON_KEY only. Never expose SUPABASE_SERVICE_KEY in browser settings/localStorage.
Run this idempotent SQL in Supabase SQL Editor:
-- Users table
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
username TEXT,
password TEXT NOT NULL,
settings JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Sessions table (required for durable auth/session expiry across restarts)
CREATE TABLE IF NOT EXISTS sessions (
token TEXT PRIMARY KEY,
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ DEFAULT NOW(),
last_seen_at TIMESTAMPTZ DEFAULT NOW()
);
-- Trades table
CREATE TABLE IF NOT EXISTS trades (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
symbol TEXT NOT NULL,
side TEXT NOT NULL,
entry_price DECIMAL,
exit_price DECIMAL,
quantity DECIMAL,
pnl DECIMAL,
mode TEXT DEFAULT 'paper',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Positions table
CREATE TABLE IF NOT EXISTS positions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
symbol TEXT NOT NULL,
side TEXT NOT NULL,
entry_price DECIMAL NOT NULL,
quantity DECIMAL,
mode TEXT DEFAULT 'paper',
opened_at TIMESTAMPTZ DEFAULT NOW()
);
-- Alerts table
CREATE TABLE IF NOT EXISTS alerts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
symbol TEXT NOT NULL,
condition TEXT NOT NULL,
target_price DECIMAL NOT NULL,
active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Settings table
CREATE TABLE IF NOT EXISTS settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
key TEXT NOT NULL,
value JSONB,
UNIQUE(user_id, key)
);
-- Trade decision telemetry (optional but recommended for rolling analytics persistence)
CREATE TABLE IF NOT EXISTS trade_decisions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
timestamp TIMESTAMPTZ DEFAULT NOW(),
expected_value_pct DECIMAL,
confidence DECIMAL,
regime TEXT,
blocked BOOLEAN DEFAULT false,
reasons JSONB DEFAULT '[]'::jsonb
);
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_trades_user_id ON trades(user_id);
CREATE INDEX IF NOT EXISTS idx_positions_user_id ON positions(user_id);
CREATE INDEX IF NOT EXISTS idx_alerts_user_id ON alerts(user_id);
CREATE INDEX IF NOT EXISTS idx_settings_user_id ON settings(user_id);
CREATE INDEX IF NOT EXISTS idx_trade_decisions_user_id_ts ON trade_decisions(user_id, timestamp DESC);
-- Enable RLS
ALTER TABLE trades ENABLE ROW LEVEL SECURITY;
ALTER TABLE positions ENABLE ROW LEVEL SECURITY;
ALTER TABLE alerts ENABLE ROW LEVEL SECURITY;
ALTER TABLE settings ENABLE ROW LEVEL SECURITY;
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE trade_decisions ENABLE ROW LEVEL SECURITY;
-- RLS Policies
DROP POLICY IF EXISTS "Users can view own trades" ON trades;
DROP POLICY IF EXISTS "Users can insert own trades" ON trades;
CREATE POLICY "Users can view own trades" ON trades FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own trades" ON trades FOR INSERT WITH CHECK (auth.uid() = user_id);
DROP POLICY IF EXISTS "Users can view own trade decisions" ON trade_decisions;
DROP POLICY IF EXISTS "Users can insert own trade decisions" ON trade_decisions;
CREATE POLICY "Users can view own trade decisions" ON trade_decisions FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "Users can insert own trade decisions" ON trade_decisions FOR INSERT WITH CHECK (auth.uid() = user_id);
-- Optional: richer UPDATE/DELETE event payloads for Supabase Realtime subscribers
ALTER TABLE trades REPLICA IDENTITY FULL;
ALTER TABLE positions REPLICA IDENTITY FULL;
ALTER TABLE setup_control_events REPLICA IDENTITY FULL;Optional Supabase Realtime setup (UX sync only):
- In Supabase Dashboard -> Database -> Replication, enable
trades,positions, andsetup_control_events. - Keep market feed on backend/exchange WebSocket (
/ws); do not move price stream to Supabase Realtime. - In frontend settings, set
supabase_url,supabase_key(anon key), andbackend_auth_tokenso user-scoped Realtime filtering works.
- Set
SUPABASE_URLandSUPABASE_SERVICE_KEYin backend.env. - Restart backend and call
GET /api/supabase/status. - Register a user, then verify rows exist in
usersandsessions. - Call authenticated
GET /api/users/me; verifysessions.last_seen_atupdates. - Call
POST /api/users/logout; verify session row is removed. - Temporarily stop/start backend and confirm the token still works until timeout/logout.
- Every HTTP response includes
X-Request-Id - Send your own
X-Request-Idheader to preserve trace correlation from client to server logs - Request logs automatically redact sensitive query keys such as token/secret/password/api_key
- Set
REQUEST_LOG_ENABLED=falseto disable request logging - Set
REQUEST_LOG_FORMAT=jsonfor structured logs (default:text)
- Global API limiter:
RATE_LIMIT_WINDOW,RATE_LIMIT_MAX - Auth endpoints limiter:
AUTH_RATE_LIMIT_WINDOW_MS,AUTH_RATE_LIMIT_MAX - AI analysis limiter:
AI_RATE_LIMIT_WINDOW_MS,AI_RATE_LIMIT_MAX - Telegram send limiter:
TELEGRAM_RATE_LIMIT_WINDOW_MS,TELEGRAM_RATE_LIMIT_MAX - Performance analytics limiter (rolling/expectancy/tuning/kpis/regime/control-loop):
PERF_RATE_LIMIT_WINDOW_MS(default 60000),PERF_RATE_LIMIT_MAX(default 60) - WebSocket abuse guard:
WS_MAX_CONNECTIONS_PER_IP,WS_MESSAGE_WINDOW_MS,WS_MAX_MESSAGES_PER_WINDOW
- Idle session timeout (ms):
SESSION_IDLE_TIMEOUT_MS(default 86400000) - Absolute session timeout (ms):
SESSION_ABSOLUTE_TIMEOUT_MS(default 604800000)
- Minimum confidence gate:
TRADE_MIN_CONFIDENCE - Maximum spread gate (bps):
TRADE_MAX_SPREAD_BPS - Maximum slippage gate (bps):
TRADE_MAX_SLIPPAGE_BPS - Minimum liquidity gate (USD):
TRADE_MIN_LIQUIDITY_USD - Portfolio notional cap (USD):
TRADE_MAX_PORTFOLIO_NOTIONAL_USD - Per-symbol exposure cap (USD):
TRADE_MAX_SYMBOL_EXPOSURE_USD - Telemetry retention window (days):
TELEMETRY_RETENTION_DAYS
- Endpoint:
GET /health - Expected response includes
status,timestamp,uptime, andbinancestate - Use request id from response headers for rapid log lookup during incident triage
- On boot, the server logs
PERSISTENCEmode as one of:Supabase persistence enabled (service key)Supabase persistence enabled (anon key fallback)Memory fallback (Supabase config invalid)Memory fallback (Supabase not configured)
- A warning is emitted when anon-key fallback or invalid partial Supabase config is detected.
- Admin runtime diagnostics endpoint:
GET /api/admin/diagnostics - Requires
Authorization: Bearer <ADMIN_DIAGNOSTICS_TOKEN> - Returns timestamp, uptime, persistence mode/report, binance connectivity, operational readiness (
healthyordegradedwith reasons), and effective session policy values.
- Check if port 3001 is available
- Verify firewall settings
- Try refreshing the page
- Check browser console for details
- Verify environment variables
- Ensure CORS is configured correctly
- Check network tab for failed requests
- Verify Binance API is accessible
- Try clearing IndexedDB cache
MIT License - Use at your own risk. This is not financial advice.
NEXUS PRO is for educational and informational purposes only. Cryptocurrency trading involves significant risk. Past performance does not guarantee future results. Always do your own research and never invest more than you can afford to lose.