거래 빠르게 안티에서 병신만든거 커서로
feat: Implement backtest source management and enhance candle data handling Changes: - Introduced a new function `_apply_backtest_source_env_from_request` to manage the environment variables for candle, tick, and order book sources based on incoming requests. - Added a teardown function `_teardown_backtest_source_env` to ensure that environment variables do not persist between requests, enhancing the stability of the backtesting environment. - Refactored existing code to utilize the new source management functions, improving code readability and maintainability. - Added new utility functions in `bt_candle_source.py` for fetching and managing candle data, ensuring consistency with live trading data sources. Impact: - These changes improve the flexibility and reliability of the backtesting framework, allowing for better management of data sources and reducing the risk of cross-request contamination.
This commit is contained in:
@@ -1704,6 +1704,13 @@ class BreakoutStrategy(BaseStrategy):
|
||||
return 0.0
|
||||
|
||||
def check_buy(self, code: str, name: str) -> Optional[Dict]:
|
||||
_cb = self._cb_prof_start(code)
|
||||
try:
|
||||
return self._check_buy_impl(code, name, _cb)
|
||||
finally:
|
||||
self._cb_prof_finish(_cb)
|
||||
|
||||
def _check_buy_impl(self, code: str, name: str, _cb) -> Optional[Dict]:
|
||||
# 골든타임 가드 (_candidate_filter 가 미리 거른 뒤에도 방어용 재검사)
|
||||
if not self._is_golden_time():
|
||||
return None
|
||||
@@ -1712,6 +1719,7 @@ class BreakoutStrategy(BaseStrategy):
|
||||
if self.use_ema_filter and not self.skip_hts_scan_dupes:
|
||||
need_n = max(need_n, self.ema_slow_period + 5)
|
||||
confirmed = self.ws.get_candles(code, self.candle_tf, n=need_n + 5)
|
||||
self._cb_prof_mark(_cb, "candles")
|
||||
if len(confirmed) < need_n - 1:
|
||||
# force 연타 금지 — 시세불가·특수코드는 fail_max 후에도 REST 폭주
|
||||
force_sec = max(30, get_env_int("BREAKOUT_CANDLE_GAP_FORCE_SEC", 120))
|
||||
@@ -1726,6 +1734,7 @@ class BreakoutStrategy(BaseStrategy):
|
||||
self.ws.fill_gap([code], force=do_force)
|
||||
except Exception:
|
||||
pass
|
||||
self._cb_prof_mark(_cb, "fill_gap")
|
||||
log_sec = max(15, get_env_int("BREAKOUT_CANDLE_SHORT_LOG_SEC", 60))
|
||||
if not hasattr(self, "_candle_short_log_ts"):
|
||||
self._candle_short_log_ts = {}
|
||||
@@ -1820,6 +1829,7 @@ class BreakoutStrategy(BaseStrategy):
|
||||
forming_close=curr_price,
|
||||
),
|
||||
)
|
||||
self._cb_prof_mark(_cb, "engine")
|
||||
if reason:
|
||||
self.logger.info("🔍 [%s] %s(%s) %s", reason, name, code, msg or "")
|
||||
return None
|
||||
@@ -1830,6 +1840,7 @@ class BreakoutStrategy(BaseStrategy):
|
||||
curr_price = float(signal.get("entry_price") or curr_price)
|
||||
else:
|
||||
reason, msg, signal = check_buy_signal_breakout_live(confirmed, params)
|
||||
self._cb_prof_mark(_cb, "engine")
|
||||
if reason:
|
||||
self.logger.info("🔍 [%s] %s(%s) %s", reason, name, code, msg or "")
|
||||
return None
|
||||
@@ -1842,6 +1853,7 @@ class BreakoutStrategy(BaseStrategy):
|
||||
_defer = self._defer_mid_enroll_entry(
|
||||
code, _ebk, int(self.candle_tf or 1), params,
|
||||
)
|
||||
self._cb_prof_mark(_cb, "mid_enroll")
|
||||
if _defer:
|
||||
self.logger.info("🔍 [%s] %s(%s)", _defer, name, code)
|
||||
return None
|
||||
@@ -1859,6 +1871,7 @@ class BreakoutStrategy(BaseStrategy):
|
||||
p = self._live_current_price(code)
|
||||
if p > 0:
|
||||
curr_price = p
|
||||
self._cb_prof_mark(_cb, "align")
|
||||
if curr_price <= 0:
|
||||
if get_env_bool("SCAN_REJECT_LOG_VERBOSE", False):
|
||||
if not hasattr(self, "_no_price_log"):
|
||||
@@ -1888,6 +1901,7 @@ class BreakoutStrategy(BaseStrategy):
|
||||
name, code, curr_price, invest_cap,
|
||||
)
|
||||
return None
|
||||
self._cb_prof_mark(_cb, "qty")
|
||||
|
||||
stop_price = curr_price * (1 + self.stop_loss_pct)
|
||||
target_price = curr_price * (1 + self.take_profit_pct)
|
||||
|
||||
Reference in New Issue
Block a user