Skip to content

fix: 체결 원장 보상 롤백 + 주문 예외 critical 승격 — 반쪽 원장 재발 차단#453

Merged
easygap merged 1 commit into
mainfrom
fix/order-ledger-atomicity
Jul 10, 2026
Merged

fix: 체결 원장 보상 롤백 + 주문 예외 critical 승격 — 반쪽 원장 재발 차단#453
easygap merged 1 commit into
mainfrom
fix/order-ledger-atomicity

Conversation

@easygap

@easygap easygap commented Jul 10, 2026

Copy link
Copy Markdown
Owner

배경 — #452의 나머지 절반

#452는 7/7 포지션 유실의 원인(레거시 UNIQUE(symbol))을 고쳤다. 이 PR은 사고를 키운 구조 두 가지를 고친다:

  1. 반쪽 원장이 그대로 남았다: 체결 반영이 save_trade(커밋) → save_position(별도 세션) 순서라, 포지션 저장이 실패해도 매매 기록과 현금 차감은 이미 확정 — 유령 -41% 낙폭·가드 오발동의 직접 원인. DB 예외는 드물지만(락·디스크), 다시 나면 같은 반쪽 원장이 된다.
  2. 3일 묻혔다: 주문 예외가 사이클 요약("실패 1건")에 섞여 통상 알림으로만 나가 3일 지나서야 발견됐다.

수정

원장 보상 롤백 — 포지션 반영 실패 시 방금 저장한 매매 기록을 되돌리고 실패를 위로 전파(원장 무변화):

  • BUY 2경로: save_position 실패 → delete_trade_by_id(신설, 보상 전용) → raise
  • SELL 경로(대칭): delete_position/reduce_position 실패 → 매도 기록 보상 삭제 → raise. 부분 익절 플래그 갱신은 보상 범위 밖 — 그 시점엔 원장이 이미 정합이라 매매를 되돌리면 오히려 깨진다
  • save_trade 반환 객체를 커밋 후 refresh+expunge — 세션 밖 id 접근이 DetachedInstanceError 나던 것 교정(보상 경로의 전제)

예외성 실패 critical 승격 — 사이클 요약과 별도로, status=error(예외) 주문이 있으면 ORDER_ERROR critical 이벤트 + 디스코드 critical 알림. 가드 거부(success=False)는 보호 동작이므로 통상 요약 유지(경보 피로 방지 원칙).

검증

  • 단위: 7/7 사고 재연(포지션 저장 실패 주입 → 매매 기록 0건 + 예외 전파), 보상 삭제 헬퍼 멱등(존재 시 True/부재 시 False) — 전체 스위트 통과
  • 실CLI: kr_pocket dry-run 정상(0주문 정착 상태, 신규 블록 무해 통과, exit 0)

포지션 유실 사고의 나머지 절반. 스키마(UNIQUE 재구축)는 원인을 고쳤고,
이번엔 사고를 키운 구조를 고친다: 체결 반영이 매매 저장(커밋) 후 포지션
저장(별도 세션) 순서라 후자가 실패하면 매매 기록과 현금 차감만 확정된
반쪽 원장이 남았고, 그 예외가 사이클 요약에 섞여 3일 묻혔다.

- BUY 2경로/SELL 1경로: 포지션 반영 실패 시 방금 저장한 매매 기록을
  보상 삭제(delete_trade_by_id 신설, 보상 전용) 후 위로 전파 — 원장 무변화.
  SELL의 부분 익절 플래그 갱신은 보상 범위 밖(그 시점엔 원장이 정합).
- save_trade 반환 객체 커밋 후 refresh+expunge — 세션 밖 id 접근이
  DetachedInstanceError 나던 것 교정(보상 경로의 전제).
- status=error(예외) 주문은 ORDER_ERROR critical 이벤트 + 디스코드 critical
  승격. 가드 거부는 보호 동작이라 통상 요약 유지(경보 피로 방지 원칙).

검증: 사고 재연 테스트(포지션 저장 실패 주입 -> 매매 0건 + 예외 전파),
보상 삭제 멱등 테스트. 스위트 1683 통과, kr_pocket dry-run 스모크 exit 0.
@easygap
easygap merged commit 82231ea into main Jul 10, 2026
1 check passed
@easygap
easygap deleted the fix/order-ledger-atomicity branch July 10, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant