"""A 股涨跌停纯函数测试(板块表 + 封板判断)。全用 raw 价格。""" import pandas as pd from sanguo_trader.limit import ( get_board, limit_ratio, limit_up_price, limit_down_price, is_one_word_lock, is_t_lock, is_locked_for_buy_symbol, is_locked_for_sell_symbol, ) from sanguo_trader.models import AccountConfig CFG = AccountConfig(initial_capital=1_000_000) def bar(open, high, low, close): return pd.Series({"open": open, "high": high, "low": low, "close": close}) # ---- 板块分类 ---- def test_board_classification(): assert get_board("600000") == "main" # 沪市主板 assert get_board("000001") == "main" # 深市主板 assert get_board("300750") == "gem" # 创业板 assert get_board("301128") == "gem" # 创业板(301) assert get_board("688981") == "star" # 科创板 assert get_board("689009") == "star" # 科创板(689) assert get_board("830799") == "bse" # 北交所 assert get_board("920002") == "bse" # 北交所(920) # ---- 幅度查表 ---- def test_limit_ratio(): assert limit_ratio("main", is_st=False) == 0.10 assert limit_ratio("gem", is_st=False) == 0.20 assert limit_ratio("star", is_st=False) == 0.20 assert limit_ratio("bse", is_st=False) == 0.30 # ST 统一 5% assert limit_ratio("main", is_st=True) == 0.05 assert limit_ratio("gem", is_st=True) == 0.05 assert limit_ratio("star", is_st=True) == 0.05 assert limit_ratio("bse", is_st=True) == 0.30 # 北交所 ST 同 30% # ---- 涨跌停价(按 pricetick 取整)---- def test_limit_up_price_rounds_to_pricetick(): # 10.00 * 1.10 = 11.00 assert limit_up_price(10.0, 0.10, 0.01) == 11.0 # 9.99 * 1.20 = 11.988 → 11.99 assert limit_up_price(9.99, 0.20, 0.01) == 11.99 # 5.00 * 1.30 = 6.5 assert limit_up_price(5.0, 0.30, 0.01) == 6.5 def test_limit_down_price_rounds_to_pricetick(): # 10.00 * 0.90 = 9.00 assert limit_down_price(10.0, 0.10, 0.01) == 9.0 # 10.00 * 0.80 = 8.00 assert limit_down_price(10.0, 0.20, 0.01) == 8.0 # ---- 一字板 / T 字板 ---- def test_one_word_lock_detected(): up = limit_up_price(10.0, 0.10, 0.01) assert is_one_word_lock(bar(11.0, 11.0, 11.0, 11.0), up) is True # 非一字 assert is_one_word_lock(bar(11.0, 11.5, 10.8, 11.0), up) is False assert is_one_word_lock(bar(11.0, 11.0, 10.5, 11.0), up) is False # T 字板非一字 def test_t_lock_detected(): up = limit_up_price(10.0, 0.10, 0.01) # T 字板:开=涨停 收=涨停 lowopen(盘中反弹过) assert is_locked_for_sell_symbol( bar(9.0, 9.5, 9.0, 9.0), "600000", 10.0, CFG, is_st=False ) is True def test_sell_not_locked_when_opened(): # 非跌停形态 → 可卖 assert is_locked_for_sell_symbol( bar(9.5, 9.8, 9.2, 9.6), "600000", 10.0, CFG, is_st=False ) is False