From 13c2b95c8ef260eacf751a4eb7d91c626dbf9406 Mon Sep 17 00:00:00 2001 From: 21in7 Date: Fri, 20 Mar 2026 00:02:02 +0900 Subject: [PATCH] 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) --- ARCHITECTURE.md | 12 +++++++++--- README.md | 12 ++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 6c244c2..afe7b0a 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -331,10 +331,13 @@ ML 필터를 통과한 신호를 실제 주문으로 변환하고, 리스크 한 ``` 1. set_leverage(10x) 2. place_order(MARKET) ← 진입 -3. place_order(STOP_MARKET) ← SL 설정 -4. place_order(TAKE_PROFIT_MARKET) ← TP 설정 +3. place_order(STOP_MARKET) ← SL 설정 (3회 재시도) +4. place_order(TAKE_PROFIT_MARKET) ← TP 설정 (3회 재시도) +※ SL/TP 최종 실패 시 → 긴급 시장가 청산 + Discord 알림 ``` +**SL/TP 원자성 보장:** SL/TP 배치는 `_place_sl_tp_with_retry()`로 3회 재시도합니다. 개별 추적(SL 성공 후 TP만 재시도)하여 불필요한 중복 주문을 방지합니다. 모든 재시도 실패 시 `_emergency_close()`가 포지션을 즉시 시장가 청산하고 Discord로 긴급 알림을 전송합니다. + **리스크 제어:** | 제어 항목 | 기준 | 방어 대상 | @@ -351,6 +354,8 @@ ML 필터를 통과한 신호를 실제 주문으로 변환하고, 리스크 한 **마진 균등 배분:** 멀티심볼 모드에서 각 봇은 전체 잔고를 심볼 수로 나눈 금액만큼만 사용합니다 (`balance / len(symbols)`). 공유 `RiskManager`의 `asyncio.Lock`으로 동시 포지션 등록/해제 시 경합 조건을 방지합니다. +**Graceful Shutdown:** `main.py`에서 `SIGTERM`/`SIGINT` 시그널을 수신하면 `_graceful_shutdown()`이 실행됩니다. 각 봇의 오픈 주문을 심볼별로 취소(5초 타임아웃)한 후 모든 asyncio 태스크를 정리합니다. Docker `docker stop` 또는 `kill` 시 고아 주문이 거래소에 남지 않습니다. + --- ### Layer 5: Event / Alert Layer @@ -659,6 +664,7 @@ sequenceDiagram - 체결 즉시 감지 (폴링 방식의 최대 15분 지연 해소) - `realized_pnl - commission` = 정확한 순수익 (슬리피지·수수료 포함) - `_is_reentering` 플래그: 반대 시그널 재진입 중에는 콜백이 신규 포지션 상태를 초기화하지 않음 +- `_close_lock`: 콜백(`_on_position_closed`)과 포지션 모니터(`_position_monitor` SYNC 경로) 간 PnL 이중기록 방지. asyncio await 포인트 사이 경쟁 조건을 Lock으로 원자화 --- @@ -729,7 +735,7 @@ bash scripts/run_tests.sh # 래퍼 스크립트 실행 | 파일 | 레이어 | 역할 | |------|--------|------| -| `main.py` | — | 진입점. 심볼별 `TradingBot` 생성 + 공유 `RiskManager` + `asyncio.gather()` | +| `main.py` | — | 진입점. 심볼별 `TradingBot` 생성 + 공유 `RiskManager` + `asyncio.gather()` + SIGTERM/SIGINT graceful shutdown | | `src/bot.py` | 오케스트레이터 | 심볼별 독립 트레이딩 루프 + 듀얼 레이어 킬스위치 | | `src/config.py` | — | 환경변수 기반 설정 (`symbols` 리스트, `correlation_symbols`, 심볼별 `SymbolStrategyParams`) | | `src/data_stream.py` | Data | Combined WebSocket 캔들 수신·버퍼 관리 | diff --git a/README.md b/README.md index a1b58ff..b18da8f 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,10 @@ Binance Futures 자동매매 봇. 복합 기술 지표와 ML 필터(LightGBM / M - **반대 시그널 재진입**: 보유 포지션과 반대 신호 발생 시 즉시 청산 후 재진입 - **리스크 관리**: 동일 방향 포지션 제한, 일일 손실 한도(5%), 동적 증거금 비율 - **듀얼 레이어 킬스위치**: Fast Kill(8연속 순손실) + Slow Kill(15거래 PF<0.75) — 심볼별 독립 차단, 기존 포지션 청산은 정상 작동 +- **SL/TP 원자성 보장**: SL/TP 배치 3회 재시도 + 최종 실패 시 긴급 시장가 청산 - **실시간 TP/SL 감지**: Binance User Data Stream으로 즉시 감지 -- **Discord 알림**: 진입·청산·킬스위치 발동·오류 이벤트 실시간 웹훅 알림 +- **Graceful Shutdown**: SIGTERM/SIGINT 시 심볼별 오픈 주문 취소 후 정상 종료 +- **Discord 알림**: 진입·청산·킬스위치 발동·긴급 청산·오류 이벤트 실시간 웹훅 알림 - **모니터링 대시보드**: 거래 내역, 수익 통계, 차트를 웹에서 조회 - **주간 전략 리포트**: 자동 성능 측정, 추이 추적, 킬스위치 모니터링, ML 재학습 시점 판단 - **종목 비교 분석**: 심볼별 파라미터 sweep + Robust Monte Carlo 포지션 사이징 @@ -82,9 +84,11 @@ python main.py 봇이 정상 실행되면 다음과 같은 로그가 출력됩니다: ``` -INFO | 봇 시작: XRPUSDT (레버리지 10x) -INFO | 과거 캔들 200개 프리로드 완료 -INFO | WebSocket 연결 완료 +INFO | 기준 잔고 설정: 1000.00 USDT +INFO | [XRPUSDT] 봇 시작, 레버리지 10x | SL=2.0x TP=2.0x Signal≥3 ADX≥25.0 Vol≥2.5x +INFO | [XRPUSDT] 기존 포지션 없음 - 신규 진입 대기 +INFO | [XRPUSDT] OI 히스토리 초기화: 5개 +INFO | Kline WebSocket 연결 완료 ``` Discord 웹훅을 설정했다면 진입/청산 시 실시간 알림을 받게 됩니다.