변경 사항 (Changes): 구문 오류(Syntax error) 및 토큰 낭비를 방지하기 위해 에이전트 쉘(Agent shell)과 파이썬 코드 스니펫에 다수의 신규 안전 규칙(Safety rules)을 추가함. 스키마 검증 및 적절한 SQL 포맷팅을 보장하기 위해 임시(Ad-hoc) 데이터베이스 쿼리 작성 가이드라인을 도입함. 코드 수정 후 UI 기능이 정상 작동하는지 확인하기 위해, 백테스트 웹 서비스 재시작 및 브라우저 검증에 대한 새로운 규칙을 구현함. 시스템 전반의 무결성(Integrity)을 유지하기 위해 실전 매매(Live trading), 웹 백테스팅, 파라미터 탐색(Parameter searches) 간의 일관성 검사(Consistency checks) 체계를 확립함. 기대 효과 (Impact): 이러한 개선 사항들은 트레이딩 시스템의 견고성(Robustness)과 신뢰성을 향상시키며, 에러 발생을 최소화하고 다양한 시스템 컴포넌트 간의 원활한 상호작용을 보장함.
71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
청산·보유 종목의 매수~매도(또는 ~now) 구간 1분봉을 키움 REST로 즉시 백필.
|
|
|
|
예:
|
|
nohup python3 -u scripts/backfill_trade_candles.py \\
|
|
--like '2026-07-16%' > /tmp/backfill_trade_candles_0716.log 2>&1 &
|
|
tail -f /tmp/backfill_trade_candles_0716.log
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from database import TradeDB
|
|
from kis_trader.engine.post_sell_candle_backfill import backfill_trades_from_db
|
|
|
|
|
|
def main() -> int:
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--like", default="2026-07-16%", help="buy_date LIKE (%% 바인딩)")
|
|
ap.add_argument(
|
|
"--strategies",
|
|
default="",
|
|
help="콤마 구분 strategy (비우면 전체)",
|
|
)
|
|
ap.add_argument("--no-active", action="store_true", help="active_trades 제외")
|
|
ap.add_argument("--active-days", type=int, default=5)
|
|
args = ap.parse_args()
|
|
|
|
strategies = [s.strip() for s in str(args.strategies).split(",") if s.strip()] or None
|
|
db = TradeDB()
|
|
try:
|
|
results = backfill_trades_from_db(
|
|
db,
|
|
buy_date_like=str(args.like),
|
|
strategies=strategies,
|
|
include_active=not args.no_active,
|
|
active_max_age_days=int(args.active_days),
|
|
)
|
|
finally:
|
|
try:
|
|
db.close()
|
|
except Exception:
|
|
pass
|
|
|
|
ok = sum(1 for r in results if r.get("ok"))
|
|
improved = sum(1 for r in results if int(r.get("after") or 0) > int(r.get("before") or 0))
|
|
print(
|
|
f"DONE jobs={len(results)} ok={ok} improved={improved} "
|
|
f"upsert_sum={sum(int(r.get('upserted') or 0) for r in results)}"
|
|
)
|
|
for r in results:
|
|
if not r.get("ok") or int(r.get("after") or 0) > int(r.get("before") or 0):
|
|
print(
|
|
f" {r.get('strategy')} {r.get('code')} "
|
|
f"{r.get('start')}~{r.get('end')} "
|
|
f"{r.get('before')}→{r.get('after')} "
|
|
f"upsert={r.get('upserted')} err={r.get('error')!r}"
|
|
)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|