feat: redesign workspaces and stabilize screeners

This commit is contained in:
leefer
2026-07-26 13:31:45 +08:00
parent 149c468240
commit 6adeb54458
21 changed files with 18786 additions and 917 deletions
+41
View File
@@ -8,6 +8,7 @@ from pathlib import Path
from database import ReviewDatabase
from market_insights import MarketInsightsService
from screener import FACTOR_FIELDS, ScreenerEngine
from tushare_client import TushareError
class FakeMarketClient:
@@ -166,6 +167,46 @@ class MarketInsightsTests(unittest.TestCase):
self.assertEqual(hot["summary"]["dual_count"], 1)
self.assertEqual(hot["combined"][0]["name"], "平安银行")
def test_feature_pages_use_local_data_when_trade_context_is_offline(self):
class OfflineClient:
def resolve_trade_context(self, requested: str):
raise TushareError("offline")
def query(self, api_name, params=None, fields=""):
raise TushareError("offline")
self.database.save_snapshot(
"20260723", "test", {"meta": {"trade_date": "2026-07-23"}}
)
self.database.save_snapshot(
"20260724", "test", {"meta": {"trade_date": "2026-07-24"}}
)
self.database.upsert_stock_master([
{"ts_code": "000001.SZ", "name": "平安银行", "industry": "银行", "market": "主板", "list_date": "19910403"}
])
self.database.upsert_auction_factors([
{"ts_code": "000001.SZ", "trade_date": "20260724", "price": 10.5, "pre_close": 10, "amount": 5_000_000, "vol": 20_000, "turnover_rate": 0.12, "volume_ratio": 1.8}
])
self.database.save_data_snapshot(
"theme_library_v1", "20260724", "market",
{"meta": {"trade_date": "2026-07-24"}, "summary": {"theme_count": 1}, "items": [{"code": "885001.TI", "name": "人工智能", "member_count": 2}]},
)
self.database.save_data_snapshot(
"popularity_v1", "20260724", "market",
{"meta": {"trade_date": "2026-07-24"}, "summary": {"ths_count": 1, "dc_count": 0, "dual_count": 0}, "combined": [{"name": "平安银行"}], "ths": [], "dc": []},
)
service = MarketInsightsService(self.database, OfflineClient(), self.service._now_provider)
auction = service.auction_center("20260725")
self.assertEqual(auction["meta"]["trade_date"], "2026-07-24")
self.assertEqual(auction["summary"]["stock_count"], 1)
themes = service.theme_library("20260725")
self.assertTrue(themes["meta"]["cached"])
self.assertEqual(themes["items"][0]["name"], "人工智能")
popularity = service.popularity("20260725")
self.assertTrue(popularity["meta"]["cached"])
self.assertEqual(popularity["combined"][0]["name"], "平安银行")
class AuctionScreenerFactorTests(unittest.TestCase):
def test_auction_fields_are_available_to_formula_and_factor_rows(self):