fix(옵투나·백테웹): 휩쏘 키 통일 + 엔진 뱃지 + 잡 삭제 + race·후처리 시그니처

휩쏘 키 통일 (bt-form-postfilter-key-parity.mdc 신설)
- 저장키 vs 조회키 불일치 해소: whipsaw_enabled(옛) → whipsaw_filter_enabled(표준)
- backtest_web.py: params[..] 세팅, static/js/backtest.js: 폼 파라미터
- optuna_web_jobs·param_search_apply_snapshot·param_search_scalping: 옛 alias 제거
- bt_post_filters: 로컬 변수도 whipsaw_filter_enabled 로 통일
- scripts/scratch: 관련 스크립트 동기 반영

엔진 뱃지 (optuna-job-engine-label.mdc 신설)
- optuna_web_jobs: use_rust 명시값만 신뢰, 미상은  (전략명 하드코딩 폴백 금지)
- 스캘핑/모멘텀/돌파 Rust 포팅 확장에도 안전한 라벨링

Optuna 웹 잡 UX
- save_job: tmp 파일 PID 접미 (멀티 프로세스 race 해소)
- _spawn_job_reaper: mode_refine 완료 시 phase1/phase2 JSON 자동 등록
  → 예전 UX 복원 (실행 잡ID 위에 결과 잡ID 노출)
- delete_job / delete_jobs_bulk 신설 + API + UI 삭제 버튼
  실행 중 잡 거부, 로그·원본 결과 JSON 보존

후처리 시그니처 수정
- bt_post_filters.orderbook_reject_for_entry 호출:
  price= → current_price=, 단일 대입 → 튜플 unpack
  (매 trial 마다 TypeError 삼켜지고 후처리 무효화되던 버그)

버그 조사·룰 강화
- verify-before-conclude-cross-strategy.mdc: 함수 추적 딥다이브 → 근본 대안 3개
- .cursorrules: 룰 27~29 추가 (해외 UI 정합·휩쏘 키·엔진 뱃지)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Your Name
2026-09-06 19:23:22 +09:00
parent 1d69c217e2
commit b5d7c5d848
13 changed files with 349 additions and 51 deletions

View File

@@ -132,7 +132,7 @@ def main() -> int:
# A) 타점만 (호가·휩쏘 OFF)
a = dict(mode_params)
a["_orderbook_filter_enabled"] = False
a["whipsaw_enabled"] = False
a["whipsaw_filter_enabled"] = False
print("[3A] mode 타점만 (호가OFF·휩쏘OFF)", flush=True)
cases.append(_pack("A_mode_only", _eval(a), "호가OFF·휩쏘OFF"))
@@ -143,13 +143,13 @@ def main() -> int:
b["_ob_min_bid_ask_ratio"] = float(ep["orderbook_min_bid_ask_ratio"])
if ep.get("orderbook_entry_ask_max_mult") is not None:
b["_ob_ask_max_mult"] = float(ep["orderbook_entry_ask_max_mult"])
b["whipsaw_enabled"] = False
b["whipsaw_filter_enabled"] = False
print("[3B] mode + 100진입호가 (휩쏘OFF)", flush=True)
cases.append(_pack("B_mode_ob100", _eval(b), "호가100 ON · 휩쏘OFF"))
# C) +100 + 휩쏘
c = dict(b)
c["whipsaw_enabled"] = True
c["whipsaw_filter_enabled"] = True
if wp.get("whipsaw_subbar_sec") is not None:
c["whipsaw_subbar_sec"] = int(wp["whipsaw_subbar_sec"])
if wp.get("whipsaw_lookback_sec") is not None:

View File

@@ -33,7 +33,7 @@ def main() -> int:
print(
"trial120 ob=%s whip=%s sl=%s tp=%s" % (
combo.get("_orderbook_filter_enabled"),
combo.get("whipsaw_enabled"),
combo.get("whipsaw_filter_enabled"),
combo.get("sl_pct"),
combo.get("tp_pct"),
),