fix(HEL-494): 日K默认45根并修复问天行业0/205覆盖

悬浮窗和详情页只画最近45个交易日,中枢仍保留250日历史。盘后缺sw_daily时保留成分日线内核,外显走免费申万;成分行情改为全市场快照+分页,不再截成前60只。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
总工
2026-09-08 17:00:01 +08:00
co-authored by Cursor multica-agent
parent 3e828b346c
commit b5d65ecb41
17 changed files with 343 additions and 127 deletions
+1 -1
View File
@@ -94,7 +94,7 @@ class GlobalSearchTests(unittest.TestCase):
self.assertIn('event.key.toLowerCase() !== "k"', script)
self.assertIn('openStock(item.id, { code: item.code', script)
self.assertNotIn('include_notes', script)
self.assertIn('const candles = (series || [])', script)
self.assertIn('const candles = visibleDailyPrices((series || [])', script)
self.assertIn('renderStockNotes(payload.notes || [])', script)
+85
View File
@@ -191,3 +191,88 @@ class EastmoneyHelperTests(unittest.TestCase):
self.assertAlmostEqual(quote["change"], 2.88)
params = get_json.call_args.args[1]
self.assertEqual(params["secids"], "90.801074")
class ChartWindowTests(unittest.TestCase):
def test_display_window_is_45_not_250(self) -> None:
from backend.features.market.charts import DAILY_CHART_LIMIT
self.assertEqual(DAILY_CHART_LIMIT, 45)
class MemberQuoteCoverageTests(unittest.TestCase):
def test_prefers_full_hub_market_over_truncated_named_quotes(self) -> None:
client = TushareClient(token="demo")
wanted = [f"{index:06d}.SZ" for index in range(205)]
market = [
{"ts_code": code, "close": 10.0, "pre_close": 9.0}
for code in wanted
]
client.try_market_quotes = MagicMock(return_value=market)
client.try_quotes = MagicMock(return_value=market[:60])
client.realtime_aggregator = MagicMock()
rows, source = client._load_member_realtime_quotes(wanted, "20260908")
self.assertEqual(len(rows), 205)
self.assertEqual(source, "datahub")
client.try_quotes.assert_not_called()
def test_ignores_non_member_quotes_from_market_snapshot(self) -> None:
client = TushareClient(token="demo")
client.try_market_quotes = MagicMock(
return_value=[
{"ts_code": "000737.SZ", "close": 12.3, "pre_close": 11.2},
{"ts_code": "600000.SH", "close": 10.0, "pre_close": 9.9},
]
)
client.try_quotes = MagicMock(return_value=[])
client._free_realtime_quotes = MagicMock(return_value=([], "empty"))
rows, _source = client._load_member_realtime_quotes(
["000737.SZ", "000630.SZ"], "20260908"
)
self.assertEqual([row["ts_code"] for row in rows], ["000737.SZ"])
def test_closed_keeps_daily_inner_when_sw_daily_missing(self) -> None:
client = TushareClient(token="demo")
client.resolve_trade_context = lambda _date: ("20260908", "20260907")
client.sw_stock_industry = MagicMock(
return_value={"l2_code": "801074.SI", "l2_name": "工业金属"}
)
client._sw_sector_members = MagicMock(
return_value=[
{"ts_code": "000737.SZ", "name": "北方铜业"},
{"ts_code": "000630.SZ", "name": "铜陵有色"},
]
)
client._stock_listing_reference = MagicMock(return_value={})
client._load_daily = MagicMock(
return_value=[
{"ts_code": "000737.SZ", "name": "北方铜业", "pct_chg": 2, "amount": 1e8},
{"ts_code": "000630.SZ", "name": "铜陵有色", "pct_chg": 1, "amount": 1e8},
]
)
client._confirmed_suspended_members = MagicMock(return_value=[])
client.query = MagicMock(return_value=[])
client._sw_realtime_sector_snapshot = MagicMock(
side_effect=AssertionError("daily inner should be kept")
)
client.realtime_aggregator = MagicMock()
client.realtime_aggregator.eastmoney_shenwan_quote.return_value = {
"code": "801074.SI",
"name": "工业金属",
"change": 1.5,
"pct_change": 1.5,
"quote_date": "20260908",
"quote_time": "2026-09-08T15:00:00+08:00",
"source": "eastmoney_sw",
}
snapshot = client.sw_sector_snapshot(
"000737.SZ", "20260908", allow_realtime_close=True
)
self.assertEqual(snapshot["quote_count"], 2)
self.assertEqual(snapshot["member_count"], 2)
self.assertTrue(snapshot["inner_precise"])
self.assertTrue(snapshot["outer_precise"])
self.assertEqual(snapshot["inner_source"], "tushare_member_daily")
self.assertEqual(snapshot["change"], 1.5)
self.assertNotIn("权限", snapshot.get("outer_error") or "")
self.assertNotIn("rt_sw_k", snapshot.get("outer_error") or "")