SuperAPI AI Directory

sxsc-tushare-analysis

General & other

View repository

Updated 10-16 07:13

About this skill

Shanxi Securities Tushare Comprehensive Analysis Skill

This skill works with shanxi-securities-tushare data skill, adding on top of the data interfaces provided by the lattera multi-dimensional cross-analysis layer, integrating scattered indicators into a structured analysis report.

How It Works

Transform "help me analyze XX" into an executableinstrument identification → dimension loading → data retrieval → calculation → interpretation → reportprocess.

Important: This skill does not encapsulate data retrieval logic. When retrieving data, reference shanxi-securities-tushare/SKILL.md 's process specifications:

  1. First run python shanxi-securities-tushare/scripts/check_env.py to validate the environment,stop when the token is missing, and first prompt the user to configure it.
  2. Before calling an interface, you must check shanxi-securities-tushare/references/API接口对应表.md,do not write interfaces from memory。
  3. For data retrieval, refer to shanxi-securities-tushare/scripts/ the demo templates under it, and choose the SDK or HTTP method based on the environment validation result.

Quick Entry (default call)

This skill has encapsulated a unified Runner. After the Agent identifies the instrument type,directly call the corresponding entry, with no need to retrieve data one by one from the raw interfaces:

Instrument Type Module Default Entry Example
Stock analysis_runner.py stock_report(ts_code, end_date=None, dimensions=None) stock_report("600519.SH")
Fund (off-exchange .OF / on-exchange ETF .SH/.SZ) fund_analysis_runner.py fund_report(ts_code, end_date=None, dimensions=None) fund_report("110011.OF")
Index index_analysis_runner.py index_report(ts_code, end_date=None, dimensions=None) index_report("000300.SH")
Futures (main continuous contract) fut_analysis_runner.py fut_report(ts_code, end_date=None, dimensions=None) fut_report("SR.ZCE")
  • dimensions is an optional dimension whitelist; by default the Runner's built-in dimensions are used; pass it in to trim only when the user explicitly says "only look at valuation/technicals".
  • *_report() returns an HTML string(including ECharts charts, inlined in the corresponding dimension section); the Agent writes it to <ts_code>_report.html for persistence; open it directly in a browser.
  • The old entry stock_analyzer.py is still retained as a compatibility wrapper; new code should preferentially use analysis_runner.stock_report。
  • Each Runner has internally implemented dimension-level parallel data retrieval, with no need for the Agent to manually parallelize.

Core Workflow

Each analysis follows this order:

  1. Environment validation — run python shanxi-securities-tushare/scripts/check_env.py, confirm the token is available, and determine the mode (sdk/http).
  2. Instrument identification — parse the user's wording to determine the instrument type + ts_code. Determine it based on the code format or name search.
  3. Dimension loading — by default load the summary dimensions for that instrument type; when the user explicitly specifies (e.g., "only look at technicals" or "only look at valuation"), load only the specified dimensions to avoid insufficient permissions/quota and excessively long output. "Full fixed set" is the default upper limit and can be trimmed.
  4. Call the Runner for analysis — directly call the corresponding Runner's *_report() / *_analyze() entry; the Runner internally retrieves data in parallel according to the default dimensions, calculates, and generates structured results. If custom dimensions are needed, trim via the dimensions parameter.
  5. Comprehensive report — Output the HTML report according to the structured template (time-series charts are inlined in the respective dimension sections).

The report must be written to disk (mandatory): each analysis reportmustbe saved as an HTML file to the current project directory, with the filename <ts_code>_report.html(e.g. 600519.SH_report.html). The CLI already defaults to automatically saving to the current working directory and printing the save path; if called through the Python interface, *_report() returns an HTML string, then the Agent must write that string to the <ts_code>_report.html file under the project directory. Printing only to the terminal without writing to disk is prohibited. The report is standalone HTML (rendered via the ECharts CDN, requires an internet connection to open), and time-series dimensions automatically generate charts andinline them in the corresponding dimension section(e.g. candlesticks in "Market Trend", PE/PB in "Valuation Analysis"), while the remaining dimensions are tables.

Instrument identification rules

User expression Instrument type Description
600519.SH / 000001.SZ / 920575.BJ Stock Already in standard format, identified directly..BJ for the Beijing Stock Exchange
600519 / 000001 Stock completed as .SH/.SZ/.BJ(Shanghai 600/601/603/605/688, Shenzhen 000/001/002/003/300/301, Beijing Stock Exchange starting with 8)
"Moutai"/"Kweichow Moutai"/"Ping An" Stock call stock_basic fuzzy matching by name, taking stocks with listing status L
000300.SH / 399001.SZ Index Standard index code, suffix .SH/.SZ/.SI
"CSI 300"/"SSE 50" Index call index_basic matching by name
000001.OF / 110011.OF Fund Standard fund code, suffix .OF over-the-counter/.SZ on-exchange
"E Fund Blue Chip"/"China Merchants Liquor" Fund call fund_basic matching by name
RB2501.SHF / CU2403.SHF Futures Standard futures contract code
"Rebar"/"Shanghai Copper"/"Crude Oil" Futures call fut_basic matching by name to obtain the main contract

Disambiguation: when name matching returns multiple results (e.g. "Ping An" = Ping An Bank 000001.SZ / Ping An Insurance 601318.SH), prioritize by market capitalization and take the largest instrument, but the report must note "N results matched, by default analyzing the largest by market capitalization XX; if you need to analyze others, please specify the code".

The broad-matching trap in fund name matching (fund_basic is substring fuzzy matching): the name will match all funds containing that word, so when analyzing a single instrument the scope must be narrowed, otherwise a bunch of similar funds are pulled by mistake:

