9fd2a842af
Block new opens while flat legs wait; emergency close bypasses the check. Co-authored-by: Cursor <cursoragent@cursor.com>
76 lines
2.1 KiB
Python
76 lines
2.1 KiB
Python
from datetime import datetime
|
||
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.exits import check_exits
|
||
from app.strategy.signal import decide
|
||
|
||
_SH = ZoneInfo("Asia/Shanghai")
|
||
|
||
|
||
def test_signal_buy_call_short_perp() -> None:
|
||
s = decide(20.0, 15.0)
|
||
assert s is not None
|
||
assert s.option_side == "call"
|
||
assert s.perp_side == "short"
|
||
|
||
|
||
def test_signal_buy_put_long_perp() -> None:
|
||
s = decide(10.0, 16.0)
|
||
assert s is not None
|
||
assert s.option_side == "put"
|
||
assert s.perp_side == "long"
|
||
|
||
|
||
def test_signal_equal() -> None:
|
||
assert decide(10.0, 10.0) is None
|
||
|
||
|
||
def test_exit_premium_and_move_pct() -> None:
|
||
assert (
|
||
check_exits(
|
||
perp_upl=50, initial_premium=40, move_pct=0.1, exit_move_pct=2
|
||
).reason
|
||
== "premium_cover"
|
||
)
|
||
assert (
|
||
check_exits(
|
||
perp_upl=1, initial_premium=40, move_pct=2.0, exit_move_pct=2
|
||
).reason
|
||
== "move_pct"
|
||
)
|
||
|
||
|
||
def test_perp_pricing() -> None:
|
||
r = perp_fill(side="long", action="open", bid=100, ask=101, qty_eth=1, fee_rate=0.001)
|
||
assert abs(r.fill_px - 101 * 1.001) < 1e-9
|
||
|
||
|
||
def test_option_open_close_pricing() -> None:
|
||
o = option_fill(action="open", bid=10, ask=12, qty_eth=2, fee_rate=0.001)
|
||
assert o.fill_px > 12
|
||
c = option_fill(action="close", bid=10, ask=12, qty_eth=2, fee_rate=0.001)
|
||
assert c.fill_px < 10
|
||
|
||
|
||
def test_window_always_open() -> None:
|
||
n = datetime(2026, 7, 24, 17, 0, tzinfo=_SH)
|
||
assert can_open_new(n) is True
|
||
assert window_key(n) == "20260724"
|
||
n2 = datetime(2026, 7, 24, 10, 0, tzinfo=_SH)
|
||
assert can_open_new(n2) is True
|
||
assert window_key(n2) == "20260724"
|
||
|
||
|
||
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)
|
||
assert ok is True
|
||
ok2, _ = bid_mark_ok(bid=6.9, mark=10.0, max_dev_pct=30)
|
||
assert ok2 is False
|
||
ok3, why = bid_mark_ok(bid=None, mark=10.0, max_dev_pct=30)
|
||
assert ok3 is False
|
||
assert "买一" in why
|