Skip to content

Wrap up A-share strategy research and gating#32

Merged
Pigbibi merged 1 commit into
mainfrom
codex/a-share-strategy-wrapup-20260705
Jul 5, 2026
Merged

Wrap up A-share strategy research and gating#32
Pigbibi merged 1 commit into
mainfrom
codex/a-share-strategy-wrapup-20260705

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Hardened A-share strategy gating and demoted weak live candidates
  • Added创业板/科创板 research scaffolds and diagnostics
  • Updated docs, tests, and candidate evaluation scripts

Verification

  • PYTHONPATH=src python3 -m pytest -q tests/test_cn_dividend_quality_snapshot.py tests/test_cn_chinext_growth_momentum_quality_snapshot.py tests/test_catalog.py tests/test_entrypoints.py tests/test_runtime_adapters.py tests/test_cn_equity_combo.py tests/test_industry_etf_rotation_presets.py tests/test_dual_track_allocator.py

@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@Pigbibi Pigbibi force-pushed the codex/a-share-strategy-wrapup-20260705 branch from 8e08d7c to 3cb6ca6 Compare July 5, 2026 12:57
@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@Pigbibi Pigbibi force-pushed the codex/a-share-strategy-wrapup-20260705 branch from 3cb6ca6 to 17fde7e Compare July 5, 2026 12:58
@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Co-Authored-By: Codex <noreply@openai.com>
@Pigbibi Pigbibi force-pushed the codex/a-share-strategy-wrapup-20260705 branch from 17fde7e to 377c1c6 Compare July 5, 2026 13:01
@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@Pigbibi Pigbibi merged commit 1bced05 into main Jul 5, 2026
3 checks passed
@Pigbibi Pigbibi deleted the codex/a-share-strategy-wrapup-20260705 branch July 5, 2026 13:07

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

"combo": _metrics_slice(combo_slice, pstart, pend),

P2 Badge Use the renamed blend series in period metrics

With the default simulation_mode='blend', this function now stores the combined return series in blend_slice, but the returned periods block still references the removed combo_slice. After the ETF and stock legs finish, building the payload raises NameError, so the combo research script cannot print or write results unless this reference is changed back to the actual blended series.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +145 to +152
& ~frame["is_st"]
& frame["adv20_cny"].ge(float(min_adv20_cny))
& frame["market_cap_cny"].ge(float(min_market_cap_cny))
& frame["revenue_yoy"].ge(float(min_revenue_yoy))
& frame["profit_yoy"].ge(float(min_profit_yoy))
& frame["mom_12_1"].ge(float(min_momentum))
& frame["list_days"].ge(int(min_list_days))
& frame[

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Filter suspended ChiNext names before ranking

The new ChiNext snapshot contract requires suspension_days_63 and the panel populates it, but the eligibility filter never applies it. Any recently suspended stock that otherwise passes liquidity, growth, and momentum thresholds remains rankable and can be selected, which makes the proxy backtest and generated targets tradability-inaccurate for those snapshots; the dividend snapshot path already excludes names with suspension days before scoring.

Useful? React with 👍 / 👎.



def run(*, start: str, end: str, target_vol: float = 0.50) -> dict[str, Any]:
market_history = _download_market_history(start, end)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Download warmup history before the reported window

This new proxy downloads data starting exactly at start, while run_proxy_backtest cannot emit a signal until DEFAULT_MIN_HISTORY_DAYS rows have elapsed. For the default start=2021-01-01, the first ~201 trading days included in full_sample and the 2021–2022 period are forced cash rather than strategy returns, so the research evidence is materially biased; fetch a pre-start warmup window and only slice metrics to the requested dates.

Useful? React with 👍 / 👎.

Comment on lines +295 to 297
"research_backtest_only_profiles": [
CN_INDUSTRY_ETF_ROTATION_AGGRESSIVE_PROFILE,
CN_INDEX_ETF_TACTICAL_ROTATION_PROFILE,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not label the live candidate as research-only

CN_INDUSTRY_ETF_ROTATION_AGGRESSIVE_PROFILE was promoted to catalog status live_candidate in this change, but the live-candidate evaluation payload still emits it under research_backtest_only_profiles. Consumers of this report will see the optional QMT target classified as research-only, which contradicts the catalog gating layer this script is supposed to summarize.

Useful? React with 👍 / 👎.

Comment on lines +145 to +149
return {
"revenue_yoy": 0.0,
"profit_yoy": 0.0,
"revenue_acceleration_2q": 0.0,
"roe_ttm": 0.0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat missing ChiNext financials as ineligible

When AkShare returns no financial rows for a ChiNext name, the panel writes zero growth/ROE values instead of missing values. Those zeros satisfy the strategy's default min_revenue_yoy=-5% and min_profit_yoy=-20% filters, and because earnings_positive is only a small bonus, a stock with no financial coverage can still be selected on momentum/liquidity, contrary to the design's requirement to exclude missing financial fields.

Useful? React with 👍 / 👎.

Comment on lines +221 to +225
growth_score * 0.50
+ momentum_score * 0.40
+ liquidity_score * 0.10
+ earnings_bonus
- risk_penalty * 0.05

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the quality factors in the ChiNext score

The final score for the new growth-momentum-quality selector only combines growth, momentum, liquidity, an earnings bonus, and volatility; it never uses the required quality columns such as roe_ttm, roe_stability_3y, or gross_margin_stability_3y. In snapshots where high-momentum names have weak quality, they rank the same as quality names, so the backtest and target weights do not actually evaluate the advertised quality sleeve.

Useful? React with 👍 / 👎.


import pandas as pd

from scripts.research_cn_dual_track_combo_proxy_backtest import (

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid importing snapshot-pipeline scripts during test collection

In the inspected CI workflow, dependencies install this package, pandas/pytest, and QuantPlatformKit, but not CnEquitySnapshotPipelines. Importing research_cn_dual_track_combo_proxy_backtest at test collection imports research_cn_dividend_quality_snapshot_proxy_backtest, whose top-level imports require cn_equity_snapshot_pipelines, so the new unit test fails before running unless that external repo happens to be checked out locally.

Useful? React with 👍 / 👎.

Comment on lines +117 to +118
if not positive_adv20.empty and float(positive_adv20.median()) < DEFAULT_ADV20_CNY_UNIT_SCALE_THRESHOLD:
frame["adv20_cny"] = frame["adv20_cny"] * DEFAULT_ADV20_CNY_UNIT_SCALE

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not infer ADV units from median size

When a snapshot is already expressed in CNY but covers a low-liquidity universe whose median positive adv20_cny is below 10m, this heuristic multiplies every ADV value by 10,000 before the liquidity floor is applied. That lets genuinely illiquid names pass the 30m CNY filter and changes scores/weights; the unit conversion should come from explicit snapshot metadata or source-specific normalization rather than the cross-sectional median.

Useful? React with 👍 / 👎.

Comment on lines +47 to +48
"benchmark_symbol": DEFAULT_BENCHMARK_SYMBOL,
"defensive_symbols": ("510300",),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enable the configured defensive leg

These presets are passed through industry_rotation.build_target_weights, where defensive_symbols are only considered when enable_benchmark_risk_off is true. Because none of the KCB presets set that flag, the listed 510300 defensive sleeve is inert and the research metrics are computed without the intended risk-off behavior.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant