Files
kis_trader/scripts/run_optuna_4strat_tpe_seq.sh
Your Name 1387fbdf47 feat(옵투나): score·min_trades·후처리 재탐색 및 웹 job 개선
PnL/(MDD+ADD) score·legacy 정렬·거래일×min_trades 게이트를 공통화한다.
후처리 ob_modes·study store·4전략 TPE 순차 스크립트와 문서를 갱신한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 16:46:27 +09:00

184 lines
6.8 KiB
Bash
Executable File

#!/bin/bash
# 4전략 Optuna mode=tpe 순차 실행 (병렬 X — RAM/틱 로딩 OOM 방지)
# 기본 기간: 어제~오늘(호출 시 START/END 오버라이드)
# --apply-best 없음 — 결과 JSON만. apply 는 사용자 승인 후.
#
# 사용:
# nohup bash scripts/run_optuna_4strat_tpe_seq.sh >> logs/optuna_4strat_tpe_master.log 2>&1 &
# tail -f logs/optuna_4strat_tpe_latest_master.logpath # 경로만
# tail -f "$(cat logs/optuna_4strat_tpe_latest_master.logpath)"
#
# START=2026-07-20 END=2026-07-21 TRIALS=200 bash scripts/run_optuna_4strat_tpe_seq.sh
set -euo pipefail
cd /home/hoon/kis_bot
mkdir -p logs kis_trader/backtest/results
START="${START:-2026-07-20}"
END="${END:-2026-07-21}"
MODE="${MODE:-tpe}"
TRIALS="${TRIALS:-200}"
STUDY_TRIALS="${STUDY_TRIALS:-}"
MIN_TRADES="${MIN_TRADES:-1}"
# 탐색 게이트 OFF — TPE 학습. 사후 후보는 JSON results_gated (REPORT_MIN_*)
MIN_WIN_RATE="${MIN_WIN_RATE:-0}"
MIN_PF="${MIN_PF:-0}"
# 공백 구분 — 기본 국내4 (해외 us_momentum 은 STRATEGIES 에 넣을 때만)
# STRATEGIES="momentum tail" bash ...
# STRATEGIES="us_momentum momentum" bash ...
STRATEGIES="${STRATEGIES:-momentum tail breakout scalp}"
# 꼬리 TPE 진입모드 — 한 스터디에 섞지 않음. 공백 구분 시 순차 2회.
# TAIL_OPTUNA_ENTRY_MODES="align limit_atr"
TAIL_OPTUNA_ENTRY_MODES="${TAIL_OPTUNA_ENTRY_MODES:-align}"
# 돌파 TPE 손절모드 — 한 스터디에 섞지 않음. 공백 구분 시 순차.
# BREAKOUT_OPTUNA_SL_MODES="fixed atr"
BREAKOUT_OPTUNA_SL_MODES="${BREAKOUT_OPTUNA_SL_MODES:-fixed}"
# 돌파 TPE 호가 스위치 — trial 축 아님. 손절×호가 최대 4순차.
# BREAKOUT_OPTUNA_OB_MODES="off on"
BREAKOUT_OPTUNA_OB_MODES="${BREAKOUT_OPTUNA_OB_MODES:-off}"
# kiwoom|ls — 웹 Optuna 이력소스 / CLI UNIVERSE_HISTORY_SOURCE
UNIVERSE_HISTORY_SOURCE="${UNIVERSE_HISTORY_SOURCE:-${BACKTEST_UNIVERSE_HISTORY_SOURCE:-kiwoom}}"
PY="${PY:-.venv/bin/python}"
TS0="$(date +%Y%m%d_%H%M%S)"
MASTER="logs/optuna_4strat_tpe_${START}_${END}_${TS0}_master.log"
{
echo "======== Optuna 4전략 TPE 순차 시작 $(date -Is) ========"
echo "START=$START END=$END MODE=$MODE TRIALS=$TRIALS STUDY_TRIALS=${STUDY_TRIALS:-}"
echo "STRATEGIES=$STRATEGIES"
echo "TAIL_OPTUNA_ENTRY_MODES=$TAIL_OPTUNA_ENTRY_MODES"
echo "BREAKOUT_OPTUNA_SL_MODES=$BREAKOUT_OPTUNA_SL_MODES"
echo "BREAKOUT_OPTUNA_OB_MODES=$BREAKOUT_OPTUNA_OB_MODES"
echo "UNIVERSE_HISTORY_SOURCE=$UNIVERSE_HISTORY_SOURCE"
echo "min_wr=$MIN_WIN_RATE min_pf=$MIN_PF min_trades=$MIN_TRADES"
echo "apply-best=OFF breakout-orderbook=스위치(스터디별) n_jobs=1 (사후 results_gated + briefing.md)"
echo "master_log=$MASTER"
free -h | sed -n '1,2p'
df -h / | tail -1
} | tee -a "$MASTER"
echo "$MASTER" > logs/optuna_4strat_tpe_latest_master.logpath
run_one() {
local strat="$1"
local entry_mode="${2:-}"
local sl_mode="${3:-}"
local ob_mode="${4:-off}"
local ts study log sort_by bo_extra
ts="$(date +%Y%m%d_%H%M%S)"
study="${strat}_tpe_${START//-/}_${END//-/}_${ts}"
log="logs/optuna_${strat}_tpe_${ts}.log"
if [[ "$strat" == "tail" && -n "$entry_mode" ]]; then
study="${strat}_${entry_mode}_tpe_${START//-/}_${END//-/}_${ts}"
log="logs/optuna_${strat}_${entry_mode}_tpe_${ts}.log"
fi
if [[ "$strat" == "breakout" && -n "$sl_mode" ]]; then
bo_extra="${sl_mode}_ob_${ob_mode}"
study="${strat}_${bo_extra}_tpe_${START//-/}_${END//-/}_${ts}"
log="logs/optuna_${strat}_${bo_extra}_tpe_${ts}.log"
fi
sort_by="${SORT_BY:-score}"
case "$sort_by" in
score|score_legacy|pnl|daily_avg|win_rate) ;;
*) sort_by="score" ;;
esac
local min_trades_arg
min_trades_arg=$("$PY" -c "from kis_trader.backtest.optuna_common import resolve_optuna_min_trades; print(resolve_optuna_min_trades('${START}', '${END}', '${strat}')['min_trades'])")
{
echo ""
echo "-------- [$strat${entry_mode:+/$entry_mode}${sl_mode:+/$sl_mode}${bo_extra:+/$bo_extra}] START $(date -Is) study=$study univ=$UNIVERSE_HISTORY_SOURCE min_trades=$min_trades_arg --------"
} | tee -a "$MASTER"
echo "$log" > "logs/optuna_${strat}_tpe_latest.logpath"
echo "$study" > "logs/optuna_${strat}_tpe_latest.study"
# 웹 진행률: 전역 latest.study 가 이전 전략에 남으면 바가 1번에서 멈춤 → 잡별 파일
if [[ -n "${OPTUNA_SEQ_ACTIVE_FILE:-}" ]]; then
if [[ "$strat" == "breakout" && -n "$bo_extra" ]]; then
extra="$bo_extra"
else
extra="${entry_mode:-${sl_mode:-}}"
fi
{
echo "strategy=$strat"
echo "study=$study"
echo "entry_mode=${entry_mode:-}"
echo "sl_mode=${sl_mode:-}"
echo "ob_mode=${ob_mode:-}"
echo "extra=${extra}"
} > "$OPTUNA_SEQ_ACTIVE_FILE"
fi
set +e
set +e
local cmd_args=(
--strategy "$strat"
--mode "$MODE"
--start "$START"
--end "$END"
--trials "$TRIALS"
--min_trades "$min_trades_arg"
--min_win_rate "$MIN_WIN_RATE"
--min_pf "$MIN_PF"
--orderbook-filter "$([[ "$strat" == "breakout" ]] && echo "$ob_mode" || echo off)"
--no-progress
--study-name "$study"
--sort-by "$sort_by"
--universe-history-source "$UNIVERSE_HISTORY_SOURCE"
)
if [[ -n "${STUDY_TRIALS:-}" && "${STUDY_TRIALS}" != "0" ]]; then
cmd_args+=(--study-trials "$STUDY_TRIALS")
fi
if [[ "$strat" == "tail" && -n "$entry_mode" ]]; then
cmd_args+=(--entry-mode "$entry_mode")
fi
if [[ "$strat" == "breakout" && -n "$sl_mode" ]]; then
cmd_args+=(--sl-mode "$sl_mode")
fi
if [[ -n "${TICK_SOURCE:-}" ]]; then
cmd_args+=("--tick-source" "$TICK_SOURCE")
fi
if [[ -n "${OB_SOURCE:-}" ]]; then
cmd_args+=("--ob-source" "$OB_SOURCE")
fi
"$PY" -u kis_trader/backtest/param_search_optuna.py "${cmd_args[@]}" >"$log" 2>&1
local rc=$?
set -e
{
echo "-------- [$strat${entry_mode:+/$entry_mode}${sl_mode:+/$sl_mode}${bo_extra:+/$bo_extra}] END rc=$rc $(date -Is) --------"
echo "LOG=$log"
grep -E 'OPTUNA_RESULT_JSON=|OPTUNA_BRIEFING_MD=|Best trial|optuna_best|❌|KeyError|Traceback' "$log" | tail -n 24 || true
} | tee -a "$MASTER"
if [[ "$rc" -ne 0 ]]; then
echo "⚠️ [$strat] 실패 rc=$rc — 다음 전략 계속" | tee -a "$MASTER"
fi
return 0
}
for s in $STRATEGIES; do
if [[ "$s" == "tail" ]]; then
for em in $TAIL_OPTUNA_ENTRY_MODES; do
run_one tail "$em"
done
elif [[ "$s" == "breakout" ]]; then
for sm in $BREAKOUT_OPTUNA_SL_MODES; do
for om in $BREAKOUT_OPTUNA_OB_MODES; do
run_one breakout "" "$sm" "$om"
done
done
else
run_one "$s"
fi
done
{
echo ""
echo "======== ALL DONE $(date -Is) ========"
echo "apply 하지 않음. JSON= kis_trader/backtest/results/optuna_*_tpe_*.json"
echo "브리핑= 같은 이름 .briefing.md (이전 장 / 앞으로 장)"
echo "검증: .venv/bin/python scripts/verify_optuna_tpe_apply_dryrun.py"
} | tee -a "$MASTER"