Files
kis_bot/scripts/smoke_candle_upsert_rollup.py
Your Name 61bec4bd1d 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.
2026-07-21 07:50:24 +09:00

145 lines
4.4 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
# 진행 중 분봉은 REST/merge confirmed 에 넣지 않음 (장초 직전봉% 왜곡 방지)
import datetime as _dt
agg3 = CandleAggregator(db=None, timeframes=[1])
code2 = "333050"
frozen = _dt.datetime(2026, 7, 16, 9, 0, 34)
# 전일 + 미완성 당일 09:00 을 넣으려 할 때 → 09:00 만 skip
n = agg3.merge_confirmed_bars(
code2, 1,
[
bar("202607151530", 5280, 5280, 5280, 5280, 960, "rest"),
bar("202607160900", 5220, 5250, 5200, 5220, 10, "rest"), # 진행분
],
log_tag="smoke_skip_open",
skip_incomplete_bucket=True,
now=frozen,
)
assert n == 1
buf3 = agg3._confirmed[(code2, 1)]
assert len(buf3) == 1 and buf3[0]["candle_time"] == "202607151530"
# 이미 들어간 진행분 purge
agg3._confirmed[(code2, 1)].append(
bar("202607160900", 5220, 5250, 5200, 5220, 10, "rest")
)
agg3.merge_confirmed_bars(
code2, 1, [], log_tag="smoke_purge", skip_incomplete_bucket=True, now=frozen,
)
assert all(
str(c["candle_time"])[:12] < "202607160900"
for c in agg3._confirmed[(code2, 1)]
)
print("SMOKE_OK candle_upsert_rollup")
if __name__ == "__main__":
main()