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>
This commit is contained in:
@@ -12,17 +12,18 @@ class RiskManager:
|
||||
self.open_positions: dict[str, str] = {} # {symbol: side}
|
||||
self._lock = asyncio.Lock()
|
||||
|
||||
def is_trading_allowed(self) -> bool:
|
||||
async def is_trading_allowed(self) -> bool:
|
||||
"""일일 최대 손실 초과 시 거래 중단"""
|
||||
if self.initial_balance <= 0:
|
||||
async with self._lock:
|
||||
if self.initial_balance <= 0:
|
||||
return True
|
||||
loss_pct = abs(self.daily_pnl) / self.initial_balance
|
||||
if self.daily_pnl < 0 and loss_pct >= self.max_daily_loss_pct:
|
||||
logger.warning(
|
||||
f"일일 손실 한도 초과: {loss_pct:.2%} >= {self.max_daily_loss_pct:.2%}"
|
||||
)
|
||||
return False
|
||||
return True
|
||||
loss_pct = abs(self.daily_pnl) / self.initial_balance
|
||||
if self.daily_pnl < 0 and loss_pct >= self.max_daily_loss_pct:
|
||||
logger.warning(
|
||||
f"일일 손실 한도 초과: {loss_pct:.2%} >= {self.max_daily_loss_pct:.2%}"
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
async def can_open_new_position(self, symbol: str, side: str) -> bool:
|
||||
"""포지션 오픈 가능 여부 (전체 한도 + 중복 진입 + 동일 방향 제한)"""
|
||||
|
||||
Reference in New Issue
Block a user