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>
3.6 KiB
Code Review Fixes Round 2 Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Fix 9 issues from code review re-evaluation (2 Critical, 3 Important, 4 Minor)
Architecture: Targeted fixes across risk_manager, exchange, bot, config, ml_filter. No new files — all modifications to existing modules.
Tech Stack: Python 3.12, asyncio, python-binance, LightGBM, ONNX Runtime
Task 1: #2 Critical — Balance reservation lock for concurrent entry
Files:
- Modify:
src/risk_manager.py— add_entry_lockto serialize entry flow - Modify:
src/bot.py:405-413— acquire entry lock around balance read → order - Test:
tests/test_risk_manager.py
The simplest fix: add an asyncio.Lock in RiskManager that serializes the entire _open_position flow across all bots. This prevents two bots from reading the same balance simultaneously.
- Add
_entry_lock = asyncio.Lock()to RiskManager - Add
async def entry_lock(self)context manager - In bot.py
_open_position, wrap balance read + order underasync with self.risk.entry_lock() - Add test for concurrent entry serialization
- Run tests
Task 2: #3 Critical — SYNC PnL startTime + single query
Files:
-
Modify:
src/exchange.py:166-185— addstart_timeparam toget_recent_income -
Modify:
src/bot.py:75-82— record_entry_timeon position open -
Modify:
src/bot.py:620-629— passstart_timeto income query -
Test:
tests/test_exchange.py -
Add
_entry_time: int | None = Noneto TradingBot -
Set
_entry_time = int(time.time() * 1000)on entry and recovery -
Add
start_timeparameter toget_recent_income() -
Use start_time in SYNC fallback
-
Add test
-
Run tests
Task 3: #1 Important — Thread-safe Client access
Files:
-
Modify:
src/exchange.py— addthreading.Lockper instance -
Add
self._api_lock = threading.Lock()in__init__ -
Wrap all
run_in_executorlambdas with lock acquisition -
Add test
-
Run tests
Task 4: #4 Important — reset_daily async with lock
Files:
-
Modify:
src/risk_manager.py:61-64— make async + lock -
Modify:
main.py:22— await reset_daily -
Test:
tests/test_risk_manager.py -
Convert
reset_dailyto async, add lock -
Update
_daily_reset_loopcall -
Add test
-
Run tests
Task 5: #8 Important — exchange_info cache TTL
Files:
-
Modify:
src/exchange.py:25-34— add TTL (24h) -
Add
_exchange_info_time: float = 0.0 -
Check TTL in
_get_exchange_info -
Add test
-
Run tests
Task 6: #7 Minor — Pass pre-computed indicators to _open_position
Files:
-
Modify:
src/bot.py:392,415,736— pass df_with_indicators -
Add
df_with_indicatorsparameter to_open_position -
Use passed df instead of re-creating Indicators
-
Run tests
Task 7: #11 Minor — Config input validation
Files:
-
Modify:
src/config.py:39— add range checks -
Test:
tests/test_config.py -
Add validation for LEVERAGE, MARGIN ratios, ML_THRESHOLD
-
Add test for invalid values
-
Run tests
Task 8: #12 Minor — Dynamic correlation symbol access
Files:
-
Modify:
src/bot.py:196-198— iterate dynamically -
Replace hardcoded [0]/[1] with dict-based access
-
Run tests
Task 9: #14 Minor — Normalize NaN handling for LightGBM
Files:
-
Modify:
src/ml_filter.py:144-147— apply nan_to_num for LightGBM too -
Add
np.nan_to_numto LightGBM path -
Run tests