feat: Enhance Optuna integration and logging for backtesting framework
Changes: - Added new API endpoints for continuing and confirming Optuna jobs, allowing for better management of ongoing studies. - Introduced detailed logging for tick feed tracking and order book processing, improving traceability of vendor performance during backtests. - Updated database schema to include new fields for managing Optuna study results, enhancing the ability to track study progress and outcomes. - Refactored existing functions to utilize the new logging and tracking features, ensuring consistency across the backtesting framework. Impact: - These enhancements improve the robustness and transparency of the Optuna backtesting process, facilitating better analysis and optimization of trading strategies.
This commit is contained in:
@@ -346,27 +346,28 @@ def load_tail_candles_by_code(
|
||||
peak_sel = ", holding_peak" if has_holding_peak else ""
|
||||
ind_cols = ws_candles_select_indicator_cols(db)
|
||||
|
||||
from kis_trader.backtest.bt_candle_source import (
|
||||
fetch_ws_candles_for_code,
|
||||
list_ws_candle_codes,
|
||||
)
|
||||
from kis_trader.backtest.bt_candle_source import fetch_ws_candles_by_code_bulk
|
||||
|
||||
codes = list_ws_candle_codes(db, tail_tf, start_key, end_key)
|
||||
|
||||
# 3분 합성 시 1분만 있는 종목도 후보에 포함
|
||||
synth_on = (
|
||||
tail_tf == 3
|
||||
and get_env_bool("TAIL_BT_SYNTH_3M_FROM_1M", True)
|
||||
)
|
||||
loaded_tf = fetch_ws_candles_by_code_bulk(
|
||||
db, tail_tf, start_key, end_key,
|
||||
extra_select=ind_cols,
|
||||
peak_sel=peak_sel,
|
||||
confirmed_only=True,
|
||||
)
|
||||
loaded_1m: Dict[str, List[Dict]] = {}
|
||||
if synth_on:
|
||||
try:
|
||||
codes_1m = list_ws_candle_codes(db, 1, start_key, end_key)
|
||||
for c in codes_1m:
|
||||
if c not in codes:
|
||||
codes.append(c)
|
||||
codes = sorted(set(codes))
|
||||
except Exception:
|
||||
pass
|
||||
loaded_1m = fetch_ws_candles_by_code_bulk(
|
||||
db, 1, start_key, end_key,
|
||||
extra_select=ind_cols,
|
||||
peak_sel=peak_sel,
|
||||
confirmed_only=True,
|
||||
)
|
||||
|
||||
codes = sorted(set(list(loaded_tf.keys()) + list(loaded_1m.keys())))
|
||||
|
||||
candles_by_code: Dict[str, List[Dict]] = {}
|
||||
total_candles = 0
|
||||
@@ -374,16 +375,11 @@ def load_tail_candles_by_code(
|
||||
synth_filled_total = 0
|
||||
|
||||
for code in codes:
|
||||
bars = fetch_ws_candles_for_code(
|
||||
db, code, tail_tf, start_key, end_key,
|
||||
extra_select=ind_cols,
|
||||
peak_sel=peak_sel,
|
||||
confirmed_only=True,
|
||||
)
|
||||
|
||||
bars = list(loaded_tf.get(code) or [])
|
||||
if synth_on:
|
||||
bars, n_fill = _synth_fill_3m_holes_from_1m(
|
||||
db, code, bars, start_key, end_key, peak_sel=peak_sel,
|
||||
rows_1m=loaded_1m.get(code) or [],
|
||||
)
|
||||
synth_filled_total += n_fill
|
||||
|
||||
@@ -428,17 +424,19 @@ def _synth_fill_3m_holes_from_1m(
|
||||
end_key: str,
|
||||
*,
|
||||
peak_sel: str = "",
|
||||
rows_1m: Optional[List[Dict]] = None,
|
||||
) -> Tuple[List[Dict], int]:
|
||||
"""DB 3분 리스트에 없는 시각만 1분→3분 롤업으로 보강."""
|
||||
from kis_trader.engine.candle_rollup import merge_fill_holes, rollup_1m_bars_to_tf
|
||||
from kis_trader.backtest.bt_candle_source import fetch_ws_candles_for_code
|
||||
|
||||
try:
|
||||
rows_1m = fetch_ws_candles_for_code(
|
||||
db, code, 1, start_key, end_key,
|
||||
peak_sel=peak_sel,
|
||||
confirmed_only=True,
|
||||
)
|
||||
if rows_1m is None:
|
||||
rows_1m = fetch_ws_candles_for_code(
|
||||
db, code, 1, start_key, end_key,
|
||||
peak_sel=peak_sel,
|
||||
confirmed_only=True,
|
||||
)
|
||||
except Exception:
|
||||
return bars_3m, 0
|
||||
if not rows_1m:
|
||||
|
||||
Reference in New Issue
Block a user