ls증권 히스토리 구독 넣음
This commit is contained in:
@@ -167,6 +167,67 @@ def align_entry_price_from_ticks(
|
||||
return fo, "ohlc_open"
|
||||
|
||||
|
||||
def _live_entry_tick_buffer_enabled() -> bool:
|
||||
"""실매 진입 계산가: RAM 틱 첫가 우선 (기본 ON). 없으면 분봉 시가 폴백."""
|
||||
from kis_trader.utils.env import get_env_bool
|
||||
return get_env_bool("LIVE_ALIGN_ENTRY_FROM_TICK_BUFFER", True)
|
||||
|
||||
|
||||
def _live_entry_tick_buffer_limit() -> int:
|
||||
from kis_trader.utils.env import get_env_int
|
||||
return max(10, int(get_env_int("LIVE_ENTRY_TICK_BUFFER_LIMIT", 300) or 300))
|
||||
|
||||
|
||||
def filter_recent_ticks_for_entry_bar(
|
||||
ticks: List[Dict[str, Any]],
|
||||
entry_bar_key: str,
|
||||
tf_min: int = 1,
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""RAM 틱 중 진입봉(T)에 속하는 것만 (시간 오름차순 유지)."""
|
||||
keys = set(tail_bar_minute_keys(entry_bar_key, tf_min))
|
||||
if not keys:
|
||||
return []
|
||||
out: List[Dict[str, Any]] = []
|
||||
for tick in ticks or []:
|
||||
tt = str(tick.get("tick_time") or "").replace(":", "").replace("-", "").replace(" ", "")
|
||||
if len(tt) >= 12 and tt[:12] in keys:
|
||||
out.append(tick)
|
||||
return out
|
||||
|
||||
|
||||
def live_align_entry_price(
|
||||
ws: Any,
|
||||
code: str,
|
||||
fallback_open: float,
|
||||
*,
|
||||
entry_bar_key: Optional[str] = None,
|
||||
tf_min: int = 1,
|
||||
enabled: Optional[bool] = None,
|
||||
) -> Tuple[float, str]:
|
||||
"""실매 진입 **계산가** — 백테 ``align_entry_price_from_ticks`` 와 동일 의미.
|
||||
|
||||
1) ``LIVE_ALIGN_ENTRY_FROM_TICK_BUFFER`` ON 이고 WS RAM에 진입봉 틱이 있으면 첫 체결가
|
||||
2) 아니면 분봉 시가(``fallback_open``)
|
||||
|
||||
주문 유형(시장가/지정가)은 바꾸지 않는다. 수량·손절·백테 정합용 기준가만 정밀화.
|
||||
"""
|
||||
fo = float(fallback_open or 0)
|
||||
use = _live_entry_tick_buffer_enabled() if enabled is None else bool(enabled)
|
||||
if not use or fo <= 0:
|
||||
return fo, "ohlc_open"
|
||||
bar_key = str(entry_bar_key or "")[:12]
|
||||
if len(bar_key) < 12:
|
||||
return fo, "ohlc_open"
|
||||
if ws is None or not code or not getattr(ws, "get_recent_ticks", None):
|
||||
return fo, "ohlc_open"
|
||||
try:
|
||||
raw = list(ws.get_recent_ticks(str(code).strip(), limit=_live_entry_tick_buffer_limit()) or [])
|
||||
except Exception:
|
||||
return fo, "ohlc_open"
|
||||
bar_ticks = filter_recent_ticks_for_entry_bar(raw, bar_key, tf_min=max(1, int(tf_min or 1)))
|
||||
return align_entry_price_from_ticks(bar_ticks, fo)
|
||||
|
||||
|
||||
def resolve_align_entry_bar(
|
||||
candles: List[Dict[str, Any]],
|
||||
signal_idx: int,
|
||||
@@ -227,10 +288,14 @@ def try_limit_fill_on_bar_with_ticks(
|
||||
from kis_trader.engine.limit_entry_common import try_limit_fill_on_bar
|
||||
|
||||
p = params or {}
|
||||
if ticks and tail_backtest_use_tick_db(p):
|
||||
use_ticks = tail_backtest_use_tick_db(p)
|
||||
if use_ticks and ticks:
|
||||
fp = try_limit_fill_from_ticks(ticks, limit_price, fill_slip_pct)
|
||||
if fp and fp > 0:
|
||||
return fp, "ws_ticks"
|
||||
# 절대규칙: 틱 진입 ON 이면 OHLC low 폴백으로 체결가 변조 금지
|
||||
if use_ticks:
|
||||
return None, "none"
|
||||
if tail_backtest_tick_fallback_ohlc(p):
|
||||
fp = try_limit_fill_on_bar(bar, limit_price, fill_slip_pct)
|
||||
if fp and fp > 0:
|
||||
|
||||
Reference in New Issue
Block a user