# State Machine & Reconciliation ## 1. 목적 이 문서는 Phase 6 실행 엔진의 상태머신과 reconciliation 절차를 정의합니다. 실전 시스템에서 가장 위험한 문제는 **내부 상태와 브로커 상태가 어긋나는 것**이므로, reconciliation은 보조 작업이 아니라 핵심 기능입니다. ## 2. 핵심 엔티티 ### 2.1 Execution Session 하루의 운영 세션 단위. 필수 필드: - `execution_session_id` - `env` - `trade_date` - `mode` (`dry_run`, `paper`, `live`) - `strategy_scope` - `status` - `started_at` - `ended_at` ### 2.2 Order Plan 전략 후보를 실행 가능한 주문 계획으로 변환한 결과. ### 2.3 Order Intent 실제로 한 번 제출하려는 logical action. 예: entry, exit_half, exit_final, stop_exit, cancel_all. ### 2.4 Broker Order 브로커가 인식하는 주문. 하나의 Order Intent가 broker replace 과정에서 여러 broker order로 이어질 수 있다. ### 2.5 Position State 실제 체결 기반 포지션 상태. ## 3. 상위 상태머신 ### 3.1 Candidate Execution State ```text candidate_ready -> planned -> risk_checked -> awaiting_approval -> approved -> entry_submitted -> entry_working -> entry_partially_filled -> position_open -> exit_pending -> partially_exited -> fully_closed -> abandoned -> error ``` ### 3.2 Position Lifecycle ```text no_position -> opening -> open -> reducing -> closed -> orphaned ``` ### 3.3 Session Lifecycle ```text booting -> pre_open_checks -> active -> soft_halt -> hard_halt -> closing -> reconciliation -> closed -> failed ``` ## 4. Event Sourcing 원칙 가능하면 상태를 직접 수정하기보다 event를 append하고 projection으로 현재 상태를 만든다. 필수 이벤트: - candidate_loaded - risk_decision_recorded - approval_ticket_created - approval_decided - order_intent_created - order_submitted - order_acknowledged - order_partially_filled - order_filled - order_cancel_requested - order_cancelled - order_replaced - order_rejected - position_opened - position_reduced - position_closed - reconciliation_mismatch_detected - reconciliation_resolved - manual_operator_action - session_halted - session_resumed ## 5. Reconciliation 유형 ### 5.1 주문 대사 비교 대상: - 내부 open orders - 브로커 open orders - 최근 fill ledger 체크 항목: - broker_order_id 누락 - client_order_id 중복 - 내부는 working인데 브로커엔 없음 - 브로커는 filled인데 내부는 accepted 상태 - cancel 요청 후 실제 잔존 여부 ### 5.2 포지션 대사 비교 대상: - 내부 position state - 브로커 position snapshot 체크 항목: - 수량 불일치 - 평균단가 불일치 - symbol 누락 - 브로커에만 존재하는 orphan position ### 5.3 세션 대사 - 장 종료 후 미처리 ticket 존재 여부 - 미완료 order intent 존재 여부 - kill switch 상태 복구 여부 ## 6. Reconciliation 주기 - 장 시작 전: full sync - 장중: 짧은 interval incremental sync - submit/cancel/replace 직후: targeted sync - 장 종료 후: final full sync - 재시작 직후: mandatory full sync ## 7. 충돌 해결 규칙 원칙적으로 **브로커 체결 사실**을 가장 강한 truth로 본다. 다만 브로커 API 지연/일시 불일치가 있을 수 있으므로, 아래 우선순위를 따른다. 1. confirmed fill / position snapshot 2. fetch order by broker id 3. stream event 4. 내부 optimistic state ### 예시 1: submit timeout - 내부 상태는 `submitted_pending_confirmation` - 즉시 재제출하지 않는다. - 먼저 client_order_id 기반 조회 또는 full reconciliation 수행 ### 예시 2: cancel 요청 후 fill 도착 - fill 이벤트가 cancel보다 우선한다. - 남은 수량만 취소되도록 재계산 ### 예시 3: 프로세스 재시작 - 마지막 checkpoint 이후 미확정 intent를 모두 reconciliation queue에 올린다. - broker 상태를 먼저 읽고 projection을 복구한 뒤에만 신규 주문 허용 ## 8. Checkpoint / Recovery 다음은 checkpoint 대상이다. - current session state - active candidate executions - open positions - working orders - latest broker cursor / stream cursor - kill switch 상태 - approval pending 목록 복구 절차: 1. durable state load 2. broker full sync 3. mismatch resolution 4. projection rebuild 5. safe-to-trade 판단 6. 신규 주문 재개 여부 결정 ## 9. 운영자 수동 개입 운영자가 브로커 화면에서 직접 주문/취소/청산한 경우를 고려해야 한다. 필수 규칙: - manual action은 별도 event로 기록 - reconciliation 시 수동 개입 감지 시 operator note 요구 - 내부 상태는 브로커 상태로 수렴 - 수동 개입이 잦은 전략/구간은 별도 review 대상