feat(selection): show gold brick chart below volume in stock detail panel

Add an optional brick_chart series to the selection chart API, computed
from the shared gold-brick formula when strategy=gold_brick, and render
a fourth grid with red/green brick bars between the volume and J grids.
This commit is contained in:
yuxuanhui
2026-09-05 13:41:25 +08:00
parent 79476252b1
commit 3b50e75ef8
13 changed files with 249 additions and 36 deletions
+24 -4
View File
@@ -109,10 +109,15 @@ class FakeChartService:
def __init__(self) -> None:
self.mode = "ok"
self.request: tuple[str, date] | None = None
self.request: tuple[str, date, bool] | None = None
def execute(self, ts_code: str, target_trade_date: date) -> SelectionChart:
self.request = (ts_code, target_trade_date)
def execute(
self,
ts_code: str,
target_trade_date: date,
include_brick_chart: bool = False,
) -> SelectionChart:
self.request = (ts_code, target_trade_date, include_brick_chart)
if self.mode == "missing":
raise SelectionChartNotFound("chart unavailable")
if self.mode == "storage_error":
@@ -135,6 +140,7 @@ class FakeChartService:
j=60.0,
trend_white=10.2,
trend_yellow=10.4,
brick_chart=5.0 if include_brick_chart else None,
),
),
)
@@ -436,7 +442,7 @@ def test_chart_returns_bounded_qfq_contract() -> None:
)
assert response.status_code == 200
assert chart_service.request == ("000001.SZ", TARGET)
assert chart_service.request == ("000001.SZ", TARGET, False)
assert response.json() == {
"ts_code": "000001.SZ",
"name": "平安银行",
@@ -455,11 +461,25 @@ def test_chart_returns_bounded_qfq_contract() -> None:
"j": 60.0,
"trend_white": 10.2,
"trend_yellow": 10.4,
"brick_chart": None,
}
],
}
def test_chart_requests_brick_series_for_gold_brick_strategy() -> None:
chart_service = FakeChartService()
response = _client(FakeSelectionService(), chart_service).get(
"/api/v1/selection/stocks/000001.SZ/chart",
params={"target_trade_date": "2026-08-08", "strategy": "gold_brick"},
)
assert response.status_code == 200
assert chart_service.request == ("000001.SZ", TARGET, True)
assert response.json()["points"][0]["brick_chart"] == 5.0
@pytest.mark.parametrize(
("mode", "status_code", "error_code"),
[