feat: Enhance trading system with new permanent subscription features and order book management

Changes:
- Added a new API endpoint for managing permanent subscriptions, allowing users to enable or disable subscriptions dynamically.
- Implemented a function to fill candle data from Kiwoom, ensuring that only relevant data is inserted into the database.
- Introduced a mechanism to handle master subscription states, improving the management of subscription statuses.
- Updated the database schema to include new fields for managing subscription states and order book filtering.

Impact:
- These enhancements improve the flexibility and reliability of the trading system, allowing for better management of subscriptions and order book data, while reducing the risk of data inconsistencies.

히스토리 align 제거 븅신같은 초기설계 아예 제거
진입모드에 구멍메움
호가진입을 켜도 호가가 안들어올때 호가 안보고 그냥 사버림
This commit is contained in:
Your Name
2026-08-15 23:01:14 +09:00
parent 4a18ce2697
commit 36a3e2b4a1
94 changed files with 6368 additions and 1639 deletions

View File

@@ -1,69 +1,84 @@
# Optuna 파라미터 탐색 및 호가 수급 최적화 구조 가이드 (옵투나.md)
이 문서는 백테스트 웹페이지 및 CLI 환경에서 구동되는 **Optuna 파라미터 최적화(Stage 1 & 2) 메커니즘**, 특히 **호가 수급 필터(Orderbook Filter) 및 수익구간 호가매도(Exit Orderbook) 수치의 탐색·표기·DB 반영 체계**를 설명합니다.
이 문서는 백테스트 웹·CLI의 **Optuna 2단계**, 호가 후처리 격자·적용 분리를 정리한다.
관련: `docs/호가.md` §8 · `kis_trader/backtest/optuna_postprocess_topn.py` · `optuna_orderbook_recommend.py` · `optuna_rerun_postprocess.py`
최종 갱신: 2026-08-15
---
## 🚀 1. 투-스테이지(2-Stage) 최적화 작동 원리
백테스트 웹페이지 또는 스크립트에서 Optuna를 돌릴 경우 다음과 같이 2단계로 연쇄 구동됩니다.
## 1. 투-스테이지
```
+---------------------------------------------------------------------------------------------+
| [Stage 1: 캔들 차트 파라미터 탐색] |
| - RSI, 손익비(TP/SL), 풀백, 휩쏘, 이평선 등 주가 차트 지표 최적 수치 탐색 |
+---------------------------------------------------------------------------------------------+
│ (Stage 1 완료 즉시 자동 연쇄 기동)
+---------------------------------------------------------------------------------------------+
| [Stage 2: 호가 수급 합의 수치 1,000회 고속 핀셋 탐색] (`optuna_orderbook_recommend.py`) |
| - Stage 1의 최우량 진입/청산 타점 데이터를 바탕으로, 진입 전후의 실매 호가 스냅샷을 분석 |
| - 최적의 호가 스프레드 상한(%), 잔량비 하한, 수익구간 호가매도 마이크로 수치 도출 |
+---------------------------------------------------------------------------------------------+
Stage 1 캔들 TPE (param_search_optuna.py)
RSI·손익·트레일 등 차트 축. 호가 ON/OFF는 넣지 않음.
Stage 2 후처리 (attach_topn_postprocess)
gated TopN(+mode/live) 체결을 호가 스냅으로 재생.
진입 스프/잔량/매도벽 · EXIT_OB · STOP_OB · 휩쏘.
```
---
Stage 2는 **이미 난 체결 + 근처 `ws_orderbook`/`ls_ws_orderbook`**.
실매 “호가 RAM 없음 → 필터 ON인데 통과” 는 `WS_ORDERBOOK_FILTER_REJECT_IF_EMPTY`(기본 true) + `WS_ORDERBOOK_FILTER_MAX_AGE_SEC` (B안, `docs/호가.md`). 1과목 차트 TPE와 별개.
## 🌐 2. 백테스트 웹페이지 연동 및 결과 표기
구 JSON만 Stage 2 다시:
### ① 웹페이지 Optuna 실행 시 자동 1,000회 탑재
* 웹 UI(`http://192.168.0.149:5050/`)에서 Optuna 버튼을 작동시키면, 서버 단의 `optuna_mode_combo.py` 모듈이 차트 최적화 종료 시점에 `attach_orderbook_recommend`를 자동으로 호출합니다.
* 별도의 추가 조작 없이도 호가 1,000회 시뮬레이션이 백그라운드에서 즉각 동반 구동됩니다.
### ② 웹 화면 및 보고서(JSON) 표기 위치
* 도출된 호가 수급 추천 합의 수치는 웹에서 반환되는 Optuna 결과 딕셔너리(`out_data``mode_combo`)의 **`"orderbook_recommend"`** 전용 블록에 실려서 화면에 출력됩니다.
```json
/* UI optuna_*_tpe_*.json */
"orderbook_recommend": {
"ok": true,
"strategy": "MOMENTUM",
"params": {
"orderbook_filter_enabled": true,
"orderbook_max_spread_pct": 0.46,
"orderbook_min_bid_ask_ratio": 0.59,
"exit_ob_enabled": true,
"exit_ob_ratio_min": 1.25,
"exit_ob_ma_window": 58
}
}
```
---
## 🚨 3. 실매매 DB 적용 안전 분리 원칙 (필수 숙지)
Optuna가 찾아낸 수치 중 **차트 파라미터**와 **호가 수급 파라미터**는 실전 DB 각인 방식이 완전히 분리되어 있습니다.
| 구분 | 차트 캔들 파라미터 (RSI, 손익 등) | 호가 수급 파라미터 (스프레드, 호가 익절 등) |
|------|---------------------------------------|-------------------------------------------|
| **웹 UI "Apply(적용)" 버튼** | ✅ 버튼 한방으로 DB 환경변수 및 웹 인풋 적용 완료 | ⚪ **미리보기 및 화면 보고서 확인 전용** (차트 수치에 휩쓸려 실수로 DB 덮어씌워짐 방지) |
| **실매매 DB 최종 갱신 커맨드** | 웹 버튼 또는 `param_search_optuna.py --apply-best` | 🚨 **반드시 전용 독립 스크립트를 가동해야 DB에 안전 새김** |
### 🛠️ 호가 수급 최적 수치 실매매 DB 전용 각인 커맨드
호가 쪽 Optuna 합의 수치를 실매매 DB에 정기적으로 세팅하거나 갱신할 때는 반드시 아래 스크립트를 가동하여 도장 찍고 적용해야 합니다.
```bash
# 특정 전략(MOMENTUM, BREAKOUT, SCALPING, TAIL) 호가 합의 수치 DB 갱신
.venv/bin/python3 scripts/apply_optuna_ob_consensus.py --strategy MOMENTUM
python3 -u kis_trader/backtest/optuna_rerun_postprocess.py \
--result-json kis_trader/backtest/results/optuna_<전략>_tpe_<TS>.json
# --apply-best 없음. 실매 DB 안 바뀜.
```
* **수행 내용:** 1,000회 고속 최적화 ➔ 합의 수치 도출 ➔ TradeDB 환경변수 세트 안전 패치 ➔ `test_live_execution_validation.py`로 사전 정합성 증명 가동!
웹 Optuna 버튼도 완료 시 후처리를 붙인다 (`optuna_postprocess_topn`).
`orderbook_recommend` 블록 + `postprocess_topn` 이 JSON에 실림.
---
## 2. 진입 후처리 격자 (env_config_ext)
`ensure_optuna_gate_env_defaults``OPTUNA_OB_*`.
`OPTUNA_OB_AXIS_TRIALS=0` 이면 `OPTUNA_OB_RECOMMEND_TRIALS`(기본 1000)/축.
| 키 | 널널 검사 기본 (2026-08-15) |
|----|------------------------------|
| `OPTUNA_OB_ENTRY_SPREAD_MIN` / `MAX` | 0.1 ~ 8.0 |
| `OPTUNA_OB_ENTRY_RATIO_MIN` / `MAX` | 0.05 ~ 1.5 |
| `OPTUNA_OB_ENTRY_ASK_MULT_MIN` / `MAX` | 1.0 ~ 80.0 (매도벽, L3 `ask_qty_l3`) |
| `OPTUNA_OB_LOOKBACK_MIN` | 30 (분) |
잔여 체결 &lt; 원본 **30%** → trial 무효. 너무 센 컷은 고르지 못하게 하는 가드.
결과는 `orderbook_filter_enabled=True` 고정(후처리가 “끌지”를 탐색하지 않음).
apply 패치에 벽이 있으면 `{전략}_ORDERBOOK_ENTRY_ASK_MAX_MULT`.
---
## 3. 꼬리 TPE 진입모드 (웹 체크)
엔진 실매 기본은 `TAIL_ENTRY_MODE`**`limit_atr`** (`limit_entry_common.short_entry_mode`).
웹 꼬리 탭 셀렉트 기본도 limit_atr. **Optuna TPE는 예외: 진입을 탐색하지 않고 스터디마다 고정.** 예전 코드는 **`align` 하드코딩**.
웹 Optuna 탭: **align** / **limit_atr** 체크.
- 기본: align만 (기존 TPE와 동일).
- 둘 다: **스터디 2개 순차** (한 TPE에 categorical 혼입 없음). `--apply-best` 없음.
CLI: `--entry-mode align|limit_atr` · 순차 스크립트 `TAIL_OPTUNA_ENTRY_MODES="align limit_atr"`.
---
## 4. 실매 DB 적용 분리
| 구분 | 차트 캔들 | 호가 후처리 숫자 |
|------|-----------|------------------|
| `--apply-best` (기본 미사용) | 차트 축 | 호가 합의 **자동 각인 아님** |
| 웹 Optuna 「적용」 `upto` | 차트 + 선택 시 entry/exit/stop (`build_upto_env_patch`) | `upto=entry` 이상이면 호가 패치가 **들어갈 수 있음** |
| 전용 스크립트 | — | `scripts/apply_optuna_ob_consensus.py --strategy MOMENTUM` |
후처리 **재실행만** 하면 JSON만 갱신. DB는 안 바뀜. 1일 best는 과적합 가능.
---
## 5. 웹 표기
`out_data["orderbook_recommend"]` · `postprocess_topn.postprocess_by_anchor`.
진입 합의 예: `orderbook_max_spread_pct` / `orderbook_min_bid_ask_ratio` / `orderbook_entry_ask_max_mult`.