Add one-expiry-per-day open rhythm gate (default on).
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,7 +3,12 @@ from zoneinfo import ZoneInfo
|
||||
|
||||
from app.sim.liquidity import bid_mark_ok
|
||||
from app.sim.pricing import option_fill, perp_fill
|
||||
from app.strategy.clock import can_open_new, window_key
|
||||
from app.strategy.clock import (
|
||||
can_open_new,
|
||||
expiry_blocked_by_one_per_day,
|
||||
used_expiry_ymds_for_day,
|
||||
window_key,
|
||||
)
|
||||
from app.strategy.exits import check_expiry_close, check_exits
|
||||
from app.strategy.signal import decide
|
||||
|
||||
@@ -142,6 +147,30 @@ def test_window_weekend_skip() -> None:
|
||||
assert window_key(fri) == "20260724"
|
||||
|
||||
|
||||
def test_one_expiry_per_day(tmp_path, monkeypatch) -> None:
|
||||
monkeypatch.setenv("MODE", "SIM")
|
||||
from app.models.db import Database
|
||||
|
||||
db = Database(tmp_path / "one_exp.db")
|
||||
day = datetime(2026, 8, 1, 12, 0, tzinfo=_SH)
|
||||
with db._lock:
|
||||
db._conn.execute(
|
||||
"""INSERT INTO groups(group_id, status, expiry_ymd, open_at_ms)
|
||||
VALUES ('G-20260801-01','closed','260802',1)"""
|
||||
)
|
||||
db._conn.execute(
|
||||
"""INSERT INTO groups(group_id, status, expiry_ymd, open_at_ms)
|
||||
VALUES ('G-20260731-01','closed','260801',1)"""
|
||||
)
|
||||
db._conn.commit()
|
||||
used = used_expiry_ymds_for_day(db, day)
|
||||
assert used == {"260802"}
|
||||
assert expiry_blocked_by_one_per_day("260802", used, enabled=True) is True
|
||||
assert expiry_blocked_by_one_per_day("260803", used, enabled=True) is False
|
||||
assert expiry_blocked_by_one_per_day("260802", used, enabled=False) is False
|
||||
db.close()
|
||||
|
||||
|
||||
def test_bid_mark_deviation_30pct() -> None:
|
||||
# |7-10|/10 = 30% → 允许(≤30%)
|
||||
ok, _ = bid_mark_ok(bid=7.0, mark=10.0, max_dev_pct=30)
|
||||
|
||||
Reference in New Issue
Block a user