Keep OO amplitude refreshed while holding a position.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -332,6 +332,8 @@ class StrategySession:
|
||||
|
||||
def align_to_held_position(self) -> OptionPair | None:
|
||||
"""有活跃仓时:监控对锁定为持仓合约的到期/行权价。"""
|
||||
if _hedge_mode() == "option_option":
|
||||
self.refresh_oo_amplitude()
|
||||
call_id, put_id = _held_option_legs()
|
||||
held = call_id or _held_option_inst_id()
|
||||
if not held:
|
||||
@@ -441,11 +443,37 @@ class StrategySession:
|
||||
)
|
||||
return self._apply_pair(pair, mark=float(mark), idx=idx)
|
||||
|
||||
def refresh_oo_amplitude(self) -> dict[str, Any] | None:
|
||||
"""刷新振幅高低(有仓/无仓都要,否则持仓后 UI 指数/振幅会空)。"""
|
||||
if _hedge_mode() != "option_option":
|
||||
return None
|
||||
try:
|
||||
from ..exchange.candles import fetch_amplitude_hl_for_runtime
|
||||
|
||||
amp_pct, amp_hours, _, _ = _oo_settings()
|
||||
amp = fetch_amplitude_hl_for_runtime(amp_hours)
|
||||
if amp is None:
|
||||
return self._oo_amp
|
||||
self._oo_amp = {
|
||||
"high": float(amp.high),
|
||||
"low": float(amp.low),
|
||||
"mid": float(amp.mid),
|
||||
"range_pct": float(amp.range_pct),
|
||||
"hours": float(amp_hours),
|
||||
"max_pct": float(amp_pct),
|
||||
"ok": float(amp.range_pct) <= float(amp_pct) + 1e-12,
|
||||
}
|
||||
return self._oo_amp
|
||||
except Exception:
|
||||
logger.exception("refresh_oo_amplitude failed")
|
||||
return self._oo_amp
|
||||
|
||||
def align_oo_instruments(self) -> OptionPair | None:
|
||||
"""期期监控:按振幅高低点选虚值 Call/Put(展示用;振幅超限仍对齐候选)。"""
|
||||
from ..exchange.candles import fetch_amplitude_hl_for_runtime
|
||||
from .oo_selection import select_oo_pair
|
||||
|
||||
# 有仓也刷新振幅(钉仓不再走选约,否则 _oo_amp 一直空)
|
||||
self.refresh_oo_amplitude()
|
||||
if _has_open_position():
|
||||
return self.align_to_held_position()
|
||||
s = self.settings
|
||||
@@ -455,26 +483,17 @@ class StrategySession:
|
||||
if mark is None or mark <= 0:
|
||||
raise RuntimeError("无法获取标的标记/指数价格,无法选期期虚值")
|
||||
underlying = float(mark)
|
||||
amp = fetch_amplitude_hl_for_runtime(amp_hours)
|
||||
if amp is None:
|
||||
self._oo_amp = None
|
||||
if self._oo_amp is None:
|
||||
raise RuntimeError("无法获取振幅 K 线高低点")
|
||||
self._oo_amp = {
|
||||
"high": float(amp.high),
|
||||
"low": float(amp.low),
|
||||
"mid": float(amp.mid),
|
||||
"range_pct": float(amp.range_pct),
|
||||
"hours": float(amp_hours),
|
||||
"max_pct": float(amp_pct),
|
||||
"ok": float(amp.range_pct) <= float(amp_pct) + 1e-12,
|
||||
}
|
||||
amp_high = float(self._oo_amp["high"])
|
||||
amp_low = float(self._oo_amp["low"])
|
||||
contracts = self.ex.list_option_contracts(s.option_inst_family)
|
||||
skip = _skip_expiry_ymds_for_next()
|
||||
picked = select_oo_pair(
|
||||
contracts,
|
||||
spot=underlying,
|
||||
high=float(amp.high),
|
||||
low=float(amp.low),
|
||||
high=amp_high,
|
||||
low=amp_low,
|
||||
min_hours=float(min_hours),
|
||||
skip_expiry_ymds=skip,
|
||||
)
|
||||
@@ -518,6 +537,16 @@ class StrategySession:
|
||||
if amp is None:
|
||||
logger.info("oo: amplitude candles unavailable")
|
||||
return None
|
||||
# 无论是否超限都写入,供「指数/振幅」面板展示
|
||||
self._oo_amp = {
|
||||
"high": float(amp.high),
|
||||
"low": float(amp.low),
|
||||
"mid": float(amp.mid),
|
||||
"range_pct": float(amp.range_pct),
|
||||
"hours": float(amp_hours),
|
||||
"max_pct": float(amp_pct),
|
||||
"ok": float(amp.range_pct) <= float(amp_pct) + 1e-12,
|
||||
}
|
||||
if float(amp.range_pct) > float(amp_pct) + 1e-12:
|
||||
logger.info(
|
||||
"oo: amplitude %.3f%% > max %.3f%% (H=%.2f L=%.2f)",
|
||||
@@ -862,7 +891,9 @@ class StrategySession:
|
||||
|
||||
async def ensure_atm_async(self, *, force: bool = False) -> OptionPair | None:
|
||||
if _has_open_position():
|
||||
# 持仓期间:钉住持仓行权价(禁止漂到新 ATM/虚值)
|
||||
# 持仓期间:钉住持仓行权价(禁止漂到新 ATM/虚值);期期仍刷新振幅供 UI
|
||||
if _hedge_mode() == "option_option":
|
||||
await asyncio.to_thread(self.refresh_oo_amplitude)
|
||||
call_id, put_id = _held_option_legs()
|
||||
held = call_id or _held_option_inst_id()
|
||||
if held and (
|
||||
|
||||
Reference in New Issue
Block a user