Commit Graph

223 Commits

Author SHA1 Message Date
21in7
dacefaa1ed docs: update for XRP-only operation — remove SOL/DOGE/TRX references
- SOL/DOGE/TRX removed: all showed PF < 1.0 across all parameter combinations
  in strategy sweep (2026-03-17) and live trading (2026-03-21)
- ML filter disabled: Walk-Forward showed ML ON PF < ML OFF PF;
  ablation confirmed signal_strength/side dependency (A→C drop 0.08-0.09)
- XRP ADX threshold: 30 → 25 (ADX=30 blocked all trades in current market)
- Current production: XRPUSDT only, SL=1.5x TP=4.0x ADX≥25, NO_ML_FILTER=true

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:47:30 +09:00
21in7
d8f5d4f1fb feat(backtest): add Kill Switch to BacktestRiskManager for fair ML comparison
Adds Fast Kill (8 consecutive losses) and Slow Kill (PF < 0.75 over 15 trades)
to the backtester, matching bot.py behavior. Without this, ML OFF overtrades
and self-destructs, making ML ON look artificially better.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:20:42 +09:00
21in7
b5a5510499 feat(backtest): add --compare-ml for ML on/off walk-forward comparison
Runs WalkForwardBacktester twice (use_ml=True/False), prints side-by-side
comparison of PF, win rate, MDD, Sharpe, and auto-judges ML filter value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:58:24 +09:00
21in7
c29d3e0569 feat(ml): add purged gap (embargo=24) to walk-forward + ablation CLI
- Add LOOKAHEAD embargo between train/val splits in all 3 WF functions
  to prevent label leakage from 6h lookahead window
- Add --ablation flag to train_model.py for signal_strength/side
  dependency diagnosis (A/B/C experiment with drop analysis)
- Criteria: A→C drop ≤0.05=good, 0.05-0.10=conditional, ≥0.10=redesign

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:42:51 +09:00
21in7
30ddb2fef4 feat(ml): relax training thresholds for 5-10x more training samples
Add TRAIN_* constants (signal_threshold=2, adx=15, vol_mult=1.5, neg_ratio=3)
as dataset_builder defaults. Remove hardcoded negative_ratio=5 from all callers.
Bot entry conditions unchanged (config.py strict values).

WF 5-fold results (all symbols AUC 0.91+):
- XRPUSDT: 0.9216 ± 0.0052
- SOLUSDT:  0.9174 ± 0.0063
- DOGEUSDT: 0.9222 ± 0.0085

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:38:15 +09:00
21in7
6830549fd6 fix: ML pipeline train-serve alignment and backtest accuracy
- Parameterize SL/TP multipliers in dataset_builder (C1)
- Pass SL/TP from all callers with CLI args --sl-mult/--tp-mult (C1)
- Align default SL/TP to 2.0/2.0 matching config.py (C1)
- Include unrealized PnL in backtester equity curve (I4)
- Remove MLX double normalization in walk-forward (C3)
- Use stratified_undersample in MLX training (I1)
- Add MLFilter.from_model() factory method (I3)
- Fix backtest_validator initial_balance hardcoding (I5)
- Deprecate legacy generate_dataset()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:44:07 +09:00
21in7
fe99885faa fix(ml): align dataset_builder default SL/TP with config (2.0/2.0)
Module-level ATR_SL_MULT was 1.5, now 2.0 to match config.py and CLI defaults.
This ensures generate_dataset_vectorized() produces correct labels even without
explicit parameters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:43:09 +09:00
21in7
4533118aab docs: update plan history with ml-pipeline-fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:39:14 +09:00
21in7
c0da46c60a chore: deprecate legacy dataset generation, remove stale comparison test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 18:38:07 +09:00
21in7
5bad7dd691 refactor(ml): add MLFilter.from_model(), fix validator initial_balance
- MLFilter.from_model() classmethod eliminates brittle __new__() private-attribute
  manipulation in backtester walk-forward model injection
- backtest_validator._check_invariants() now accepts cfg and uses cfg.initial_balance
  instead of a hardcoded 1000.0 for the negative-balance invariant check
