TSP自托管、零运维的 A 股「自建策略 + 监控 + 回测」量化工作台 | LLM能力驱使策略定制+个股分析+复盘 | 自由接入第三方数据源与个性化扩展数据 | 个人开源
This report summarizes scanner evidence for shy3130/tick-stock-panel, a Python project with 5,778 GitHub stars. SynthScan examined 239,182 lines of code across 831 source files, recording 4729 pattern matches distributed across 15 syntactic categories. The legacy adjusted pattern signal is 27.9 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 2785 finding(s).
Are imports declared and package/API names verified? 586 finding(s).
Are wrappers, guards, and repeated structures necessary? 3921 finding(s).
Which changes need focused human review? 4729 finding(s).
Run additional scans to build a history of the legacy pattern signal. Score changes are not a measure of AI adoption or code quality.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 4729 distinct pattern matches across 15 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | frontend/src/extensions/registry.ts | 110 | export function finalizeFrontendExtensions(reservedPaths: ReadonlySet<string>) { | CODE |
| LOW | frontend/src/extensions/registry.ts | 163 | export function getFrontendExtensionRoutes() { | CODE |
| LOW | frontend/src/extensions/registry.ts | 168 | export function getFrontendExtensionNavigation() { | CODE |
| LOW | frontend/src/extensions/registry.ts | 181 | export function getFrontendExtensionLoadErrors() { | CODE |
| LOW | frontend/src/extensions/bootstrap.ts | 8 | export async function initializeFrontendExtensions() { | CODE |
| LOW | frontend/src/components/DimensionMembersDialog.tsx | 22 | export function dimensionKindForSourceField(sourceField: string): DimensionKind | null { | CODE |
| LOW | frontend/src/components/ListColumnCustomizerInner.tsx | 150 | export function ListColumnCustomizerInner({ | CODE |
| LOW | frontend/src/components/StockPreviewDialogContent.tsx | 92 | export function StockPreviewDialogContent({ symbol, name, onClose, triggerInfo, navList: navListSource, onNavigate }: Pr | CODE |
| LOW | …ntend/src/components/DimensionMembersDialogContent.tsx | 70 | export function DimensionMembersDialogContent({ target, onClose, onStockClick }: Omit<Props, 'target'> & { target: Dimen | CODE |
| LOW | frontend/src/components/EChartsCandlestick.tsx | 1174 | function updateCompactPresentation() { | CODE |
| LOW | frontend/src/components/StockMultiDayIntradayChart.tsx | 22 | export function StockMultiDayIntradayChart({ | CODE |
| LOW | frontend/src/components/ExtDimensionAnalysis.tsx | 66 | function pickDefaultDimensionField(config: ExtDataConfig | undefined, fallbackFieldNames: string[]) { | CODE |
| LOW | …rc/components/screener/DefaultStrategyParamsDialog.tsx | 36 | export function DefaultStrategyParamsDialog({ show, onClose }: Props) { | CODE |
| LOW | frontend/src/lib/watchlist-group-colors.ts | 30 | export function resolveWatchlistGroupColor(color?: string | null): WatchlistGroupColorOption { | CODE |
| LOW | frontend/src/lib/kline.ts | 32 | export function klineDailyLatestQueryOptions(symbol: string) { | CODE |
| LOW | frontend/src/lib/kline.ts | 129 | export function klineMinuteRangeQueryOptions(symbol: string, days: number) { | CODE |
| LOW | frontend/src/lib/useFinancials.ts | 23 | export function financialMetricsQueryOptions(symbol?: string) { | CODE |
| LOW | frontend/src/lib/minuteBatchIncremental.ts | 41 | export async function fetchMinuteBatchIncremental( | CODE |
| LOW | frontend/src/lib/stock-external-link.ts | 16 | export function loadStockExternalTemplate(): string { | CODE |
| LOW | frontend/src/lib/stock-external-link.ts | 20 | export function saveStockExternalTemplate(tpl: string): void { | CODE |
| LOW | frontend/src/pages/settings/MenuSettings.tsx | 211 | export function SettingsMenuSettingsPanel() { | CODE |
| LOW | …end/src/pages/factors/GenerateFactorStrategyDialog.tsx | 47 | export function GenerateFactorStrategyDialog({ | CODE |
| LOW | backend/app/secrets_store.py | 122 | def get_custom_webhook_secret() -> str: | CODE |
| LOW | backend/app/secrets_store.py | 127 | def set_custom_webhook_secret(secret: str) -> str: | CODE |
| LOW | backend/app/market_time.py | 40 | def trading_minutes_elapsed_from_dt(dt: datetime) -> float: | CODE |
| LOW | backend/app/market_time.py | 70 | def trading_minutes_elapsed_from_ts(ts_ms: int | float | None) -> float: | CODE |
| LOW | backend/app/enriched_generation.py | 113 | def _exclusive_generation_lock(data_dir: Path, asset_type: str) -> Iterator[None]: | CODE |
| LOW | backend/app/enriched_generation.py | 166 | def _publication_claim_is_running(payload: dict[str, Any]) -> bool: | CODE |
| LOW | backend/app/enriched_generation.py | 178 | def _orphaned_publishing_claim(payload: dict[str, Any]) -> bool: | CODE |
| LOW | backend/app/enriched_generation.py | 238 | def enriched_publication_incomplete( | CODE |
| LOW | backend/app/price_limits.py | 89 | def no_limit_window_margin_days(symbol: str) -> int: | CODE |
| LOW | backend/app/price_limits.py | 156 | def polars_is_risk_warning_name(name: pl.Expr) -> pl.Expr: | CODE |
| LOW | backend/app/price_limits.py | 196 | def write_numpy_price_limit_matrix( | CODE |
| LOW | backend/app/main.py | 292 | def _schedule_matrix_cache_prewarm() -> None: | CODE |
| LOW | backend/app/main.py | 608 | async def capability_denied_handler(request: Request, exc: CapabilityDenied) -> JSONResponse: | CODE |
| LOW | backend/app/share_capital.py | 27 | def apply_historical_float_shares( | CODE |
| LOW | backend/app/desktop.py | 33 | def _ensure_data_dir_writable() -> None: | CODE |
| LOW⚡ | backend/app/indicators/pipeline.py | 97 | def _custom_prev_fields_today() -> set[str]: | CODE |
| LOW⚡ | backend/app/indicators/pipeline.py | 103 | def invalidate_custom_signals() -> None: | CODE |
| LOW | backend/app/indicators/pipeline.py | 73 | def _get_custom_signal_exprs_today() -> dict[str, pl.Expr]: | CODE |
| LOW | backend/app/indicators/pipeline.py | 608 | def _split_custom_exprs_by_limit_deps( | CODE |
| LOW | backend/app/indicators/pipeline.py | 625 | def _needed_references_limit_prices(needed: set[str]) -> bool: | CODE |
| LOW | backend/app/indicators/pipeline.py | 1326 | def attach_deviation_columns_today( | CODE |
| LOW | backend/app/indicators/pipeline.py | 1419 | def compute_enriched_history_window( | CODE |
| LOW | backend/app/indicators/pipeline.py | 2210 | def _compute_limit_signals_today(df: pl.DataFrame, instruments: pl.DataFrame) -> pl.DataFrame: | CODE |
| LOW | backend/app/extensions/registry.py | 42 | def register_notification_formatter( | CODE |
| LOW | backend/app/extensions/registry.py | 67 | def has_notification_formatters(self) -> bool: | CODE |
| LOW | backend/app/extensions/loader.py | 36 | def configure_backend_extensions( | CODE |
| LOW | backend/app/extensions/loader.py | 67 | def _validate_router_conflicts(app: FastAPI, registrar: BackendExtensionRegistrar) -> None: | CODE |
| LOW | backend/app/extensions/loader.py | 106 | def current_extension_context(*, data_dir, repository) -> ExtensionContext: | CODE |
| LOW | backend/app/backtest/worker.py | 113 | def _decode_walkforward_config(payload: dict[str, Any]): | CODE |
| LOW | backend/app/backtest/matrix.py | 68 | def _raise_if_matrix_cancelled(cancel_event: threading.Event | None) -> None: | CODE |
| LOW | backend/app/backtest/matrix.py | 345 | def active_matrix_compute_cache() -> MatrixComputeCache | None: | CODE |
| LOW | backend/app/backtest/matrix.py | 350 | def _activate_valid_bar_index(index: ValidBarIndex) -> Iterator[None]: | CODE |
| LOW | backend/app/backtest/matrix.py | 680 | def load_market_data_matrix_from_parquet( | CODE |
| LOW | backend/app/backtest/matrix.py | 845 | def _validate_matrix_dataset_schema(dataset: pads.Dataset) -> None: | CODE |
| LOW | backend/app/backtest/matrix.py | 853 | def _normalize_matrix_cache_fields( | CODE |
| LOW | backend/app/backtest/matrix.py | 871 | def _normalize_symbol_request(symbols: list[str] | None) -> tuple[str, ...] | None: | CODE |
| LOW | backend/app/backtest/matrix.py | 877 | def _matrix_filter_expression( | CODE |
| LOW | backend/app/backtest/matrix.py | 890 | def _resolve_matrix_storage_fields( | CODE |
| 2487 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | packaging/generate_icon_designs.py | 69 | # ── 方案 1: 渐变紫底 + 白色发光主体 (现代 App 风格) ────────────── | COMMENT |
| MEDIUM | packaging/generate_icon_designs.py | 120 | # ── 方案 2: 透明底 + 渐变紫发光主体 (优雅线条) ────────────────── | COMMENT |
| MEDIUM | packaging/generate_icon_designs.py | 160 | # ── 方案 3: 深色底 + 金紫上涨 K 线柱 (金融图表感) ──────────────── | COMMENT |
| MEDIUM | packaging/generate_icon_designs.py | 201 | # ── 方案 4: 渐变底 + K线被方括号"框选" (品牌强调) ──────────────── | COMMENT |
| MEDIUM | frontend/src/components/signals/ConditionEditor.tsx | 126 | // ── 字段选择器: 搜索 + 分组居中对话框 ─────────────────── | COMMENT |
| MEDIUM | frontend/src/components/signals/ConditionEditor.tsx | 245 | // ── 日期偏移控件: "最新" / "前N日" ─────────────────────── | COMMENT |
| MEDIUM | frontend/src/components/signals/ConditionEditor.tsx | 289 | // ── 右操作数: 字段(弹出) / 常量 切换 ───────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Regime.tsx | 49 | // ── 时间范围 ────────────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Regime.tsx | 87 | // ── EChart hook ─────────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Regime.tsx | 136 | // ── 卡片容器样式 (Dashboard 同款) ───────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Regime.tsx | 139 | // ── 主组件 ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Regime.tsx | 1274 | // ── 主线过滤设置面板 ────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Regime.tsx | 1404 | // ── 自定义天数输入弹窗 ──────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Dev.tsx | 10 | // ── 分钟K探测 (迁移自 MinuteDataProbe) ───────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Dev.tsx | 184 | // ── 演示数据生成 ────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Dev.tsx | 319 | // ── 封单监控模拟触发 ────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Dev.tsx | 447 | // ── Dev 主页面 ──────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Monitor.tsx | 337 | // ── 触发记录列表 ────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Monitor.tsx | 704 | // ── 监控规则列表 ────────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Monitor.tsx | 1036 | // ── 规则编辑对话框 ──────────────────────────────────── | COMMENT |
| MEDIUM | frontend/src/pages/Monitor.tsx | 1075 | // ── 确认对话框 ──────────────────────────────────────── | COMMENT |
| MEDIUM | mcp-server/src/tsp_mcp_server/server.py | 61 | # ── read:market 行情 ────────────────────────────────── | COMMENT |
| MEDIUM | mcp-server/src/tsp_mcp_server/server.py | 86 | # ── read:analysis 策略/环境/告警 ─────────────────────── | COMMENT |
| MEDIUM | mcp-server/src/tsp_mcp_server/server.py | 111 | # ── read:ext / write:ext 扩展数据 ───────────────────── | COMMENT |
| MEDIUM | mcp-server/src/tsp_mcp_server/server.py | 136 | # ── run:backtest 回测 ───────────────────────────────── | COMMENT |
| MEDIUM | backend/app/config.py | 11 | # ── 运行环境检测 ────────────────────────────────────────── | COMMENT |
| MEDIUM | backend/app/price_limits.py | 47 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/price_limits.py | 58 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/main.py | 451 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/main.py | 453 | # ================================================================ | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 124 | # ================================================================ | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 128 | # ================================================================ | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 130 | # ── 存储列 (parquet 持久化) ────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 145 | # ── 基础指标 ───────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 150 | # ── 均线 MA ────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 156 | # ── 指数均线 EMA ───────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 162 | # ── MACD ───────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 166 | # ── 布林带 BOLL ────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 169 | # ── KDJ ────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 173 | # ── ATR ────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 175 | # ── 量价 ───────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 179 | # ── 极值 ───────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 182 | # ── 动量 ───────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 188 | # ── 异动偏离 (运行时由 repository 附着, 不落盘) ──────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 192 | # ── 波动率 ─────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 194 | # ── RSI ────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 311 | # ================================================================ | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 313 | # ================================================================ | COMMENT |
| MEDIUM⚡ | backend/app/indicators/pipeline.py | 315 | # ── compute_indicators 的列依赖关系 (供 needed 裁剪时求闭包) ──────────── | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 48 | # ── 自定义信号缓存 ───────────────────────────────────── | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1029 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1031 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1084 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1091 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1360 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1372 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1903 | # ================================================================ | COMMENT |
| MEDIUM | backend/app/indicators/pipeline.py | 1905 | # ================================================================ | COMMENT |
| MEDIUM⚡ | backend/app/indicators/levels.py | 23 | # ================================================================ | COMMENT |
| MEDIUM⚡ | backend/app/indicators/levels.py | 25 | # ================================================================ | COMMENT |
| 500 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | mcp-server/src/tsp_mcp_server/server.py | 50 | except Exception: # noqa: BLE001 | CODE |
| LOW | backend/app/secrets_store.py | 47 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/__init__.py | 22 | except Exception: | CODE |
| LOW | backend/app/__init__.py | 35 | except Exception: # noqa: BLE001 | CODE |
| LOW⚡ | backend/app/main.py | 179 | except Exception as e: # noqa: BLE001 | CODE |
| LOW⚡ | backend/app/main.py | 187 | except Exception as e: # noqa: BLE001 | CODE |
| LOW⚡ | backend/app/main.py | 197 | except Exception as e: | CODE |
| LOW⚡ | backend/app/main.py | 210 | except Exception as e: # noqa: BLE001 | CODE |
| LOW⚡ | backend/app/main.py | 220 | except Exception as e: # noqa: BLE001 | CODE |
| LOW⚡ | backend/app/main.py | 229 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 87 | except Exception as _e: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 103 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 118 | except Exception as exc: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 146 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 285 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 329 | except Exception: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 363 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/main.py | 370 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/share_capital.py | 23 | except Exception: | CODE |
| LOW | backend/app/desktop.py | 47 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/desktop.py | 66 | except Exception: # noqa: BLE001 | CODE |
| LOW | backend/app/desktop.py | 85 | except Exception: # noqa: BLE001 | CODE |
| LOW | backend/app/desktop.py | 146 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/desktop.py | 165 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/desktop.py | 218 | except Exception: | CODE |
| LOW | backend/app/desktop.py | 240 | except Exception: | CODE |
| LOW | backend/app/desktop.py | 302 | except Exception: | CODE |
| LOW | backend/app/desktop.py | 337 | except Exception: | CODE |
| LOW | backend/app/plugins/fuyao/provider.py | 383 | except Exception: # 缓存损坏不致命, 换下一个/重拉 | CODE |
| LOW | backend/app/plugins/fuyao/provider.py | 597 | except Exception: | CODE |
| LOW | backend/app/plugins/fuyao/provider.py | 1132 | except Exception as e: # 缓存损坏等不致命: 回退逐标的接口 | CODE |
| LOW⚡ | backend/app/indicators/pipeline.py | 90 | except Exception as e: | CODE |
| LOW | backend/app/indicators/pipeline.py | 67 | except Exception as e: | CODE |
| LOW | backend/app/indicators/pipeline.py | 1188 | except Exception as exc: # noqa: BLE001 | CODE |
| LOW | backend/app/indicators/pipeline.py | 1390 | except Exception: | CODE |
| LOW | backend/app/indicators/pipeline.py | 1551 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/indicators/pipeline.py | 1851 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/indicators/pipeline.py | 1881 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/indicators/levels.py | 590 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/factors/store.py | 43 | except Exception as exc: | CODE |
| LOW | backend/app/factors/store.py | 186 | except Exception as exc: | CODE |
| LOW | backend/app/factors/registry.py | 343 | except Exception: | CODE |
| LOW | backend/app/factors/ext_factors.py | 229 | except Exception as e: | CODE |
| LOW | backend/app/factors/ext_factors.py | 263 | except Exception as e: | CODE |
| LOW | backend/app/factors/ext_factors.py | 321 | except Exception as e: | CODE |
| LOW | backend/app/factors/ext_factors.py | 353 | except Exception as e: | CODE |
| LOW | backend/app/extensions/loader.py | 59 | except Exception as exc: | CODE |
| LOW | backend/app/extensions/loader.py | 102 | except Exception as exc: | CODE |
| LOW | backend/app/backtest/mining.py | 1616 | except Exception as exc: | CODE |
| LOW | backend/app/backtest/mining.py | 1629 | except Exception as exc: | CODE |
| LOW | backend/app/backtest/fundamentals.py | 56 | except Exception as exc: | CODE |
| LOW | backend/app/backtest/strategy.py | 514 | except Exception as exc: | CODE |
| LOW | backend/app/backtest/strategy.py | 851 | except Exception: # noqa: BLE001 | CODE |
| LOW | backend/app/backtest/strategy.py | 1638 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/backtest/strategy.py | 1816 | except Exception as exc: | CODE |
| LOW | backend/app/backtest/strategy.py | 2361 | except Exception as e: | CODE |
| LOW | backend/app/backtest/strategy.py | 2374 | except Exception as e: | CODE |
| LOW | backend/app/backtest/strategy.py | 2409 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | backend/app/backtest/strategy.py | 2523 | except Exception as e: | CODE |
| MEDIUM | backend/app/backtest/engine.py | 1350 | def _valid_price(value) -> bool: | CODE |
| 516 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | packaging/generate_icon_designs.py | 10 | CODE | |
| LOW | packaging/generate_icon_designs.py | 13 | CODE | |
| LOW | mcp-server/smoke_test.py | 5 | CODE | |
| LOW | mcp-server/src/tsp_mcp_server/server.py | 10 | CODE | |
| LOW | backend/app/secrets_store.py | 8 | CODE | |
| LOW | backend/app/db_safe.py | 6 | CODE | |
| LOW | backend/app/config.py | 2 | CODE | |
| LOW | backend/app/parquet.py | 2 | CODE | |
| LOW | backend/app/watchdog.py | 14 | CODE | |
| LOW | backend/app/polars_guard.py | 16 | CODE | |
| LOW | backend/app/market_time.py | 7 | CODE | |
| LOW | backend/app/enriched_generation.py | 1 | CODE | |
| LOW | backend/app/price_limits.py | 3 | CODE | |
| LOW | backend/app/main.py | 2 | CODE | |
| LOW | backend/app/share_capital.py | 5 | CODE | |
| LOW | backend/app/desktop.py | 16 | CODE | |
| LOW | backend/app/desktop.py | 24 | CODE | |
| LOW | backend/app/plugins/fuyao/provider.py | 27 | CODE | |
| LOW | backend/app/plugins/fuyao/client.py | 10 | CODE | |
| LOW | backend/app/indicators/pipeline.py | 16 | CODE | |
| LOW | backend/app/indicators/levels.py | 13 | CODE | |
| LOW | backend/app/factors/store.py | 7 | CODE | |
| LOW | backend/app/factors/dsl.py | 15 | CODE | |
| LOW | backend/app/factors/registry.py | 15 | CODE | |
| LOW | backend/app/factors/ext_factors.py | 25 | CODE | |
| LOW | backend/app/extensions/registry.py | 2 | CODE | |
| LOW | backend/app/extensions/__init__.py | 1 | CODE | |
| LOW | backend/app/extensions/__init__.py | 1 | CODE | |
| LOW | backend/app/extensions/__init__.py | 1 | CODE | |
| LOW | backend/app/extensions/__init__.py | 1 | CODE | |
| LOW | backend/app/extensions/__init__.py | 7 | CODE | |
| LOW | backend/app/extensions/__init__.py | 7 | CODE | |
| LOW | backend/app/extensions/loader.py | 2 | CODE | |
| LOW | backend/app/extensions/contracts.py | 2 | CODE | |
| LOW | backend/app/backtest/worker.py | 2 | CODE | |
| LOW | backend/app/backtest/matrix.py | 2 | CODE | |
| LOW | backend/app/backtest/stats_v2.py | 13 | CODE | |
| LOW | backend/app/backtest/regime_alignment.py | 1 | CODE | |
| LOW | backend/app/backtest/mining.py | 2 | CODE | |
| LOW | backend/app/backtest/fundamentals.py | 17 | CODE | |
| LOW | backend/app/backtest/walkforward.py | 9 | CODE | |
| LOW | backend/app/backtest/strategy.py | 5 | CODE | |
| LOW | backend/app/backtest/numba_runtime.py | 9 | CODE | |
| LOW | backend/app/backtest/mining_runtime.py | 2 | CODE | |
| LOW | backend/app/backtest/engine.py | 5 | CODE | |
| LOW | backend/app/backtest/engine.py | 12 | CODE | |
| LOW | backend/app/backtest/minute_replay.py | 12 | CODE | |
| LOW | backend/app/backtest/minute_trigger.py | 6 | CODE | |
| LOW | backend/app/backtest/factor.py | 5 | CODE | |
| LOW | backend/app/backtest/optimizer.py | 9 | CODE | |
| LOW | backend/app/backtest/candidates.py | 3 | CODE | |
| LOW | backend/app/data_providers/tickflow_provider.py | 2 | CODE | |
| LOW | backend/app/data_providers/registry.py | 2 | CODE | |
| LOW | backend/app/data_providers/__init__.py | 5 | CODE | |
| LOW | backend/app/data_providers/__init__.py | 5 | CODE | |
| LOW | backend/app/data_providers/__init__.py | 5 | CODE | |
| LOW | backend/app/data_providers/__init__.py | 6 | CODE | |
| LOW | backend/app/data_providers/schemas.py | 2 | CODE | |
| LOW | backend/app/data_providers/capabilities.py | 24 | CODE | |
| LOW | backend/app/data_providers/normalizer.py | 2 | CODE | |
| 453 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | backend/app/__init__.py | 35 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/desktop.py | 85 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/desktop.py | 264 | except (urllib.error.URLError, ConnectionError, OSError): | CODE |
| HIGH | backend/app/indicators/pipeline.py | 1415 | except OSError: | CODE |
| HIGH | backend/app/backtest/matrix.py | 1328 | except (OSError, ValueError): | CODE |
| HIGH | backend/app/backtest/matrix.py | 1334 | except (OSError, ValueError): | CODE |
| HIGH | backend/app/backtest/strategy.py | 851 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/backtest/engine.py | 1101 | except Exception: | CODE |
| HIGH | backend/app/backtest/engine.py | 1527 | except Exception: | CODE |
| HIGH | backend/app/backtest/engine.py | 1299 | except (TypeError, ValueError): | CODE |
| HIGH | backend/app/backtest/engine.py | 2055 | except Exception: | CODE |
| HIGH | backend/app/backtest/engine.py | 2410 | except (TypeError, ValueError): | CODE |
| HIGH | backend/app/backtest/engine.py | 2781 | except Exception: | CODE |
| HIGH | backend/app/backtest/factor.py | 1047 | except ValueError: | CODE |
| HIGH | backend/app/data_providers/custom/loader.py | 449 | except (TypeError, ValueError): | CODE |
| HIGH | backend/app/data_providers/custom/loader.py | 454 | except (TypeError, ValueError): | CODE |
| HIGH | backend/app/tickflow/repository.py | 990 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/tickflow/repository.py | 1967 | except duckdb.CatalogException: | CODE |
| HIGH | backend/app/api/alerts.py | 45 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/screener.py | 870 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/screener.py | 1115 | except Exception: | CODE |
| HIGH | backend/app/api/ext_data.py | 1410 | except Exception: | CODE |
| HIGH | backend/app/api/ext_data.py | 1440 | except Exception: | CODE |
| HIGH | backend/app/api/settings.py | 1144 | except Exception: | CODE |
| HIGH | backend/app/api/settings.py | 1970 | except Exception: | CODE |
| HIGH | backend/app/api/kline.py | 1224 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/kline.py | 1420 | except Exception: | CODE |
| HIGH | backend/app/api/kline.py | 1276 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/kline.py | 1669 | except Exception: | CODE |
| HIGH | backend/app/api/monitor_rules.py | 161 | except Exception: | CODE |
| HIGH | backend/app/api/monitor_rules.py | 621 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/monitor_rules.py | 674 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/monitor_rules.py | 262 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/monitor_rules.py | 688 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/monitor_rules.py | 695 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/data.py | 165 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/data.py | 200 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/data.py | 239 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/data.py | 304 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/data.py | 475 | except PermissionError: | CODE |
| HIGH | backend/app/api/data.py | 542 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/api/data.py | 528 | except OSError: | CODE |
| HIGH | backend/app/api/data.py | 453 | except OSError: | CODE |
| HIGH | backend/app/api/data.py | 472 | except OSError: | CODE |
| HIGH | backend/app/jobs/daily_pipeline.py | 1120 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/custom/assistant/tools.py | 884 | except Exception: | CODE |
| HIGH | backend/app/services/strategy_run_queue.py | 59 | except (FileNotFoundError, ValueError, OSError): | CODE |
| HIGH | backend/app/services/wecom_bot_service.py | 156 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/services/wecom_bot_service.py | 241 | except asyncio.TimeoutError: | CODE |
| HIGH | backend/app/services/api_gateway.py | 107 | except (IndexError, ValueError): | CODE |
| HIGH | backend/app/services/ai_provider.py | 1163 | except OSError: | CODE |
| HIGH | backend/app/services/ai_provider.py | 949 | except OSError: | CODE |
| HIGH | backend/app/services/financial_sync.py | 428 | except asyncio.CancelledError: | CODE |
| HIGH | backend/app/services/events.py | 63 | except (queue.Empty, queue.Full): | CODE |
| HIGH | backend/app/services/auction_benchmark.py | 235 | except FuyaoError: | CODE |
| HIGH | backend/app/services/screener.py | 422 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/services/index_sync.py | 144 | except Exception: # noqa: BLE001 | CODE |
| HIGH | backend/app/services/fs_utils.py | 28 | except OSError: | CODE |
| HIGH | backend/app/services/data_integrity.py | 403 | except JobCancelledError: | CODE |
| HIGH | backend/app/services/ext_pull.py | 607 | except asyncio.CancelledError: | CODE |
| 23 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | backend/app/indicators/pipeline.py | 880 | # 无涨跌幅限制日 / 昨收缺失 → null (引用它的信号条件为 null, 下游按未命中处理)。 | COMMENT |
| HIGH | backend/app/indicators/pipeline.py | 2102 | # ---- 动量 3d (异动偏离 deviate_3d 用; 旧 live_agg 未带该状态时跳过, 偏离列自然置 null) ---- | COMMENT |
| HIGH | backend/app/indicators/pipeline.py | 2325 | # 无涨跌幅限制日 / 昨收与权威价均缺失 → null; 引用它的自定义信号 | COMMENT |
| HIGH | backend/app/indicators/pipeline.py | 708 | 无涨跌幅限制日为 null) | STRING |
| HIGH | backend/app/indicators/pipeline.py | 1127 | 无可用指数数据时返回 None (偏离列置 null, 不阻塞主流程)。 | STRING |
| HIGH | backend/app/indicators/pipeline.py | 1336 | 缺失动量的窗口 (如全量回退路径无 momentum_3d) 置 null, 不阻塞主流程。 | STRING |
| HIGH | backend/app/factors/dsl.py | 6 | 窗口纪律 (Polars 嵌套窗口会静默产出全 null, 必须在编译期杜绝): | STRING |
| HIGH | backend/app/factors/dsl.py | 661 | # 阶段二: 提取截面算子的含窗口子树为临时列 (Polars 嵌套窗口会静默全 null) | COMMENT |
| HIGH | backend/app/backtest/fundamentals.py | 6 | (公告多在盘后发布, 保守取 T+1 生效), 此前保持 null; | STRING |
| HIGH | backend/app/backtest/fundamentals.py | 9 | - 无财务数据的标的/日期一律为 null, 绝不填 0 (填 0 会污染截面排名, | STRING |
| HIGH | backend/app/backtest/fundamentals.py | 107 | # 公告当日取到「尚未生效」的新一期并被门控置 null, 打断上一期的前向填充, | COMMENT |
| HIGH | backend/app/backtest/mining_runtime.py | 387 | "mining factor panel requires non-null, unique symbol/date keys " | CODE |
| HIGH | backend/app/backtest/engine.py | 655 | # 按 asset_type 取维表: ETF 回测须用 ETF 维表, 否则名称 JOIN 失败(全 null)、 | COMMENT |
| HIGH | backend/app/tickflow/repository.py | 2339 | if not existing.is_empty() and existing.equals(merged): | CODE |
| HIGH | backend/app/api/factors.py | 139 | # 截面值全相同时 pl.corr 返回 NaN (非 null), 与 FactorBacktestService 同口径剔除 | COMMENT |
| HIGH | backend/app/api/watchlist.py | 492 | # 不在 enriched 缓存里的标的 (新股/冷门股/新用户未同步) 指标为 null, 前端渲染为 "—". | COMMENT |
| HIGH | backend/app/api/watchlist.py | 595 | # 旧 schema 迁移补的空串归一为 null, 前端只需判断一种「缺失」 | COMMENT |
| HIGH | backend/app/api/watchlist.py | 623 | # 装饰列失败不得影响自选主表; 两列必须存在 (值可为 null), 否则前端排序/筛选静默失效 | COMMENT |
| HIGH | backend/app/services/regime_builder.py | 575 | concat 前给旧数据补缺失列(null), 让旧 parquet 首次重写时自动迁移到新 schema。 | STRING |
| HIGH | backend/app/services/regime_builder.py | 587 | # schema 对齐: 以 new_rows 的列名+顺序为权威, 旧数据补缺失列(null), | COMMENT |
| HIGH | backend/app/services/regime_builder.py | 589 | # 这样旧 parquet 首次重写时自动迁移到新 schema(新列在旧日期为 null)。 | COMMENT |
| HIGH | backend/app/services/market_phase.py | 12 | - promo 晋级率: 昨日连板池今日继续封板的比例 (池 <10 家记 null) | STRING |
| HIGH | backend/app/services/market_phase.py | 176 | (promo_rate 允许 null)。处理: promo 前向填充 → 各驱动 EMA 平滑 → | STRING |
| HIGH | backend/app/services/quote_service.py | 1017 | # 修复: API 在非交易时段可能返回 open/high/low=0 或 null, | COMMENT |
| HIGH | backend/app/services/quote_service.py | 1076 | # prev_close=0 → inf (非合法 JSON), prev_close=null → null; 用 when 守护 | COMMENT |
| HIGH | backend/app/services/kline_sync.py | 500 | # 除权事件明细列 (可选, 缺省为 null): 等差显示投影 (原始价 - Σ未来每股分红, | COMMENT |
| HIGH | backend/app/services/kline_sync.py | 502 | # 存量 all.parquet 只有规范三列, 合并用 how="diagonal" 自动补 null; | COMMENT |
| HIGH | backend/app/services/kline_sync.py | 745 | # trade_time 等字符串路径: 先解析成 Datetime (失败置 null), 再做时段分类 | COMMENT |
| HIGH | backend/app/services/kline_sync.py | 577 | how="diagonal" 兼容存量三列 schema (旧行明细自动为 null); | STRING |
| HIGH | backend/app/services/kline_sync.py | 582 | (dividend/prev_close 等补 null) 不改变复权价格 → 不计入变化列表, | STRING |
| HIGH | backend/app/services/depth_service.py | 386 | # polars 会按首行推断类型, 后续遇到不一致 (bool vs null) 报 | COMMENT |
| HIGH | backend/app/strategy/intraday_features.py | 9 | - null 语义: 窗口不足、基准为零、缺昨收、开盘未满 30 分钟 → 特征为 null, | STRING |
| HIGH | backend/app/strategy/intraday_features.py | 64 | OHLC 缺失时相关特征降级为 null)。可包含多个交易日, 特征按日分组。 | STRING |
| HIGH | backend/app/strategy/intraday_features.py | 69 | 返回: symbol/datetime + INTRADAY_FEATURES 全部特征列(Float64, 可 null)。 | STRING |
| HIGH | backend/app/strategy/custom_signals.py | 703 | 上升沿: 条件 false→true 的那根 bar 为 true; 首根 bar(前值为 null)不触发; | STRING |
| HIGH | backend/tests/test_minute_partition_merge.py | 73 | assert stored.equals(stored.sort("symbol", "datetime")) | CODE |
| HIGH | backend/tests/test_fundamental_factors.py | 66 | # 无财务数据标的全 null, 绝不填 0 | COMMENT |
| HIGH | backend/tests/test_fundamental_factors.py | 148 | null), 两条路径给出不同的因子值。 | STRING |
| HIGH | backend/tests/test_adj_factor_event_columns.py | 5 | - 存量 all.parquet 只有规范三列 → diagonal 合并自动补 null, 读取方零改动; | STRING |
| HIGH | backend/tests/test_custom_batch_isolation.py | 47 | # 非法字符串维持 strict=False 宽松行为 (null, 不抛异常) | COMMENT |
| HIGH⚡ | backend/tests/test_minute_adjust.py | 97 | assert out_index.equals(df) | CODE |
| HIGH⚡ | backend/tests/test_minute_adjust.py | 100 | assert out_no_factors.equals(df) | CODE |
| HIGH⚡ | backend/tests/test_minute_adjust.py | 104 | assert out_no_events.equals(df) | CODE |
| HIGH⚡ | backend/tests/test_factor_dsl.py | 122 | # A 组: [null, null, 10, 11, 12, 13]; B 组: [null, null, 100, 90, 80, 70] | COMMENT |
| HIGH⚡ | backend/tests/test_factor_dsl.py | 129 | # A 组 2 日窗: [null, 10.5, 11.5, 12.5, 13.5, 14.5] | COMMENT |
| HIGH⚡ | backend/tests/test_factor_dsl.py | 146 | # Polars 嵌套窗口会静默全 null; 编译器必须走两阶段 (临时列 + 截面) | COMMENT |
| HIGH⚡ | backend/tests/test_factor_dsl.py | 190 | # A 组全为负 → null; B 组 100-15=85 → log 正常 | COMMENT |
| HIGH⚡ | backend/tests/test_factor_dsl.py | 197 | # 常数序列或完全单调: 只验证产出为有限值或 null, 无串组异常即可 | COMMENT |
| HIGH | backend/tests/test_intraday_signals.py | 93 | # 上午 8 根: idx5 起 3/3 窗口成立(idx5,6,7 非 null); 下午 4 根全部 null(窗口不足) | COMMENT |
| HIGH⚡ | backend/tests/test_intraday_signals.py | 313 | assert out is df or out.equals(df) | CODE |
| HIGH | backend/tests/test_data_integrity.py | 4 | null); 历史交易日的 quote_ts 时刻 < 15:00 即盘中快照 → 坏。 | STRING |
| HIGH | backend/tests/test_abnormal_moves.py | 65 | # 无指数数据: 偏离列为 null, 不抛异常 | COMMENT |
| HIGH | backend/tests/test_abnormal_moves.py | 158 | # 全量回退路径可能缺 momentum_3d: 该窗口置 null, 其余窗口正常 | COMMENT |
| HIGH⚡ | backend/tests/test_overlay_filter.py | 103 | # A: [null, 8>null, 9>8] → [F, F, T] | COMMENT |
| HIGH | backend/tests/test_watchlist_enriched_join.py | 281 | # 指数无换手率: 列缺失或 null, 不报错 | COMMENT |
| HIGH | backend/tests/test_watchlist_enriched_join.py | 118 | assert row_999["close"] is None, f"缺失指标应为 null, 实际: {row_999['close']}" | CODE |
| HIGH | backend/tests/test_watchlist_enriched_join.py | 5 | (新股 / 冷门股 / 新用户未同步). 缺失标的的指标字段为 null, 前端渲染为 "—". | STRING |
| HIGH | backend/tests/test_watchlist_enriched_join.py | 99 | """核心回归: 自选里有但 enriched 缓存里没有的标的, 必须仍返回一行 (指标 null).""" | STRING |
| HIGH | backend/tests/test_watchlist_enriched_join.py | 165 | """ETF 同样: 自选了但 ETF enriched 缓存没有的, 也应返回 (指标 null).""" | STRING |
| HIGH | backend/tests/test_watchlist_enriched_join.py | 253 | - 指数行 turnover_rate 为 None (列不存在或 null, 不报错) | STRING |
| 10 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backend/app/main.py | 582 | CODE | |
| LOW | backend/app/desktop.py | 249 | CODE | |
| LOW | backend/app/plugins/fuyao/provider.py | 480 | CODE | |
| LOW | backend/app/plugins/fuyao/provider.py | 693 | CODE | |
| LOW | backend/app/plugins/fuyao/provider.py | 935 | CODE | |
| LOW | backend/app/plugins/fuyao/provider.py | 970 | CODE | |
| LOW | backend/app/plugins/fuyao/provider.py | 1043 | CODE | |
| LOW | backend/app/plugins/fuyao/provider.py | 1150 | CODE | |
| LOW | backend/app/plugins/fuyao/client.py | 279 | CODE | |
| LOW | backend/app/indicators/pipeline.py | 1121 | CODE | |
| LOW | backend/app/indicators/pipeline.py | 1419 | CODE | |
| LOW | backend/app/indicators/pipeline.py | 1503 | CODE | |
| LOW | backend/app/indicators/levels.py | 408 | CODE | |
| LOW | backend/app/indicators/levels.py | 515 | CODE | |
| LOW | backend/app/factors/store.py | 166 | CODE | |
| LOW | backend/app/factors/dsl.py | 305 | CODE | |
| LOW | backend/app/factors/ext_factors.py | 268 | CODE | |
| LOW | backend/app/extensions/loader.py | 67 | CODE | |
| LOW | backend/app/backtest/worker.py | 136 | CODE | |
| LOW | backend/app/backtest/worker.py | 178 | CODE | |
| LOW | backend/app/backtest/worker.py | 285 | CODE | |
| LOW | backend/app/backtest/matrix.py | 1609 | CODE | |
| LOW | backend/app/backtest/matrix.py | 1840 | CODE | |
| LOW | backend/app/backtest/matrix.py | 2311 | CODE | |
| LOW | backend/app/backtest/matrix.py | 2934 | CODE | |
| LOW | backend/app/backtest/matrix.py | 3077 | CODE | |
| LOW | backend/app/backtest/matrix.py | 3678 | CODE | |
| LOW | backend/app/backtest/mining.py | 610 | CODE | |
| LOW | backend/app/backtest/mining.py | 824 | CODE | |
| LOW | backend/app/backtest/walkforward.py | 192 | CODE | |
| LOW | backend/app/backtest/strategy.py | 805 | CODE | |
| LOW | backend/app/backtest/strategy.py | 1108 | CODE | |
| LOW | backend/app/backtest/strategy.py | 2333 | CODE | |
| LOW | backend/app/backtest/strategy.py | 2615 | CODE | |
| LOW | backend/app/backtest/strategy.py | 2710 | CODE | |
| LOW | backend/app/backtest/engine.py | 674 | CODE | |
| LOW | backend/app/backtest/engine.py | 850 | CODE | |
| LOW | backend/app/backtest/engine.py | 1203 | CODE | |
| LOW | backend/app/backtest/engine.py | 1802 | CODE | |
| LOW | backend/app/backtest/engine.py | 2266 | CODE | |
| LOW | backend/app/backtest/engine.py | 1009 | CODE | |
| LOW | backend/app/backtest/engine.py | 1283 | CODE | |
| LOW | backend/app/backtest/engine.py | 2391 | CODE | |
| LOW | backend/app/backtest/engine.py | 2583 | CODE | |
| LOW | backend/app/backtest/engine.py | 2610 | CODE | |
| LOW | backend/app/backtest/minute_replay.py | 125 | CODE | |
| LOW | backend/app/backtest/minute_trigger.py | 22 | CODE | |
| LOW | backend/app/backtest/optimizer.py | 36 | CODE | |
| LOW | backend/app/backtest/candidates.py | 182 | CODE | |
| LOW | backend/app/data_providers/custom/provider.py | 53 | CODE | |
| LOW | backend/app/data_providers/custom/provider.py | 108 | CODE | |
| LOW | backend/app/data_providers/custom/mapper.py | 43 | CODE | |
| LOW | backend/app/data_providers/custom/loader.py | 148 | CODE | |
| LOW | backend/app/tickflow/pools.py | 75 | CODE | |
| LOW | backend/app/tickflow/repository.py | 148 | CODE | |
| LOW | backend/app/tickflow/repository.py | 564 | CODE | |
| LOW | backend/app/tickflow/repository.py | 1299 | CODE | |
| LOW | backend/app/tickflow/repository.py | 1450 | CODE | |
| LOW | backend/app/api/alerts.py | 98 | CODE | |
| LOW | backend/app/api/signals.py | 252 | CODE | |
| 129 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backend/app/secrets_store.py | 18 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/watchdog.py | 28 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/main.py | 66 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/desktop.py | 26 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/desktop.py | 120 | def _setup_logging() -> None: | CODE |
| LOW | backend/app/plugins/fuyao/provider.py | 48 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/plugins/fuyao/client.py | 18 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/indicators/pipeline.py | 45 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | backend/app/indicators/levels.py | 20 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/factors/store.py | 19 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/factors/ext_factors.py | 36 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/extensions/__init__.py | 9 | __all__ = [ | CODE |
| LOW | backend/app/extensions/loader.py | 15 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/worker.py | 21 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/matrix.py | 61 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/mining.py | 16 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/fundamentals.py | 27 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/walkforward.py | 17 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/strategy.py | 66 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | backend/app/backtest/engine.py | 33 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/factor.py | 35 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/backtest/optimizer.py | 19 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/data_providers/tickflow_provider.py | 18 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/data_providers/__init__.py | 8 | __all__ = ["AssetType", "MarketDataProvider", "ProviderCapabilities", "get_provider"] | CODE |
| LOW | backend/app/data_providers/custom/provider.py | 28 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/data_providers/custom/__init__.py | 23 | __all__ = [ | CODE |
| LOW | backend/app/data_providers/custom/loader.py | 26 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/tickflow/pools.py | 20 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/tickflow/client.py | 20 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/tickflow/policy.py | 26 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/tickflow/repository.py | 40 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/auth.py | 29 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/market_recap.py | 26 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/financials.py | 17 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/screener.py | 24 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/screener.py | 282 | def _update_cache_strategy(data_dir, as_of: str, strategy_id: str, safe_data: dict) -> None: | CODE |
| LOW | backend/app/api/paper.py | 19 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/strategy.py | 35 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | backend/app/api/ext_data.py | 38 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/watchlist.py | 27 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/pipeline.py | 23 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/stock_analysis.py | 29 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/settings.py | 25 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/indices.py | 18 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/kline.py | 27 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/backtest.py | 23 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/api/data.py | 17 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/jobs/daily_pipeline.py | 32 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/jobs/daily_pipeline.py | 1413 | def set_app_state(app_state) -> None: | CODE |
| LOW | backend/app/services/strategy_run_queue.py | 25 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/services/wecom_bot_service.py | 29 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | backend/app/services/wecom_bot_service.py | 57 | def set_app_state(self, app_state) -> None: | CODE |
| LOW | backend/app/services/auth.py | 27 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/services/auth.py | 106 | def set_password(password: str) -> None: | CODE |
| LOW | backend/app/services/notify_adapter.py | 21 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/services/market_recap.py | 24 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/services/strategy_cache.py | 35 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/services/webhook_adapter.py | 25 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | backend/app/services/financial_sync.py | 20 | logger = logging.getLogger(__name__) | CODE |
| LOW | backend/app/services/financial_sync.py | 381 | def update_capabilities(self, capset: CapabilitySet) -> None: | CODE |
| 74 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL⚡ | backend/tests/test_index_minute_history.py | 52 | request.app.state.repo.get_index_daily.assert_not_called() | CODE |
| CRITICAL⚡ | backend/tests/test_index_minute_history.py | 72 | request.app.state.repo.get_index_daily.assert_not_called() | CODE |
| CRITICAL⚡ | backend/tests/test_index_minute_history.py | 90 | request.app.state.repo.get_index_daily.assert_not_called() | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …tend/src/components/screener/StrategyBuilderDialog.tsx | 322 | // Step 1: 生成 | COMMENT |
| LOW | …tend/src/components/screener/StrategyBuilderDialog.tsx | 370 | // Step 2: AI 修改 | COMMENT |
| LOW | backend/app/tickflow/repository.py | 588 | # Step 1: 直接读最新日期的分区文件 (仅 14 列) | COMMENT |
| LOW | backend/app/tickflow/repository.py | 605 | # Step 2: 读近 300 天 14 列数据 → compute → filter(latest) → 缓存 | COMMENT |
| LOW | backend/app/api/kline.py | 760 | # Step 1: 本地优先 — 一次 scan 读全部 symbol 当日分钟K (股票 / ETF 分钟数据分开存储) | COMMENT |
| LOW | backend/app/api/kline.py | 843 | # Step 2: 补拉并落盘 (取到即写, upsert 语义; 下一轮命中本地, 请求量骤降)。 | COMMENT |
| LOW⚡ | backend/app/jobs/daily_pipeline.py | 768 | # Step 3: 刷新视图 | COMMENT |
| LOW | backend/app/jobs/daily_pipeline.py | 212 | # Step 0: 先同步个股维表, 再解析标的池 — 确保标的池基于最新 instruments | COMMENT |
| LOW | backend/app/jobs/daily_pipeline.py | 224 | # Step 1: 日 K 同步 | COMMENT |
| LOW | backend/app/jobs/daily_pipeline.py | 429 | # Step 2: 计算 enriched | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …tend/src/components/screener/StrategyBuilderDialog.tsx | 322 | // Step 1: 生成 | COMMENT |
| LOW | …tend/src/components/screener/StrategyBuilderDialog.tsx | 370 | // Step 2: AI 修改 | COMMENT |
| LOW | backend/app/tickflow/repository.py | 588 | # Step 1: 直接读最新日期的分区文件 (仅 14 列) | COMMENT |
| LOW | backend/app/tickflow/repository.py | 605 | # Step 2: 读近 300 天 14 列数据 → compute → filter(latest) → 缓存 | COMMENT |
| LOW | backend/app/api/kline.py | 760 | # Step 1: 本地优先 — 一次 scan 读全部 symbol 当日分钟K (股票 / ETF 分钟数据分开存储) | COMMENT |
| LOW | backend/app/api/kline.py | 843 | # Step 2: 补拉并落盘 (取到即写, upsert 语义; 下一轮命中本地, 请求量骤降)。 | COMMENT |
| LOW⚡ | backend/app/jobs/daily_pipeline.py | 768 | # Step 3: 刷新视图 | COMMENT |
| LOW | backend/app/jobs/daily_pipeline.py | 212 | # Step 0: 先同步个股维表, 再解析标的池 — 确保标的池基于最新 instruments | COMMENT |
| LOW | backend/app/jobs/daily_pipeline.py | 224 | # Step 1: 日 K 同步 | COMMENT |
| LOW | backend/app/jobs/daily_pipeline.py | 429 | # Step 2: 计算 enriched | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | backend/tests/test_strategy_publish.py | 0 | def filter(df: pl.dataframe, params: dict) -> pl.expr: return pl.lit(true) | STRING |
| HIGH | backend/tests/test_strategy_code_save.py | 0 | def filter(df: pl.dataframe, params: dict) -> pl.expr: return pl.lit(true) | STRING |
| HIGH | backend/tests/test_strategy_build_stream.py | 0 | def filter(df: pl.dataframe, params: dict) -> pl.expr: return pl.lit(true) | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | dev.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | tiers.yaml | 1 | # tickflow-stock-panel —— TickFlow 推荐套餐能力对照表(§5.2) | COMMENT |
| LOW | frontend/src/lib/queryKeys.ts | 141 | // 扩展表 schema 清单 (板块切换的资金流列选择器等) | COMMENT |
| LOW | backend/pyproject.toml | 81 | line-length = 100 | COMMENT |
| LOW | backend/app/price_limits.py | 41 | and trade_date < MAIN_BOARD_ST_LIMIT_CHANGE_DATE | COMMENT |
| LOW | backend/app/indicators/pipeline.py | 1081 | return df.select(cols) | COMMENT |
| LOW | backend/app/indicators/pipeline.py | 1361 | # 全量重建流式暂存 + 自适应批次 (#208/#174) | COMMENT |
| LOW | backend/app/services/webhook_adapter.py | 221 | COMMENT | |
| LOW | backend/app/services/ext_data.py | 101 | # 接口按日期查询的参数名 (如 "date"): 非 None 时请求 | COMMENT |
| LOW | backend/app/services/pipeline_jobs.py | 561 | # ================================================================ | COMMENT |
| LOW | backend/app/strategy/monitor.py | 341 | self._strategy_signal_state: dict[tuple[str, str, str, str], tuple[str, set[str]]] = {} | COMMENT |
| LOW | .github/workflows/release.yml | 1 | name: 桌面客户端发布 | COMMENT |
| LOW | .github/workflows/release.yml | 121 | # --no-dev 排除 pytest/ruff/mypy; --extra desktop 装 pywebview | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backend/app/indicators/pipeline.py | 1245 | CODE | |
| LOW | backend/app/backtest/matrix.py | 680 | CODE | |
| LOW | backend/app/backtest/mining.py | 610 | CODE | |
| LOW | backend/app/api/sector_rotation.py | 15 | CODE | |
| LOW | backend/app/api/ext_data.py | 527 | CODE | |
| LOW | backend/app/api/backtest.py | 491 | CODE | |
| LOW | backend/app/api/backtest.py | 800 | CODE | |
| LOW | backend/app/api/backtest.py | 1022 | CODE | |
| LOW | backend/app/custom/assistant/chat_service.py | 142 | CODE | |
| LOW | backend/app/services/market_mainline.py | 250 | CODE | |
| LOW | backend/app/services/sector_rotation.py | 324 | CODE | |
| LOW | backend/app/services/minute_adjust.py | 162 | CODE | |
| LOW | backend/app/services/ext_data.py | 58 | CODE | |
| LOW | backend/app/services/kline_sync.py | 1030 | CODE | |
| LOW | backend/app/strategy/intraday_signals.py | 178 | CODE | |
| LOW | backend/tests/test_watchlist_enriched_join.py | 24 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | backend/tests/test_strategy_build_stream.py | 177 | CODE | |
| MEDIUM | backend/tests/test_custom_assistant.py | 228 | CODE |