# CoinEx Dashboard Scoring Fix + Trader Features **Priority:** HIGH **Assigned:** Glitch **Date:** 2026-03-06 --- ## 1. BUG FIX: TA Score Integration (Dashboard) **Project:** `projects/coinex-dashboard/` ### Problem - `composite_score` from TA service is directional: positive = bullish, negative = bearish - Dashboard (`app/page.tsx` lines ~608-609, ~646-647) blindly adds `taScore` to BOTH long and short scores - `isLongSignal` and `isShortSignal` in `scanner.ts` (line 284-285) use base scores only — TA is ignored for threshold checks - Result: scores displayed to user are wrong, and signal triggers don't account for TA ### Fix **Frontend (`app/page.tsx`):** - Long total = `base + max(0, taScore)` — only add TA when composite is positive (bullish) - Short total = `base + max(0, abs(taScore))` when taScore < 0 — only add TA when composite is negative (bearish) - Display should show: `Base: X | TA: +Y | Total: Z` where Y is the directional contribution (or 0/hidden if TA doesn't help that direction) **Scanner (`lib/server/scanner.ts`):** - `isLongSignal` should use: `longScore.total + max(0, taScore) >= long_threshold` - `isShortSignal` should use: `shortScore.total + (taScore < 0 ? abs(taScore) : 0) >= short_threshold` - Add `combinedLongScore` and `combinedShortScore` to `CoinData` type so frontend and signal history use the correct totals **Types (`lib/types.ts`):** - Add `combinedLongScore?: number` and `combinedShortScore?: number` to `CoinData` ### TA composite_score reference - Redis key: `ta:latest:{SYMBOL}` (no USDT suffix) - `composite_score`: integer, range roughly -100 to +100 - Positive = bullish signal, negative = bearish signal - Example: BTC composite_score = -25 means bearish → adds 25 to short score, 0 to long score --- ## 2. FEATURE: Trade Confirmation Page (Dashboard) **Project:** `projects/coinex-dashboard/` (UI) + `projects/crypto-signals/scripts/coinex_live_trader.py` (bot) ### Concept When the trader bot identifies a trade to execute, it does NOT execute immediately. Instead: 1. Bot writes a **pending trade** to a JSON file or Redis key 2. Dashboard shows pending trades on the `/trader` page (or new `/confirm` page) 3. Each pending trade shows: - Symbol, direction (LONG/SHORT), recommended leverage - Base score breakdown (RSI, VWAP, Change, BB) - TA score breakdown (EMA ribbons, TTM squeeze, StochRSI) - Combined total score - Position size ($ amount, % of equity) - TP/SL targets - Timestamp of signal 4. D J clicks **Approve** or **Reject** 5. Bot polls for approval status, executes only approved trades 6. Rejected trades are logged with reason (optional) 7. Pending trades expire after a configurable timeout (e.g. 15 minutes) — auto-rejected if not confirmed ### Data Flow ``` Bot detects signal → writes pending_trades.json → Dashboard reads & displays → D J approves/rejects → Bot reads approval → executes or skips ``` ### Pending trade schema ```json { "id": "uuid", "symbol": "BTCUSDT", "direction": "long", "leverage": 5, "position_size_usdt": 6.64, "position_size_pct": 5, "entry_price": 68100.00, "tp_price": 71505.00, "sl_price": 66057.00, "scores": { "base_long": 35, "base_short": 0, "ta_composite": -25, "combined_long": 35, "combined_short": 25 }, "indicators": { "rsi": 42.3, "vwap_pct": -1.2, "change_24h": -3.5, "bb_pos": 0.15, "ema_state": "mixed", "ttm_squeeze": false, "stochrsi_k": 33.97 }, "created_at": "2026-03-06T21:15:00Z", "expires_at": "2026-03-06T21:30:00Z", "status": "pending", "approved_at": null, "rejected_at": null } ``` ### File locations - Pending trades: `projects/crypto-signals/data/coinex-live/pending_trades.json` - Approval is done by updating `status` field to `"approved"` or `"rejected"` ### Dashboard API routes needed - `GET /api/trader/pending` — list pending trades - `POST /api/trader/pending/[id]/approve` — approve a trade - `POST /api/trader/pending/[id]/reject` — reject a trade ### Bot changes (`coinex_live_trader.py`) - When signal detected: write to `pending_trades.json` instead of executing - New polling loop: check for approved trades, execute them - Handle expired trades: auto-reject after timeout - Keep existing dry-run mode working (dry-run can skip confirmation) --- ## 3. FEATURE: Exchange-Side TP/SL Orders (Trader Bot) **Project:** `projects/crypto-signals/scripts/coinex_live_trader.py` ### Concept After opening a position, immediately place TP and SL orders on CoinEx so the exchange handles exits — not our polling bot. ### Current behavior (bad) - Bot opens position - Bot polls every 5 minutes checking if price hit TP/SL - If bot is down, positions have NO protection - 5-minute gaps between checks = missed exits ### New behavior (good) - Bot opens position - Bot immediately places: - **Take Profit order** at TP price (limit or market trigger) - **Stop Loss order** at SL price (market trigger) - Bot polls CoinEx for **position status changes** (open → closed) - When position closes (TP/SL hit, or manual close), bot logs it and cleans up - If one side fills (e.g. TP hit), cancel the other side (SL) ### CoinEx API endpoints needed - `POST /v2/futures/order` with `order_type` for stop/take-profit orders - Or use CoinEx conditional order / trigger order API - Research: Check CoinEx API docs for `stop_loss_price` / `take_profit_price` fields on position or order creation ### Key requirements - TP/SL orders placed within same API call or immediately after position opens - If TP/SL placement fails, alert via Telegram and log error (don't leave position unprotected) - Bot should verify TP/SL orders exist on each polling cycle - When position closes, cancel remaining open TP/SL orders - Trailing stop: if supported by CoinEx API, use it; otherwise keep current trailing logic as supplement ### Polling changes - Instead of checking price vs TP/SL, check: - Are my positions still open? - Did any TP/SL orders fill? - Log the exit reason (TP hit, SL hit, manual close, liquidation) --- ## Testing Requirements ### Scoring fix - Verify BTC with composite_score=-25: long shows +0 TA, short shows +25 TA - Verify a coin with positive composite_score: long shows +X TA, short shows +0 - Verify signal thresholds use combined scores - Verify signal history records correct combined scores ### Trade confirmation - Create a mock pending trade, verify it displays on dashboard - Approve it, verify bot executes - Reject it, verify bot skips - Let one expire, verify auto-rejection - Test with dry-run mode (should skip confirmation) ### Exchange-side TP/SL - Open a position in dry-run, verify TP/SL order placement API calls are logged - Verify cancellation of remaining order when one side fills - Verify Telegram alert if TP/SL placement fails - Test: what happens if CoinEx doesn't support the order type we need? --- ## File References - Dashboard: `projects/coinex-dashboard/` - Indicators: `projects/coinex-dashboard/lib/indicators.ts` (DO NOT MODIFY scoring functions) - Scanner: `projects/coinex-dashboard/lib/server/scanner.ts` - Frontend: `projects/coinex-dashboard/app/page.tsx` - Types: `projects/coinex-dashboard/lib/types.ts` - Trader bot: `projects/crypto-signals/scripts/coinex_live_trader.py` - Trader config: `projects/crypto-signals/data/coinex-live/trader_config.json` - TA service: `workspace-glitch/projects/coinex-ta-service/` - CoinEx credentials: `.credentials/coinex.env`