이번에 들어간 내용
한투 호가 = 2번째 앱키 전용 키 없거나 start 실패 시 메인에 H0STASP0 안 붙임. 운영설정 WS_ORDERBOOK_SAVE_KIS 빨간 danger. LS RAM 합집합 후보∪보유∪영구∪grace. sync_targets와 split reconcile 둘 다. 틱 DB 영구 게이트는 그대로. 분봉 쓰레기 → 다음 소스 봉 통째 그 분 틱 0건이거나 전부 봉끝 대비 LIVE_FEED_FALLBACK_MAX_AGE_SEC 초과면 구멍. 메인 WS → 2차 → LS → REST → rollup. CANDLE_GARBAGE_FALLBACK 기본 true. 파일: feed_fallback.py(신규), ws_manager.py, kis_ws.py, candle_series.py, bt_candle_source.py, live_config_schema.py, database.py, 스모크, MD 2개. 같은 ws_manager/database/kis_ws/live_config에는 직전 커밋 이후 쌓여 있던 시세 폴백·ENV 키 정리도 같이 들어갔습니다. 파일 단위로 나눌 수 없어서입니다.
This commit is contained in:
209
docs/화요일확인.md
Normal file
209
docs/화요일확인.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# 화요일 확인 — ALIGN 폐기 + 호가필터 구멍 + 가격 TTL/EOD
|
||||
|
||||
확인일: **2026-08-18 (화) 장중**.
|
||||
|
||||
토~월에 쌓인 일이 **세 묶음**. 봉 정합(`T−1` 신호 / `T` 진입 / freeze)과 **다른 이야기**.
|
||||
`*_LIVE_BACKTEST_ALIGN`(봉 진입)은 **끄지 않음**. 없앤 건 유니버스 history 교집합뿐.
|
||||
|
||||
| 묶음 | 한 줄 | 화요일 봇 |
|
||||
|------|--------|-----------|
|
||||
| A. 유니버스 ALIGN | 키움 RAM ∩ history 교집합 삭제. history는 INSERT만 | 토에 재시작. **또 안 해도 됨** |
|
||||
| B. 호가 눈가림 | 사진 만료=통과 폐기 + 사진 없으면 안 삼 | 월 23:55 재시작에 포함되면 OK |
|
||||
| C. 가격 TTL / EOD | 체결 없어도 마지막가 유지. EOD는 `min_hold`·유령삭제에 안 막힘 | **월 23:55 `kis_trader_main` 재시작함** → 화 장부터 이 코드 |
|
||||
|
||||
웹: `kis_backtest_web` 재시작됨. 운영 설정만 보면 됨.
|
||||
|
||||
시세·호가 = **실키**(키움 `mock=False`, 한투 WS `:21000`). 매매 REST = **한투 모의** (`openapivts`). 이번 패치로 모의키를 시세에 붙인 적 없음.
|
||||
|
||||
---
|
||||
|
||||
## 왜 고쳤나 (한 줄씩)
|
||||
|
||||
- **A.** 운영 ON이던 `LIVE_UNIVERSE_SLOT_ALIGN`이 RAM 후보를 history와 교집합 → 중간 사진 ∩ 실시간 = `universe_wipe`.
|
||||
- **B.** 호가 저장 TTL과 검사 TTL을 같이 써서 사진이 `None`이면 필터 ON인데 **통과(눈가림 매수)**.
|
||||
- **C.** REST→WS 바꿀 때 “오래된 캐시=죽음”으로 가격을 `None` → 매도 `continue`. 199원이 체결이 없어도 **계속 199원**인데 지워서 손절·EOD가 안 나감 (8/5 돌파, 금요일 leftover). 호가 B와 **같은 병**.
|
||||
|
||||
---
|
||||
|
||||
## 적용된 내용
|
||||
|
||||
### 1. ALIGN 스위치 완전 삭제 (눈앞·코드·DB·MD)
|
||||
|
||||
| 위치 | 결과 |
|
||||
|------|------|
|
||||
| 실매 후보 | `base.py` `_post_filter_candidates` — history 교집합 **없음**. RAM에 있으면 후보 |
|
||||
| UI | 운영 설정에서 `LIVE_UNIVERSE_SLOT_ALIGN` 토글 삭제. `/api/live_config` JSON에도 키 없음 |
|
||||
| DB | `env_config_ext` 행 DELETE. 전략 config 컬럼 DROP |
|
||||
| 알림 | `universe_wipe` 발송 경로 삭제 |
|
||||
| 문서 | `code_architecture.md` · `MODIFICATION_GUIDE.md` · `정합성.md` 유니버스 한 줄 |
|
||||
|
||||
실매 진실 = 키움 REAL I/D → RAM 푸시/팝. history는 **백테 재생용 복사본**만.
|
||||
|
||||
### 2. 키움 history: INSERT만 + 마이크로초
|
||||
|
||||
| 항목 | 전 | 후 |
|
||||
|------|----|----|
|
||||
| 쓰기 | 같은 슬롯 DELETE 후 한 줄씩 INSERT (중간 노출) | DELETE 없음. N종목 한 트랜잭션 |
|
||||
| `event_time` | 초 `varchar(19)` | 마이크로초 `varchar(26)` |
|
||||
| 같은 초 두 변동 | 두 번째가 첫 장을 지움 | **두 장 다 남음** |
|
||||
|
||||
백테: 그 초의 **마지막** 스냅샷. ±1분 슬롯 해킹 없음.
|
||||
건드리지 않음: `ls_candidates_history`, `WS_TICK_GRACE_SEC` 기본 180.
|
||||
|
||||
### 3. 호가 — 대기표 사진 없이 사던 구멍
|
||||
|
||||
1. **만료=통과** → 검사 시계 `WS_ORDERBOOK_FILTER_MAX_AGE_SEC` 기본 **0**(마지막 사진). 저장 `WS_ORDERBOOK_TICK_MAX_AGE_SEC`(30초)와 **합치지 말 것**.
|
||||
2. **사진 0장인데 통과** → `WS_ORDERBOOK_FILTER_REJECT_IF_EMPTY` 기본 ON. REST 없음.
|
||||
|
||||
한산해서 사진이 **안 바뀌는 것** ≠ 사진이 **없는 것**. 팔 때 지정가·익절/손절 호가매도는 안 바꿈.
|
||||
|
||||
### 4. 가격 TTL / EOD (월 밤) — 화요일 실매 본체
|
||||
|
||||
초등: 칠판에 199원. 체결이 10분 없어도 **199원**. 지우고 “없다”고 하면 손절·장마감이 **안 돌아간다**.
|
||||
|
||||
| 위치 | 결과 |
|
||||
|------|------|
|
||||
| 매도 | `live_sell_price.py` — 마지막 WS(나이 무시). 죽은선만 REST 1회·쿨다운 30초. 실패해도 WS 유지 |
|
||||
| EOD | 타이머 없음. WS 없으면 매수가 폴백. **무조건 청산** |
|
||||
| `min_hold` | EOD를 **막지 않음** (모멘텀/스캘프/꼬리) |
|
||||
| 매수 | `_ws_last_quote` / `get_price_last`. `WS_PRICE_MAX_AGE_SEC` 기본 **0** |
|
||||
| WS 기본 | KIS·키움·LS·해외 `get_price` 기본 `None`(나이 무시). LS 옛 10초·해외 옛 20분 폐기 |
|
||||
| 40240000 | 잔고검증 **qty>0** 이면 「잔고 없음」 문구로 **ghost_purge 금지** |
|
||||
| 기동 | `ORPHAN_RECONCILE_ON_STARTUP` — 전략 전 잔고=DB 맞춤(매도 없음) |
|
||||
|
||||
옵투나·웹백테는 DB 봉·틱 재생이라 **이 TTL이 봉을 성기게 만들지 않음**. 예전 옵투나 best는 “실매가 안 팔던 세상”과 어긋날 수 있음. 화 하루 쌓인 뒤에 수요일 재탐색이 그 하루만 가깝다. `--apply-best` 하지 말 것.
|
||||
|
||||
---
|
||||
|
||||
## 재시작 기록
|
||||
|
||||
| 때 | 무엇 |
|
||||
|----|------|
|
||||
| 토 | 웹 + (ALIGN) 실매 |
|
||||
| 월 23:55 | `kis_trader_main` 재시작 (PID 바뀜). `🚀 통합 봇 시작` · 키움 LOGIN OK · 시세 실키 · 매매 모의 REST |
|
||||
| 화 장전 | **또 재시작 불필요** (월 밤에 C묶음까지 올린 프로세스). 의심되면 한 번 더 |
|
||||
|
||||
```bash
|
||||
systemctl is-active kis_trader_main.service
|
||||
journalctl -u kis_trader_main.service --since '2026-08-18 08:50' --no-pager | head -40
|
||||
```
|
||||
|
||||
정상 시그니처: `🚀 kis_trader 통합 봇 시작`, `키움 WS LOGIN OK`, `실키/실전 도메인`, `heartbeat … dead=[]`.
|
||||
이상: `Traceback`, `ImportError`, `universe_wipe`, 시세 URL `:31000`(모의 WS).
|
||||
|
||||
---
|
||||
|
||||
## 화요일 장중 체크리스트
|
||||
|
||||
### A. 실매 — 가짜 전량탈락이 없어야 함
|
||||
|
||||
1. `kis_trader_main.service` active.
|
||||
2. 알림/저널에 **`universe_wipe`**, `history=kiwoom 교집합`, `[유니버스슬롯] … 후보 N→0` **없어야** 함.
|
||||
3. 키움 RAM과 매수 후보가 같이 움직임. HTS가 진짜로 비우면 RAM도 0인 것은 정상.
|
||||
4. `universe_zero`는 **키움 조건이 진짜 0**일 때만.
|
||||
|
||||
```bash
|
||||
journalctl -u kis_trader_main.service --since '2026-08-18 09:00' --no-pager \
|
||||
| grep -E 'universe_wipe|유니버스슬롯|교집합|universe_zero' | head -50
|
||||
```
|
||||
|
||||
### B. history 저장 — 중간 1종목 사진이 없어야 함
|
||||
|
||||
- `event_time`에 **점 + 마이크로초**.
|
||||
- 같은 초 안 두 번 변동이면 **행이 두 세트**.
|
||||
|
||||
```sql
|
||||
SHOW COLUMNS FROM target_candidates_history;
|
||||
-- event_time varchar(26)
|
||||
|
||||
SELECT strategy_id, event_time, COUNT(*) n
|
||||
FROM target_candidates_history
|
||||
WHERE event_time >= '2026-08-18 09:00:00'
|
||||
GROUP BY strategy_id, event_time
|
||||
ORDER BY event_time DESC
|
||||
LIMIT 20;
|
||||
```
|
||||
|
||||
pymysql `LIKE`의 `%`는 바인딩.
|
||||
|
||||
### C. 웹
|
||||
|
||||
`http://192.168.0.149:5050/` → 운영 설정
|
||||
|
||||
- **유니버스 히스토리 교집합** 토글 **없음**
|
||||
- 「호가 사진 없으면 매수 안 함」 **켜짐**
|
||||
- `WS_ORDERBOOK_FILTER_MAX_AGE_SEC` = **0**
|
||||
- `WS_PRICE_MAX_AGE_SEC` = **0** (마지막 체결가 유지)
|
||||
|
||||
### D. 백테 (여유 있으면)
|
||||
|
||||
최근 거래일 1일. 유니버스가 비어 거래 0이면 안 됨. 백테 = **완성 스냅샷 재생**. ALIGN ON 시절 숫자와 같을 필요 없음.
|
||||
|
||||
### E. 호가 — 눈가림이 없어야 함
|
||||
|
||||
1. 저널 `탈락-호가없음` 이 **가끔**은 정상(구독 직후). **같은 종목 종일만**이면 구독 실패.
|
||||
2. 「매수호가」가 빨강인데 체결 — 예전 구멍이면 화요일부터 줄어야 함. 빨강 = 나중에 그린 사진일 수도.
|
||||
3. 한산하다고 거래 **전부 0**이면 안 됨. 사진 한 장이 있으면 검사하고 통과하면 산다.
|
||||
|
||||
```bash
|
||||
journalctl -u kis_trader_main.service --since '2026-08-18 09:00' --no-pager \
|
||||
| grep -E '탈락-호가없음|호가없음' | head -40
|
||||
```
|
||||
|
||||
### F. 가격 TTL / EOD — 횡보해도 팔아야 함 (화 신규)
|
||||
|
||||
1. 보유 중 체결이 뜸해도 저널에 **현재가 없음으로 매도 스킵이 쌓이면 안 됨**.
|
||||
2. 손절·트레일이 **횡보 종목에서도** 나와야 함 (가격을 지워서 `continue` 하던 패턴 재발 금지).
|
||||
3. 전략 EOD 시각에 **매도 주문이 나가야** 함. 모멘텀은 살아 있고 돌파만 EOD 0건이면 예전 구멍.
|
||||
4. `40240000` / 「잔고 없음」인데 계좌에 주식이 있으면 **ghost_purge 로그가 아니라** `실잔고 N주 → 유령정리 안 함` 이어야 함. 그다음 EOD 재시도.
|
||||
5. `min_hold` 때문에 EOD가 스킵되면 안 됨.
|
||||
6. leftover(당일 못 판 종목)가 **전날처럼 대량**이면 실패. 장 마감 후 `active_trades` vs 잔고.
|
||||
|
||||
```bash
|
||||
journalctl -u kis_trader_main.service --since '2026-08-18 09:00' --no-pager \
|
||||
| grep -E '유령정리 안 함|ghost_purge|장마감|EOD|sell_ws|현재가 없음|탈락-가격' | head -60
|
||||
```
|
||||
|
||||
장 마감 후: 당일 매수 → 당일 EOD/손절 주문 유무. 8/5 티앤엘처럼 **EOD 0건 다음날 손절**이 반복되면 C묶음 미적용(구 프로세스).
|
||||
|
||||
---
|
||||
|
||||
## 영향 분류
|
||||
|
||||
| 축 | ALIGN | 호가 눈가림 | 가격 TTL/EOD |
|
||||
|----|--------|-------------|--------------|
|
||||
| 실매 | 후보가 history에 안 막힘 | 필터 ON이면 사진 없이 안 삼 | 횡보해도 마지막가로 손절·EOD |
|
||||
| 백테 | history 재생. 타임스탬프만 촘촘 | 호가 검사 ON이면 사진 없는 타점 안 삼 | **봉·틱 재생. TTL 없음** |
|
||||
| Optuna | 엔진 분기 없음 | 1과목은 호가 끈 채 | 예전 best ≠ 화 실매 예고편. 수요일은 **화 하루**만 가깝다 |
|
||||
| freeze / SKIP_HTS | 없음 | 없음 | 없음 |
|
||||
|
||||
---
|
||||
|
||||
## 안 바뀐 것 (헷갈리지 말 것)
|
||||
|
||||
- `*_LIVE_BACKTEST_ALIGN` / 형성봉 ALIGN — **봉 진입 정합**. 유니버스 ALIGN 삭제와 다른 키. **ON 유지**.
|
||||
- `LIVE_PORTFOLIO_BUDGET_ALIGN` — 총한도. 유지.
|
||||
- `WS_TICK_GRACE_SEC` 180초.
|
||||
- `*_SKIP_HTS_SCAN_DUPES` false.
|
||||
- LS t1859 / `ls_candidates_history`.
|
||||
- 매도 지정가 · 익절/손절 호가매도.
|
||||
- 프로그램매매 “스냅 없으면 통과”.
|
||||
- 시세 실키 / 매매 한투 모의 분리.
|
||||
|
||||
---
|
||||
|
||||
## 화요일에 이상하면
|
||||
|
||||
| 증상 | 볼 곳 |
|
||||
|------|--------|
|
||||
| 또 N→0 알림 | 교집합 재유입? `universe_zero`(진짜 0) vs `universe_wipe`(없어져야 함) |
|
||||
| history 초만 찍힘 | 구버전 프로세스 |
|
||||
| 백테 유니버스 구멍 | `event_time` 문자열. 초 조회 상한 `.999999` |
|
||||
| 같은 초 명단 유실 | INSERT에 DELETE가 다시 생겼는지 |
|
||||
| 호가 없이 또 매수 | 구버전 / `REJECT_IF_EMPTY` OFF / 전략 필터 OFF |
|
||||
| 한산 종목 종일 0건 | 차트 무신호 vs 사진 보고 탈락 vs 사진 0장 |
|
||||
| `탈락-호가없음` 폭주 | 호가 구독 실패. REST로 메우지 말 것 |
|
||||
| 횡보인데 손절·EOD 0건 | **가격 TTL 재발**. `WS_PRICE_MAX_AGE_SEC`가 양수인지, 매도가 `get_price_last`인지 |
|
||||
| EOD 주문 0 + 다음날 손절 | 8/5와 동일. 봇 PID가 월 23:55 이후인지 |
|
||||
| 「잔고 없음」으로 포지션 DB 삭제 | qty>0인데 ghost_purge 탄 것. 패치 미적용 |
|
||||
| 시세가 모의 | WS `:31000` / 키움 `mock=True`. 매매만 `openapivts`는 정상 |
|
||||
Reference in New Issue
Block a user