mirror of
https://github.com/ZhuLinsen/daily_stock_analysis
synced 2026-09-20 10:53:33 +08:00
feat: 将参考 AlphaSift 的选股实现纳入主项目 (#2136)
* feat: integrate built-in stock screening engine * test: verify screening routes via public contract * refactor: make screening integration fully native * fix(review-feedback-2136): [Verification blocker] 当前 Head 的阻断型 CI 已最终失败:backend-gate。请在本地运行对应 * feat: persist screening runs and reuse DSA analysis * fix(review-feedback-2136): 对选股重排应用统一的模型参数兼容逻辑 * fix(review-feedback-2136): 将字段缺失计入数据源失败 * fix(review-feedback-2136): 评审结论 - 代码检查 :当前整个 PR 仍有 3 个未关闭的高置信度代码 blocker。最新复核摘要:当前整个 PR 仍有 3 * fix(review-feedback-2136): 延迟写入候选直到覆盖率通过校验 and 将 DSA 日线成功结果写入 last-good 缓存 * fix(review-feedback-2136): 将直连日线源纳入统一调用超时 and 将新增的选股缓存目录加入桌面更新备份 * fix(review-feedback-2136): 保留完整热点缓存而非请求切片 and 遵守 DSA 上下文声明的候选上限 * fix(review-feedback-2136): 补一条端到端回归:把真实 ScreenResult 经 ScreeningService.screen 落到 /history 和 * fix(review-feedback-2136): 补一个 refresh=true 且 live fetch 失败时返回 stale cache 的回归测试,避免当前只更新 stale
This commit is contained in:
@@ -44,8 +44,8 @@ log "Installing backend dependencies..."
|
||||
log "Checking python-multipart availability..."
|
||||
"${PYTHON_BIN}" -c "import multipart, multipart.multipart"
|
||||
|
||||
log "Checking AlphaSift adapter availability..."
|
||||
"${PYTHON_BIN}" -c "import alphasift.dsa_adapter"
|
||||
log "Checking built-in screening engine availability..."
|
||||
"${PYTHON_BIN}" -c "import src.services.screening.pipeline"
|
||||
|
||||
log "Checking Futu SDK availability..."
|
||||
"${PYTHON_BIN}" -c "import futu"
|
||||
@@ -83,7 +83,7 @@ hidden_imports=(
|
||||
"api.v1.endpoints.history"
|
||||
"api.v1.endpoints.stocks"
|
||||
"api.v1.endpoints.health"
|
||||
"api.v1.endpoints.alphasift"
|
||||
"api.v1.endpoints.screening"
|
||||
"api.v1.schemas"
|
||||
"api.v1.schemas.analysis"
|
||||
"api.v1.schemas.history"
|
||||
@@ -95,9 +95,9 @@ hidden_imports=(
|
||||
"src.services.task_queue"
|
||||
"src.services.analysis_service"
|
||||
"src.services.history_service"
|
||||
"src.services.alphasift_service"
|
||||
"alphasift"
|
||||
"alphasift.dsa_adapter"
|
||||
"src.services.screening_service"
|
||||
"src.services.screening"
|
||||
"src.services.screening.pipeline"
|
||||
"orjson"
|
||||
"uvicorn.logging"
|
||||
"uvicorn.loops"
|
||||
@@ -118,7 +118,7 @@ done
|
||||
|
||||
pushd "${ROOT_DIR}" >/dev/null
|
||||
cmd=("${PYTHON_BIN}" -m PyInstaller --name stock_analysis --onedir --noconfirm --noconsole --add-data "static:static" --add-data "strategies:strategies" --collect-data litellm --collect-data tiktoken --collect-data akshare)
|
||||
cmd+=("--collect-all" "alphasift")
|
||||
cmd+=("--collect-all" "src.services.screening")
|
||||
cmd+=("--collect-all" "futu")
|
||||
cmd+=("${hidden_import_args[@]}" "main.py")
|
||||
|
||||
@@ -147,7 +147,7 @@ if ! "${packaged_entry}" --help >/tmp/dsa-packaged-help.log 2>&1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for module in alphasift.dsa_adapter futu orjson; do
|
||||
for module in src.services.screening.pipeline futu orjson; do
|
||||
if DSA_PACKAGED_IMPORT_PROBE="${module}" "${packaged_entry}" >/tmp/dsa-packaged-import.log 2>&1; then
|
||||
cat /tmp/dsa-packaged-import.log
|
||||
else
|
||||
@@ -194,4 +194,20 @@ if [[ "${packaged_strategy_count}" != "${source_strategy_count}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Verifying packaged screening strategies..."
|
||||
source_screening_strategy_count="$(find "${ROOT_DIR}/src/services/screening/strategies" -maxdepth 1 -type f -name '*.yaml' | wc -l | tr -d '[:space:]')"
|
||||
packaged_screening_strategies="${ROOT_DIR}/dist/backend/stock_analysis/_internal/src/services/screening/strategies"
|
||||
if [[ ! -d "${packaged_screening_strategies}" ]]; then
|
||||
packaged_screening_strategies="${ROOT_DIR}/dist/backend/stock_analysis/src/services/screening/strategies"
|
||||
fi
|
||||
if [[ ! -d "${packaged_screening_strategies}" ]]; then
|
||||
echo "ERROR: packaged screening strategies directory not found under dist/backend/stock_analysis."
|
||||
exit 1
|
||||
fi
|
||||
packaged_screening_strategy_count="$(find "${packaged_screening_strategies}" -maxdepth 1 -type f -name '*.yaml' | wc -l | tr -d '[:space:]')"
|
||||
if [[ "${packaged_screening_strategy_count}" != "${source_screening_strategy_count}" ]]; then
|
||||
echo "ERROR: packaged screening strategies count mismatch: expected ${source_screening_strategy_count}, got ${packaged_screening_strategy_count}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Backend build completed."
|
||||
|
||||
@@ -51,9 +51,9 @@ if (-not (Test-PythonCode -Python $pythonBin -Code "import multipart, multipart.
|
||||
throw 'python-multipart is not importable in the selected Python environment.'
|
||||
}
|
||||
|
||||
Write-Host 'Checking AlphaSift adapter availability...'
|
||||
if (-not (Test-PythonCode -Python $pythonBin -Code "import alphasift.dsa_adapter")) {
|
||||
throw 'alphasift.dsa_adapter is not importable after installing requirements.'
|
||||
Write-Host 'Checking built-in screening engine availability...'
|
||||
if (-not (Test-PythonCode -Python $pythonBin -Code "import src.services.screening.pipeline")) {
|
||||
throw 'src.services.screening.pipeline is not importable.'
|
||||
}
|
||||
|
||||
Write-Host 'Checking Futu SDK availability...'
|
||||
@@ -97,9 +97,9 @@ $hiddenImports = @(
|
||||
'api.v1.endpoints.history',
|
||||
'api.v1.endpoints.stocks',
|
||||
'api.v1.endpoints.health',
|
||||
'api.v1.endpoints.alphasift',
|
||||
'alphasift',
|
||||
'alphasift.dsa_adapter',
|
||||
'api.v1.endpoints.screening',
|
||||
'src.services.screening',
|
||||
'src.services.screening.pipeline',
|
||||
'api.v1.schemas',
|
||||
'api.v1.schemas.analysis',
|
||||
'api.v1.schemas.history',
|
||||
@@ -111,7 +111,7 @@ $hiddenImports = @(
|
||||
'src.services.task_queue',
|
||||
'src.services.analysis_service',
|
||||
'src.services.history_service',
|
||||
'src.services.alphasift_service',
|
||||
'src.services.screening_service',
|
||||
'uvicorn.logging',
|
||||
'uvicorn.loops',
|
||||
'uvicorn.loops.auto',
|
||||
@@ -136,7 +136,7 @@ $pyInstallerArgs = @(
|
||||
'--collect-data', 'litellm',
|
||||
'--collect-data', 'tiktoken',
|
||||
'--collect-data', 'akshare',
|
||||
'--collect-all', 'alphasift',
|
||||
'--collect-all', 'src.services.screening',
|
||||
'--collect-all', 'futu'
|
||||
)
|
||||
$pyInstallerArgs += $hiddenImportArgs
|
||||
@@ -161,7 +161,7 @@ if (-not (Test-Path $packagedEntry)) {
|
||||
}
|
||||
$previousProbe = $env:DSA_PACKAGED_IMPORT_PROBE
|
||||
try {
|
||||
foreach ($module in @('alphasift.dsa_adapter', 'futu', 'orjson')) {
|
||||
foreach ($module in @('src.services.screening.pipeline', 'futu', 'orjson')) {
|
||||
$env:DSA_PACKAGED_IMPORT_PROBE = $module
|
||||
$probeProcess = Start-Process -FilePath $packagedEntry -Wait -PassThru
|
||||
if ($probeProcess.ExitCode -ne 0) {
|
||||
@@ -213,4 +213,19 @@ if ($packagedStrategyCount -ne $sourceStrategyCount) {
|
||||
throw "Packaged strategies count mismatch: expected $sourceStrategyCount, got $packagedStrategyCount."
|
||||
}
|
||||
|
||||
Write-Host 'Verifying packaged screening strategies...'
|
||||
$sourceScreeningStrategies = Join-Path 'src\services\screening' 'strategies'
|
||||
$sourceScreeningStrategyCount = @(Get-ChildItem -Path $sourceScreeningStrategies -Filter '*.yaml' -File).Count
|
||||
$packagedScreeningStrategies = Join-Path 'dist\backend\stock_analysis' '_internal\src\services\screening\strategies'
|
||||
if (-not (Test-Path $packagedScreeningStrategies)) {
|
||||
$packagedScreeningStrategies = Join-Path 'dist\backend\stock_analysis' 'src\services\screening\strategies'
|
||||
}
|
||||
if (-not (Test-Path $packagedScreeningStrategies)) {
|
||||
throw 'Packaged screening strategies directory not found under dist\backend\stock_analysis.'
|
||||
}
|
||||
$packagedScreeningStrategyCount = @(Get-ChildItem -Path $packagedScreeningStrategies -Filter '*.yaml' -File).Count
|
||||
if ($packagedScreeningStrategyCount -ne $sourceScreeningStrategyCount) {
|
||||
throw "Packaged screening strategies count mismatch: expected $sourceScreeningStrategyCount, got $packagedScreeningStrategyCount."
|
||||
}
|
||||
|
||||
Write-Host 'Backend build completed.'
|
||||
|
||||
Reference in New Issue
Block a user