- backtester.py walk-forward injection block simplified to use the new factory method

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 18:36:30 +09:00
21in7
a34fc6f996 fix(mlx): use stratified_undersample consistent with LightGBM
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 18:33:36 +09:00
21in7
24f0faa540 fix(mlx): remove double normalization in walk-forward validation
Add normalize=False parameter to MLXFilter.fit() so external callers
can skip internal normalization. Remove the external normalization +
manual _mean/_std reset hack from walk_forward_auc() in train_mlx_model.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 18:31:11 +09:00
21in7
0fe87bb366 fix(backtest): include unrealized PnL in equity curve for accurate MDD
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 18:26:09 +09:00
21in7
0cc5835b3a fix(ml): pass SL/TP multipliers to dataset generation — align train/serve
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 18:16:50 +09:00
21in7
75d1af7fcc feat(ml): parameterize SL/TP multipliers in dataset_builder
Add atr_sl_mult and atr_tp_mult parameters to _calc_labels_vectorized
and generate_dataset_vectorized, defaulting to existing constants (1.5,
2.0) for full backward compatibility. Callers (train scripts, backtester)
can now pass symbol-specific multipliers without modifying module-level
constants.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 18:03:24 +09:00
21in7
41b0aa3f28 fix: address code review round 2 — 9 issues (2 critical, 3 important, 4 minor)
Critical:
- #2: Add _entry_lock in RiskManager to serialize concurrent entry (balance race)
- #3: Add startTime to get_recent_income + record _entry_time_ms (SYNC PnL fix)

Important:
- #1: Add threading.Lock + _run_api() helper for thread-safe Client access
- #4: Convert reset_daily to async with lock
- #8: Add 24h TTL to exchange_info_cache

