거래 빠르게 안티에서 병신만든거 커서로
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:
@@ -70,6 +70,7 @@ class MomentumStrategy(BaseStrategy):
|
||||
return super()._reentry_cooldown_sec()
|
||||
|
||||
def check_buy(self, code: str, name: str) -> Optional[Dict]:
|
||||
_cb = self._cb_prof_start(code)
|
||||
try:
|
||||
if get_env_bool("FORCE_BUY_TEST", False):
|
||||
return self._force_buy_test(code, name)
|
||||
@@ -93,14 +94,17 @@ class MomentumStrategy(BaseStrategy):
|
||||
cur_d = dict(cur)
|
||||
cur_d["is_confirmed"] = 0
|
||||
candles_raw.append(cur_d)
|
||||
self._cb_prof_mark(_cb, "candles")
|
||||
if len(candles_raw) < 6:
|
||||
try:
|
||||
# force: EXIT 후 _gap_filled 잔존 시에도 재채움 (봉부족 복구)
|
||||
self.ws.fill_gap([code], force=True)
|
||||
except Exception:
|
||||
pass
|
||||
self._cb_prof_mark(_cb, "fill_gap")
|
||||
return None
|
||||
candles = [self._norm_candle(c) for c in candles_raw]
|
||||
self._cb_prof_mark(_cb, "norm")
|
||||
|
||||
today = dt.now().strftime("%Y%m%d")
|
||||
last_exit_dt = None
|
||||
@@ -115,13 +119,14 @@ class MomentumStrategy(BaseStrategy):
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
today_trades = self.db.get_trades_by_date(today)
|
||||
today_trades = self._get_today_trades(today)
|
||||
daily_cnt = len([
|
||||
t for t in today_trades
|
||||
if t.get("code") == code and str(t.get("strategy", "")).upper() == "MOMENTUM"
|
||||
])
|
||||
except Exception:
|
||||
daily_cnt = 0
|
||||
self._cb_prof_mark(_cb, "trades_db")
|
||||
state = {"last_exit_dt": last_exit_dt, "daily_cnt": daily_cnt}
|
||||
|
||||
params = dict(self._engine_params or {})
|
||||
@@ -133,6 +138,7 @@ class MomentumStrategy(BaseStrategy):
|
||||
params["_program_code"] = code
|
||||
params["slot_money"] = self.slot_money
|
||||
reject, msg, sig = me.check_buy_signal_momentum_live(candles, params, state)
|
||||
self._cb_prof_mark(_cb, "engine")
|
||||
if reject:
|
||||
# 갭보정 워밍업 중 — 전일시가 없음·봉부족 시 force 재큐 (로그 스팸 전에 복구)
|
||||
if reject in ("탈락-전일시가없음", "탈락-봉부족"):
|
||||
@@ -140,6 +146,7 @@ class MomentumStrategy(BaseStrategy):
|
||||
self.ws.fill_gap([code], force=True)
|
||||
except Exception:
|
||||
pass
|
||||
self._cb_prof_mark(_cb, "fill_gap")
|
||||
if reject == "탈락-전일시가없음" and len(candles_raw) < min_need:
|
||||
return None
|
||||
if reject == "탈락-봉부족":
|
||||
@@ -155,6 +162,7 @@ class MomentumStrategy(BaseStrategy):
|
||||
int(self.candle_tf or 1),
|
||||
self._engine_params,
|
||||
)
|
||||
self._cb_prof_mark(_cb, "mid_enroll")
|
||||
if _defer:
|
||||
self.logger.info("🔍 [%s] %s(%s)", _defer, name, code)
|
||||
return None
|
||||
@@ -182,6 +190,7 @@ class MomentumStrategy(BaseStrategy):
|
||||
) or curr_price
|
||||
except Exception:
|
||||
pass
|
||||
self._cb_prof_mark(_cb, "align")
|
||||
if curr_price <= 0 or curr_price < self.min_price:
|
||||
return None
|
||||
# entry_src: ws_ticks | ohlc_open — 수량/손절 계산가 출처 (시장가 체결가와 별개)
|
||||
@@ -195,6 +204,7 @@ class MomentumStrategy(BaseStrategy):
|
||||
qty, rej = self._resolve_buy_qty_live(
|
||||
curr_price, hard_cap=hard_cap,
|
||||
)
|
||||
self._cb_prof_mark(_cb, "qty")
|
||||
if rej:
|
||||
self.logger.info(
|
||||
"🔍 [탈락-%s] %s(%s) price=%.0f",
|
||||
@@ -225,6 +235,8 @@ class MomentumStrategy(BaseStrategy):
|
||||
except Exception as e:
|
||||
self.logger.info("🔍 [탈락-예외] %s %s: %s", name, code, e)
|
||||
return None
|
||||
finally:
|
||||
self._cb_prof_finish(_cb)
|
||||
|
||||
def _force_buy_test(self, code: str, name: str) -> Optional[Dict]:
|
||||
wsd = self.ws.get_price(code)
|
||||
|
||||
Reference in New Issue
Block a user