refactor(selection): 统一信号与股票处理逻辑,重构相关数据结构与接口,更新前端展示以支持股票信息
This commit is contained in:
@@ -283,8 +283,10 @@ class LoadConnection:
|
||||
)
|
||||
if "FROM selection_run_item" in query:
|
||||
return LoadResult(rows=[("000001.SZ", "平安银行", "selected", 2, None)])
|
||||
if "COUNT(*) FROM selection_signal" in query:
|
||||
if "COUNT(DISTINCT ts_code) FROM selection_signal" in query:
|
||||
return LoadResult(row=(2,))
|
||||
if "SELECT DISTINCT ts_code" in query:
|
||||
return LoadResult(rows=[("000001.SZ",)])
|
||||
return LoadResult(
|
||||
rows=[
|
||||
(
|
||||
@@ -301,7 +303,7 @@ class LoadConnection:
|
||||
"平安银行",
|
||||
TARGET,
|
||||
"zhixing_b1",
|
||||
ZHIXING_B1_SIGNAL_ORDER[0].value,
|
||||
ZhixingB1Category.ORIGINAL_B1.value,
|
||||
Decimal("10.5"),
|
||||
{},
|
||||
),
|
||||
@@ -309,6 +311,16 @@ class LoadConnection:
|
||||
)
|
||||
|
||||
|
||||
class EmptyStockPageConnection(LoadConnection):
|
||||
"""Return a non-zero filtered total with no stocks on the requested page."""
|
||||
|
||||
def execute(self, query: str, parameters: tuple[object, ...]) -> "LoadResult":
|
||||
if "SELECT DISTINCT ts_code" in query:
|
||||
self.statements.append((query, parameters))
|
||||
return LoadResult(rows=[])
|
||||
return super().execute(query, parameters)
|
||||
|
||||
|
||||
class LoadResult:
|
||||
def __init__(
|
||||
self,
|
||||
@@ -326,7 +338,9 @@ class LoadResult:
|
||||
return self.rows
|
||||
|
||||
|
||||
def test_get_run_orders_signals_by_formula_priority(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
def test_get_run_pages_stocks_and_loads_all_signals_for_category_matches(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
connection = LoadConnection()
|
||||
|
||||
def connect(database_url: str) -> LoadConnection:
|
||||
@@ -337,7 +351,7 @@ def test_get_run_orders_signals_by_formula_priority(monkeypatch: pytest.MonkeyPa
|
||||
run = PostgresSelectionRunRepository("postgresql://test").get_run(
|
||||
"run-1",
|
||||
query=SelectionResultQuery(
|
||||
page=2,
|
||||
page=1,
|
||||
page_size=1,
|
||||
search="100%",
|
||||
category="pullback",
|
||||
@@ -346,20 +360,57 @@ def test_get_run_orders_signals_by_formula_priority(monkeypatch: pytest.MonkeyPa
|
||||
|
||||
assert run is not None
|
||||
assert [signal.category for signal in run.signals] == [
|
||||
ZHIXING_B1_SIGNAL_ORDER[0],
|
||||
ZhixingB1Category.ORIGINAL_B1,
|
||||
ZHIXING_B1_SIGNAL_ORDER[-1],
|
||||
]
|
||||
assert run.stocks_total == 2
|
||||
count_query, count_parameters = next(
|
||||
(query, parameters)
|
||||
for query, parameters in connection.statements
|
||||
if "COUNT(*) FROM selection_signal" in query
|
||||
if "COUNT(DISTINCT ts_code) FROM selection_signal" in query
|
||||
)
|
||||
assert "name ILIKE %s ESCAPE" in count_query
|
||||
assert count_parameters == ("run-1", "%100\\%%", "%100\\%%", "zhixing_b1_pullback_%")
|
||||
page_query, page_parameters = next(
|
||||
stock_page_query, page_parameters = next(
|
||||
(query, parameters)
|
||||
for query, parameters in connection.statements
|
||||
if "LIMIT %s OFFSET %s" in query
|
||||
if "SELECT DISTINCT ts_code" in query
|
||||
)
|
||||
assert "ORDER BY ts_code, CASE category" in page_query
|
||||
assert page_parameters[-2:] == (1, 1)
|
||||
assert "ORDER BY ts_code" in stock_page_query
|
||||
assert page_parameters[-2:] == (1, 0)
|
||||
signal_query, signal_parameters = next(
|
||||
(query, parameters)
|
||||
for query, parameters in connection.statements
|
||||
if "ts_code = ANY(%s)" in query and "SELECT\n" in query
|
||||
)
|
||||
assert "ORDER BY ts_code, CASE category" in signal_query
|
||||
assert "category LIKE" not in signal_query
|
||||
assert signal_parameters == ("run-1", ["000001.SZ"])
|
||||
|
||||
|
||||
def test_get_run_does_not_load_signals_for_an_empty_stock_page(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
connection = EmptyStockPageConnection()
|
||||
|
||||
def connect(database_url: str) -> EmptyStockPageConnection:
|
||||
assert database_url == "postgresql://test"
|
||||
return connection
|
||||
|
||||
monkeypatch.setattr(psycopg, "connect", connect)
|
||||
run = PostgresSelectionRunRepository("postgresql://test").get_run(
|
||||
"run-1",
|
||||
query=SelectionResultQuery(page=3, page_size=1),
|
||||
)
|
||||
|
||||
assert run is not None
|
||||
assert run.stocks_total == 2
|
||||
assert run.signals == ()
|
||||
stock_page_query, stock_page_parameters = next(
|
||||
(query, parameters)
|
||||
for query, parameters in connection.statements
|
||||
if "SELECT DISTINCT ts_code" in query
|
||||
)
|
||||
assert "ORDER BY ts_code" in stock_page_query
|
||||
assert stock_page_parameters[-2:] == (1, 2)
|
||||
assert not any("ts_code = ANY(%s)" in query for query, _ in connection.statements)
|
||||
|
||||
Reference in New Issue
Block a user