Minor:
- #7: Remove duplicate Indicators creation in _open_position (use ATR directly)
- #11: Add input validation for LEVERAGE, MARGIN ratios, ML_THRESHOLD
- #12: Replace hardcoded corr[0]/corr[1] with dict-based dynamic access
- #14: Add fillna(0.0) to LightGBM path for NaN consistency with ONNX

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 17:26:15 +09:00
21in7
e3623293f7 fix(dashboard): trades pagination + reproducible Docker build
- Add pagination controls to Trades tab (prev/next, offset support)
- Reset page on symbol change
- Use package-lock.json + npm ci for reproducible UI builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 17:15:48 +09:00
21in7
13c2b95c8e docs: update README/ARCHITECTURE with critical bugfix features
Add SL/TP atomicity (retry + emergency close), graceful shutdown,
_close_lock race condition fix, and update startup log examples.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:02:02 +09:00
21in7
9f0057e29d fix(dashboard): address code review — auth, DB stability, idempotency, UI fixes
C1: /api/reset에 API key 인증 추가 (DASHBOARD_RESET_KEY 환경변수)
C2: /proc 스캐닝 제거, PID file + SIGHUP 기반 파서 재파싱으로 교체
C3: daily_pnl 업데이트를 trades 테이블에서 재계산하여 idempotent하게 변경
I1: CORS origins를 CORS_ORIGINS 환경변수로 설정 가능하게 변경
I2: offset 파라미터에 ge=0 검증 추가
I3: 매 줄 commit → 파일 단위 배치 commit으로 성능 개선
I4: _pending_candles 크기 제한으로 메모리 누적 방지
I5: bot.log glob 중복 파싱 제거 (sorted(set(...)))
I6: /api/health 에러 메시지에서 내부 경로 미노출
I7: RSI 차트(데이터 없음)를 OI 변화율 차트로 교체
M1: pnlColor 변수 shadowing 수정 (posPnlColor)
M2: 거래 목록에 API total 필드 사용
M3: dashboard/ui/.dockerignore 추가
M4: API Dockerfile Python 3.11→3.12
M5: 테스트 fixture에서 temp DB cleanup 추가
M6: 누락 테스트 9건 추가 (health, daily, reset 인증, offset, pagination)
M7: 파서 SIGTERM graceful shutdown + entrypoint.sh signal forwarding
DB: 양쪽 busy_timeout=5000 + WAL pragma 설정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:00:16 +09:00
21in7
f14c521302 fix: critical bugs — double fee, SL/TP atomicity, PnL race, graceful shutdown
C5: Remove duplicate entry_fee deduction in backtester (balance and net_pnl)
C1: Add SL/TP retry (3x) with emergency market close on final failure
C3: Add _close_lock to prevent PnL double recording between callback and monitor
C8: Add SIGTERM/SIGINT handler with per-symbol order cancellation before exit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:55:14 +09:00
21in7
e648ae7ca0 fix: critical production issues — WebSocket reconnect, ghost positions, ONNX NaN
- fix(data_stream): add reconnect loop to MultiSymbolStream matching UserDataStream pattern
  Prevents bot-wide crash on WebSocket disconnect (#3 Critical)

- fix(data_stream): increase buffer_size 200→300 and preload 200→300
  Ensures z-score window (288) has sufficient data (#5 Important)

- fix(bot): sync risk manager when Binance has no position but local state does
  Prevents ghost entries in open_positions blocking future trades (#1 Critical)

- fix(ml_filter): add np.nan_to_num for ONNX input to handle NaN features
  Prevents all signals being blocked during initial ~2h warmup (#2 Critical)

- fix(bot): replace _close_handled_by_sync with current_trade_side==None guard
  Eliminates race window in SYNC PnL double recording (#4 Important)

- feat(bot): add _ensure_sl_tp_orders in _recover_position
  Detects and re-places missing SL/TP orders on bot restart (#6 Important)

- feat(exchange): add get_open_orders method for SL/TP verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:37:47 +09:00
21in7
e3a78974b3 fix: address follow-up review findings
- fix(notifier): capture fire-and-forget Future exceptions via done_callback
- fix(bot): add _close_event.set() in SYNC path to unblock _close_and_reenter
- fix(ml_features): apply z-score to oi_price_spread (oi_z - ret_1_z) matching training
- fix(backtester): clean up import ordering after _calc_trade_stats extraction
- fix(backtester): correct Sharpe annualization for 24/7 crypto (365d × 96 = 35,040)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:10:02 +09:00
21in7
181f82d3c0 fix: address critical code review issues (PnL double recording, sync HTTP, race conditions)
- fix(bot): prevent PnL double recording in _close_and_reenter using asyncio.Event
- fix(bot): prevent SYNC detection PnL duplication with _close_handled_by_sync flag
- fix(notifier): move sync HTTP call to background thread via run_in_executor
- fix(risk_manager): make is_trading_allowed async with lock for thread safety
- fix(exchange): cache exchange info at class level (1 API call for all symbols)
- fix(exchange): use `is not None` instead of truthy check for price/stop_price
- refactor(backtester): extract _calc_trade_stats to eliminate code duplication
- fix(ml_features): apply rolling z-score to OI/funding rate in serving (train-serve skew)
- fix(bot): use config.correlation_symbols instead of hardcoded BTCUSDT/ETHUSDT
- fix(bot): expand OI/funding history deque to 96 for z-score window
- cleanup(config): remove unused stop_loss_pct, take_profit_pct, trailing_stop_pct fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:03:52 +09:00
21in7
24ed7ddec0 docs: add kill switch, SOL symbol swap, and analysis tools to docs
- README: add kill switch section with Slow Bleed explanation, env vars
- README: update SYMBOLS to XRPUSDT,SOLUSDT,DOGEUSDT, add SOL params
- README: add compare_symbols.py and position_sizing_analysis.py to tree
- ARCHITECTURE: add Gate 0 (kill switch) to entry flow, update risk table
- ARCHITECTURE: add trade recording + kill check to TP/SL scenario
- ARCHITECTURE: update weekly report pipeline (7 steps with kill monitoring)
- CLAUDE.md: add kill switch description to architecture section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 00:04:06 +09:00
21in7
b86aa8b072 feat(weekly-report): add kill switch monitoring section
- Load trade history from data/trade_history/{symbol}.jsonl
- Show per-symbol: consecutive loss streak vs threshold, recent 15-trade PF
- 2-tier alert: clean numbers for normal, ⚠/🔴 KILLED for danger zone
- Inserted before ML retraining checklist in Discord report

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 23:58:22 +09:00
21in7
42e53b9ae4 perf: optimize kill switch - tail-read only last N lines on boot
- Replace full file scan with _tail_lines() that reads from EOF
- Only load max(FAST_KILL=8, SLOW_KILL=15) lines on boot
- Trim in-memory trade history to prevent unbounded growth
- No I/O bottleneck regardless of history file size

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 23:50:17 +09:00
21in7
4930140b19 feat: add dual-layer kill switch (Fast Kill + Slow Kill)
- Fast Kill: 8 consecutive net losses → block new entries for symbol
- Slow Kill: last 15 trades PF < 0.75 → block new entries for symbol
- Trade history persisted to data/trade_history/{symbol}.jsonl (survives restart)
- Boot-time retrospective check restores kill state from history
- Manual reset via RESET_KILL_SWITCH_{SYMBOL}=True in .env + restart
- Entry blocked, exits (SL/TP/manual) always work normally
- Discord alert on kill switch activation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 23:48:52 +09:00
21in7
f890009a92 chore: replace TRXUSDT with SOLUSDT in trading symbols
- Switch SYMBOLS from XRPUSDT,TRXUSDT,DOGEUSDT to XRPUSDT,SOLUSDT,DOGEUSDT
- Add SOLUSDT params: SL=1.0x, TP=4.0x, ADX=20, margin_max=0.08
- Remove TRXUSDT params from .env.example

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 23:38:32 +09:00
21in7
5b3f6af13c feat: add symbol comparison and position sizing analysis tools
- Add payoff_ratio and max_consecutive_losses to backtester summary
- Add compare_symbols.py: per-symbol parameter sweep for candidate evaluation
- Add position_sizing_analysis.py: robust Monte Carlo position sizing
- Fetch historical data for SOL, LINK, AVAX candidates (365 days)
- Update existing symbol data (XRP, TRX, DOGE)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 23:35:42 +09:00
21in7
9d9f4960fc fix(dashboard): update signal regex to match new log format with extra fields
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:57:51 +09:00
21in7
8c1cd0422f fix(dashboard): use actual leverage from bot_status instead of hardcoded 10x
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:07:54 +09:00
21in7
4792b0f9cf fix(dashboard): clean up stale position cache on unmatched close events
_handle_close was not clearing _current_positions when no matching OPEN
trade was found in DB, causing all subsequent entries for the same
symbol+direction to be silently skipped. Also add PYTHONUNBUFFERED=1
and python -u to make log parser crashes visible in docker logs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:10:15 +09:00
21in7
652990082d fix(weekly-report): calculate combined metrics directly from trades
The combined summary (PF, MDD, win_rate) was indirectly reconstructed
from per-symbol averages using round(win_rate * n), which introduced
rounding errors. MDD was max() of individual symbol MDDs, ignoring
simultaneous drawdowns across the correlated crypto portfolio.

Now computes all combined metrics directly from the trade list:
- PF: sum(wins) / sum(losses) from actual trade PnLs
- MDD: portfolio equity curve from time-sorted trades
- Win rate: direct count from trade PnLs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 20:12:42 +09:00
21in7
5e3a207af4 chore: update strategy parameters and add weekly report for 2026-03-15
- Increased ATR_SL_MULT_TRXUSDT from 1.0 to 2.0 and adjusted ADX_THRESHOLD_TRXUSDT from 30 to 25 in README.
- Added new weekly report files in HTML and JSON formats for 2026-03-15, including detailed backtest summaries and trade data for XRPUSDT, TRXUSDT, and DOGEUSDT.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 19:53:31 +09:00
21in7
ab032691d4 docs: update README/ARCHITECTURE with per-symbol strategy params
- Add per-symbol env var override examples to README strategy section
- Add per-symbol env vars to environment variable reference table
- Update ARCHITECTURE multi-symbol section with SymbolStrategyParams
- Update CLAUDE.md configuration section
- Update test counts to 138

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 17:31:47 +09:00
21in7
55c20012a3 feat: add per-symbol strategy params with sweep-optimized values
Support per-symbol strategy parameters (ATR_SL_MULT_XRPUSDT, etc.)
via env vars, falling back to global defaults. Sweep results:
- XRPUSDT: SL=1.5 TP=4.0 ADX=30 (PF 2.39, Sharpe 61.0)
- TRXUSDT: SL=1.0 TP=4.0 ADX=30 (PF 3.87, Sharpe 62.8)
- DOGEUSDT: SL=2.0 TP=2.0 ADX=30 (PF 1.80, Sharpe 44.1)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 17:28:14 +09:00
21in7
106eaf182b fix: accumulate partial fills in UserDataStream for accurate PnL
MARKET orders can fill in multiple trades (PARTIALLY_FILLED → FILLED).
Previously only the last fill's rp/commission was captured, causing
under-reported PnL. Now accumulates rp and commission across all
partial fills per order_id and sums them on final FILLED event.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:47:34 +09:00
21in7
64f56806d2 fix: resolve 6 warning issues from code review
5. Add daily PnL reset loop — UTC midnight auto-reset via
   _daily_reset_loop in main.py, prevents stale daily_pnl accumulation
6. Fix set_base_balance race condition — call once in main.py before
   spawning bots, instead of each bot calling independently
7. Remove realized_pnl != 0 from close detection — prevents entry
   orders with small rp values being misclassified as closes
8. Rename xrp_btc_rs/xrp_eth_rs → primary_btc_rs/primary_eth_rs —
   generic column names for multi-symbol support (dataset_builder,
   ml_features, and tests updated consistently)
9. Replace asyncio.get_event_loop() → get_running_loop() — fixes
   DeprecationWarning on Python 3.10+
10. Parallelize candle preload — asyncio.gather for all symbols
    instead of sequential REST calls, ~3x faster startup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:44:40 +09:00
21in7
8803c71bf9 fix: resolve 4 critical bugs from code review
1. Margin ratio calculated on per_symbol_balance instead of total balance
   — previously amplified margin reduction by num_symbols factor
2. Replace Algo Order API (algoType=CONDITIONAL) with standard
   futures_create_order for SL/TP — algo API is for VP/TWAP, not
   conditional orders; SL/TP may have silently failed
3. Fallback PnL (SYNC close) now sums all recent income rows instead
   of using only the last entry — prevents daily_pnl corruption in
   multi-fill scenarios
4. Explicit state transition in _close_and_reenter — clear local
   position state after close order to prevent race with User Data
   Stream callback on position count

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:39:51 +09:00
21in7
b188607d58 fix(dashboard): use dynamic DNS resolution for API proxy
Nginx caches DNS at startup, so when dashboard-api restarts and gets
a new container IP, the proxy breaks with 502. Use Docker's embedded
DNS resolver (127.0.0.11) with a variable-based proxy_pass to
re-resolve on every request.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:07:52 +09:00
21in7
9644cf4ff0 fix(dashboard): prevent duplicate trades on container restart
Add UNIQUE(symbol, entry_time, direction) constraint to trades table
and use INSERT OR IGNORE to skip duplicates. Includes auto-migration
to clean up existing duplicate entries on startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 16:34:05 +09:00
21in7
805f1b0528 fix: fetch actual PnL from Binance income API on SYNC close detection
When the position monitor detects a missed close via API fallback, it
now queries Binance futures_income_history to get the real realized PnL
and commission instead of logging zeros. Exit price is estimated from
entry price + PnL/quantity. This ensures the dashboard records accurate
profit data even when WebSocket events are missed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 12:43:27 +09:00
21in7
363234ac7c fix: add fallback position sync check to detect missed WebSocket closes
The position monitor now checks Binance API every 5 minutes to verify
the bot's internal state matches the actual position. If the bot thinks
a position is open but Binance shows none, it syncs state and logs a
SYNC close event. This prevents the bot from being stuck in a phantom
position when User Data Stream misses a TP/SL fill event.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 12:41:23 +09:00
21in7
de27f85e6d chore: update .gitignore, modify log file pattern, and add package-lock.json
- Added entries to .gitignore for node_modules and dist directories in the dashboard UI.
- Updated log file pattern in log_parser.py to match 'bot*.log' instead of 'bot_*.log'.
- Introduced package-lock.json for the dashboard UI to manage dependencies.
- Updated CLAUDE.md to reflect the status of code review improvements.
- Added new weekly report files in HTML and JSON formats for 2026-03-07.
- Updated binary parquet files for dogeusdt, trxusdt, and xrpusdt with new data.
2026-03-09 22:57:23 +09:00
21in7
cdde1795db fix(dashboard): preserve DB data across log parser restarts
Changed _init_db() from DROP+CREATE to CREATE IF NOT EXISTS so that
trade history, candle data, and daily PnL survive container restarts.
Previously all tables were dropped on every parser start, losing
historical data if log files had been rotated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:55:04 +09:00
21in7
d03012bb04 fix(dashboard): detect symbols from any bot_status key, not just last_start
The /api/symbols endpoint only returned symbols that had a :last_start
key, which requires the log parser to catch the bot start log. If the
dashboard was deployed after the bot started, the start log was already
past the file position and symbols showed as 0. Now extracts symbols
from any colon-prefixed key in bot_status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:52:21 +09:00
21in7
af91b36467 feat(dashboard): show unrealized PnL on position cards (5min update)
Parse position monitor logs (5min interval) to update current_price,
unrealized_pnl and unrealized_pnl_pct in bot_status. Position cards
now display USDT amount and percentage, colored green/red. Falls back
to entry/current price calculation if monitor data unavailable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:55:53 +09:00
21in7
c6c60b274c fix: use dynamic quantity/price precision per symbol from exchange info
Hardcoded round(qty, 1) caused -1111 Precision errors for TRXUSDT and
DOGEUSDT (stepSize=1, requires integers). Now lazily loads quantityPrecision
and pricePrecision from Binance futures_exchange_info per symbol. SL/TP
prices also use symbol-specific precision instead of hardcoded 4 decimals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:07:23 +09:00
21in7
97aef14d6c fix: add retry with exponential backoff to OI/funding API calls (#4)
_fetch_oi_hist and _fetch_funding_rate had no retry logic, causing
crashes on rate limit (429) or transient errors during weekly report
data collection. Added _get_json_with_retry helper (max 3 attempts,
exponential backoff). Updated code-review docs to reflect completion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:00:52 +09:00
21in7
afdbacaabd fix(dashboard): prevent infinite API polling loop
useCallback dependency on `symbols` state caused fetchAll to recreate
on every call (since it sets symbols), triggering useEffect to restart
the interval immediately. Use symbolsRef to break the cycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 14:31:28 +09:00