You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|**signal_generator.py**|`strategies.yaml` 스코어링 가중치로 점수 합산 → BUY/SELL/HOLD. `generate(df)`, `get_latest_signal(df)`. **`collinearity_mode`**: `max_per_direction`(방향별 최대 1개) 또는 `representative_only`(3그룹 대표 1개씩=MACD+볼린저+거래량만 사용, 권장). 초기화 시 가격 모멘텀 그룹 다중공선성 경고 자동 출력. |
| **order_executor.py** | `trading.mode`: paper면 DB만, live면 KIS API. 거래 시간·블랙스완 쿨다운·**실적 발표일 필터**(`skip_earnings_days`) 검사, 재시도(지수 백오프+지터). PositionLock, OrderGuard·KIS 미체결 조회. `max_monthly_roundtrips`로 종목·모드·계좌별 월간 신규 BUY 횟수를 운영 주문에서도 제한하고, `drawdown.max_portfolio_mdd`/`max_daily_loss`에 닿으면 신규 BUY만 fail-closed 차단한다. live 손실 한도 확인에서 KIS 잔고가 확인되지 않으면 DB fallback 평가금액으로 신규 BUY를 판단하지 않고 차단한다. 시장 국면 필터가 `allow_buys=false`를 반환하면 직접 executor BUY 호출도 주문 전 중단한다. SELL/exit는 손실 축소 경로라 월간 cap·손실 한도와 무관하게 계속 허용한다. live 주문 전 미체결 조회 실패는 `live_unfilled_check.checked=False`로 fail-closed 차단한다. live 주문 ACK 뒤 체결가·체결수량 확인이 안 되거나 부분체결이면 `ACKED`/`PARTIAL_FILLED` pending으로 `order_records`에 저장하고 DB 거래·포지션 반영을 보류한다. `SUBMITTED`/`ACKED`/`PARTIAL_FILLED` 상태가 남아 있으면 OrderGuard TTL이 지나도 같은 종목 신규 주문을 차단한다. 이때 반환값의 `success=False`는 브로커 주문 없음이 아니라 reconcile 필요 상태다. **Dead-letter 큐**: 모든 재시도 실패 시 `FailedOrder` 테이블에 영구 저장. |
275
+
| **order_executor.py** | `trading.mode`: paper면 DB만, live면 KIS API. 거래 시간·블랙스완 쿨다운·**실적 발표일 필터**(`skip_earnings_days`) 검사, 재시도(지수 백오프+지터). PositionLock, OrderGuard·KIS 미체결 조회. `max_monthly_roundtrips`로 종목·모드·계좌별 월간 신규 BUY 횟수를 운영 주문에서도 제한하고, `drawdown.max_portfolio_mdd`/`max_daily_loss`에 닿으면 신규 BUY만 fail-closed 차단한다. MDD 한도 돌파 후에는 **히스테리시스**(RiskManager.check_mdd의 `_is_halted`)가 한도의 절반 아래로 회복할 때까지 신규 BUY 차단을 유지한다 — 한도 경계 깜빡 회복 시 재진입→재돌파 반복 방지(상시 스케줄러에서 누적 동작, 1회성 CLI는 정적 체크와 동일). live 손실 한도 확인에서 KIS 잔고가 확인되지 않으면 DB fallback 평가금액으로 신규 BUY를 판단하지 않고 차단한다. 시장 국면 필터가 `allow_buys=false`를 반환하면 직접 executor BUY 호출도 주문 전 중단한다. SELL/exit는 손실 축소 경로라 월간 cap·손실 한도와 무관하게 계속 허용한다. live 주문 전 미체결 조회 실패는 `live_unfilled_check.checked=False`로 fail-closed 차단한다. live 주문 ACK 뒤 체결가·체결수량 확인이 안 되거나 부분체결이면 `ACKED`/`PARTIAL_FILLED` pending으로 `order_records`에 저장하고 DB 거래·포지션 반영을 보류한다. `SUBMITTED`/`ACKED`/`PARTIAL_FILLED` 상태가 남아 있으면 OrderGuard TTL이 지나도 같은 종목 신규 주문을 차단한다. 이때 반환값의 `success=False`는 브로커 주문 없음이 아니라 reconcile 필요 상태다. **Dead-letter 큐**: 모든 재시도 실패 시 `FailedOrder` 테이블에 영구 저장. |
276
276
|**portfolio_manager.py**| 보유 포지션·잔고·수익률. `sync_with_broker()`로 KIS 잔고↔DB 크로스체크. live `get_portfolio_summary()`는 조회용 DB fallback 여부를 `broker_balance_ok/source/error`로 표시하고, 주문 sizing에 쓰는 `get_current_capital()`/`get_available_cash()`는 KIS 잔고 미확인 시 예외로 fail-closed 처리한다. 자동보정 시 KIS 기준 수량을 절대값으로 반영하고, 복구 포지션에는 손절·익절·트레일링 스탑을 재생성한다. |
277
277
|**basket_rebalancer.py**| 바스켓 리밸런싱 엔진. `baskets.yaml`에서 바스켓 로드. `get_target_weights()`(신호 가중 지원), `get_current_weights()`, `calculate_drift()`, `should_rebalance()`(drift/weekly/monthly 트리거), `plan_rebalance()`(SELL→BUY 순서, max_turnover 제한), `execute()`(dry_run 지원). paper BUY 실행은 `PortfolioManager.get_current_capital()`/`get_available_cash()`로 자본과 현금을 조회한 뒤 `OrderExecutor.execute_buy_quantity()`에 넘긴다. live 실행은 `basket_rebalance:<basket>` 승인 단위가 account_key와 주문 strategy에 동일하게 전달되고, KIS↔DB 포지션 동기화가 성공해야 주문 실행부에 도달한다. CLI와 스케줄러 자동 체크 모두 같은 승인 단위를 사용한다. `get_status_report()`로 현황 리포트 생성. |
278
278
|**scheduler.py**| 실전 무한 루프. 장전/장중/장마감. **시장 국면 필터**(단계적: bearish→매수 중단, caution→사이징 축소). 장중 10분 간격. 루프 10분 초과 시 다음 사이클 스킵. 장전 단계에서 **바스켓 리밸런싱 자동 체크** (`_run_basket_rebalance_check`). live에서는 바스켓별 `basket_rebalance:<basket>` readiness gate와 KIS↔DB 동기화를 통과한 뒤에만 주문 계획과 실행으로 넘어간다. live 신규 진입 중 `requires_reconcile` 또는 `order_pending` 결과가 나오면 남은 BUY 후보와 같은 루프 재스캔을 중단하고, 다음 성공적인 KIS↔DB 동기화 전까지 미확정 체결분을 무시한 추가 진입을 막는다. **전략 레지스트리** 기반 `_get_strategy()`. |
0 commit comments