9427d9c429
Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.4 KiB
Python
87 lines
2.4 KiB
Python
"""日历日分组键;可选周末跳过开仓(上海时区)。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from datetime import datetime
|
||
from typing import Any
|
||
from zoneinfo import ZoneInfo
|
||
|
||
_SH = ZoneInfo("Asia/Shanghai")
|
||
|
||
|
||
def now_sh(now: datetime | None = None) -> datetime:
|
||
return (now or datetime.now(tz=_SH)).astimezone(_SH)
|
||
|
||
|
||
def window_key(now: datetime | None = None) -> str:
|
||
"""组号日期键:日历日 YYYYMMDD。"""
|
||
return now_sh(now).strftime("%Y%m%d")
|
||
|
||
|
||
def is_weekend(now: datetime | None = None) -> bool:
|
||
"""上海时区:周六=5、周日=6。"""
|
||
return now_sh(now).weekday() >= 5
|
||
|
||
|
||
def can_open_new(
|
||
now: datetime | None = None,
|
||
*,
|
||
skip_weekends: bool = True,
|
||
open_hhmm: str = "16:00",
|
||
stop_hhmm: str = "08:00",
|
||
) -> bool:
|
||
"""是否允许新开仓。开仓窗已取消;可选跳过周六日。持仓平仓不受此限制。"""
|
||
_ = open_hhmm, stop_hhmm
|
||
if skip_weekends and is_weekend(now):
|
||
return False
|
||
return True
|
||
|
||
|
||
def group_date_ymd(now: datetime | None = None) -> str:
|
||
return window_key(now)
|
||
|
||
|
||
def used_expiry_ymds_for_day(db: Any, now: datetime | None = None) -> set[str]:
|
||
"""
|
||
上海日历日已开过的期权到期日(groups.expiry_ymd,YYMMDD)。
|
||
按当日组号 G-{YYYYMMDD}-% 统计;含已平仓,用于「同到期一天只开一次」。
|
||
"""
|
||
wkey = window_key(now)
|
||
rows = db.fetchall(
|
||
"SELECT DISTINCT expiry_ymd FROM groups WHERE group_id LIKE ?",
|
||
(f"G-{wkey}-%",),
|
||
)
|
||
out: set[str] = set()
|
||
for r in rows or []:
|
||
y = str(r["expiry_ymd"] or "").strip()
|
||
if y:
|
||
out.add(y)
|
||
return out
|
||
|
||
|
||
def pending_residual_expiry_ymds(db: Any) -> set[str]:
|
||
"""待到期结算的残留期权到期日(YYMMDD);监控/下一组开仓应跳过这些档。"""
|
||
rows = db.fetchall(
|
||
"""SELECT DISTINCT expiry_ymd FROM residual_options
|
||
WHERE status='pending' AND expiry_ymd IS NOT NULL AND TRIM(expiry_ymd) != ''"""
|
||
)
|
||
out: set[str] = set()
|
||
for r in rows or []:
|
||
y = str(r["expiry_ymd"] or "").strip()
|
||
if y:
|
||
out.add(y)
|
||
return out
|
||
|
||
|
||
def expiry_blocked_by_one_per_day(
|
||
expiry_ymd: str | None,
|
||
used: set[str],
|
||
*,
|
||
enabled: bool = True,
|
||
) -> bool:
|
||
"""开启时:候选到期已在当日用过则拦截。"""
|
||
if not enabled:
|
||
return False
|
||
y = str(expiry_ymd or "").strip()
|
||
return bool(y and y in used)
|