feat: Add DART strategy and related configurations
ㅇ Changes: - Introduced the DART strategy to the trading system, including its configuration and integration into the existing framework. - Updated the database schema to include DART-specific tables for disclosures and watchlists. - Enhanced the backtesting and parameter search functionalities to support the DART strategy. - Implemented new rules for browser verification and API interactions to ensure compliance with the updated DART strategy. Impact: - These additions expand the trading capabilities of the system, allowing for more comprehensive analysis and execution of DART-related strategies, while maintaining system integrity and performance.
This commit is contained in:
@@ -737,6 +737,8 @@ def evaluate_scalp_param_combo(
|
||||
ticks_by_code: Any = None,
|
||||
orderbook_by_code: Any = None,
|
||||
program_by_code: Any = None,
|
||||
start_key: str = "",
|
||||
end_key: str = "",
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""단일 스캘핑(reversal) 조합 백테 — Grid 워커·Optuna objective 공통.
|
||||
|
||||
@@ -757,6 +759,19 @@ def evaluate_scalp_param_combo(
|
||||
engine_params["_bt_program_by_code"] = program_by_code
|
||||
|
||||
meta: Dict[str, Any] = {}
|
||||
sk = str(start_key or "").strip()
|
||||
ek = str(end_key or "").strip()
|
||||
if len(sk) >= 12:
|
||||
meta["start_key"] = sk[:12]
|
||||
engine_params["_backtest_period_start_key"] = sk[:12]
|
||||
elif len(sk) >= 8:
|
||||
meta["start_key"] = sk[:8] + "0000"
|
||||
engine_params["_backtest_period_start_key"] = meta["start_key"]
|
||||
if len(ek) >= 12:
|
||||
meta["end_key"] = ek[:12]
|
||||
elif len(ek) >= 8:
|
||||
meta["end_key"] = ek[:8] + "2359"
|
||||
|
||||
trades = sbc.run_scalping_backtest_web_aligned(
|
||||
codes_candles, engine_params, universe_by_slot,
|
||||
slot_money=slot_money, fee_rate=fee_rate, sell_tax=sell_tax,
|
||||
@@ -920,12 +935,14 @@ def _evaluate_scalp_chunk(
|
||||
"""워커: 청크 내 조합 평가 — 시각순 포트폴리오·총한도 (scalping_backtest_common)."""
|
||||
shared = worker_shared_get()
|
||||
ticks_preloaded = None
|
||||
period_start_key = ""
|
||||
if shared:
|
||||
if codes_candles is None:
|
||||
codes_candles = shared.get("codes_candles") or {}
|
||||
if universe_by_slot is None:
|
||||
universe_by_slot = shared.get("universe_by_slot")
|
||||
ticks_preloaded = shared.get("ticks_by_code")
|
||||
period_start_key = str(shared.get("start_key") or "")[:12]
|
||||
# ws_ticks 공유메모리(opt-in): descriptor 로 read-only attach (워커당 1회 재사용).
|
||||
if not ticks_preloaded:
|
||||
_desc = shared.get("ticks_shared_descriptor")
|
||||
@@ -948,8 +965,12 @@ def _evaluate_scalp_chunk(
|
||||
engine_params["max_stocks"] = int(max_stocks)
|
||||
engine_params["total_budget_krw"] = float(total_budget_krw)
|
||||
engine_params["portfolio_mode"] = True
|
||||
if period_start_key:
|
||||
engine_params["_backtest_period_start_key"] = period_start_key
|
||||
|
||||
meta: Dict[str, Any] = {}
|
||||
if period_start_key:
|
||||
meta["start_key"] = period_start_key
|
||||
trades = sbc.run_scalping_backtest_web_aligned(
|
||||
codes_candles, engine_params, universe_by_slot,
|
||||
slot_money=slot_money, fee_rate=fee_rate, sell_tax=sell_tax,
|
||||
@@ -1043,6 +1064,11 @@ def _load_candles_for_search(start: str, end: str, rsi_period: int) -> dict:
|
||||
if len(rows) < rsi_period + 5:
|
||||
continue
|
||||
codes_candles[code] = [dict(r) for r in rows]
|
||||
if codes_candles:
|
||||
from kis_trader.backtest.scalping_backtest_common import (
|
||||
prepend_scalp_candle_warmup,
|
||||
)
|
||||
prepend_scalp_candle_warmup(db, codes_candles, start_key[:12])
|
||||
finally:
|
||||
db.close()
|
||||
return codes_candles
|
||||
@@ -1186,17 +1212,13 @@ def run_search(start: str, end: str, mode: str, top_n: int,
|
||||
print("📌 [유니버스] --fallback-universe: 저장 이력 무시 → 시뮬레이션 유니버스 (조합별 거래 수 확대)")
|
||||
elif start_ymd and end_ymd:
|
||||
try:
|
||||
# 신봇 이력 (초단위 event_time) → 1분 캔들 시각으로 리샘플링
|
||||
from kis_trader.database.db_manager import get_db as _get_ext_db # type: ignore
|
||||
_ext = _get_ext_db()
|
||||
history = _ext.get_universe_by_candle_time(
|
||||
strategy_id="SCALP",
|
||||
start_ymd=start_ymd,
|
||||
end_ymd=end_ymd,
|
||||
# Optuna/웹과 동일 — resolve_scalp_universe (EXIT debounce 포함)
|
||||
from kis_trader.backtest.scalping_backtest_common import resolve_scalp_universe
|
||||
history, _src, n_bins, _scan_iv = resolve_scalp_universe(
|
||||
start_ymd, end_ymd, use_saved_history=True, strategy_id="SCALP",
|
||||
)
|
||||
if history:
|
||||
universe_by_slot = history
|
||||
n_bins = len(history)
|
||||
avg = sum(len(v) for v in history.values()) / max(1, n_bins)
|
||||
print(
|
||||
f"✅ 유니버스: 신봇 이력 사용 (event_time → 1분 캔들 리샘플링) | "
|
||||
@@ -1271,6 +1293,8 @@ def run_search(start: str, end: str, mode: str, top_n: int,
|
||||
"ticks_by_code": ticks_by_code,
|
||||
"ticks_shared_descriptor": (shared_tick_store.descriptor() if shared_tick_store else None),
|
||||
"tick_backtest_meta": tick_backtest_meta,
|
||||
"start_key": start_key[:12] if start_key else "",
|
||||
"end_key": end_key[:12] if end_key else "",
|
||||
})
|
||||
payload_bytes = shared.estimate_bytes()
|
||||
n_cpu = os.cpu_count() or 4
|
||||
|
||||
Reference in New Issue
Block a user