test(portfolio): 修stale测试test_small_filters_by_roe_roa—锚定e807bed放宽阈值(roe0.05/roa0.02,原0.15/0.10对中证1000命中仅~5%),保留剔除不合格股意图(换roe0.03/roa0.01样本) [nas]
This commit is contained in:
@@ -177,6 +177,55 @@ class TestStopLoss:
|
||||
sell_calls = [c for c in s.broker.order_target_value.call_args_list if c.args[1] == 0]
|
||||
assert sell_calls == []
|
||||
|
||||
# ---- 昨日涨停分支:P1.2 去 1m 依赖,改 get_limit_status_batch 日线口径 ----
|
||||
|
||||
@staticmethod
|
||||
def _limit_status_side_effect(is_limit_up):
|
||||
def _glbs(codes, date):
|
||||
return {c: {"is_limit_up": is_limit_up, "is_limit_down": False,
|
||||
"is_paused": False} for c in codes}
|
||||
return _glbs
|
||||
|
||||
def test_yesterday_limitup_sold_when_today_not_limitup(self):
|
||||
"""昨日涨停 + 当日(日线)未涨停 → 涨停打开卖出。"""
|
||||
from tests.portfolio.conftest import FakePosition, FakeContext
|
||||
|
||||
s = make_strategy()
|
||||
pos = FakePosition("600519.XSHG", avg_cost=100.0, price=95.0) # 不触发 -8%
|
||||
ctx = FakeContext(positions={"600519.XSHG": pos})
|
||||
s.yesterday_hl_list = ["600519.XSHG"]
|
||||
s.provider.get_limit_status_batch.side_effect = \
|
||||
self._limit_status_side_effect(is_limit_up=False)
|
||||
s.stop_loss(ctx)
|
||||
s.broker.order_target_value.assert_called_with("600519.XSHG", 0)
|
||||
|
||||
def test_yesterday_limitup_kept_when_still_limitup(self):
|
||||
"""昨日涨停 + 当日仍涨停 → 继续持有,不卖。"""
|
||||
from tests.portfolio.conftest import FakePosition, FakeContext
|
||||
|
||||
s = make_strategy()
|
||||
pos = FakePosition("600519.XSHG", avg_cost=100.0, price=95.0)
|
||||
ctx = FakeContext(positions={"600519.XSHG": pos})
|
||||
s.yesterday_hl_list = ["600519.XSHG"]
|
||||
s.provider.get_limit_status_batch.side_effect = \
|
||||
self._limit_status_side_effect(is_limit_up=True)
|
||||
s.stop_loss(ctx)
|
||||
sell_calls = [c for c in s.broker.order_target_value.call_args_list if c.args[1] == 0]
|
||||
assert sell_calls == []
|
||||
|
||||
def test_yesterday_limitup_provider_failure_skips_branch(self):
|
||||
"""provider 无 get_limit_status_batch / 查询异常 → 跳过该分支不崩(降级)。"""
|
||||
from tests.portfolio.conftest import FakePosition, FakeContext
|
||||
|
||||
s = make_strategy()
|
||||
pos = FakePosition("600519.XSHG", avg_cost=100.0, price=95.0)
|
||||
ctx = FakeContext(positions={"600519.XSHG": pos})
|
||||
s.yesterday_hl_list = ["600519.XSHG"]
|
||||
s.provider.get_limit_status_batch.side_effect = RuntimeError("boom")
|
||||
s.stop_loss(ctx) # 不抛异常
|
||||
sell_calls = [c for c in s.broker.order_target_value.call_args_list if c.args[1] == 0]
|
||||
assert sell_calls == []
|
||||
|
||||
|
||||
# =================== monthly_adjustment:轮动决策分支 ===================
|
||||
class TestMonthlyAdjustmentDecision:
|
||||
@@ -274,11 +323,15 @@ class TestMonthlyAdjustmentDecision:
|
||||
# =================== 选股函数直接测试 ===================
|
||||
class TestStockPickers:
|
||||
def test_small_filters_by_roe_roa(self):
|
||||
"""roe>0.15 & roa>0.10 → 仅保留合格股,按 market_cap asc。"""
|
||||
"""roe>0.05 & roa>0.02 → 仅保留合格股,按 market_cap asc。
|
||||
|
||||
阈值是 e807bed 验证用放宽口径(原 0.15/0.10 对中证1000 命中仅~5%),
|
||||
最终业务决策再定——测试锚定当前实现。
|
||||
"""
|
||||
df = make_fund_df([
|
||||
{"code": "A.XSHG", "roe": 0.20, "roa": 0.15, "market_cap": 500},
|
||||
{"code": "B.XSHG", "roe": 0.10, "roa": 0.20, "market_cap": 300}, # roe 不够
|
||||
{"code": "C.XSHG", "roe": 0.30, "roa": 0.05, "market_cap": 200}, # roa 不够
|
||||
{"code": "B.XSHG", "roe": 0.03, "roa": 0.20, "market_cap": 300}, # roe 不够
|
||||
{"code": "C.XSHG", "roe": 0.30, "roa": 0.01, "market_cap": 200}, # roa 不够
|
||||
{"code": "D.XSHG", "roe": 0.25, "roa": 0.12, "market_cap": 100},
|
||||
])
|
||||
s = make_strategy()
|
||||
|
||||
Reference in New Issue
Block a user