feat(execution): 체결가 0/None 시 지정가 백필 가드 + WARN 로깅 (dcy-032/BAT-048)
REQ-095(슬롯 평단·원장 price 지정가 백필, 0 오염 방지) + REQ-096(백필/미해결 WARN 로깅) 구현. 지정가 부재 시 skip+강WARN. application 단일화(_resolve_fill_price), wire/LedgerTrade 스키마 불변. 575 passed/0 fail, opus QC PASS. REQ-097 알람=스파이크 산출물만(impl 후속). - _resolve_fill_price 헬퍼 추가: avg_price 검증, limit_price 백필, 미해결 WARN - _on_filled/_on_partial_cancel 통합: 백필 적용, 슬롯/원장 일관성 - _record_ledger 시그니처: resolved_price 파라미터 (backward compat) - test_execution_fill_price_backfill.py: 21 시나리오 (avg=None/0, limit=있음/없음 등) - docs: dcy-032, req-095/096/097, bat-048 설계/검증 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
+50
-2
@@ -149,7 +149,54 @@ trex-core는 발행 연결의 idle 종료를 예방하기 위해 `trex-execution
|
||||
|
||||
---
|
||||
|
||||
## 5. 디버깅 / 트러블슈팅
|
||||
## 5. 체결가 백필 WARN 발생 시 운영자 점검 절차 (REQ-095/096 / dcy-032 / BAT-048)
|
||||
|
||||
KIS 체결조회가 체결수량은 보고하면서 평균체결가(`avg`)를 None 또는 0으로 반환하는 순간 레이스가 발생하면, trex-core는 주문 지정가로 백필해 슬롯 평단·원장 cost basis에 0이 저장되지 않도록 보호하고 WARN 로그를 발행한다.
|
||||
|
||||
### WARN 유형 및 로그 식별
|
||||
|
||||
| WARN 유형 | `reason` | 발생 조건 | 의미 |
|
||||
|---|---|---|---|
|
||||
| `avg_price_backfill` | `reason=avg_price_backfill` | avg_price=None/0, limit_price>0 | 지정가로 백필 성공 — 값은 보정됐으나 추적 필요 |
|
||||
| `fill_price_unresolvable` | `reason=fill_price_unresolvable` | avg_price=None/0, limit_price=None/≤0 | 백필 불가 — 체결 skip, 슬롯 PENDING 유지 |
|
||||
|
||||
```bash
|
||||
# avg_price_backfill 확인 (백필 성공)
|
||||
grep "avg_price_backfill" /tmp/trex-core.log
|
||||
|
||||
# fill_price_unresolvable 확인 (백필 불가, 운영자 즉시 개입)
|
||||
grep "fill_price_unresolvable" /tmp/trex-core.log
|
||||
```
|
||||
|
||||
Loki LogQL:
|
||||
```logql
|
||||
{job="trex-core"} | json | line_contains "avg_price_backfill"
|
||||
{job="trex-core"} | json | line_contains "fill_price_unresolvable"
|
||||
```
|
||||
|
||||
### `avg_price_backfill` WARN 발생 시 점검 항목
|
||||
|
||||
1. **로그에서 슬롯·주문 정보 확인**: `slot_id`, `symbol`, `broker_order_id`, `avg_price`(원 값, None 또는 0), `backfill_price`(대체 지정가)를 로그에서 추출.
|
||||
2. **원장 레코드 확인**: 해당 `slot_id`의 `ledger_outbox` price가 백필값(지정가)으로 기록됐는지 확인.
|
||||
```bash
|
||||
psql "$TREX_POSTGRESQL_DSN" -c "SELECT * FROM ledger_outbox WHERE correlation_id LIKE '%<broker_order_id>%'"
|
||||
```
|
||||
3. **슬롯 평단 확인**: `trex-core slots` 또는 DB에서 해당 슬롯의 `avg_price`가 0이 아닌 지정가 기반 값인지 확인.
|
||||
4. **판단**: 백필 지정가는 "0보다 합리적인 근사"지만 실제 체결가와 다를 수 있다. 중요한 포지션이라면 KIS HTS/API에서 실제 체결가를 확인해 `ledger_outbox` 수기 보정 여부를 검토한다(Discovery R-1).
|
||||
|
||||
### `fill_price_unresolvable` WARN 발생 시 즉시 조치
|
||||
|
||||
1. **로그에서 슬롯 정보 확인**: `slot_id`, `symbol`, `broker_order_id` 추출.
|
||||
2. **슬롯 상태 확인**: `trex-core slots --status pending` — 해당 슬롯이 PENDING_BUY 상태로 고착됐는지 확인.
|
||||
3. **KIS HTS/API에서 실제 체결 여부와 가격 확인**.
|
||||
4. **운영자 조치 선택**:
|
||||
- 체결됐다면: `trex-core cancel <slot_id>`로 슬롯을 롤백 후 재진입 매수.
|
||||
- 미체결이라면: `trex-core cancel <slot_id>`로 주문 취소 → 슬롯 rollback(다음 폴링에서 is_terminal_reject 경로).
|
||||
5. **상황이 반복된다면**: Discovery 또는 이슈 트래커에 기록 — `limit_price=None` 매수 주문이 들어온 경로 조사 필요(정상 운용 시 orb 전략은 지정가 주문을 제출한다, Discovery A-1).
|
||||
|
||||
---
|
||||
|
||||
## 6. 디버깅 / 트러블슈팅
|
||||
|
||||
| 증상 | 원인 | 조치 |
|
||||
|---|---|---|
|
||||
@@ -159,7 +206,8 @@ trex-core는 발행 연결의 idle 종료를 예방하기 위해 `trex-execution
|
||||
| intent `rejected: capacity_full` | `max_active_slots`(M) 도달 | 매도 후 재시도 또는 M 상향 |
|
||||
| 매도 미발생 + WARN `sell dispatch skipped` | 브로커 잔고 0(divergence) | reconcile(운영자) — 미러 fallback 없음(설계) |
|
||||
| `RpcTimeoutError` | 데몬 미기동/소비 스레드 크래시 | `/tmp/trex-core.log` traceback 확인 |
|
||||
| 미체결 `pending_*` 고착 | 취소 감지 누락/timeout 미설정 | `trex-core cancel <slot_id>` 백스톱; pending stale WARN 확인 |
|
||||
| 미체결 `pending_*` 고착 | 취소 감지 누락/timeout 미설정/fill_price_unresolvable | `trex-core cancel <slot_id>` 백스톱; pending stale WARN + `fill_price_unresolvable` WARN 확인(§5) |
|
||||
| `avg_price_backfill` WARN | KIS avg_price 순간 레이스(None/0 반환) | 슬롯 평단·원장 price는 지정가로 보정됨 — §5 점검 절차 참고 |
|
||||
|
||||
### DB 직접 조회
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user