You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
4.6 KiB
Markdown
200 lines
4.6 KiB
Markdown
# 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 대상
|