Equity Live — /api/equity/live/*
라이브 모드 활성화 게이팅 라우트입니다. P4-01에서 추가됨.
공통
- 베이스 경로:
/api/equity/live - Feature flag:
FEATURE_EQUITY_LIVEON - 인증: 모든 라우트 JWT 필요
- 영속성: 활성화 이력은
broker_order_eventsaudit log에live_request_confirm/live_enabled/live_disabledevent_type으로 기록
절대 룰
라이브 활성화 전에 페이퍼 90일 + 50거래 검증이 필수입니다. /live/status의 is_ready=true인 자산군만 다음 단계 진행 가능.
POST /api/equity/live/request_confirm
확인 토큰을 발급하고 이메일/로그로 전달합니다.
요청 (RequestConfirmIn)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
asset_class | crypto|us_equity|kr_equity | Y | 토큰 대상 자산군 |
recaptcha_token | string | 조건부 | RECAPTCHA_SECRET_KEY 설정 시 필수 |
응답 200 (RequestConfirmOut)
{
"token_delivered_via": "email",
"token": null,
"expires_at": "2026-04-26T11:11:53Z",
"asset_class": "us_equity"
}
token_delivered_via=email— 등록 이메일로 전송, 응답 본문에는 plaintext 미포함token_delivered_via=log— SMTP 미설정 환경 (개발용). 응답 본문 + 서버 로그에 plaintext 포함
에러
- 400 — recaptcha_token 누락 (RECAPTCHA_SECRET_KEY 설정된 경우)
- 403 — 페이퍼 30일+50거래 미충족 (
is_ready=false) - 503 —
FEATURE_EQUITY_LIVE=false
cURL
curl -X POST http://localhost:8000/api/equity/live/request_confirm \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"asset_class": "us_equity",
"recaptcha_token": "<reCAPTCHA v3 client token>"
}'
POST /api/equity/live/enable
토큰을 검증하고 자산군별 live_enabled 플래그를 ON으로 전환.
요청 (EnableLiveIn)
| 필드 | 타입 | 필수 |
|---|---|---|
asset_class | crypto|us_equity|kr_equity | Y |
confirm_token | string | Y |
응답 200 (EnableLiveOut)
{
"asset_class": "us_equity",
"enabled": true
}
에러
- 400 — 토큰 invalid / 만료 / 이미 사용
- 403 —
request_confirm이후 페이퍼 드로다운으로 readiness 깨짐 - 503 —
FEATURE_EQUITY_LIVE=false
cURL
curl -X POST http://localhost:8000/api/equity/live/enable \
-H "Authorization: Bearer $JWT" \
-d '{
"asset_class": "us_equity",
"confirm_token": "<token from email or log>"
}'
POST /api/equity/live/disable
자산군별 live_enabled 플래그를 OFF로 전환. 토큰 / readiness 체크 없음 (안전한 방향).
요청 (DisableLiveIn)
| 필드 | 타입 | 필수 |
|---|---|---|
asset_class | crypto|us_equity|kr_equity | Y |
응답 200 (EnableLiveOut)
{
"asset_class": "us_equity",
"enabled": false
}
cURL
curl -X POST http://localhost:8000/api/equity/live/disable \
-H "Authorization: Bearer $JWT" \
-d '{"asset_class": "us_equity"}'
GET /api/equity/live/status
자산군별 readiness + 활성화 스냅샷.
응답 200 (LiveStatusOut)
{
"feature_live_enabled": true,
"feature_paper_enabled": true,
"entries": [
{
"asset_class": "crypto",
"live_enabled": false,
"is_ready": true,
"reason": null,
"days_active": 95,
"paper_trades_count": 124,
"oldest_paper_trade": "2026-01-21T00:00:00Z"
},
{
"asset_class": "us_equity",
"live_enabled": true,
"is_ready": true,
"reason": null,
"days_active": 92,
"paper_trades_count": 67,
"oldest_paper_trade": "2026-01-24T03:11:00Z"
},
{
"asset_class": "kr_equity",
"live_enabled": false,
"is_ready": false,
"reason": "Need 50 paper trades, currently 31",
"days_active": 60,
"paper_trades_count": 31,
"oldest_paper_trade": "2026-02-25T05:22:00Z"
}
]
}
cURL
curl -H "Authorization: Bearer $JWT" \
http://localhost:8000/api/equity/live/status
라이브 모드 주문 흐름
라이브 활성화 후 라이브 주문 시 equity-orders의 PlaceOrderRequest.live_mode=true를 사용합니다. 게이트:
FEATURE_EQUITY_LIVE글로벌 ON- 사용자
live_enabled[asset_class]=true LIVE_DAILY_TRADE_LIMIT(기본 10) 미초과- RiskManager v2 (1-2% / -5%)
라이브 첫 주문은 audit log에 first_live_order=true 마커를 기록 + 모니터링 알림 발송.
멀티유저 격리
- 모든 라우트는
OperationsService(db)경유로user_id필터 강제 - 다른 user의 토큰을 가지고 있어도 본인 user_id+asset_class 조합이 아니면 검증 실패
비고
- 토큰 만료 시간: 기본 1시간 (
LIVE_CONFIRM_TOKEN_TTL_MIN) - 토큰은 1회용 — 한 번 enable로 소비되면 재사용 불가
- SMTP 미설정 시
token_delivered_via=log로 응답되어 개발/테스트 흐름이 끊기지 않음 crypto자산군은 readiness 윈도 (90일/50거래)는 동일 적용되지만 시장 시간 제약 없음