Full sync - all projects, memory, configs
This commit is contained in:
78
data/tasks/coinex-dashboard-rebuild.md
Normal file
78
data/tasks/coinex-dashboard-rebuild.md
Normal file
@ -0,0 +1,78 @@
|
||||
# CoinEx Futures Dashboard — Rebuild in Next.js
|
||||
|
||||
**Priority:** HIGH
|
||||
**Assigned:** Glitch (build) → Hawk (review)
|
||||
**Created:** 2026-02-26
|
||||
**Port:** 8891 (same as current)
|
||||
|
||||
## Overview
|
||||
Rebuild the CoinEx Futures Scanner dashboard from plain HTML into the standard stack.
|
||||
|
||||
## Stack (MANDATORY)
|
||||
- **Next.js 15** (App Router)
|
||||
- **Tailwind CSS v4**
|
||||
- **Framer Motion** (animations)
|
||||
- **ShadCN UI** (component library)
|
||||
- **Lucide Icons**
|
||||
- **TypeScript** throughout
|
||||
- **SSE or WebSockets** for real-time data (no third-party backend — we handle it ourselves)
|
||||
- **NO Convex**
|
||||
|
||||
## Current Dashboard Features (must replicate)
|
||||
The existing dashboard at `projects/crypto-signals/dashboard/index.html` (433 lines) has:
|
||||
|
||||
### Header
|
||||
- Title: "⚡ CoinEx Futures Scanner"
|
||||
- Live indicator, last scan timestamp, auto-refresh countdown (30s)
|
||||
|
||||
### Controls
|
||||
- Sort: Long Score, Short Score, Name, 24h Change, RSI
|
||||
- Filter: All Coins, Long Signals Only, Short Signals Only, Any Signal
|
||||
|
||||
### Summary Bar
|
||||
- Coin count, Long signals count, Short signals count, Average RSI
|
||||
|
||||
### Thresholds Display
|
||||
- LONG threshold: 45 pts, SHORT threshold: 50 pts
|
||||
- TP: +5%, SL: -3%
|
||||
- Leverage: 5x / 7x (score≥60)
|
||||
|
||||
### Coin Cards (grid layout, responsive)
|
||||
Each card shows:
|
||||
- Coin name + signal badges (LONG ✓ / SHORT ✓)
|
||||
- Price + 24h change %
|
||||
- 4 indicator boxes: RSI (14) with gauge, VWAP %, 24h Change, BB Position
|
||||
- Each indicator shows Long/Short point contributions
|
||||
- Score bars for LONG and SHORT with threshold markers
|
||||
- Signal badge with direction + leverage
|
||||
|
||||
### Data Source
|
||||
- Binance US API: `https://api.binance.us/api/v3/klines?symbol=${symbol}&interval=1h&limit=100`
|
||||
- 29 coins: BTC, ETH, SOL, XRP, DOGE, ADA, AVAX, LINK, DOT, MATIC, NEAR, ATOM, LTC, UNI, AAVE, FIL, ALGO, XLM, VET, ICP, APT, SUI, ARB, OP, SEI, HYPE, TRUMP, PUMP, ASTER
|
||||
- All client-side calculated: RSI(14), VWAP(24h), Bollinger Bands(20), scoring
|
||||
|
||||
### Scoring System
|
||||
- **Long score** (max 80): RSI(<25=30, <30=25, <35=15, <40=5) + VWAP(<-3%=20, <-1.5%=15, <0=8) + 24hChange(<-10%=15, <-5%=10, <-2%=5) + BB(<0=15, <0.2=10)
|
||||
- **Short score** (max 80): RSI(>75=30, >70=25, >65=15, >60=5) + VWAP(>3%=20, >1.5%=15, >0=8) + 24hChange(>10%=15, >5%=10, >2%=5) + BB(>1=15, >0.8=10)
|
||||
|
||||
## Enhancements for v2
|
||||
1. **Dark theme** (keep the current dark aesthetic — bg #0a0e17 / #111827)
|
||||
2. **Animated transitions** with Framer Motion when data updates
|
||||
3. **Mobile responsive** — card grid should work on phone
|
||||
4. **SSE endpoint** for real-time price updates instead of polling from client
|
||||
5. **Live positions panel** — read from `projects/crypto-signals/data/coinex-live/trader_state.json` to show current open positions with P&L
|
||||
6. **Trade history** — read from `projects/crypto-signals/data/coinex-live/trade_log.json`
|
||||
|
||||
## Project Location
|
||||
`projects/coinex-dashboard/` (new directory, clean Next.js project)
|
||||
|
||||
## Systemd
|
||||
Create `~/.config/systemd/user/coinex-dashboard.service` on port 8891.
|
||||
Kill the old Python server first (pid of old `server.py`).
|
||||
|
||||
## Context7
|
||||
Use Context7 for Next.js 15, Tailwind v4, ShadCN UI, and Framer Motion docs before writing any code.
|
||||
|
||||
## Tests
|
||||
- Unit tests for scoring functions
|
||||
- E2E smoke test that the page loads and renders coin cards
|
||||
290
data/tasks/coinex-platform-v3.md
Normal file
290
data/tasks/coinex-platform-v3.md
Normal file
@ -0,0 +1,290 @@
|
||||
# CoinEx Trading Platform v3 — Unified Architecture
|
||||
|
||||
**Created:** 2026-03-01
|
||||
**Owner:** Case (CSO)
|
||||
**Priority:** HIGH
|
||||
**Environment:** DEV (all services on 192.168.86.45)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Unify the CoinEx trading ecosystem under a Redis-backed message bus. Four pieces:
|
||||
|
||||
1. **Redis** — Message bus + shared state + cache
|
||||
2. **TA Service** — Technical Analysis engine (EMA Ribbons, Stoch RSI Divergence, TTM Squeeze)
|
||||
3. **Dashboard Integration** — Subscribe to Redis instead of polling Binance directly
|
||||
4. **Trader Bot Integration** — Subscribe to TA signals + publish state to Redis
|
||||
|
||||
All deployed as DEV instances on 192.168.86.45 with `-dev` suffixed service names and separate ports.
|
||||
|
||||
---
|
||||
|
||||
## Piece 1: Redis Setup
|
||||
|
||||
**Install:** `apt install redis-server` (or Docker)
|
||||
**Port:** 6379 (default)
|
||||
**Config:** `bind 127.0.0.1` (local only), no auth needed for dev
|
||||
**Service:** systemd `redis-server`
|
||||
|
||||
### Channel/Key Schema
|
||||
|
||||
```
|
||||
# Pub/Sub Channels
|
||||
market:candles:{symbol} # OHLCV candle updates (published by Market Data fetcher)
|
||||
signals:ta:{symbol} # TA indicator signals (published by TA Service)
|
||||
signals:scan # Composite scan results (published by Dashboard scanner)
|
||||
trader:events # Trade events, position changes (published by Trader Bot)
|
||||
|
||||
# Key/Value State (GET/SET)
|
||||
cache:candles:{symbol} # Latest candle data (JSON, TTL 60s)
|
||||
cache:candles:{symbol}:1h # 1h candles for TA (JSON, TTL 300s)
|
||||
cache:candles:{symbol}:4h # 4h candles for TA (JSON, TTL 600s)
|
||||
state:positions # Current CoinEx positions (JSON)
|
||||
state:balance # Current CoinEx balance (JSON)
|
||||
state:trader:config # Trader runtime config (JSON)
|
||||
state:trader:status # Trader status: enabled/disabled/locked (JSON)
|
||||
ta:latest:{symbol} # Latest TA result per symbol (JSON, TTL 120s)
|
||||
```
|
||||
|
||||
### Market Data Fetcher (embedded in TA Service)
|
||||
- Single point of contact for Binance API
|
||||
- Fetches 5m, 1h, 4h candles for all 29 coins
|
||||
- Publishes to `market:candles:{symbol}` channel
|
||||
- Caches in `cache:candles:{symbol}:{timeframe}` keys with TTL
|
||||
- Runs on 30s loop (5m candles) and 5min loop (1h/4h candles)
|
||||
|
||||
---
|
||||
|
||||
## Piece 2: TA Service
|
||||
|
||||
**Language:** Python 3.12
|
||||
**Dependencies:** `redis`, `pandas`, `pandas-ta`, `numpy`
|
||||
**Port:** 8894 (health check only)
|
||||
**Repo:** `git.letsgetnashty.com/case/coinex-ta-service` (private)
|
||||
**Service:** `coinex-ta-dev.service`
|
||||
|
||||
### Indicators
|
||||
|
||||
#### EMA Ribbons (8/13/21/34/55/89)
|
||||
- Calculated on 5m and 1h timeframes
|
||||
- Output state: `bullish` (all stacked ascending), `bearish` (all stacked descending), `mixed`
|
||||
- Output ribbon spread: normalized 0-100 (tight = low conviction, wide = strong trend)
|
||||
- Score contribution: +10 to long/short score when aligned with direction
|
||||
|
||||
#### TTM Squeeze
|
||||
- Bollinger Bands (20, 2.0) vs Keltner Channels (20, 1.5)
|
||||
- Squeeze ON: BB inside KC (volatility compression)
|
||||
- Squeeze OFF: BB outside KC (expansion beginning)
|
||||
- Momentum histogram: positive = bullish, negative = bearish
|
||||
- Output: `{ squeeze: bool, momentum: float, direction: 'bullish'|'bearish', bars_in_squeeze: int }`
|
||||
- Score contribution: +15 when squeeze fires in signal direction
|
||||
|
||||
#### Stochastic RSI Divergence
|
||||
- Stoch RSI (14, 14, 3, 3)
|
||||
- Detect bullish divergence: price makes lower low, Stoch RSI makes higher low
|
||||
- Detect bearish divergence: price makes higher high, Stoch RSI makes lower high
|
||||
- Lookback window: 50 candles for swing detection
|
||||
- Use `pandas-ta` for Stoch RSI calculation, custom swing detection for divergence
|
||||
- Output: `{ divergence: 'bullish'|'bearish'|'none', strength: float, candles_ago: int }`
|
||||
- Score contribution: +20 for divergence aligned with signal direction
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
Binance API (OHLCV)
|
||||
│
|
||||
▼
|
||||
TA Service
|
||||
├── fetch candles (5m, 1h, 4h) for 29 coins
|
||||
├── cache in Redis (cache:candles:*)
|
||||
├── compute indicators
|
||||
├── publish to Redis (signals:ta:{symbol})
|
||||
└── store latest in Redis (ta:latest:{symbol})
|
||||
```
|
||||
|
||||
### Output Schema (per symbol)
|
||||
|
||||
```json
|
||||
{
|
||||
"symbol": "BTCUSDT",
|
||||
"timestamp": "2026-03-01T12:00:00Z",
|
||||
"ema_ribbon": {
|
||||
"state_5m": "bullish",
|
||||
"state_1h": "bullish",
|
||||
"spread_5m": 72.5,
|
||||
"spread_1h": 85.3,
|
||||
"values": [67200, 67150, 67050, 66900, 66700, 66400]
|
||||
},
|
||||
"ttm_squeeze": {
|
||||
"squeeze": true,
|
||||
"momentum": 0.45,
|
||||
"direction": "bullish",
|
||||
"bars_in_squeeze": 8,
|
||||
"timeframe": "5m"
|
||||
},
|
||||
"stoch_rsi_divergence": {
|
||||
"divergence": "none",
|
||||
"strength": 0,
|
||||
"candles_ago": 0,
|
||||
"stoch_k": 45.2,
|
||||
"stoch_d": 42.1
|
||||
},
|
||||
"composite_score_adjustment": {
|
||||
"long_bonus": 25,
|
||||
"short_bonus": 0,
|
||||
"reasoning": ["EMA ribbon bullish aligned (+10)", "TTM squeeze bullish (+15)"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Scan Loop
|
||||
- Every 30 seconds: fetch 5m candles, compute all indicators, publish
|
||||
- Every 5 minutes: fetch 1h and 4h candles, update longer-term EMA ribbons
|
||||
- Health check: `GET /health` returns status + last scan time
|
||||
|
||||
---
|
||||
|
||||
## Piece 3: Dashboard Integration (DEV)
|
||||
|
||||
**Branch:** `feature/redis-integration` on `coinex-dashboard` repo
|
||||
**Dev Port:** 8892
|
||||
**Dev Service:** `coinex-dashboard-dev.service`
|
||||
|
||||
### Changes
|
||||
|
||||
1. **Subscribe to Redis channels:**
|
||||
- `signals:ta:*` — receive TA indicator updates
|
||||
- `trader:events` — receive trade events
|
||||
|
||||
2. **Read from Redis keys instead of direct API:**
|
||||
- `state:positions` and `state:balance` instead of CoinEx API calls
|
||||
- `cache:candles:{symbol}` instead of Binance API calls
|
||||
- `ta:latest:{symbol}` for indicator data
|
||||
|
||||
3. **Keep existing Binance fetch as fallback** if Redis is unavailable
|
||||
|
||||
4. **New UI elements per coin card:**
|
||||
- EMA Ribbon indicator: colored bar (green/red/yellow) with spread %
|
||||
- TTM Squeeze: dot indicator (red = squeeze on, green = squeeze fired, gray = no squeeze)
|
||||
- Stoch RSI Divergence: alert badge when divergence detected
|
||||
- Composite score now includes TA bonus points (displayed separately)
|
||||
|
||||
5. **WebSocket payload additions:**
|
||||
```json
|
||||
{
|
||||
"coinData": [...],
|
||||
"positions": {...},
|
||||
"signalHistory": [...],
|
||||
"taSignals": {
|
||||
"BTCUSDT": { "ema_ribbon": {...}, "ttm_squeeze": {...}, "stoch_rsi_divergence": {...} },
|
||||
...
|
||||
},
|
||||
"errors": [...]
|
||||
}
|
||||
```
|
||||
|
||||
6. **New tooltips:**
|
||||
- EMA Ribbon: "EMA Ribbon (8/13/21/34/55/89). Green = all EMAs stacked bullish. Red = bearish. Yellow = mixed."
|
||||
- TTM Squeeze: "TTM Squeeze. Red dot = volatility compression (coiled spring). Green dot = squeeze just fired. Direction shown by momentum."
|
||||
- Stoch RSI Div: "Stochastic RSI Divergence. Bullish divergence = price falling but momentum rising (reversal signal)."
|
||||
|
||||
### Scoring Integration
|
||||
- Display original score + TA bonus separately: `45 + 25 = 70`
|
||||
- TA bonus is informational in v1 — does NOT feed into trader bot decisions yet
|
||||
- Dashboard shows combined view, trader still uses original scoring until validated
|
||||
|
||||
---
|
||||
|
||||
## Piece 4: Trader Bot Integration (DEV)
|
||||
|
||||
**Branch:** `feature/redis-integration` on `coinex-trader` repo
|
||||
**Dev Service:** `coinex-trader-dev.timer` (every 5min)
|
||||
|
||||
### Changes
|
||||
|
||||
1. **Publish to Redis on every cycle:**
|
||||
- `state:positions` — current positions from CoinEx API
|
||||
- `state:balance` — current balance
|
||||
- `trader:events` — trade opens, closes, TP/SL hits, errors
|
||||
|
||||
2. **Read TA signals from Redis (OPTIONAL, off by default):**
|
||||
- Config flag: `use_ta_signals: false` (disabled until backtested)
|
||||
- When enabled: read `ta:latest:{symbol}` and add TA bonus to scoring
|
||||
- Safety: TA bonus capped at +30 max (can't override a bad base score)
|
||||
|
||||
3. **Publish trader status:**
|
||||
- `state:trader:status` — enabled/disabled/locked, uptime, last trade
|
||||
- `state:trader:config` — current config (thresholds, TP/SL, leverage)
|
||||
|
||||
4. **Keep all existing logic as-is.** Redis is additive — if Redis is down, trader operates exactly as before.
|
||||
|
||||
---
|
||||
|
||||
## Dev Environment Ports
|
||||
|
||||
| Service | Port | Systemd Service |
|
||||
|---------|------|-----------------|
|
||||
| Redis | 6379 | redis-server (system) |
|
||||
| TA Service | 8894 | coinex-ta-dev.service |
|
||||
| Dashboard (dev) | 8892 | coinex-dashboard-dev.service |
|
||||
| Dashboard (prod) | 8891 | coinex-dashboard.service |
|
||||
| Trader Bot (dev) | — | coinex-trader-dev.timer |
|
||||
| Trader Bot (prod) | — | coinex-live-trader.timer |
|
||||
| Trader API (dev) | 8895 | coinex-trader-api-dev.service |
|
||||
|
||||
**Dev services do NOT interfere with prod.** Separate ports, separate service names, separate config files.
|
||||
|
||||
---
|
||||
|
||||
## Git Repos
|
||||
|
||||
| Repo | URL | Branch |
|
||||
|------|-----|--------|
|
||||
| TA Service | `git.letsgetnashty.com/case/coinex-ta-service` | `main` |
|
||||
| Dashboard | `git.letsgetnashty.com/case/coinex-dashboard` | `feature/redis-integration` |
|
||||
| Trader Bot | `git.letsgetnashty.com/case/coinex-trader` | `feature/redis-integration` |
|
||||
|
||||
---
|
||||
|
||||
## Pipeline
|
||||
|
||||
### Phase 1: Foundation (Glitch)
|
||||
1. Install Redis on VM
|
||||
2. Build TA Service (Python, all 3 indicators, Redis pub/sub)
|
||||
3. Unit tests for each indicator against known data
|
||||
4. Health check endpoint
|
||||
5. Gitea repo + systemd dev service
|
||||
|
||||
### Phase 2: Dashboard Integration (Glitch)
|
||||
1. Add Redis subscriber to dashboard scanner
|
||||
2. New UI components for TA indicators
|
||||
3. Merge TA data into WebSocket payload
|
||||
4. Tooltips for new indicators
|
||||
5. Dev service on port 8892
|
||||
|
||||
### Phase 3: Trader Integration (Glitch)
|
||||
1. Trader publishes state to Redis
|
||||
2. Read TA signals (disabled by default)
|
||||
3. Config flag for TA integration
|
||||
4. Dev timer service
|
||||
|
||||
### Phase 4: QA
|
||||
- **Hawk:** Code review all three pieces
|
||||
- **Jinx:** Functional — verify Redis pub/sub works, TA calculations are correct, dashboard displays data, trader publishes state
|
||||
- **Pixel:** Visual — new indicator displays, tooltips, layout doesn't break
|
||||
|
||||
### Phase 5: Deploy Dev
|
||||
- **Forge:** systemd services, verify all dev instances running, no interference with prod
|
||||
|
||||
---
|
||||
|
||||
## Constraints
|
||||
|
||||
- **Dev ONLY** — no changes to production services until validated
|
||||
- **Redis local only** — bind 127.0.0.1, no external access
|
||||
- **TA bonus is display-only** — does not affect trader decisions until backtested
|
||||
- **Trader safety unchanged** — all kill switches, circuit breakers, lockfiles preserved
|
||||
- **Binance API rate limits** — TA service is the ONLY Binance fetcher in the new architecture. Dashboard reads from Redis cache.
|
||||
- **29 coins** — same list as current scanner
|
||||
- **All scoring logic in `lib/indicators.ts` preserved exactly** — TA bonus is additive, shown separately
|
||||
197
data/tasks/coinex-scoring-fix-and-features.md
Normal file
197
data/tasks/coinex-scoring-fix-and-features.md
Normal file
@ -0,0 +1,197 @@
|
||||
# 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`
|
||||
169
data/tasks/coinex-upgrades-v2.md
Normal file
169
data/tasks/coinex-upgrades-v2.md
Normal file
@ -0,0 +1,169 @@
|
||||
# CoinEx Upgrades v2 — Task Spec
|
||||
|
||||
**Created:** 2026-02-27
|
||||
**Owner:** Case (CSO)
|
||||
**Priority:** HIGH
|
||||
|
||||
---
|
||||
|
||||
## Project A: CoinEx Futures Trading Bot — API + Config + Docker
|
||||
|
||||
**Repo:** `git.letsgetnashty.com/case/coinex-trader` (NEW private repo, branch: `feature/api`)
|
||||
**Source:** `projects/crypto-signals/scripts/coinex_live_trader.py` (1,047 lines)
|
||||
**Stack:** Python 3 + FastAPI + Uvicorn + Swagger (auto-generated)
|
||||
|
||||
### Current Hardcoded Config
|
||||
```python
|
||||
POSITION_SIZE_PCT = 5.0 # 5% equity per trade
|
||||
MAX_LEVERAGE = 10 # Cap leverage at 10x
|
||||
TP_PCT = 5.0 # Take profit at 5% on margin
|
||||
SL_PCT = -3.0 # Stop loss at -3% on margin
|
||||
KILL_SWITCH_DRAWDOWN = 0.50 # 50% drawdown kill switch
|
||||
# Max positions: not explicitly set (implicit max 3)
|
||||
# Thresholds: defined in scanner, not trader
|
||||
```
|
||||
|
||||
### Requirements
|
||||
|
||||
#### 1. FastAPI REST API (with Swagger at /docs)
|
||||
All endpoints prefixed `/api/v1/`
|
||||
|
||||
**Config endpoints:**
|
||||
- `GET /config` — return all current config
|
||||
- `PATCH /config` — partial update config (validates ranges)
|
||||
- `POST /config/reset` — reset to defaults
|
||||
|
||||
**Config flags (all runtime-mutable):**
|
||||
```json
|
||||
{
|
||||
"enabled": true, // global on/off toggle
|
||||
"max_positions": 3,
|
||||
"long_threshold": 55, // score threshold to enter long
|
||||
"short_threshold": 55, // score threshold to enter short
|
||||
"tp_pct": 5.0, // take profit %
|
||||
"sl_pct": 3.0, // stop loss % (stored positive, applied negative)
|
||||
"position_size_pct": 5.0, // % of equity per trade
|
||||
"max_leverage": 10,
|
||||
"leverage_rules": { // leverage by score bracket
|
||||
"60+": 7,
|
||||
"default": 5
|
||||
},
|
||||
"kill_switch_drawdown": 0.50,
|
||||
"trailing_stop": true
|
||||
}
|
||||
```
|
||||
|
||||
**Account/credentials endpoints:**
|
||||
- `GET /account` — return balance, equity, margin info (from CoinEx API)
|
||||
- `GET /account/config` — return configured API key ID (masked), base URL
|
||||
- `PUT /account/config` — update CoinEx API credentials at runtime
|
||||
|
||||
**Position endpoints:**
|
||||
- `GET /positions` — current open positions from CoinEx
|
||||
- `POST /positions/{market}/close` — manually close a position
|
||||
|
||||
**Status endpoints:**
|
||||
- `GET /status` — bot status (enabled/disabled, uptime, last scan time, lockfile status)
|
||||
- `POST /status/enable` — enable trading
|
||||
- `POST /status/disable` — disable trading (graceful, doesn't close positions)
|
||||
- `DELETE /status/lockfile` — clear lockfile (same as manual delete)
|
||||
|
||||
**Log endpoints:**
|
||||
- `GET /logs` — return recent logs (query params: `limit`, `level`, `since`)
|
||||
- `GET /logs/trades` — trade-specific log entries
|
||||
- Logs stored in structured JSON format (not just print statements)
|
||||
|
||||
#### 2. Config Persistence
|
||||
- Config saved to `config.json` alongside existing `trader_state.json`
|
||||
- Loaded on startup, merged with defaults
|
||||
- Changes via API written immediately to disk
|
||||
|
||||
#### 3. Structured Logging
|
||||
- Replace print-based logging with Python `logging` module
|
||||
- JSON-structured log entries to `trader.log` (rotated, max 10MB x 3)
|
||||
- Each entry: timestamp, level, category (TRADE/SCAN/API/SYSTEM), message, metadata
|
||||
- Keep Telegram alerts for critical events
|
||||
|
||||
#### 4. Docker
|
||||
- `Dockerfile` (python:3.12-slim, pip install, uvicorn entrypoint)
|
||||
- `docker-compose.yml` with env vars for all credentials
|
||||
- `.dockerignore`
|
||||
- Health check endpoint: `GET /health`
|
||||
- Port: 8893 (configurable via PORT env var)
|
||||
- Volume mount for persistent data (config.json, trader_state.json, logs)
|
||||
|
||||
#### 5. Git
|
||||
- Create NEW private repo: `git.letsgetnashty.com/case/coinex-trader`
|
||||
- Branch: `feature/api`
|
||||
- Include: requirements.txt, Dockerfile, docker-compose.yml, README.md, .env.example
|
||||
|
||||
### Constraints
|
||||
- **DO NOT change trading logic** — all entry/exit/scoring logic stays identical
|
||||
- **Preserve all safety features** — kill switch, circuit breaker, lockfile, retry logic
|
||||
- When `enabled: false`, scanner still runs (for dashboard data) but no trades are placed
|
||||
- API must be secured: API key auth via `X-API-Key` header (configurable)
|
||||
- Existing systemd timer must still work (API is additive, not replacement)
|
||||
|
||||
---
|
||||
|
||||
## Project B: CoinEx Dashboard Upgrades
|
||||
|
||||
**Repo:** `git.letsgetnashty.com/case/coinex-dashboard` (existing)
|
||||
**Branch:** `feature/v2-upgrades`
|
||||
**Stack:** Next.js 15 + Tailwind v4 + Framer Motion + ShadCN + TypeScript
|
||||
|
||||
### Requirements
|
||||
|
||||
#### 1. Account Config (Settings Page)
|
||||
- New `/settings` page or settings modal
|
||||
- Configure CoinEx API credentials (Access ID + Secret Key)
|
||||
- Credentials stored in server memory (env vars take precedence)
|
||||
- Test connection button (calls CoinEx balance endpoint)
|
||||
- Show connection status indicator in header
|
||||
|
||||
#### 2. Signal History
|
||||
- Track when each signal first appeared: `{ symbol, direction, score, firstSeen, lastSeen, stale: boolean }`
|
||||
- Signal is "stale" if it's been active for > 30 minutes without score change > 5 points
|
||||
- Display staleness indicator on coin cards (e.g., clock icon + time since first seen)
|
||||
- History stored server-side in memory (reset on restart is OK for v1)
|
||||
- WebSocket pushes signal age with each update
|
||||
|
||||
#### 3. Error/Issue Logging
|
||||
- Server-side log ring buffer (last 200 entries)
|
||||
- Log categories: API_ERROR, SCAN_ERROR, WS_ERROR, POSITION_ERROR
|
||||
- Display in collapsible log panel at bottom of dashboard
|
||||
- Each entry: timestamp, category, message
|
||||
- New errors auto-expand the panel with a badge count
|
||||
|
||||
#### 4. Tooltips
|
||||
All coin card elements get tooltips explaining what they are:
|
||||
- **RSI**: "Relative Strength Index (0-100). <30 oversold, >70 overbought"
|
||||
- **VWAP %**: "Volume-Weighted Average Price deviation. Positive = above VWAP"
|
||||
- **BB Position**: "Bollinger Band position. 0 = lower band, 1 = upper band"
|
||||
- **Long Score / Short Score**: "Composite score (0-80). Signal threshold: {threshold}"
|
||||
- **24h Change**: "Price change over last 24 hours"
|
||||
- **Leverage badge**: "Suggested leverage based on signal strength"
|
||||
- Position cards: entry price, mark price, margin, unrealized P&L descriptions
|
||||
- Use ShadCN Tooltip component
|
||||
|
||||
### Constraints
|
||||
- All existing scoring logic in `lib/indicators.ts` preserved exactly
|
||||
- Zero client-side Binance/CoinEx API calls (server fetches, pushes via WS)
|
||||
- Dark theme maintained
|
||||
- Mobile-responsive (existing layout is fine, tooltips work on tap)
|
||||
|
||||
---
|
||||
|
||||
## Pipeline
|
||||
|
||||
1. **Glitch** builds both projects on feature branches
|
||||
2. **Hawk** reviews code + runs tests
|
||||
3. **Jinx** functional QA (API endpoints, WebSocket data, config persistence)
|
||||
4. **Pixel** visual QA (tooltips, layout, log panel, settings page)
|
||||
5. **Forge** handles Gitea repos, Docker builds, Coolify prep
|
||||
6. Ship to main branches after all pass
|
||||
|
||||
## Deployment Notes
|
||||
- Trader bot: Docker image ready but NOT deployed to Coolify yet (D J will decide when)
|
||||
- Dashboard: deploy via `tools/coolify-deploy.sh` after QA pass
|
||||
- Use `coolify-deploy.sh` for dashboard, manual for trader bot
|
||||
176
data/tasks/dashboard-nav-reorganize.md
Normal file
176
data/tasks/dashboard-nav-reorganize.md
Normal file
@ -0,0 +1,176 @@
|
||||
# Task: CoinEx Dashboard — Unified Navigation & Settings Consolidation
|
||||
|
||||
**Priority:** HIGH
|
||||
**Assigned:** Glitch → Hawk → Jinx + Pixel
|
||||
**Status:** Spec
|
||||
**Date:** 2026-03-01
|
||||
|
||||
## Overview
|
||||
|
||||
Reorganize the CoinEx Dashboard with a consistent nav bar across all pages and consolidate all settings into one centralized Settings page. Settings flow downstream: Scanner uses them for signal calculation, Trader bot uses them for trade execution.
|
||||
|
||||
## Navigation Bar
|
||||
|
||||
Every page gets the same persistent nav bar at the top:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ⚡ CoinEx Platform [Home] [Trader] [Settings] [Logs] [Status] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- **Home** (`/`) — Futures scanner grid (existing)
|
||||
- **Trader** (`/trader`) — Trader control panel (existing, minus config tab)
|
||||
- **Settings** (`/settings`) — NEW: all configuration in one place
|
||||
- **Logs** (`/logs`) — Unified audit log (existing)
|
||||
- **Status** (`/status`) — System status (existing)
|
||||
|
||||
Active page is highlighted. Nav is a shared component used by all pages.
|
||||
|
||||
### Implementation
|
||||
- Create `components/NavBar.tsx` — shared nav component
|
||||
- Use `usePathname()` from `next/navigation` for active state
|
||||
- Replace the ad-hoc headers on each page with `<NavBar />`
|
||||
- Remove the back arrows (← ) since nav handles navigation now
|
||||
- Remove inline "Trader Control" and "Audit Log" links from home page header
|
||||
|
||||
## Settings Page (`/settings`)
|
||||
|
||||
### Single Source of Truth
|
||||
All settings stored in one config file: `trader_config.json` at
|
||||
`/home/wdjones/.openclaw/workspace/projects/crypto-signals/data/coinex-live/trader_config.json`
|
||||
|
||||
The scanner reads thresholds and coin list from this config too — no more hardcoded values in `scanner.ts`.
|
||||
|
||||
### Settings Sections
|
||||
|
||||
**1. Signal Configuration**
|
||||
These control how the homepage scanner calculates and displays signals:
|
||||
- Long signal threshold (currently hardcoded 45 in scanner.ts)
|
||||
- Short signal threshold (currently hardcoded 50 in scanner.ts)
|
||||
- Coin watchlist (currently hardcoded COINS array in scanner.ts) — add/remove coins with search
|
||||
- Scan interval (currently 30s in scanner.ts)
|
||||
|
||||
**2. Trading Configuration**
|
||||
These control how the trader bot operates:
|
||||
- Mode: LIVE / DRY-RUN / PAUSED
|
||||
- Position size % (default 5%)
|
||||
- Max concurrent positions (default 3)
|
||||
- Max leverage cap (default 10x)
|
||||
- Leverage tiers (score-based, e.g. ≥45→5x, ≥60→7x)
|
||||
- TP % / SL %
|
||||
- Trailing stop %
|
||||
- Circuit breaker failure count (default 3)
|
||||
- Kill switch drawdown % (default 50%)
|
||||
|
||||
**3. Coin Blacklist / Whitelist**
|
||||
- Which coins can be traded (separate from which coins are scanned)
|
||||
- Toggle individual coins on/off for trading
|
||||
|
||||
**4. CoinEx API Connection**
|
||||
- Move the existing Settings modal content here (API credentials, connection test)
|
||||
|
||||
### Config File Schema Update
|
||||
```json
|
||||
{
|
||||
"mode": "paused",
|
||||
"scan_interval_seconds": 30,
|
||||
"long_threshold": 45,
|
||||
"short_threshold": 50,
|
||||
"coin_watchlist": ["BTCUSDT", "ETHUSDT", ...],
|
||||
"position_size_pct": 5.0,
|
||||
"max_positions": 3,
|
||||
"max_leverage": 10,
|
||||
"leverage_tiers": [
|
||||
{"min_score": 45, "leverage": 5},
|
||||
{"min_score": 60, "leverage": 7}
|
||||
],
|
||||
"kill_switch_drawdown_pct": 50,
|
||||
"tp_pct": 5.0,
|
||||
"sl_pct": -3.0,
|
||||
"trailing_stop_pct": 2.0,
|
||||
"circuit_breaker_threshold": 3,
|
||||
"coin_blacklist": [],
|
||||
"coin_whitelist": [],
|
||||
"coinex_access_id": "",
|
||||
"coinex_secret_key": "",
|
||||
"last_updated": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### Backend Changes
|
||||
|
||||
**Scanner (`lib/server/scanner.ts`):**
|
||||
- Remove hardcoded `COINS` array — read `coin_watchlist` from config
|
||||
- Remove hardcoded `LONG_THRESHOLD` / `SHORT_THRESHOLD` — read from config
|
||||
- Read config at start of each scan cycle (hot reload)
|
||||
- Add config reading utility (same `trader_config.json` file)
|
||||
|
||||
**API route (`/api/trader/config`):**
|
||||
- Already exists — reuse for all settings reads/writes
|
||||
- Add `scan_interval_seconds` and `coin_watchlist` to validation
|
||||
|
||||
**Home page (`app/page.tsx`):**
|
||||
- Remove hardcoded `LONG_THRESHOLD` / `SHORT_THRESHOLD` constants
|
||||
- Read thresholds from config via WebSocket data (scanner sends them)
|
||||
- Or fetch from `/api/trader/config` on mount
|
||||
|
||||
**Trader page (`app/trader/page.tsx`):**
|
||||
- Remove the "Configuration" tab entirely — it lives in Settings now
|
||||
- Keep: Overview, Positions, Activity Logs tabs
|
||||
- Overview still shows a summary of current settings (read-only)
|
||||
|
||||
**Settings Modal (`components/SettingsModal.tsx`):**
|
||||
- Remove or deprecate — functionality moves to Settings page
|
||||
|
||||
## Page Changes Summary
|
||||
|
||||
| Page | Add | Remove |
|
||||
|------|-----|--------|
|
||||
| All pages | `<NavBar />` component | Ad-hoc headers, back arrows |
|
||||
| Home (`/`) | — | Inline nav links, hardcoded thresholds |
|
||||
| Trader (`/trader`) | — | Configuration tab (moves to Settings) |
|
||||
| Settings (`/settings`) | NEW: all config UI | — |
|
||||
| Logs (`/logs`) | — | Back arrow |
|
||||
| Status (`/status`) | — | Back arrow |
|
||||
|
||||
## Files to Modify
|
||||
- `components/NavBar.tsx` — NEW shared nav
|
||||
- `app/page.tsx` — replace header, read thresholds from config
|
||||
- `app/trader/page.tsx` — remove config tab, replace header
|
||||
- `app/settings/page.tsx` — NEW settings page
|
||||
- `app/logs/page.tsx` — replace header
|
||||
- `app/status/page.tsx` — replace header
|
||||
- `app/layout.tsx` — possibly add NavBar here instead of per-page
|
||||
- `lib/server/scanner.ts` — read config instead of hardcoded values
|
||||
- `app/api/trader/config/route.ts` — extend validation for new fields
|
||||
- `lib/types.ts` — extend TraderConfig type
|
||||
|
||||
## Constraints
|
||||
- All existing scoring logic in `lib/indicators.ts` PRESERVED EXACTLY
|
||||
- Dark theme, monospace aesthetic
|
||||
- Zero client-side CoinEx API calls
|
||||
- Use `api.binance.us` not `api.binance.com`
|
||||
- Standard stack: Next.js 16 + Tailwind v4 + Framer Motion + ShadCN + Lucide + TS
|
||||
- Context7 mandatory for library docs
|
||||
- Include unit tests for new components
|
||||
- Must pass build (`npm run build`) before submitting
|
||||
|
||||
## QA Pipeline
|
||||
1. **Glitch builds** — implements all changes
|
||||
2. **Hawk reviews** — code review + verifies tests pass
|
||||
3. **Jinx E2E** — functional testing: nav works on all pages, settings save/load, scanner reads config, trader reads config
|
||||
4. **Pixel visual** — consistent nav styling, responsive, dark theme, no layout breaks
|
||||
|
||||
## Definition of Done
|
||||
- [ ] NavBar component renders on all 5 pages with correct active state
|
||||
- [ ] Settings page has all 4 sections with working save/load
|
||||
- [ ] Scanner reads thresholds + coin list from config (no hardcoded values)
|
||||
- [ ] Trader page config tab removed (settings are in /settings)
|
||||
- [ ] All pages use consistent header via NavBar
|
||||
- [ ] Changing thresholds in Settings affects scanner behavior on next cycle
|
||||
- [ ] Build passes
|
||||
- [ ] Unit tests for NavBar and Settings page
|
||||
- [ ] Hawk PASS
|
||||
- [ ] Jinx PASS
|
||||
- [ ] Pixel PASS
|
||||
115
data/tasks/learning-feed-reels-redesign.md
Normal file
115
data/tasks/learning-feed-reels-redesign.md
Normal file
@ -0,0 +1,115 @@
|
||||
# Learning Feed — Reels-Style Visual Redesign
|
||||
|
||||
## Goal
|
||||
Transform the Learning Feed from a traditional card-based feed into an Instagram Reels / TikTok-style visual experience with full-bleed images and bold text overlays.
|
||||
|
||||
## Reference Style (from D J's examples)
|
||||
1. **Hero/Title cards**: Full-bleed background image, large bold white text at bottom with dark gradient overlay, topic badge or author info subtle
|
||||
2. **Content cards**: Dark solid background (#0a0a0a), clean white serif-ish text, numbered listicle format, generous line spacing
|
||||
3. **Carousel/pagination**: Dots at bottom, slide counter badge top-right (e.g., "1/11")
|
||||
4. **Mobile-first**: Cards should feel like full-viewport-height items on phone (not literal 100vh, but tall — aspect ratio ~4:5 or 9:16)
|
||||
|
||||
## Project Location
|
||||
`/home/wdjones/.openclaw/workspace/projects/learning-feed`
|
||||
|
||||
## Stack
|
||||
- Next.js 16 (App Router), Tailwind CSS v4, Framer Motion, ShadCN UI, Lucide Icons, TypeScript
|
||||
- SQLite via better-sqlite3 (in `serverExternalPackages`)
|
||||
- Database at `data/learning-feed.db`
|
||||
|
||||
## Current State
|
||||
- 21 posts, 1 topic (Private Pilot License), 14 posts have Unsplash image URLs
|
||||
- Post types: `quick_fact`, `quiz`, `deep_dive`
|
||||
- Feed is a vertical scroll of traditional `Card` components (gray border, small image, text below)
|
||||
- Interactions: save, got_it, more_like_this, expand, view
|
||||
|
||||
## What to Build
|
||||
|
||||
### 1. Redesign `PostCard` component (`components/post-card.tsx`)
|
||||
|
||||
**For posts WITH images (`image_url` is not null):**
|
||||
- Full-width card, tall aspect ratio (min-height ~400px, or aspect-[4/5])
|
||||
- Background image covers entire card (`object-cover`, `absolute inset-0`)
|
||||
- Dark gradient overlay from bottom (~60% of card height, `bg-gradient-to-t from-black/90 via-black/50 to-transparent`)
|
||||
- Title in **large, bold, uppercase white text** at the bottom over the gradient
|
||||
- Topic badge (small pill) top-left
|
||||
- Author avatar + name bottom-left (small, subtle, over gradient)
|
||||
- Post type indicator subtle (icon or small badge)
|
||||
- Rounded corners (`rounded-2xl`), overflow hidden
|
||||
|
||||
**For posts WITHOUT images (text-only content cards):**
|
||||
- Same card dimensions
|
||||
- Solid dark background (`bg-gray-950` or `bg-[#0a0a0a]`)
|
||||
- Content text: white, serif-style font (use `font-serif` or a Google Font like Playfair Display), larger size (~text-lg or text-xl), generous leading (`leading-relaxed` or `leading-8`)
|
||||
- Numbered items if content has multiple points
|
||||
- Clean, minimal — no borders, no badges cluttering
|
||||
|
||||
**Both card types:**
|
||||
- Rounded corners (`rounded-2xl`)
|
||||
- No visible card border
|
||||
- Subtle shadow or none
|
||||
- Tap/click to expand (for deep_dive and quiz types)
|
||||
|
||||
### 2. Interaction overlay (bottom of card)
|
||||
- Floating action buttons on right side (vertical stack, like Instagram Reels):
|
||||
- ⭐ Save (star icon, fills yellow when active)
|
||||
- ✅ Got it (check icon, turns green)
|
||||
- 🔄 More like this
|
||||
- Semi-transparent, only visible on hover/tap or always subtle
|
||||
- Remove the old horizontal action bar at the bottom
|
||||
|
||||
### 3. Feed layout changes (`components/feed-page.tsx`)
|
||||
- Remove the `max-w-2xl` constraint — cards should be wider on mobile (full width with small padding `px-3`)
|
||||
- On desktop, keep `max-w-lg` centered (phone-width experience even on desktop)
|
||||
- Reduce gap between cards (`space-y-4` instead of `space-y-6`)
|
||||
- Keep infinite scroll behavior
|
||||
- Keep the sticky header but make it more minimal (just "Learning Feed" text, no border, transparent bg with blur)
|
||||
|
||||
### 4. Image handling
|
||||
- Unsplash `source.unsplash.com` URLs are being deprecated. For now they work — keep using them.
|
||||
- Add error fallback: if image fails to load, render as a text-only card instead (gradient background with topic-colored tint)
|
||||
- Posts without images should NOT look broken — they should look intentionally text-only (like slides 2/3 in the reference)
|
||||
|
||||
### 5. Quiz post type special treatment
|
||||
- Show question on the card face
|
||||
- "Tap to reveal" hint text
|
||||
- Tap flips/expands to show the answer (use Framer Motion)
|
||||
|
||||
### 6. Typography
|
||||
- Title text on image cards: bold, possibly uppercase, large (text-2xl or text-3xl), tight leading
|
||||
- Content text on text cards: slightly serif, comfortable reading size, generous spacing
|
||||
- Use CSS `text-shadow: 0 2px 4px rgba(0,0,0,0.8)` on text over images for readability
|
||||
|
||||
## Files to Modify
|
||||
- `components/post-card.tsx` — Complete redesign (main work)
|
||||
- `components/feed-page.tsx` — Layout adjustments
|
||||
- `app/globals.css` — Any custom CSS needed (text-shadow utility, font imports)
|
||||
- `tailwind.config.ts` — If adding custom fonts
|
||||
|
||||
## Files NOT to Touch
|
||||
- `lib/database.ts` — No schema changes
|
||||
- `app/api/*` — No API changes
|
||||
- `scripts/*` — No seed changes
|
||||
|
||||
## Build & Test
|
||||
```bash
|
||||
cd /home/wdjones/.openclaw/workspace/projects/learning-feed
|
||||
npm run build
|
||||
# Must succeed with 0 errors
|
||||
# Start: PORT=3001 npm start
|
||||
```
|
||||
|
||||
## Quality Bar
|
||||
- Cards must look like Instagram/TikTok content — not like a blog or documentation
|
||||
- Dark mode only
|
||||
- Mobile-first (test at 390px width mentally)
|
||||
- Images must have gradient overlays so text is always readable
|
||||
- Text-only cards must look intentional, not like broken image cards
|
||||
- Smooth animations (Framer Motion) on card entry and interactions
|
||||
- No layout shift when images load
|
||||
|
||||
## DO NOT
|
||||
- Change the database schema
|
||||
- Add new dependencies unless truly necessary (prefer Tailwind + Framer Motion)
|
||||
- Add carousel/swipe between slides (that's Phase 3 — each post is still one card for now)
|
||||
- Add audio/video elements
|
||||
242
data/tasks/learning-feed-spec.md
Normal file
242
data/tasks/learning-feed-spec.md
Normal file
@ -0,0 +1,242 @@
|
||||
# Learning Feed — Personal Knowledge Feed App
|
||||
|
||||
**Priority:** HIGH
|
||||
**Assigned:** Glitch
|
||||
**Date:** 2026-03-13
|
||||
**Requested by:** D J
|
||||
|
||||
---
|
||||
|
||||
## Concept
|
||||
|
||||
A social media-style infinite scroll feed where every "post" is an AI-generated learning nugget. Hijacks the dopamine loop of social media scrolling but replaces the content with real knowledge. Designed for people who don't "sit down to study" but check their phone 50+ times a day.
|
||||
|
||||
**This is a personal tool, not a product. No monetization, no auth, no multi-user.**
|
||||
|
||||
---
|
||||
|
||||
## Core Experience
|
||||
|
||||
The app should feel like opening Instagram or Twitter — not like opening a textbook.
|
||||
|
||||
### The Feed
|
||||
- Infinite scroll of "posts" that look like social media content
|
||||
- Each post is a bite-sized learning nugget (1-3 paragraphs max)
|
||||
- Mixed post formats to keep it interesting (see Post Types below)
|
||||
- Fake "authors" with avatars and names to make it feel like a real feed (e.g. "Dr. Sarah Chen · Tax Strategy" or "Marcus Webb · Real Estate")
|
||||
- Timestamps ("2h ago", "Yesterday") — cosmetic, makes it feel alive
|
||||
- Clean, mobile-first design — this lives on D J's iPhone
|
||||
|
||||
### Post Types (variety prevents fatigue)
|
||||
1. **Quick Fact** — "Did you know: A 1031 exchange lets you defer capital gains tax by reinvesting sale proceeds into a like-kind property within 180 days."
|
||||
2. **Deep Dive** — Longer post (expandable) explaining a concept in detail with examples
|
||||
3. **Quiz/Challenge** — "What's the monthly payment on a $276K loan at 6.25% over 30 years?" with reveal on tap
|
||||
4. **Myth Buster** — "MYTH: You need 20% down to buy a house. REALITY: FHA loans require as little as 3.5%."
|
||||
5. **Comparison** — Side-by-side: "S&P 500 vs Real Estate: 20-year returns comparison"
|
||||
6. **Story/Case Study** — "How Warren Buffett made $2.6B from a single Coca-Cola investment in 1988"
|
||||
7. **Number of the Day** — "$337,877 — The amount of passive losses that accumulate over 5 years on a $345K rental property at >$150K AGI"
|
||||
8. **Chain/Thread** — Multi-part posts that build on each other (Part 1 of 3)
|
||||
|
||||
### Interaction
|
||||
- **Tap to expand** — Deep dives and quiz answers expand inline
|
||||
- **Save/Bookmark** — Star posts to review later
|
||||
- **Got It / Already Knew This** — Light feedback so the AI knows your level
|
||||
- **More Like This** — Tells the system to generate more on this topic
|
||||
- **Surprise Me** — Shuffle in random topics
|
||||
|
||||
---
|
||||
|
||||
## Topic System
|
||||
|
||||
### Seeded Topics
|
||||
- User picks initial interests from a list or types custom topics
|
||||
- These seed the initial feed generation
|
||||
- Stored in a simple JSON config
|
||||
|
||||
### Dynamic Expansion
|
||||
- Track which posts the user engages with (expands, saves, "more like this")
|
||||
- AI uses engagement patterns to introduce adjacent/related topics
|
||||
- Example: User reads about cap rates → system introduces DSCR, NOI, 1031 exchanges
|
||||
- Gradual difficulty progression — start with basics, introduce advanced concepts as engagement shows comprehension
|
||||
|
||||
### Surprise Layer
|
||||
- 10-20% of feed is random interesting content outside the user's topic bubbles
|
||||
- History, science, psychology, economics, technology
|
||||
- Mimics serendipity of a real social feed
|
||||
- If user engages with a surprise topic, it can become a seeded topic
|
||||
|
||||
### On-Demand Topics
|
||||
- Text input: "teach me about options trading"
|
||||
- Floods the feed with that topic for the next ~20 posts, then blends back to normal mix
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition (Hidden)
|
||||
|
||||
This is the secret sauce. The feed naturally resurfaces content for retention:
|
||||
|
||||
- **Day 1:** New fact appears
|
||||
- **Day 3:** Same fact reappears as a quiz ("Do you remember...?")
|
||||
- **Day 7:** Fact appears in a different format (comparison, myth buster, deeper context)
|
||||
- **Day 14:** Quick recall quiz
|
||||
- **Day 30:** Final reinforcement
|
||||
|
||||
The user never sees "spaced repetition" — it just feels like the feed naturally revisits things. Like how Twitter shows you things you liked from last week.
|
||||
|
||||
Track each post's retention schedule in the database.
|
||||
|
||||
---
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
### Stack
|
||||
- **Next.js 16** (App Router) — standard stack
|
||||
- **Tailwind CSS v4**
|
||||
- **Framer Motion** — smooth animations, card transitions, expand/collapse
|
||||
- **ShadCN UI** — component library
|
||||
- **Lucide Icons**
|
||||
- **TypeScript**
|
||||
- **SQLite** (via better-sqlite3) — local database, no external dependencies
|
||||
- **AI Generation** — Claude API via Anthropic SDK (use D J's existing API key)
|
||||
|
||||
### Data Model
|
||||
|
||||
```
|
||||
topics (id, name, category, seed_or_discovered, engagement_score, created_at)
|
||||
posts (id, topic_id, post_type, title, content, expanded_content, author_name, author_avatar, author_specialty, difficulty, created_at, generated_at)
|
||||
interactions (id, post_id, type [view/expand/save/got_it/more_like_this], created_at)
|
||||
retention_schedule (id, post_id, stage [new/day3/day7/day14/day30], scheduled_at, shown_at, recalled)
|
||||
feed_requests (id, topic_override, created_at) -- for on-demand topic floods
|
||||
```
|
||||
|
||||
### API Routes
|
||||
- `GET /api/feed` — returns next batch of posts (mix of new + retention + surprise)
|
||||
- `POST /api/feed/generate` — triggers AI generation of new posts for topics
|
||||
- `POST /api/interact` — log interaction (view, expand, save, got_it, more_like_this)
|
||||
- `GET /api/topics` — list current topics with engagement scores
|
||||
- `POST /api/topics` — add/remove seeded topics
|
||||
- `POST /api/topics/request` — on-demand topic flood
|
||||
- `GET /api/saved` — bookmarked posts
|
||||
- `GET /api/stats` — learning stats (posts read, topics explored, retention rate)
|
||||
|
||||
### Feed Algorithm
|
||||
1. Pull retention-scheduled posts due today (highest priority — these are reinforcement)
|
||||
2. Pull new posts from seeded topics (weighted by engagement score)
|
||||
3. Pull 10-20% surprise posts
|
||||
4. If topic override active, weight heavily toward that topic
|
||||
5. Mix and shuffle for natural feel
|
||||
6. Never show the same post twice in one session (except retention)
|
||||
|
||||
### AI Generation
|
||||
- Use Claude Sonnet (cost-effective for content generation)
|
||||
- Batch generate: create 20-50 posts per topic in advance, store in DB
|
||||
- Background generation: when post inventory for a topic drops below threshold, auto-generate more
|
||||
- System prompt should specify: post type, topic, difficulty level, target length
|
||||
- Generate fake author profiles per topic area (reuse for consistency)
|
||||
|
||||
### Pre-seeded Authors (examples)
|
||||
- "Dr. Sarah Chen" — Tax & Financial Strategy
|
||||
- "Marcus Webb" — Real Estate Investing
|
||||
- "Alex Rivera" — Crypto & Blockchain
|
||||
- "Prof. James Okafor" — Economics & Markets
|
||||
- "Nina Patel" — Technology & Engineering
|
||||
- "Ray Tanaka" — History & Culture
|
||||
- Generate more as topics expand
|
||||
|
||||
---
|
||||
|
||||
## UI Design
|
||||
|
||||
### Mobile-First Layout
|
||||
- Single column feed (like Instagram/Twitter)
|
||||
- Pull to refresh
|
||||
- Smooth scroll with card-based posts
|
||||
- Bottom nav: Feed | Saved | Topics | Stats
|
||||
|
||||
### Post Card Design
|
||||
- Author avatar (small circle) + name + specialty + timestamp
|
||||
- Post type badge (small pill: "Quick Fact", "Quiz", "Deep Dive", etc.)
|
||||
- Content area
|
||||
- Expandable section (tap to reveal for quizzes/deep dives)
|
||||
- Action bar: Save ⭐ | Got It ✓ | More Like This 🔄
|
||||
- Clean, readable typography — no clutter
|
||||
|
||||
### Topics Page
|
||||
- Grid/list of active topics with engagement indicators
|
||||
- Add topic button (text input)
|
||||
- Toggle topics on/off
|
||||
- "Discover" section showing topics the AI is introducing based on your engagement
|
||||
|
||||
### Saved Page
|
||||
- Bookmarked posts in reverse chronological order
|
||||
- Search/filter by topic
|
||||
|
||||
### Stats Page
|
||||
- Posts read today / this week / all time
|
||||
- Topics explored
|
||||
- Retention rate (% of spaced repetition quizzes answered correctly)
|
||||
- Streak (days in a row you opened the app)
|
||||
- Simple, motivating — not gamified to the point of being annoying
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
- Run as systemd service on D J's VM (192.168.86.45)
|
||||
- Port: 3001 (knowledge-builder is archived, port is free)
|
||||
- Mobile access via local network or Cloudflare tunnel for remote access
|
||||
- PWA manifest so it can be added to iPhone home screen (feels like a native app)
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 (MVP)
|
||||
|
||||
1. Feed page with infinite scroll
|
||||
2. 3 post types: Quick Fact, Quiz, Deep Dive
|
||||
3. Seeded topics (manual config)
|
||||
4. AI post generation (Claude Sonnet)
|
||||
5. Basic interactions (expand, save)
|
||||
6. SQLite storage
|
||||
7. Mobile-responsive
|
||||
8. PWA manifest (add to home screen)
|
||||
|
||||
## Phase 2
|
||||
|
||||
1. All 8 post types
|
||||
2. Dynamic topic expansion based on engagement
|
||||
3. Spaced repetition engine
|
||||
4. On-demand topic floods
|
||||
5. Stats page
|
||||
6. Fake author system with consistent personas
|
||||
|
||||
## Phase 3
|
||||
|
||||
1. Push notifications ("You haven't scrolled today" — optional)
|
||||
2. Topic difficulty progression
|
||||
3. Export: "What I learned this week" summary
|
||||
4. Chain/thread posts
|
||||
5. Share individual posts (screenshot or link)
|
||||
|
||||
---
|
||||
|
||||
## Context7 Required
|
||||
|
||||
Glitch MUST use Context7 for Next.js 16, Tailwind v4, Framer Motion, and ShadCN UI documentation before writing any code.
|
||||
|
||||
## Testing
|
||||
|
||||
- Hawk code review before merge
|
||||
- Mobile viewport testing (iPhone dimensions)
|
||||
- Feed should load and scroll smoothly with 100+ posts
|
||||
- AI generation should handle rate limits gracefully
|
||||
- SQLite should handle concurrent reads without blocking the UI
|
||||
|
||||
---
|
||||
|
||||
## File References
|
||||
- This spec: `data/tasks/learning-feed-spec.md`
|
||||
- Project directory: `projects/learning-feed/`
|
||||
- Standard stack: Next.js 16 + Tailwind v4 + Framer Motion + ShadCN + Lucide + TypeScript
|
||||
- Anthropic API key: available in environment (openclaw config)
|
||||
- Port: 3001
|
||||
- Systemd service: `learning-feed.service`
|
||||
163
data/tasks/market-data-service.md
Normal file
163
data/tasks/market-data-service.md
Normal file
@ -0,0 +1,163 @@
|
||||
# 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:
|
||||
1. **Dashboard scanner** (`lib/server/scanner.ts`) — 29 coins × 1h × every 30s
|
||||
2. **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:
|
||||
1. Fetches ALL OHLCV data from `api.binance.us` (29 coins × 3 timeframes)
|
||||
2. Caches everything in Redis with TTLs
|
||||
3. Publishes updates to Redis pub/sub channels on each refresh
|
||||
4. 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}:1h` Redis keys instead
|
||||
- Subscribe to `market:update:1h` channel 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`, email `case-lgn@protonmail.com`
|
||||
- Push initial commit before starting development
|
||||
- Commit frequently throughout build
|
||||
|
||||
## Constraints
|
||||
- `api.binance.us` ONLY (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/log` endpoint 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
|
||||
61
data/tasks/polymarket-sports-arb.md
Normal file
61
data/tasks/polymarket-sports-arb.md
Normal file
@ -0,0 +1,61 @@
|
||||
# Polymarket Sports Arbitrage Scanner
|
||||
|
||||
**Priority:** HIGH — D J's top money-making project
|
||||
**Assigned:** Glitch (build) → Hawk (review) → Jinx (QA)
|
||||
**Created:** 2026-02-26
|
||||
|
||||
## Overview
|
||||
Build a scanner that compares odds from D J's existing odds aggregation database (Postgres on VPS) against Polymarket sports market prices to find arbitrage opportunities.
|
||||
|
||||
## Architecture
|
||||
```
|
||||
[D J's VPS Postgres] ──→ Scanner ──→ [Polymarket API] ──→ Compare ──→ [Telegram Alerts]
|
||||
(odds from books) (market prices) (find arb) (notify D J)
|
||||
```
|
||||
|
||||
## Phase 1: Polymarket Sports Markets Reader (BUILD NOW)
|
||||
- Fetch all active sports markets from Polymarket Gamma API
|
||||
- Parse market structure: teams, outcomes, prices, liquidity, close time
|
||||
- Store in local SQLite for comparison
|
||||
- Telegram alerts when opportunities found
|
||||
- **No DB dependency** — this phase uses only Polymarket public API
|
||||
|
||||
### Key APIs
|
||||
- Gamma API: `https://gamma-api.polymarket.com/markets?active=true&closed=false`
|
||||
- CLOB API: `https://clob.polymarket.com/` (order book depth, best bid/ask)
|
||||
- Filter for sports: tags contain "Sports", "NFL", "NBA", "NHL", "MLB", "Soccer", etc.
|
||||
|
||||
## Phase 2: Odds DB Integration (AFTER D J provides PG access)
|
||||
- Connect to D J's Postgres on VPS (read-only)
|
||||
- Map book odds → implied probability
|
||||
- Compare implied prob vs Polymarket price
|
||||
- Flag when: `book_implied_prob > polymarket_price + fee + margin`
|
||||
|
||||
## Phase 3: Backtesting
|
||||
- Historical odds vs Polymarket resolution
|
||||
- Win rate, ROI, optimal thresholds
|
||||
|
||||
## Phase 4: Auto-execution (Future)
|
||||
- Place bets via Polymarket CLOB API
|
||||
- Position sizing, bankroll management
|
||||
|
||||
## Technical Notes
|
||||
- Polymarket Data API is public, no auth for reads
|
||||
- kch123 wallet analysis shows sports arb is proven ($9.37M P&L)
|
||||
- kch123's edge: ~30-60s detection window, negligible for pre-game bets
|
||||
- Reference: `data/investigations/polymarket-15min-arb.md` (different strategy but same platform)
|
||||
- Existing scanner: `projects/crypto-signals/scripts/polymarket_arb_scanner.py` (15-min crypto, reuse patterns)
|
||||
|
||||
## Constraints
|
||||
- Python (match existing infra)
|
||||
- Telegram alerts (same pattern as CoinEx trader)
|
||||
- Systemd timer (5-15 min interval)
|
||||
- Zero AI tokens — pure Python
|
||||
- Paper trade first, log all opportunities
|
||||
|
||||
## Deliverables
|
||||
1. `projects/crypto-signals/scripts/polymarket_sports_scanner.py`
|
||||
2. Systemd service + timer
|
||||
3. Telegram alert integration
|
||||
4. Local SQLite for market history
|
||||
5. Unit tests
|
||||
126
data/tasks/trader-dashboard-controls.md
Normal file
126
data/tasks/trader-dashboard-controls.md
Normal file
@ -0,0 +1,126 @@
|
||||
# Task: CoinEx Trader Bot — Full Dashboard Control Suite
|
||||
|
||||
**Priority:** HIGH
|
||||
**Assigned:** Glitch
|
||||
**Status:** Spec
|
||||
**Date:** 2026-03-01
|
||||
|
||||
## Context
|
||||
|
||||
The live trader bot (`coinex_live_trader.py`) currently runs as a headless systemd timer with no UI control. D J wants ALL configuration and control moved into the CoinEx Dashboard (port 8891) before any more live trading happens.
|
||||
|
||||
## Requirements
|
||||
|
||||
### 1. Master Controls (Top Priority)
|
||||
- **Global ON/OFF toggle** — starts/stops the trading bot entirely
|
||||
- **Mode selector** — LIVE / DRY-RUN / PAUSED
|
||||
- **Emergency Stop button** — immediately halts bot + attempts to close all positions
|
||||
- **Lockfile status** — show if circuit breaker is tripped, with a "Clear Lockfile" button
|
||||
|
||||
### 2. Position Management
|
||||
- **View all open positions** — symbol, side, entry price, current price, P&L, P&L%, margin, leverage
|
||||
- **Close individual position** button
|
||||
- **Close ALL positions** button
|
||||
- **Position history** — recent closed trades with P&L
|
||||
|
||||
### 3. Runtime Configuration (all hot-reloadable, no restart needed)
|
||||
- **Position size %** (currently 5%)
|
||||
- **Max concurrent positions** (currently 3)
|
||||
- **Max leverage** (currently 10x)
|
||||
- **Kill switch drawdown %** (currently 50%)
|
||||
- **TP threshold %** (take profit)
|
||||
- **SL threshold %** (stop loss)
|
||||
- **Circuit breaker failure count** (currently 3)
|
||||
- **Scan interval** (currently 5 min)
|
||||
- **Long signal threshold** (currently 45 pts)
|
||||
- **Short signal threshold** (currently 50 pts)
|
||||
- **Coin whitelist/blacklist** — toggle which coins can be traded
|
||||
|
||||
### 4. Account Overview
|
||||
- **Total equity** (available + margin)
|
||||
- **Available balance**
|
||||
- **Margin in use**
|
||||
- **Unrealized P&L total**
|
||||
- **Starting balance** and **drawdown %**
|
||||
- **Kill switch distance** (how far from trigger)
|
||||
|
||||
### 5. Activity Log
|
||||
- **Trade log** — every open/close with timestamps, prices, P&L
|
||||
- **Error log** — API failures, circuit breaker events
|
||||
- **Signal log** — what signals were generated and whether acted on
|
||||
- **Bot cycle log** — last N cycle summaries (scanned, signals found, actions taken)
|
||||
|
||||
### 6. Configuration Persistence
|
||||
- All settings saved to `trader_config.json`
|
||||
- Bot reads config at start of each cycle (hot reload)
|
||||
- Dashboard reads/writes same config file
|
||||
- Default values match current hardcoded settings
|
||||
|
||||
## Architecture
|
||||
|
||||
### Backend
|
||||
- New API routes in the dashboard:
|
||||
- `GET /api/trader/status` — bot state, positions, balance, config
|
||||
- `POST /api/trader/config` — update runtime config
|
||||
- `POST /api/trader/control` — start/stop/pause/emergency-stop/clear-lockfile
|
||||
- `POST /api/trader/close-position` — close specific position
|
||||
- `POST /api/trader/close-all` — close all positions
|
||||
- `GET /api/trader/logs` — recent trade/error/signal logs
|
||||
|
||||
### Config File: `trader_config.json`
|
||||
```json
|
||||
{
|
||||
"mode": "paused",
|
||||
"position_size_pct": 5.0,
|
||||
"max_positions": 3,
|
||||
"max_leverage": 10,
|
||||
"kill_switch_drawdown_pct": 50,
|
||||
"tp_pct": null,
|
||||
"sl_pct": null,
|
||||
"circuit_breaker_threshold": 3,
|
||||
"scan_interval_minutes": 5,
|
||||
"long_threshold": 45,
|
||||
"short_threshold": 50,
|
||||
"coin_blacklist": [],
|
||||
"coin_whitelist": []
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend
|
||||
- New `/trader` page in the dashboard (linked from main nav)
|
||||
- Dark theme matching existing dashboard aesthetic
|
||||
- Real-time updates via the existing WebSocket
|
||||
|
||||
### Trader Bot Changes
|
||||
- Read `trader_config.json` at start of each cycle
|
||||
- Respect `mode` field: "live" | "dry-run" | "paused"
|
||||
- If "paused", exit immediately (no API calls)
|
||||
- All hardcoded values replaced with config reads
|
||||
- Bot NO LONGER managed by systemd timer — dashboard API controls start/stop
|
||||
|
||||
## Files
|
||||
- Dashboard project: `~/.openclaw/workspace/projects/coinex-dashboard/`
|
||||
- Trader script: `~/.openclaw/workspace/projects/crypto-signals/scripts/coinex_live_trader.py`
|
||||
- Trader state: `~/.openclaw/workspace/projects/crypto-signals/data/coinex-live/trader_state.json`
|
||||
- Lockfile: `~/.openclaw/workspace/projects/crypto-signals/data/coinex-live/live-trader-lock.json`
|
||||
- New config: `~/.openclaw/workspace/projects/crypto-signals/data/coinex-live/trader_config.json`
|
||||
- CoinEx creds: `~/.openclaw/workspace/.credentials/coinex.env`
|
||||
|
||||
## Constraints
|
||||
- **Zero client-side CoinEx API calls** — all CoinEx calls go through server-side API routes
|
||||
- **All existing scoring logic in `lib/indicators.ts` preserved exactly**
|
||||
- **Use api.binance.us NOT api.binance.com** (451 geo-blocking)
|
||||
- **Must include unit tests**
|
||||
- **Context7 mandatory** for any library usage
|
||||
- **Dark theme, monospace font aesthetic**
|
||||
- Standard stack: Next.js 16 + Tailwind v4 + Framer Motion + ShadCN + Lucide + TypeScript
|
||||
|
||||
## Definition of Done
|
||||
- [ ] All controls functional from dashboard UI
|
||||
- [ ] Bot reads config from file each cycle (hot reload)
|
||||
- [ ] Emergency stop works
|
||||
- [ ] Position management works (view, close individual, close all)
|
||||
- [ ] All settings persisted and reloadable
|
||||
- [ ] Activity logs visible in UI
|
||||
- [ ] Unit tests for API routes
|
||||
- [ ] No live trading until D J explicitly flips the switch in the UI
|
||||
Reference in New Issue
Block a user