A股全栈数据工具包:行情K线·当日逐笔·研报·信号·资金面·新闻·财务·公告·打板·ETF期权·舆情·宏观利率·期货大宗(含大商所日K)·事件驱动·可转债 | 15层·87端点·34数据源·除iwencai外免Key | A-share data for AI agents: K-lines, ticks, reports, fund flow, news, financials, filings, options, macro, futures, events, convertibles | 15 layers·87 endpoints·34 sources
This report summarizes scanner evidence for simonlin1212/a-stock-data, a Python project with 10,776 GitHub stars. SynthScan examined 12,421 lines of code across 10 source files, recording 196 pattern matches distributed across 6 syntactic categories. The legacy adjusted pattern signal is 14.0 (Moderate 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? 174 finding(s).
Are imports declared and package/API names verified? 0 finding(s).
Are wrappers, guards, and repeated structures necessary? 188 finding(s).
Which changes need focused human review? 196 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
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 196 distinct pattern matches across 6 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 | SKILL.md | 2015 | def eastmoney_industry_reports(industry_code: str = "*", max_pages: int = 5, | CODE |
| LOW | SKILL.md | 2426 | def _save_northbound_snapshot(date: str, hgt: float, sgt: float): | CODE |
| LOW | SKILL.md | 2527 | def eastmoney_fund_flow_minute(code: str) -> list[dict]: | CODE |
| LOW | SKILL.md | 3951 | def baostock_valuation_history(code: str, start_date: str, end_date: str) -> pd.DataFrame: | CODE |
| LOW⚡ | tests/test_v39_sources.py | 313 | def test_network_and_http_errors_become_runtime_errors(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 321 | def test_allowed_status_is_returned_for_caller_to_judge(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 326 | def test_non_json_is_runtime_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 330 | def test_unrecognised_source_values_are_runtime_errors(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 497 | def test_recent_package_without_bse_files_is_an_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 504 | def test_missing_shanghai_or_shenzhen_is_an_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 508 | def test_market_files_present_but_empty_is_an_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 513 | def test_bad_name_bytes_or_blank_name_is_an_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 617 | def test_network_error_fails_over_to_next_host(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 624 | def test_all_hosts_empty_raises(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 629 | def test_unparseable_row_is_runtime_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 634 | def test_window_without_period_key_is_an_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 687 | def test_non_positive_adjusted_price_rejected(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 692 | def test_non_dict_payload_tries_every_host(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 699 | def test_minute_payload_without_period_list_is_runtime_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 707 | def test_bool_nan_or_blank_price_is_runtime_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 808 | def test_sort_count_mismatch_rejected_before_network(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 818 | def test_partial_pagination_raises(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 828 | def test_empty_first_page_of_many_or_changed_page_count_raises(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 838 | def test_short_page_or_count_mismatch_raises(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 863 | def test_transport_errors_are_runtime_not_value_errors(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 871 | def test_malformed_structure_is_runtime_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 879 | def test_pagination_stops_at_last_page(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 1066 | def test_complete_pages_match_record_count(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 1070 | def test_unparsable_shares_is_an_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 1078 | def test_empty_page_or_count_mismatch_raises(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 1086 | def test_snapshot_changing_between_pages_raises(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 1096 | def test_missing_snapshot_date_is_a_source_error(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 1104 | def test_paging_fields_must_be_real_counts(self): | CODE |
| LOW⚡ | tests/test_v39_sources.py | 1113 | def test_malformed_top_level_is_runtime_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 159 | def test_marker_blocks_in_order_and_all_endpoints_defined(self): | CODE |
| LOW | tests/test_v39_sources.py | 166 | def test_every_new_endpoint_is_in_route_table(self): | CODE |
| LOW | tests/test_v39_sources.py | 182 | def test_every_new_endpoint_is_wrapped(self): | CODE |
| LOW | tests/test_v39_sources.py | 187 | def test_missing_row_field_becomes_runtime_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 207 | def test_three_tenors_are_required(self): | CODE |
| LOW | tests/test_v39_sources.py | 223 | def test_joinquant_suffix_accepted(self): | CODE |
| LOW | tests/test_v39_sources.py | 238 | def test_bad_suffix_still_rejected(self): | CODE |
| LOW | tests/test_v39_sources.py | 255 | def test_check_argument_validated_before_network(self): | CODE |
| LOW | tests/test_v39_sources.py | 260 | def test_finance_check_does_not_touch_bars(self): | CODE |
| LOW | tests/test_v39_sources.py | 286 | def test_bars_dead_finance_alive(self): | CODE |
| LOW | tests/test_v39_sources.py | 359 | def test_malformed_payload_is_runtime_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 373 | def test_channels_must_be_a_list_of_labels(self): | CODE |
| LOW | tests/test_v39_sources.py | 384 | def test_zero_values_kept_blank_values_missing(self): | CODE |
| LOW | tests/test_v39_sources.py | 395 | def test_source_importance_must_be_one_to_four(self): | CODE |
| LOW | tests/test_v39_sources.py | 406 | def test_importance_and_country_filters_are_checked(self): | CODE |
| LOW | tests/test_v39_sources.py | 428 | def test_empty_full_past_week_is_an_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 434 | def test_window_returning_other_dates_raises(self): | CODE |
| LOW | tests/test_v39_sources.py | 463 | def test_malformed_items_are_runtime_errors(self): | CODE |
| LOW | tests/test_v39_sources.py | 469 | def test_empty_single_day_or_far_future_is_no_data(self): | CODE |
| LOW | tests/test_v39_sources.py | 485 | def test_parses_all_three_markets(self): | CODE |
| LOW | tests/test_v39_sources.py | 526 | def test_each_market_below_its_floor_is_an_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 533 | def test_duplicate_code_blank_code_or_seq_is_an_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 556 | def test_non_digit_code_or_non_finite_value_is_an_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 590 | def test_corrupt_zip_is_runtime_error(self): | CODE |
| LOW | tests/test_v39_sources.py | 606 | def test_empty_response_fails_over_to_next_host(self): | CODE |
| LOW | tests/test_v39_sources.py | 651 | def test_unadjusted_key_and_empty_windows_are_fine(self): | CODE |
| 106 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | SKILL.md | 939 | def wrapper(*args, **kwargs): | CODE |
| MEDIUM | SKILL.md | 5577 | def _official_excel(response): | CODE |
| LOW | SKILL.md | 479 | except Exception: | CODE |
| LOW | SKILL.md | 508 | except Exception: | CODE |
| LOW | SKILL.md | 530 | except Exception: | CODE |
| LOW | SKILL.md | 537 | except Exception: | CODE |
| LOW | SKILL.md | 766 | except Exception: | CODE |
| LOW | SKILL.md | 834 | except Exception: | CODE |
| LOW | SKILL.md | 2489 | except Exception as e: | CODE |
| LOW | SKILL.md | 2554 | except Exception as e: | CODE |
| LOW | SKILL.md | 3168 | except Exception as e: | CODE |
| LOW | SKILL.md | 4245 | except Exception as e: | CODE |
| LOW | SKILL.md | 4340 | except Exception as e: | CODE |
| LOW | SKILL.md | 4423 | except Exception as e: | CODE |
| LOW | SKILL.md | 4650 | except Exception: return x | CODE |
| LOW | SKILL.md | 4668 | except Exception as e: | CODE |
| LOW | SKILL.md | 4746 | except Exception as e: | CODE |
| LOW | SKILL.md | 4779 | except Exception as e: | CODE |
| LOW | SKILL.md | 4809 | except Exception as e: | CODE |
| LOW | SKILL.md | 4829 | except Exception as e: | CODE |
| LOW | SKILL.md | 7080 | except Exception as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | SKILL.md | 749 | # ── 东财防封:全局节流 + 会话复用 ──────────────────────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | SKILL.md | 7087 | # Step 1: iwencai 多 query 语义搜索 | COMMENT |
| LOW | SKILL.md | 7104 | # Step 2: 东财补充同标的研报 + PDF | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_v39_sources.py | 931 | CODE | |
| LOW | tests/test_v39_sources.py | 1290 | CODE | |
| LOW | tests/test_v310_sources.py | 79 | CODE | |
| LOW | tests/test_v310_sources.py | 190 | CODE | |
| LOW | tests/test_v310_sources.py | 365 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | SKILL.md | 1881 | # === K线数据 === | COMMENT |