User expression Trap Correct handling
"ChiNext ETF" "ChiNext" will match 87 thematic ETFs/blended funds Use the exact code or filter by names containing "ChiNext ETF", and take only on-exchange ETFs (excluding LOFs/feeder funds)
"STAR 50" The full Tushare name is "SSE STAR Market 50 Constituent ETF"; names containing "STAR 50" may be other products Use names containing "STAR Market 50" or identify directly by code
"Gold ETF" May incorrectly match thematic products such as "Golden Industry Stock ETF" Name exactly contains "Golden ETF"
"CSI 300" There are dozens of funds whose names contain this term (on-exchange ETFs + off-exchange feeder funds + multiple tracking funds) First determine the target type (on-exchange/off-exchange), then narrow down by the fund type field

When name matching results > 1: first narrow down by fund type (on-exchange/off-exchange/feeder) and listing status; if still not unique, then apply the above "ambiguity disambiguation" rules, and note the number of matches and the final scope in the report.

Analysis dimensions (full set by default, trimmed as needed)

I. Stocks (11 dimensions by default)

Each dimension outputs:Descriptive sentence → data table → analysis and evaluation

# Dimension Data interface Key analysis indicators
1 Overview stock_basic、stock_company、fina_mainbz、namechange、new_share Company full name, industry (SW), listing date, registered location, number of employees, main business description;Main business composition(in the latest reporting period, by top three product revenue and their proportions), former names, recent IPO marker (IPO within the past 1 year with issue price/PE)
2 Market trend daily、daily_basic、adj_factor、index_daily(CSI 300 + industry index); weekly/monthly lines are resampled from daily lines (not separately fetched weekly/monthly) 20/60/250-day returns (based on adjusted prices), MA5/MA20/MA60,MACD/RSI/KDJ/Bollinger Bands, turnover rate, amplitude, volatility, period high/low;Benchmark comparison: calculate the same-caliber return, annualized volatility, maximum drawdown, and Sharpe ratio for the CSI 300 and the sector index to which it belongs, and compare them side by side with the target (to judge excess return and relative risk)
3 Valuation analysis daily_basic、index_dailybasic(industry),index_member(industry constituent stocks),dividend(dividends implemented in the past 3 years) PE(TTM), PB, PS(TTM), dividend yield, total market cap, float market cap, number of dividends in the past 3 years and cumulative dividend per share (cash_div_tax is on a pre-tax per-share basis);Comparison with industry averages(take index_classify to obtain the industry index code → index_member to obtain constituent stocks → take each one's daily_basic PE/PB, first winsorize_cross_section cross-sectional winsorization before calculating the mean/median, to avoid a single anomalous stock skewing the result);PE/PB dual-caliber percentile(5-year historical percentile + same-day same-industry cross-sectional percentile; when the two calibers diverge, the reason must be identified; for historical percentile use calc_percentile_rank, and before the cross-sectional mean use winsorize_cross_section for winsorization)
4 Financial quality fina_indicator、income、balancesheet、cashflow、forecast、express(earnings flash report),fina_audit(audit opinion),disclosure_date(disclosure schedule) ROE, gross margin, net margin, revenue/profit growth (YoY), debt-to-asset ratio, operating cash flow; earnings forecast type and change range;Piotroski F-Score (9-item quantitative score, ≥7 strong / ≤2 weak); earnings flash report (revenue/net profit YoY earlier than regular reports); audit opinion (non-standard unqualified → risk signal); scheduled disclosure date of the next financial report (event window)
5 Capital flows moneyflow、moneyflow_hsgt、block_trade、hsgt_top10(northbound top ten transactions),repurchase(buybacks),broker_recommend(brokerage golden stocks) Main net inflow over the past 5-20 days (note:net_mf_amount is full-caliber net inflow,buy_elg_amount - sell_elg_amount is the extra-large order caliber; the two directions may be opposite, so choose the caliber according to the analysis objective), changes in northbound holdings, block trade premium/discount and institutional buy/sell direction; number of appearances and net buying in the top ten active stocks of Shanghai-Hong Kong Stock Connect (net_amount unit: yuan), buyback amount over the past year (yuan, for cumulative snapshots take the latest implemented value, do not sum;proc are not counted if they are proposals/shareholders' meeting approvals), broker golden stock selections in the past 3 months (month must be queried by month and then filtered locally)
6 Shareholders/chips top10_holders、top10_floatholders、stk_holdernumber、stk_holdertrade、pledge_stat/pledge_detail(equity pledge),stk_managers/stk_rewards(management), concentration of top ten shareholders/circulating shareholders,time series analysis of shareholder count (chip concentration indicator), direction and proportion of major shareholder increases/decreases; equity pledge ratio (>30% is a relatively high risk signal); executive disclosure records (stk_managers actually does not return end_date and includes historical records; current scale is based on the number disclosed in the latest reporting period of stk_rewards ) and compensation/shareholding

Chip concentration analysis (time series of shareholder count)

The time series change in shareholder count is the core indicator for judging chip concentration/dispersion, and is more meaningful than a single-point value:

  • Decrease in shareholder count (consistent with the direction of chip concentration): increase in shares per capita. This is usually a signal that chips are tending to concentrate, but the change in number of households is only a correlation,one cannot directly assert main force accumulation; it needs to be cross-validated with trading, stock price movement, and shareholder structure.
  • Increase in shareholder count (consistent with the direction of chip dispersion): decrease in shares per capita. This is usually consistent with chips tending to disperse, but likewiseone cannot directly assert main force distribution; it needs to be validated with volume and price.
  • Analysis points:
    • Compare the change rate of shareholder count over the past 4 quarters to judge the trend direction
    • Cross-validate with stock price movement (all are correlation observations, not causal conclusions): continuous decrease in number of households + rising stock price = consistent with the characteristics of a chip lock-up situation; continuous decrease in number of households + falling stock price = consistent with the characteristics of the main force being trapped; continuous increase in number of households + rising stock price = consistent with the characteristics of retail investors taking over
    • Use the stk_holdernumber interface to obtain historical data, sort by end_date and then calculate the quarter-on-quarter change rate | 7 | Margin financing/leverage sentiment | margin_detail、margin_secs(margin trading eligible list) | Margin financing balance and change rate, securities lending balance, change in margin financing balance over the past 5 days; whether it is a margin trading eligible stock (when details are empty, used to distinguish "not a margin trading eligible stock" from "missing data") | | 8 | Market anomalies | limit_list_d、top_list、top_inst、stk_shock/stk_high_shock(abnormal fluctuations),stk_alert(key alerts),stk_limit(limit-up/limit-down prices),hm_detail/hm_list(hot money),suspend_d(suspension/resumption) | Recent limit-up/limit-down records, number of appearances on the dragon-tiger list, institutional net buy/sell; abnormal fluctuation/serious abnormal fluctuation records over the past year, exchange key alerts, latest trading day limit-up/limit-down prices, hot money listing details over the past 120 days (net_amount unit: yuan), suspension/resumption records over the past 60 days (suspend_type: S-suspension R-resumption) | | 9 | Share unlock pressure | share_float | Number and proportion of shares to be unlocked in the next 3 months | | 10 | Macro/market environment | index_daily(CSI 300),cn_cpi、cn_ppi、shibor_lpr、cn_gdp、cn_m(money supply),shibor、daily_info+sz_daily_info(market turnover statistics) | Recent market trend, CPI/PPI trend and direction, LPR interest rate level, GDP year-on-year, M1/M2 year-on-year and scissors gap, Shibor 3M, A-share total turnover and Shanghai market average PE (daily_info use SH_A sector,sz_daily_info use "stocks" sector;daily_info.amount unit: 100 million yuan,sz_daily_info.amount unit: yuan, to convert to 100 million yuan divide by /1e8) | | 11 | Risk warning | Summarize the above dimensions | Comprehensive risk rating: high/medium/low, list specific risk signals |

Factor-based insights: the momentum quality dimension of fund/index reports is implemented by scripts/factor_signals.py (QuantsPlaybook research report factors, pure time-series single-instrument calculation—does not depend on the full-market cross-section, factors are raw values not pure factors). The factor dimensions of stock reports (momentum quality/microstructure/behavioral finance) have all been removed due to insufficient interpretability; the functions are retained in factor_signals.py for future use;DimensionResult.insights fields and the "Factor Insights" rendering pipeline are retained.

II. Index (default 9 dimensions)

# Dimension Data interface Key analytical indicators
1 Overview index_basic Publisher, base period, base point, category, listing date
2 Market trend index_daily 20/60/250-day return, MA alignment, annualized volatility, maximum drawdown, Sharpe ratio;Benchmark comparison: calculate the same-caliber indicators for CSI 300 and compare side by side
3 Valuation index_dailybasic PE(TTM), PB historical percentile.Note:index_dailybasic does not cover STAR Market indices(such as STAR 50 000688.SH); for such indices, valuation is downgraded to aggregation estimation using constituent stocks' daily_basic (cross-sectional median + historical percentile), and the data source is annotated
4 Constituent weights index_weight Top ten weighted stocks and their weight proportions, supplemented with stock names (stock_basic batch query)
5 Industry distribution index_weight obtain constituent stocks + stock_basic look up industry Classify constituent stocks by Shenwan industry, count the number and proportion of each industry (proportion of top three industries)
6 Margin financing/market leverage margin(full-market margin financing summary) Total margin financing balance of the two markets, direction of change over the past year (250 trading days), leverage sentiment judgment
7 Comparison index_global Compare recent performance with similar indices/international indices.index_global 's ts_code has no dot prefix(such as DJI/SPX/IXIC/N225/HSI, not .DJI); the code format requires checking the references/国际指数.md documentation.Note:index_global returns data in descending order (latest first); before calculation you must .sort_values('trade_date'), otherwise the date direction obtained by iloc index lookup is reversed, causing the return direction to be wrong
8 Momentum quality (factor-based) index_daily High-quality momentum (r_60-3000σ²), amplitude-split momentum A/B (sum of ret on low/high amplitude days); source scripts/factor_signals.py, pure time-series single-instrument calculation
9 Risk warning Summarize the above dimensions Risk signals such as elevated volatility/deep drawdown/high valuation

III. Public funds (default 10 dimensions)

# Dimension Data interface Key analysis metrics
1 Overview fund_basic、fund_company(manager) Fund type, inception date, listing date, fund short name; manager information (fund_company No input returns all; filter locally by fund_basic.management name: short name/inception date/registered capital/chairman)
2 Net value trend fund_nav、fund_adj、fund_daily(on-exchange ETF) Returns for the past 1/3/6 months and past 1/3 years (based on adjusted net value);On-exchange ETFs must use fund_daily + apply_etf_adj adjusted(daily interface returns empty for ETFs, and unadjusted prices are severely distorted during share splits)
3 Performance metrics Calculated based on fund_nav/fund_daily calculation Annualized volatility, Sharpe ratio, maximum drawdown
4 Peer comparison fund_basic(filter same type),fund_daily/fund_nav(one by one), Peer ranking (percentile over the past 20/60/120/250 days); for ETFs, prefer comparing on-exchange funds with the same suffix, and prioritize earlier-listed ones by inception date
5 Fund manager fund_manager Start date of tenure, years of tenure
6 Holdings analysis fund_portfolio Top ten heavyweight stocks and their proportions (stk_mkv_ratio), supplemented with stock names; fields are symbol/mkv/stk_mkv_ratio(not name/ratio/market_val)
7 Scale changes fund_share Quarterly sampling (groupby quarter-end), share change trend over the past 4 quarters
8 Dividends fund_div Cumulative number of dividends, dividend amount; fields are ex_date/div_cash(not div_date)
9 Momentum quality (factorized) fund_daily+fund_adj(ETF)、fund_nav(off-exchange) High-quality momentum (r_60-3000σ²); ETFs additionally have amplitude-cut momentum A/B (OHLC full-column adjusted); the off-exchange sub-item is not applicable without OHLC
10 Risk warning Summarize the above dimensions Risk signals such as relatively deep drawdown/high volatility/share shrinkage

Share scope statement (must be written in the evaluation sentences for the scale change/peer comparison dimensions):fund_share.fd_share issingle fundshares. The same index often has on-exchange ETFs + off-exchange feeder funds + multiple tracking funds coexisting (e.g., dozens of funds with "CSI 300" in their names), and share/scale data are all on a single-fund basis and must not be expressed as "the combined total of all funds tracking the index." Evaluation sentences must specify whether it is "the single share class of fund XX" or "the combined on-exchange and off-exchange total," to avoid users misreading it as the overall scale of the index.

IV. Futures (7 dimensions by default)

# Dimension Data interface Key analysis metrics
1 Overview fut_basic Contract underlying, exchange, contract multiplier, minimum price fluctuation, trading unit, margin rate
2 Market trend fut_daily(main continuous contract such as JM.DCE/RB.SHF, not a specific contract) Price change over the past 20/60 days, settlement price trend, intraday amplitude, volatility
3 Position analysis fut_holding Open interest changes, volume/open interest ratio, long-short ratio of the top 20 members' positions
4 Main contract fut_mapping Main contract code, rollover date, basis (spot vs futures)
5 Warehouse receipt inventory fut_wsr Changes in registered warehouse receipts, inventory/consumption ratio
6 Settlement Parameters fut_settle Daily settlement price, delivery settlement price, margin adjustments
7 Risk Alert Summary of the above dimensions Risk signals such as elevated volatility / rollover gaps / abnormal positions

Interface Coverage Design Decisions(Interfaces available on the data side but not integrated into the report and the reasons, to avoid misjudging them as omissions):

  • Stocks weekly/monthly, indices index_weekly/index_monthly: weekly/monthly lines can both be obtained by resampling daily lines, and are not fetched separately.
  • shibor_quote(quote line details),hibor/libor(offshore interest rates),wz_index(private lending rates): the signal is weak for single-underlying reports, so they are not integrated; they can be expanded later if cross-market interest rate environment analysis is needed.
  • index_member_all: duplicates the industry matching capability of index_weight + stock_basic , so it is not integrated.
  • index_classify/index_member It is consumed by the stock report's "valuation-industry comparison" dimension, and the index report does not integrate it again.

Report Structure

Each analysis report is output as an independent HTML file (opened directly in a browser, with time series charts inlined within each dimension section). The content structure is as follows, with each dimension following the format of meaning quote block → descriptive sentence → data table → analysis evaluation (the meaning quote block is a one-sentence dimension explanation for non-professional readers), and an overall analysis evaluation is appended at the end (including comprehensive factor scores, three-dimensional factor positioning, and risk budget reference):

# 标的名称 全景研究报告

> 数据日期:YYYY-MM-DD(Tushare 数据为 T-1 日)

## 1. 概况
描述句(如:银行ETF,华宝基金发行,跟踪中证银行指数,规模居同类前列)
- 关键指标汇总表

## 2. 行情趋势
描述句(近20日涨跌幅、波动率、回撤等核心指标概述)
- 涨跌幅对比表(标的 vs 沪深300并列)
- 风控指标对比表(波动率/回撤/夏普 vs 基准)
- 技术指标表(MACD/RSI/KDJ/布林带合并一张表)
- 进阶量化指标(Beta/Alpha/Sortino/滚动Beta/RS/VaR等)
- **分析评价**:对本维度数据的解读,包含明确的投资参考含义

## 3. 估值分析
描述句(PE/PB/历史分位等概述)
- 估值指标表
- 行业截面估值对比表(如适用)
- **分析评价**:(如"PE历史分位23.7%偏低,PB低于行业中位数,估值需结合业绩增速判断")

## N. 风险提示
- 风险信号 1
- 风险信号 2
- 数据缺失说明(如有维度失败)

## N+1. 整体分析评价
**综合判断**:一句话定位标的特征标签(如"低估值、防御型、高股息")
- 分维度要点列表(趋势/估值/财务/资金/筹码/杠杆/宏观各一行)
**风格定位**:标的属于什么风格型资产
**结论**:综合各维度给出投资参考含义和适用场景

---
*本报告由AI基于山西证券Tushare平台数据自动生成,基于 T-1 日历史数据,仅供技术交流与学习参考,不构成任何投资建议或财务指导。*

The analysis evaluation for each dimension must include a methodology statement and historical comparison (such as "valuation is at a historical low, and this range historically corresponds to samples with a relatively high medium- to long-term win rate"), all using descriptive language such as "indicates/reflects/is consistent with... characteristics," andmust not contain operational guidance(such as caution/attention/recommendation/suitable/needs attention).

This report is automatically generated by AI based on data from the Shanxi Securities Tushare platform, based on T-1 historical data, and is for technical exchange and learning reference only. It does not constitute any investment advice or financial guidance.


多列数据示例(列数必须对齐,如份额一栏拆成两列):

| 标的 | 最新份额 | 份额变化 |
|------|---------|---------|
| 沪深300ETF | 248亿份 | -0.1% |

每维度分析评价必须包含口径说明与历史对照(如"估值处于历史低位,历史上该区间对应较高的中长期胜率样本"),全部使用"表明/反映/与…特征相符"等描述性语言,**不得包含操作指引**(如警惕/注意/建议/适合/需关注)。

**报告表格约束**:每个 markdown 表格的表头行与数据行的列数必须一致。如果一列有多项数据(如"份额 + 变化率"),要么拆成两列分别填入,要么合并到一列中并调整表头,避免出现空列。
**表格合并建议**:同一维度内的数据优先合并为一张表(如涨跌幅 + 风控指标 + 技术指标合并),避免拆成多个独立表格造成视觉割裂。若列数过多导致横向过长,可分组但需紧邻排列。

## 关键默认值

| 模糊中文 | 默认口径 |
|---------|---------|
| "最近"/"近期" | 近 20 个交易日 |
| "最近三个月" | 近 60 个交易日 |
| "今年" | 当年 1 月 1 日至今 |
| "历史"(股票/指数) | 近 3 年 |
| "历史"(基金) | 成立以来 |
| 证券代码 | 标准 `600519.SH` 格式 |
| 基金代码 | 场外 `.OF`,场内 `.SZ`/`.SH` |
| 期货代码 | 标准 `RB2501.SHF` 格式 |
| 行业分类 | 申万 2021 版 |
| 对比基准(股票) | 所属申万一级行业均值 |
| 对比基准(基金) | 同类基金(同类型+同投资方向) |
| 对比基准(指数) | 沪深 300(000300.SH) |

> **数据充分性**:取数时按最大周期(如"近 250 日")再往前多取 30 个交易日,确保有足够数据计算。寒武纪从 20250801 到 20260812 仅 249 个交易日,不足以计算近 250 日涨跌幅,此时应前移起始日期(如 `start_date = '20250601'`)获取更多数据,或降级为"近 120 日"并标注"数据不足"。
> **数据不足时的报告处理**:若某标的上市不足请求周期(如具体期货合约仅 197 日不足 250 日),则:
> 1. **优先改用主力连续合约**(期货场景)或前移 start_date(股票场景)补充数据
> 2. 若仍不足,计算自上市以来的全长收益率,标注为"数据不足(仅 N 日,自上市 X%)"
> 3. 不可直接显示 N/A——用户无法判断是数据问题还是计算结果问题

## 量化分析方法

### 纵向对比(单标的时间序列)

单标的历史走势分析必须消除除权除息(送股/转增/分红/配股)导致的价格跳变,否则区间收益率和技术指标会失真。

- **股票复权**:`daily` 返回的是**未复权**数据(含除权除息跳变),趋势/收益率/技术指标计算前**必须复权**,否则除权日会产生虚假跳空。取 `adj_factor` 自行计算:
  - 后复权价 = 原始价 × 当日复权因子(`apply_adj_factor` 一并复权 open/high/low/close/pre_close,`*_post` 列同 scale,可安全用于 OHLC 类指标如 KDJ/布林带)
  - 前复权价 = 原始价 × 当日复权因子 / 最新复权因子
  - 长期收益率、定投收益、回撤、技术指标均应基于复权价;⚠️ 切勿用 `close_post` 配合未复权的 `high/low`——scale 不一致会令 KDJ 等指标失真
- **基金复权**:`fund_nav` 返回单位净值和累计净值。计算区间收益率时用 `fund_adj` 复权因子构建复权净值序列,消除分红除权影响:
  - 复权净值 = 单位净值 × 当日复权因子 / 最新复权因子
  - 夏普、最大回撤、Calmar 等指标均基于复权净值序列计算
- **ETF 复权**:`fund_daily` 返回的是不复权价,`apply_etf_adj`(`fund_adj` 因子)产出 `close_post`。**ETF 的 `fund_adj` 因子口径与股票 `adj_factor` 不同(实测方向/量级不统一,如 510500 ~0.34、512100 ~0.373、510300 ~1.27),`close_post` 绝对值非后复权价,仅供收益/夏普/回撤等 scale-invariant 计算(全程同列 pct_change 与因子绝对值无关);展示价用未复权 `close`。** 股票 `adj_factor` 则是标准后复权因子(单调递增,`后复权价=原始价×adj_factor`,可展示)。`apply_*_adj` 返回 trade_date/nav_date 索引的 df,可直接喂给 `rebase_series`/`compare_returns`(二者校验日期索引,传整数索引会抛 TypeError)。
  - **函数选型**:`apply_etf_adj` **只复权 close**(产出 close_post,供收益/夏普/回撤);KDJ/布林带等需 high/low/close 同 scale 的 OHLC 类指标,**改用 `apply_adj_factor`**(它复权全部 open/high/low/close/pre_close,`*_post` 列同 scale,fund_daily 同样适用)。误用 `apply_etf_adj` 喂 KDJ 会因 high_post/low_post 不存在而 KeyError。
- **基金规模取数**:`fund_nav.total_netasset` 是季报口径(稀疏,多为 NaN),仅作季度规模快照;需连续日度规模时用 `fund_share.fd_share`(万份)× `fund_nav.unit_nav` 计算:`规模亿元 = fd_share × unit_nav / 1e4`(先按 trade_date 对齐)。`fund_nav` 同 nav_date 可能有重复行,使用前按 nav_date 去重。
- **期货连续合约**:期货存在换月跳空,纵向分析时用 `fut_mapping` 识别主力合约区间,跨主力合约的连续走势需拼接或用 `fut_daily` 按合约分段分析,不得简单拼接。

### 横向对比(多标的归一化)

多标的横向对比时,不同标的价格量纲不同(如茅台 1500 元 vs 农业银行 4 元),直接比较价格序列无意义,必须归一化。

- **序列归一化(rebase)**:将各标的复权价格序列统一缩放到基准日 = 100,公式:`归一化净值 = 当日复权价 / 基准日复权价 × 100`。基准日取对比区间起点,使得所有标的从同一起跑线出发。
- **收益率对比**:计算各标的同期收益率(近 1 月/3 月/6 月/1 年/YTD),放同一张表横向排序。
- **估值分位数对比**:不同标的 PE/PB 不可直接比绝对值(行业属性不同),应转换为各自近 5 年历史分位数,再横排对比。跨标的截面均值/分位计算前,对截面值先 `winsorize_cross_section` 去极值(MAD 3σ)或直接取截面中位数,避免单只异常股拉偏;估值优先给"历史分位 + 同业截面分位"双口径。
- **财务指标对比**:ROE、毛利率等已是比率指标,可直接横排;营收/利润等绝对值指标应转换为增速(YoY/QoQ)或人均值后再对比。
- **波动率/回撤对比**:年化波动率、最大回撤本身量纲统一,可直接横排;但夏普比率等需确认无风险利率口径一致。

### 进阶量化指标

在基础指标之上,以下方法用于提升分析的深度与科学性:

- **技术指标**:MACD(趋势动能/金叉死叉)、RSI(超买>70/超卖<30)、KDJ(随机指标)、布林带(波动区间/触及上下轨)。MA 单独不足以判断买卖时机,技术指标组合可提供更丰富的信号。
- **历史分位数**:当前 PE/PB 等估值指标在近 5 年历史序列中的百分位排名(`percentile_rank`)。85 分位 = 当前估值高于历史 85% 的时间 → 偏高。
- **Sortino 比率**:夏普的改进版,分母仅用下行波动(仅亏损日的波动率),对不对称收益分布更合理。适合评估基金下行风险控制能力。
- **信息比率(IR)**:超额收益年化 / 跟踪误差年化。衡量基金经理主动选股能力,IR > 0.5 为优秀。
- **Piotroski F-Score**:9 项财务健康量化打分——盈利能力(ROA>0、经营现金流>0、ΔROA>0、经营现金流>净利润)、杠杆/流动/融资(Δ资产负债率≤0、Δ流动比率>0、未新增股本)、运营效率(Δ毛利率>0、Δ总资产周转率>0),总分 0-9,≥7 为强,≤2 为弱。按年报(end_date 1231)去重后取最近 2 期同比,数据来自 `fina_indicator`/`income`/`cashflow`/`balancesheet`(可选)。
- **量价分析**:OBV(能量潮,价升量增=趋势健康)、量比(当日量/近 5 日均量,>2 放量/<0.5 缩量)、量价背离(价升量缩=顶部信号/价跌量缩=底部信号)。
- **Beta/Alpha 归因**:CAPM 回归分解,Beta = 个股对市场的敏感度(>1.2 高弹性/<0.8 防御型),Alpha = 扣除市场收益后的超额收益年化。需取个股与沪深 300 同期日收益率对齐回归。

### 风险建模与分布分析

- **VaR/CVaR(在险价值)**:历史法计算 95%/99% 置信水平的最大日亏损。VaR = 损失分位数,CVaR = 超过 VaR 的平均损失(更保守)。是风险管理的国际标准指标。
- **尾部风险(偏度/峰度)**:偏度 < 0 = 左偏(亏损侧尾部更长,崩盘风险大);峰度 > 0(超额)= 厚尾(极端事件概率高于正态假设)。两者结合可判断收益分布是否偏离正态。
- **回撤深度分析**:在最大回撤之外,补充回撤持续期(水下天数)、痛苦指数(平均回撤深度),衡量"被套牢"的实际体感。
- **Amihud 非流动性**:|日收益率| / 日成交额,衡量单位资金引起的价格变动。值大 = 流动性差,大资金进出成本高。

### 滚动分析与动态监控

- **滚动 Beta**:60 日滚动窗口计算 Beta 变化趋势,展示市场敏感度随时间演变(上升 = 波动加大或防御减弱)。
- **滚动夏普**:60 日滚动窗口的风险调整收益趋势,比单点夏普更能反映稳定性。
- **相对强度(RS)**:标的累计收益 / 基准累计收益,RS > 1 跑赢、< 1 跑输,趋势走强 = 相对优势扩大。

### 统计检验方法

- **Z-Score 标准化**:将指标转为与群体均值的标准差倍数。|Z| > 1.96 = 在 5% 显著性水平下显著偏离。用于跨标的估值/财务指标对比。
- **事件研究法**:估计窗口(事件前 30 日)用市场模型回归估算正常收益,事件窗口(后 10 日)计算异常收益 AR 与累计异常收益 CAR。CAR > 2% = 事件正向显著。适用于财报发布、解禁、增减持等事件冲击分析。
- **CAGR(复合年化增长率)**:基于持有天数精确年化,比简单区间收益率更适合跨周期对比。

## 分析原则

1. **结论先行**:每个维度先写结论句,再给数据,不要只列数据让用户自己判断。
2. **交叉验证**:单一维度信号不充分时,结合多个维度交叉判断(如"资金面流入但估值已高")。
3. **数据时效**:Tushare 数据为 T-1 日,报告顶部注明数据日期。
4. **风险汇总独立成节**:**风险提示必须在报告末尾单独一节**,清晰列出。"前置"指分析过程中随时收集风险信号、最终在末尾汇总呈现,二者不矛盾。
5. **不替用户决策**:分析结论用"表明""反映""风险信号"等描述性语言,不用"建议买入/卖出"。
6. **空结果处理**:空结果不一定是失败——可能是非交易日/标未上市/参数错误/权限不足。区分清楚再下结论。

## 维度状态与部分失败策略

每个维度执行后必须标注以下四态之一,并在报告中体现:

| 状态 | 含义 | 处理 |
|------|------|------|
| `success` | 取数 + 计算均成功 | 正常输出结论与数据表 |
| `empty` | 接口返回空(非交易日/标的未覆盖/无业务) | 该维度标注"无数据(原因)"并跳过,不阻断报告 |
| `permission_denied` | 接口提示无权限/配额不足 | 该维度标注"权限不足",跳过并提示用户,不伪造数据,不终止整份报告 |
| `insufficient_history` | 历史数据不足请求周期 | 降级为可用区间(如近 120 日)并标注"数据不足(仅 N 日)",不直接显示 N/A |

**部分失败原则**:单个维度失败不终止整份报告——已成功的维度照常输出,失败维度按上表降级或跳过,并在"整体分析评价"中说明哪些维度缺失及对结论可信度的影响。仅当核心维度(行情趋势/估值)全部失败时才终止并提示用户。

## 分析反模式(禁止)

- **前视偏差(look-ahead bias)**:计算任何时点指标时,只能用该时点及之前的数据;禁止用未来期财报/未来价格反推当前结论。
- **幸存者偏差**:回看历史表现时,不得只统计仍上市标的,忽略已退市/停牌标的;对比同类时需说明样本是否含退市。
- **报告发布日期泄露**:财报有 `ann_date`(公告日)与 `end_date`(报告期)之别;时点对齐必须用 `ann_date`(公告后才可用),禁止用 `end_date` 当作可用日,否则会"提前"看到未公布的财报。
- **过期业绩预告当最新**:`forecast` 返回该公司**所有历史预告**(按 `ann_date` 窗口筛选),若此后未再发新预告,最新一条可能已很旧。展示必须标注**报告期 + 公告日**;距公告日超 150 天未更新须标注"可能已过期",且不得用它驱动当前的风险/结论信号。
- **基准选择偏差**:对比基准须与标的口径匹配(股票对所属申万一级、指数对沪深 300、基金对同类),不得随意选有利基准美化结论。
- **相关性当因果**:户数变化、资金流向、技术信号与涨跌仅为相关性,禁止表述为"主力在吸筹/派发""必然上涨/下跌"等因果结论。


## 接口调用规则

- 每次调用前必须查 `shanxi-securities-tushare/references/API接口对应表.md` 确认接口名和文档路径。
- 环境校验走 `python shanxi-securities-tushare/scripts/check_env.py`。
- 取数统一走 `sxsc-tushare-analysis/scripts/data_api.py` 的 `DataAPI` 类(SDK/HTTP 双模式自动选择,内置 T-0 占位行过滤、安全调用)。
  - 各 Runner 通过 `DataAPI` 实例调用接口,如 `api.get_daily(ts_code, start, end)`。
  - 日期推算用 `data_api.shift_date(end_date, -n_days)` 回溯交易日。
- 分析计算参考 `sxsc-tushare-analysis/scripts/` 下按方法分模块的参考模板:
  - `basic_metrics.py` — 收益率/MA/波动率/回撤/夏普/Sortino/IR/财务趋势/风险信号
  - `adjustment.py` — 复权处理/序列归一化/收益率对比/历史分位数/`winsorize_cross_section`(截面去极值)
  - `technical_indicators.py` — MACD/RSI/KDJ/布林带/OBV/量比
  - `risk_modeling.py` — VaR/CVaR/尾部风险/回撤深度/Amihud/滚动Beta/滚动夏普/RS
  - `attribution.py` — CAPM Beta-Alpha/Piotroski F-Score/事件研究法
  - `composite.py` — 跨维度组合分析:技术共振/量价模式/多因子综合评分/三维定位/业绩拐点/配对相对价值/风险预算/筹码-股价交叉
- **字段单位注意**:各接口字段单位不同,取数后必须确认字段含义与单位再计算。常见单位差异:
  - `moneyflow` 的 `*_amount` 字段单位为**万元**,换算亿元需 `/1e4`
  - `daily` 的 `amount` 字段单位为**千元**(即元×1000),换算亿元需 `/1e5`
  - `daily_basic` 的 `total_mv` 字段单位为**万元**,换算亿元需 `/1e4`
  - `margin_detail` 的 `rzye` 字段单位为**元**,换算亿元需 `/1e8`
  - `hm_detail` 的 `net_amount` 单位为**元**;`hsgt_top10` 的 `net_amount` 单位为**元**
  - `repurchase` 的 `amount` 单位为**元**(**非万元**),且同一回购计划的多条公告为**累计快照**(`vol`/`amount` 随 `ann_date` 单调递增,增量÷增量股数落在当日 `high_limit`/`low_limit` 区间内)——**取最新一条已实施记录的 `amount` 作为累计已回购金额,禁止对多条记录求和**;`proc` 为「预案」「股东大会通过」的属未实施计划,不计入已回购金额。接口无 ts_code 入参,按公告日期区间取全市场后本地过滤
  - `daily_info` 的 `amount` 单位为**亿元**;`sz_daily_info` 的 `amount` 单位为**元**(换算亿元需 `/1e8`,两接口口径不同;板块口径:沪市 `SH_A`、深市 `股票`)
  - `dividend` 的 `cash_div_tax` 为**每股**分红(税前),非每10股口径;`div_proc` 需筛"实施"
  - `broker_recommend` 的 `month`(YYYYMM)为**必选**入参,按月循环查询后本地过滤标的
  - `daily_basic` 的 `turnover_rate` 为**百分比**(2.5=2.5%),参与因子乘法(如 CGO 换手率衰减加权)前必须 `/100` 转比例(factor_signals 内部已处理)
  - CGO 因子 VWAP = `amount`×1000 / (`vol`×100)(`amount` 单位千元、`vol` 手=100股,得元/股)

  - `fund_share` 的 `fd_share` 字段单位为**万份**,换算亿份需 `/1e4`
  - 其他接口以对应接口文档标注为准,不得猜单位
- **场内基金(ETF)特殊处理**:
  - 取数必须用 `fund_daily` 接口(`daily` 对 ETF 返回空)
  - 价格必须用 `apply_etf_adj` 复权(`fund_adj` 复权因子校正),否则份额拆分/分红会导致不复权价严重失真
  - 基金接口字段名与股票不同,**必须查文档确认**(如 `fund_manager` 字段是 `name` 非 `manager_name`,`fund_div` 字段是 `div_cash` 非 `div_amount`)
- **指数成分权重注意**:
  - `index_weight` 的入参是 `index_code`(非 ts_code),输出字段为 `trade_date`/`con_code`/`weight`,无 `con_name` 字段——需用 `con_code` 调 `stock_basic` 获取名称
  - `index_weight` 为**月度数据**(月末发布):取数需用**整月范围**(`start_date`=月初、`end_date`=月末),半月范围或未发布月份返回空;取最新一期权重:先按 `trade_date` 降序取最大日期,再按 `weight` 降序取前 N 行
- **期货接口注意**:
  - 上期所交易所代码是 `SHFE`(非 SHF),大商所是 `DCE`,郑商所 `CZCE`,中金所 `CFFEX`
  - **期货分析必须用主力连续合约**(`fut_basic` 的 `fut_type='2'`,合约代码如 `JM.DCE`/`RB.SHF`),而非具体合约(如 `JM2610.DCE`)。具体合约仅上市约 10 个月(~200 日),不足 250 个交易日;主力连续合约拼接了各时期主力合约,有足够历史数据,且消除换月跳空。
  - 主力合约查询:`fut_mapping` 可能返回空,需用 `fut_basic(exchange=..., fut_type='2')` 获取连续合约代码
  - `fut_holding` 仅覆盖大商所(DCE)合约,SHFE 螺纹钢等无持仓排名数据,需在报告中注明接口覆盖限制
- **北交所股票特殊处理**:
  - 代码后缀为 `.BJ`(如 `920575.BJ`),区别于沪深主板
  - `moneyflow`(个股资金流向)接口不覆盖北交所,资金面维度不可用,需在报告中注明
  - `margin_detail`(融资融券明细)接口对北交所股票通常无数据,两融维度不可用
  - 北交所股票流动性通常低于沪深主板,分析评价中需提示流动性风险
  - 其他接口(`daily`/`daily_basic`/`fina_indicator`/`stk_holdernumber` 等)正常可用
  - `fut_wsr` 用 `trade_date` + `symbol`(产品代码如 `JM`/`RB`),返回各仓库明细须按 `symbol` 汇总 `vol`;`ts_code` 参数无效
  - `fut_settle` 返回降序数据(最新在前),取最新行需 `iloc[0]`;最新交易日结算中时 settle/保证金率为 NaN,需 `dropna(subset=['settle'])` 取最近有值行
- **宏观/市场接口参数注意**(参数风格不统一,易错):
  - `cn_cpi`/`cn_ppi` 用 `start_m`/`end_m`(**月份 YYYYMM,非 start_date/end_date**);CPI 同比字段是 `nt_yoy`(非 nt_m),PPI 同比字段是 `ppi_yoy`(非 ppi)
  - `shibor_lpr` 用标准 `start_date`/`end_date`(与 cn_cpi/cn_ppi 不同,勿混用)
  - `margin`(全市场两融汇总)的交易所参数/字段是 `exchange_id`(非 `exchange`),`rzye` 单位为元
- **指数成分权重参数注意**:`index_weight` 的入参是 `index_code`(**非 ts_code**,传 ts_code 会报 "index_code required");输出字段为 `trade_date`/`con_code`/`weight`
- 日期格式统一 `YYYYMMDD`。
- **日期窗口口径(实测教训)**:`data_api.shift_date` 是**自然日**,不是交易日——"近 250 交易日"不能写 `-250`(实际只有约 166 交易日),"近 5 年"不能写 `-250*5`(约 3.4 年)。需要按交易日回溯时用 `data_api.shift_trade_days`;快速折算按 250 交易日 ≈ 365 自然日。
- 未来日期自动裁剪到最近可用日期并提示用户。
- **T-0 占位行处理**:Tushare 数据为 T-1,`end_date` 传当天时行情接口(`daily`/`fund_daily`/`index_daily` 等)会返回当天行但全字段为 NaN(T-0 数据未出)。取数后必须 `dropna(subset=['close'])` 去掉占位行,否则 `iloc[-1]` 取到 NaN 导致后续计算全错。
- **交易日计数**:"近 N 个交易日"需调 `trade_cal` 获取交易日历,按实际交易日回溯,不得按自然日估算。
- **数据排序规范**:所有 `pro.*` 接口均返回**降序**数据(最新在前),包括 `index_daily`、`daily`、`index_global`、`fut_settle` 等。**任何涉及 `iloc[-1]`(取最新)或区间涨跌幅的计算前,必须先 `.sort_values('trade_date')` 确认升序**,否则取到的日期方向相反,导致结论方向错误。取数函数(如 `get_daily_for_period`)已内置排序,但直接调用 `pro.*` 时必须自行处理。

## 边缘情况处理

- **ST/*ST 股票**:2026-07-06 起 ST 股涨跌停幅度已调整为 10%(与普通股一致),此前为 5%;分析涨跌停维度时需注意日期界限,`stk_limit` 返回的涨停价会体现对应时期的幅度。
- **次新股/上市不足 1 年**:历史数据不足 250 个交易日时,MA250、年化波动率等指标不可用或不稳定,应标注"数据不足"并降级为可用区间(如近 60 日)。
- **停复牌**:停牌期间价格序列出现断裂,`suspend_d` 接口可查停复牌记录;计算收益率/MA 时需跳过停牌日,不得用停牌前价格填充。
- **数据质量异常**:如 `fund_portfolio` 返回 ratio 全为 0(IPO 打新微量持仓等场景),应标注"数据异常"而非当作正常持仓分析。

## What this skill is NOT for

- 买卖建议、替代投资顾问
- 自动下单或交易执行
- 实时行情(仅 T-1 日数据)
- 回测引擎、组合优化系统的实现
- 公告/新闻/研报直连数据(应告知限制,建议改查价格异动、资金流等替代)
- 无 token / 无权限时伪造数据

## 依赖

- `shanxi-securities-tushare` 数据 skill(必须在本项目同级目录下)
- 环境变量 `SXSC_TUSHARE_TOKEN` 已配置
- `sxsc_tushare` 库或 HTTP 协议通道(按环境校验结果自动选择)