feat(selection): implement gold brick resonance strategy with evaluation and logging enhancements
This commit is contained in:
+33
-9
@@ -14,7 +14,14 @@ from uuid import uuid4
|
||||
import psycopg
|
||||
from psycopg.types.json import Jsonb
|
||||
|
||||
from ..domain.models import SelectionSignal, ZhixingB1Category
|
||||
from ..domain.gold_brick import GOLD_BRICK_SIGNAL_ORDER
|
||||
from ..domain.models import (
|
||||
GoldBrickCategory,
|
||||
SelectionSignal,
|
||||
SelectionSignalCategory,
|
||||
SelectionStrategyName,
|
||||
ZhixingB1Category,
|
||||
)
|
||||
from ..domain.pattern_scoring import (
|
||||
ZHIXING_B1_PATTERN_CASES,
|
||||
PatternScore,
|
||||
@@ -35,19 +42,26 @@ from ..domain.runs import (
|
||||
from ..domain.zhixing_b1 import ZHIXING_B1_SIGNAL_ORDER
|
||||
from .postgres_pool import SelectionConnectionPool, SelectionPostgresPool
|
||||
|
||||
_SIGNAL_PRIORITY = {category: index for index, category in enumerate(ZHIXING_B1_SIGNAL_ORDER)}
|
||||
_SELECTION_SIGNAL_ORDER: tuple[SelectionSignalCategory, ...] = (
|
||||
*ZHIXING_B1_SIGNAL_ORDER,
|
||||
*GOLD_BRICK_SIGNAL_ORDER,
|
||||
)
|
||||
_SIGNAL_PRIORITY = {
|
||||
category: index for index, category in enumerate(_SELECTION_SIGNAL_ORDER)
|
||||
}
|
||||
_CATEGORY_PREFIXES = {
|
||||
"pullback": "zhixing_b1_pullback_",
|
||||
"oversold": "zhixing_b1_oversold_",
|
||||
"original": "zhixing_b1_original_b1",
|
||||
"resonance": "gold_brick_resonance",
|
||||
}
|
||||
_SIGNAL_ORDER_SQL = (
|
||||
"CASE category "
|
||||
+ " ".join(
|
||||
f"WHEN '{category.value}' THEN {index}"
|
||||
for index, category in enumerate(ZHIXING_B1_SIGNAL_ORDER)
|
||||
for index, category in enumerate(_SELECTION_SIGNAL_ORDER)
|
||||
)
|
||||
+ f" ELSE {len(ZHIXING_B1_SIGNAL_ORDER)} END"
|
||||
+ f" ELSE {len(_SELECTION_SIGNAL_ORDER)} END"
|
||||
)
|
||||
_PATTERN_CASES_BY_ID = {definition.id: definition for definition in ZHIXING_B1_PATTERN_CASES}
|
||||
_STOCK_ORDER_SQL = {
|
||||
@@ -120,7 +134,7 @@ class PostgresSelectionRunRepository(SelectionRunStore):
|
||||
|
||||
def prepare_run(
|
||||
self,
|
||||
strategy: Literal["zhixing_b1"],
|
||||
strategy: SelectionStrategyName,
|
||||
target_trade_date: date,
|
||||
source: SelectionExecutionSource,
|
||||
*,
|
||||
@@ -332,7 +346,7 @@ class PostgresSelectionRunRepository(SelectionRunStore):
|
||||
|
||||
def get_latest_run(
|
||||
self,
|
||||
strategy: Literal["zhixing_b1"],
|
||||
strategy: SelectionStrategyName,
|
||||
target_trade_date: date | None = None,
|
||||
*,
|
||||
query: SelectionResultQuery | None = None,
|
||||
@@ -463,6 +477,7 @@ class PostgresSelectionRunRepository(SelectionRunStore):
|
||||
"no_signal",
|
||||
"insufficient_history",
|
||||
"missing_target_bar",
|
||||
"missing_turnover_rate",
|
||||
"data_error",
|
||||
],
|
||||
str(value[2]),
|
||||
@@ -476,7 +491,7 @@ class PostgresSelectionRunRepository(SelectionRunStore):
|
||||
)
|
||||
return SelectionRun(
|
||||
id=str(row[0]),
|
||||
strategy=cast(Literal["zhixing_b1"], str(row[1])),
|
||||
strategy=cast(SelectionStrategyName, str(row[1])),
|
||||
target_trade_date=_as_date(row[2]),
|
||||
market_sync_batch_id=str(row[3]) if row[3] is not None else None,
|
||||
status=cast(SelectionRunStatus, str(row[4])),
|
||||
@@ -537,13 +552,22 @@ def _signal_from_row(row: tuple[object, ...]) -> SelectionSignal:
|
||||
ts_code=str(row[0]),
|
||||
name=str(row[1] or ""),
|
||||
target_trade_date=_as_date(row[2]),
|
||||
strategy=cast(Literal["zhixing_b1"], str(row[3])),
|
||||
category=ZhixingB1Category(str(row[4])),
|
||||
strategy=cast(SelectionStrategyName, str(row[3])),
|
||||
category=_signal_category(str(row[4])),
|
||||
close=float(str(row[5])),
|
||||
details=_details(row[6]),
|
||||
)
|
||||
|
||||
|
||||
def _signal_category(value: str) -> SelectionSignalCategory:
|
||||
"""Map a persisted category for either supported selection strategy."""
|
||||
|
||||
try:
|
||||
return ZhixingB1Category(value)
|
||||
except ValueError:
|
||||
return GoldBrickCategory(value)
|
||||
|
||||
|
||||
def _stock_filter(query: SelectionResultQuery, run_id: str) -> tuple[str, list[object]]:
|
||||
"""Build the signal predicate used to select distinct matching stocks.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user