Files
kis_trader/scripts/smoke_candle_upsert_rollup.py
Your Name fc27e726f9 feat: 새로운 안전 규칙 및 최적화 적용을 통한 트레이딩 시스템 개선
변경 사항 (Changes):

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

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

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

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

기대 효과 (Impact):

이러한 개선 사항들은 트레이딩 시스템의 견고성(Robustness)과 신뢰성을 향상시키며, 에러 발생을 최소화하고 다양한 시스템 컴포넌트 간의 원활한 상호작용을 보장함.
2026-07-17 01:09:09 +09:00

114 lines
3.3 KiB
Python

#!/usr/bin/env python3
"""
스모크: 1M→N분 완전버킷 롤업 + confirm/merge volume upsert.
근본원인(2026-07-16 샘표): 불완전 롤업 삽입 + 동일 candle_time append 중복
→ RAM prior volume 왜곡 → 실매 vol 통과 / 백테 탈락.
실행:
python3 -u scripts/smoke_candle_upsert_rollup.py
"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from kis_trader.engine.candle_rollup import floor_candle_time_to_tf, rollup_1m_bars_to_tf
from kis_trader.ws.kis_ws import CandleAggregator
def bar(ct, o, h, l, c, v, src="ws"):
return {
"candle_time": ct,
"open": o,
"high": h,
"low": l,
"close": c,
"volume": v,
"source": src,
}
def main() -> None:
assert floor_candle_time_to_tf("202607160912", 3) == "202607160912"
assert floor_candle_time_to_tf("202607160913", 3) == "202607160912"
assert floor_candle_time_to_tf("202607160914", 3) == "202607160912"
partial = [
bar("202607160912", 100, 101, 99, 100, 100),
bar("202607160913", 100, 102, 99, 101, 200),
]
assert rollup_1m_bars_to_tf(partial, 3) == []
full = partial + [bar("202607160914", 101, 110, 100, 105, 4226)]
rolled = rollup_1m_bars_to_tf(full, 3)
assert len(rolled) == 1
assert rolled[0]["candle_time"] == "202607160912"
assert rolled[0]["volume"] == 100 + 200 + 4226
more = full + [
bar("202607160915", 105, 106, 104, 105, 50),
bar("202607160916", 105, 107, 104, 106, 60),
]
assert len(rollup_1m_bars_to_tf(more, 3)) == 1
agg = CandleAggregator(db=None, timeframes=[1, 3])
code = "007540"
assert agg.merge_confirmed_bars(
code, 3,
[bar("202607160912", 43000, 44000, 42000, 43500, 515, "rollup_1m")],
log_tag="smoke_partial",
) == 1
assert agg.merge_confirmed_bars(
code, 3,
[bar("202607160912", 43000, 44500, 42000, 43800, 4526, "rest")],
log_tag="smoke_full",
) == 1
buf = agg._confirmed[(code, 3)]
assert len(buf) == 1 and buf[0]["volume"] == 4526
assert agg.merge_confirmed_bars(
code, 3,
[bar("202607160912", 43000, 44000, 42000, 43700, 100, "ws")],
log_tag="smoke_small",
) == 0
assert buf[0]["volume"] == 4526
agg2 = CandleAggregator(db=None, timeframes=[3])
key = (code, 3)
agg2.merge_confirmed_bars(
code, 3,
[bar("202607160912", 43000, 44000, 42000, 43500, 515, "rollup_1m")],
)
with agg2._lock:
confirmed = agg2._confirm_current_bucket(key, {
"candle_time": "202607160912",
"open": 43000,
"high": 44200,
"low": 42000,
"close": 43600,
"volume": 800,
"source": "ws",
})
assert len(agg2._confirmed[key]) == 1
assert confirmed["volume"] == 800
with agg2._lock:
agg2._confirm_current_bucket(key, {
"candle_time": "202607160912",
"open": 43000,
"high": 44100,
"low": 42000,
"close": 43400,
"volume": 100,
"source": "ws",
})
assert agg2._confirmed[key][0]["volume"] == 800
print("SMOKE_OK candle_upsert_rollup")
if __name__ == "__main__":
main()