feat: 새로운 안전 규칙 및 최적화 적용을 통한 트레이딩 시스템 개선

변경 사항 (Changes):

구문 오류(Syntax error) 및 토큰 낭비를 방지하기 위해 에이전트 쉘(Agent shell)과 파이썬 코드 스니펫에 다수의 신규 안전 규칙(Safety rules)을 추가함.

스키마 검증 및 적절한 SQL 포맷팅을 보장하기 위해 임시(Ad-hoc) 데이터베이스 쿼리 작성 가이드라인을 도입함.

코드 수정 후 UI 기능이 정상 작동하는지 확인하기 위해, 백테스트 웹 서비스 재시작 및 브라우저 검증에 대한 새로운 규칙을 구현함.

시스템 전반의 무결성(Integrity)을 유지하기 위해 실전 매매(Live trading), 웹 백테스팅, 파라미터 탐색(Parameter searches) 간의 일관성 검사(Consistency checks) 체계를 확립함.

기대 효과 (Impact):

이러한 개선 사항들은 트레이딩 시스템의 견고성(Robustness)과 신뢰성을 향상시키며, 에러 발생을 최소화하고 다양한 시스템 컴포넌트 간의 원활한 상호작용을 보장함.
This commit is contained in:
Your Name
2026-07-17 01:09:09 +09:00
parent a4626e0351
commit fc27e726f9
151 changed files with 20718 additions and 6450 deletions

View File

@@ -9,14 +9,16 @@ from __future__ import annotations
import logging
import os
import time
from typing import Any, Dict, Optional
logger = logging.getLogger("kis_trader.env")
# 순환 import 방지용 레이지 TradeDB 참조
_db_instance = None
# get_merged_env_snapshot() — 프로세스당 1회 (백테·파라서치 env 키 반복 조회 가속)
# get_merged_env_snapshot() — TTL 내 재사용 (실매: 웹에서 MAX_DAILY 등 변경 즉시 반영)
_merged_env_cache: Optional[Dict[str, str]] = None
_merged_env_cache_ts: float = 0.0
# env 캐시 세대 카운터 — invalidate 시 +1. 파생 캐시(예: whipsaw 파라미터)가
# 이 값으로 무효화를 감지해 안전하게 재계산한다(값은 그대로, 재계산 시점만 동일).
_env_generation: int = 0
@@ -43,11 +45,20 @@ def set_db(db_obj) -> None:
def invalidate_merged_env_cache() -> None:
"""env/config 저장 후 스냅샷 캐시 무효화 (insert_env_snapshot 등)."""
global _merged_env_cache, _env_generation
global _merged_env_cache, _merged_env_cache_ts, _env_generation
_merged_env_cache = None
_merged_env_cache_ts = 0.0
_env_generation += 1
def _merged_env_cache_ttl_sec() -> float:
"""DB env 스냅샷 메모리 TTL(초). os.environ 만 사용(순환 import 방지)."""
try:
return max(0.0, float(os.environ.get("ENV_MERGED_CACHE_TTL_SEC", "60")))
except (ValueError, TypeError):
return 60.0
def env_cache_generation() -> int:
"""현재 env 캐시 세대. invalidate 될 때마다 증가.
@@ -66,13 +77,15 @@ def _strip_comment(val: Any) -> Any:
def get_merged_env_dict() -> dict:
"""env_config + config_scalp/short/momentum/… 최신 행 병합 flat dict."""
global _merged_env_cache
if _merged_env_cache is not None:
global _merged_env_cache, _merged_env_cache_ts
ttl = _merged_env_cache_ttl_sec()
now = time.time()
if _merged_env_cache is not None and (ttl <= 0 or (now - _merged_env_cache_ts) < ttl):
return _merged_env_cache
db = _get_db()
if db is None:
return {}
return _merged_env_cache or {}
try:
if hasattr(db, "get_merged_env_snapshot"):
merged = db.get_merged_env_snapshot()
@@ -80,10 +93,11 @@ def get_merged_env_dict() -> dict:
row = db.get_latest_env()
merged = dict((row or {}).get("snapshot") or {})
_merged_env_cache = dict(merged or {})
_merged_env_cache_ts = now
return _merged_env_cache
except Exception as e:
logger.debug("merged env 조회 실패: %s", e)
return {}
return _merged_env_cache or {}
def get_strategy_env_dict(strategy_id: str) -> dict: