feat(옵투나·웹): 후처리 재탐색·ob_modes·적용감사·수집통계
- Optuna web jobs/TPE/apply snapshot·틱로더 정합, jobs limit·감사로그 - 백테 UI 호가모드·후보 적용 흐름, feed_collect_stats API/탭 - 가설검증·교차검증 룰, 4전략 스모크·OB slot41 진단 스크립트 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -216,3 +216,115 @@ def suggest_ratchet_tiers_pct(
|
||||
format_ratchet_tiers_string(pairs) if ascending_ok else str(off_token)
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
# ── 호가·휩쏘 TPE 축 (본 trial 엔진 평가용, 사후「필터후」대체) ───────────────
|
||||
# multivariate TPE: 키는 항상 suggest (OFF 여부와 무관). 범위는 OPTUNA_OB_ENTRY_* env.
|
||||
# 임계값만 (스터디 스위치로 ON/OFF 고정할 때 — 돌파 등)
|
||||
ORDERBOOK_TPE_THRESHOLD_KEYS: List[str] = [
|
||||
"max_spread_pct",
|
||||
"min_bid_ask_ratio",
|
||||
"ask_max_mult",
|
||||
]
|
||||
ORDERBOOK_TPE_AXIS_KEYS: List[str] = [
|
||||
"_orderbook_filter_enabled",
|
||||
*ORDERBOOK_TPE_THRESHOLD_KEYS,
|
||||
]
|
||||
|
||||
WHIPSAW_TPE_AXIS_KEYS: List[str] = [
|
||||
"whipsaw_enabled",
|
||||
"whipsaw_subbar_sec",
|
||||
"whipsaw_lookback_sec",
|
||||
"whipsaw_dip_pct",
|
||||
"whipsaw_recovery_tol_pct",
|
||||
]
|
||||
|
||||
|
||||
def optuna_tpe_include_orderbook() -> bool:
|
||||
"""본 TPE에 호가 축 포함 (기본 ON). 끄면 구 타점-only 탐색."""
|
||||
from kis_trader.utils.env import get_env_bool
|
||||
|
||||
return bool(get_env_bool("OPTUNA_TPE_INCLUDE_ORDERBOOK", True))
|
||||
|
||||
|
||||
def optuna_tpe_include_whipsaw() -> bool:
|
||||
"""본 TPE에 휩쏘 축 포함 (기본 ON). 꼬리·스캘·모멘텀."""
|
||||
from kis_trader.utils.env import get_env_bool
|
||||
|
||||
return bool(get_env_bool("OPTUNA_TPE_INCLUDE_WHIPSAW", True))
|
||||
|
||||
|
||||
def optuna_tpe_needs_orderbook_feed(mode: str, orderbook_filter: str = "off") -> bool:
|
||||
"""TPE+호가축 또는 CLI 호가 ON → ws_orderbook 스냅 로드."""
|
||||
m = (mode or "").strip().lower()
|
||||
ob = (orderbook_filter or "off").strip().lower()
|
||||
if ob in ("on", "auto"):
|
||||
return True
|
||||
if m == "tpe" and optuna_tpe_include_orderbook():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def suggest_orderbook_thresholds_tpe(trial: optuna.Trial) -> Dict[str, Any]:
|
||||
"""호가 임계값만 (ON/OFF 는 스터디 스위치·CLI). 돌파 TPE 등."""
|
||||
from kis_trader.utils.env import get_env_float
|
||||
|
||||
lo_s = float(get_env_float("OPTUNA_OB_ENTRY_SPREAD_MIN", 0.1))
|
||||
hi_s = float(get_env_float("OPTUNA_OB_ENTRY_SPREAD_MAX", 8.0))
|
||||
lo_r = float(get_env_float("OPTUNA_OB_ENTRY_RATIO_MIN", 0.05))
|
||||
hi_r = float(get_env_float("OPTUNA_OB_ENTRY_RATIO_MAX", 1.5))
|
||||
lo_a = float(get_env_float("OPTUNA_OB_ENTRY_ASK_MULT_MIN", 1.0))
|
||||
hi_a = float(get_env_float("OPTUNA_OB_ENTRY_ASK_MULT_MAX", 80.0))
|
||||
if hi_s < lo_s:
|
||||
lo_s, hi_s = hi_s, lo_s
|
||||
if hi_r < lo_r:
|
||||
lo_r, hi_r = hi_r, lo_r
|
||||
if hi_a < lo_a:
|
||||
lo_a, hi_a = hi_a, lo_a
|
||||
return {
|
||||
"max_spread_pct": r1(trial.suggest_float("max_spread_pct", lo_s, hi_s, step=0.1)),
|
||||
"min_bid_ask_ratio": r2(trial.suggest_float("min_bid_ask_ratio", lo_r, hi_r, step=0.05)),
|
||||
"ask_max_mult": r1(trial.suggest_float("ask_max_mult", lo_a, hi_a, step=1.0)),
|
||||
}
|
||||
|
||||
|
||||
def suggest_orderbook_entry_tpe(trial: optuna.Trial) -> Dict[str, Any]:
|
||||
"""진입 호가 필터 축 — evaluate 의 _orderbook_filter_enabled / max_spread_* 와 동일 키.
|
||||
|
||||
모멘텀·스캘·꼬리: trial 마다 ON/OFF categorical.
|
||||
돌파는 ``suggest_breakout_params_tpe`` 가 CLI 스위치로 고정(여기 안 씀).
|
||||
"""
|
||||
if not optuna_tpe_include_orderbook():
|
||||
return {}
|
||||
enabled = bool(trial.suggest_categorical("_orderbook_filter_enabled", [False, True]))
|
||||
out = {
|
||||
"_orderbook_filter_enabled": enabled,
|
||||
# apply(orderbook_params_to_env_patch) 별칭
|
||||
"ob_filter_enabled": enabled,
|
||||
}
|
||||
out.update(suggest_orderbook_thresholds_tpe(trial))
|
||||
return out
|
||||
|
||||
|
||||
def suggest_whipsaw_tpe(trial: optuna.Trial, *, force: bool = False) -> Dict[str, Any]:
|
||||
"""휩쏘 TRIGGER 축 — merge_whipsaw_cfg_from_params / 꼬리 TPE 와 동일 키.
|
||||
|
||||
force=True: 꼬리처럼 축이 필수인 전략 (INCLUDE_WHIPSAW OFF 여도 키 공간 유지).
|
||||
"""
|
||||
if not force and not optuna_tpe_include_whipsaw():
|
||||
return {}
|
||||
return {
|
||||
"whipsaw_enabled": trial.suggest_categorical("whipsaw_enabled", [False, True]),
|
||||
"whipsaw_subbar_sec": trial.suggest_categorical(
|
||||
"whipsaw_subbar_sec", [15, 30, 45, 60],
|
||||
),
|
||||
"whipsaw_lookback_sec": trial.suggest_categorical(
|
||||
"whipsaw_lookback_sec", [60, 90, 120, 180],
|
||||
),
|
||||
"whipsaw_dip_pct": r4(
|
||||
trial.suggest_float("whipsaw_dip_pct", 0.001, 0.01, step=0.001),
|
||||
),
|
||||
"whipsaw_recovery_tol_pct": r4(
|
||||
trial.suggest_float("whipsaw_recovery_tol_pct", 0.0005, 0.003, step=0.0005),
|
||||
),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user