SuperAPI AI Directory

etf-analysis

Data & analytics

View repository

Updated 10-15 22:13

About this skill

ETF Analysis Skill

Positioning

ETFs (Exchange-Traded Funds) are a core tool for passive investing and asset allocation. This skill covers ETF product analysis, selection methodology, strategy application, characteristics of the Chinese market, and data-driven quantitative analysis methods, providing a complete framework for building ETF-based quantitative strategies and portfolios.


1. ETF Product Classification

1.1 Classification by Underlying Asset

Type Representative Products Characteristics
Broad-Based ETF CSI 300 ETF (510300), CSI 500 ETF (510500), ChiNext ETF (159915), STAR 50 ETF (588000) Best liquidity, lowest trading costs, suitable for core positions
Sector ETF Consumer ETF (159928), Healthcare ETF (512170), Semiconductor ETF (512480), Bank ETF (512800) Sector rotation tool, high position concentration
Thematic ETF New Energy ETF (516160), Carbon Neutrality ETF, Metaverse ETF Strong thematic speculation attributes, short lifecycle
Strategy ETF / Smart Beta Dividend ETF (510880), Low Volatility ETF, Quality ETF, Momentum ETF Clear factor exposure, fees usually slightly higher than broad-based
Commodity ETF Gold ETF (518880), Soybean Meal ETF (159985), Crude Oil ETF (162411) Backed by physical/futures, watch for roll yield loss
Bond ETF Treasury Bond ETF (511010), Credit Bond ETF, Convertible Bond ETF (511380) Interest rate sensitive, duration management is key
Cross-Border ETF (QDII) Nasdaq ETF (159632), S&P 500 ETF (513500), Nikkei 225 ETF (513880) Double exposure to currency risk + premium risk
Money Market ETF Hwabao Tianyi (511990), Yinhua Rili (511880) T+0 subscription/redemption, liquidity management tool

1.2 Structural Types

  • Ordinary ETF: Exchanged on-market, physical subscription/redemption (basket of stocks for shares), premium/discount automatically converges via arbitrage mechanism
  • LOF (Listed Open-Ended Fund): Tradable both on-market and off-market, same premium/discount arbitrage path but slightly less efficient
  • ETF Feeder Fund: ETF substitute purchased through off-market channels, T+1 subscription/redemption, no premium/discount, suitable for regular investment plans
  • Leveraged/Inverse ETF: Constant intraday leverage, decay effect when held long-term (see Section 3.4)

2. Core ETF Metrics

2.1 Tracking Error

The most core metric for measuring an ETF's ability to replicate its index.

日跟踪误差 = std(ETF日收益率 - 指数日收益率)
年化跟踪误差 = 日跟踪误差 × √252

Rating Standards (A-share Broad-Based ETF):

  • Excellent: annualized tracking error < 0.2%
  • Qualified: 0.2% ~ 0.5%
  • Poor: > 0.5%

Sources of Tracking Error:

  1. Management fees and custody fees (continuous drag, accrued daily)
  2. Dividend processing timing (delay in dividend reinvestment)
  3. Buy/sell impact when constituent stocks are included/excluded
  4. Cash position (temporary cash drag from subscriptions/redemptions)
  5. Handling of suspended stocks (using substitutes or cash substitutes)
  6. Index construction methodology (full replication vs sampling replication)

2.2 Information Ratio (IR)

IR = (ETF年化收益率 - 指数年化收益率) / 年化跟踪误差

For ETFs, IR is usually negative (due to fee drag); the closer the IR is to 0, the better.

2.3 Premium/Discount Rate

折溢价率 = (ETF市价 - ETF净值IOPV) / ETF净值IOPV × 100%
  • Premium: market price > NAV; arbitrageurs sell the ETF / subscribe a basket of stocks to exchange, and the premium converges
  • Discount: market price < NAV; arbitrageurs buy the ETF / redeem a basket of stocks, and the discount converges
  • Abnormal premium scenario: cross-border QDII ETFs (quota restrictions lead to sustained premiums), sector ETFs with a high proportion of suspended stocks

2.4 Liquidity Indicators

Indicator Meaning Reference threshold
Average daily turnover Ease of buying and selling Broad-based > 100 million, sector > 20 million
Bid-ask spread (Spread) Immediate trading cost < 0.05% is high quality
Order book depth Impact of a single large trade Cumulative 5 levels each on bid and ask > 5 million is preferable
Turnover rate Activity level Too low means high liquidity risk

2.5 Fee Structure

综合费率 = 管理费 + 托管费 + 指数使用费
(不含交易佣金、印花税、申赎费)

Long-term fee impact formula:

N年费率复利损耗 = (1 - 年费率)^N
例:年费率0.5% vs 0.15%,10年差距 ≈ 3.5%,20年差距 ≈ 6.8%

Comparison of fee rates of mainstream broad-based ETFs (2025):

  • China AMC/E Fund/Southern CSI 300 ETF: 0.15% (management) + 0.05% (custody) = 0.20%
  • Some small-scale broad-based ETFs: 0.5%+, significant disadvantage for long-term holding

2.6 Scale and Liquidity Assessment

  • Scale threshold:

    • < 200 million: relatively high liquidation risk, poor liquidity
    • 200 million to 1 billion: normal trading possible, large funds are constrained
    • 1 billion: sufficient liquidity, active market makers

    • 10 billion: flagship ETF, first choice for institutions

  • Liquidation risk signals: scale continues to decline, average daily scale < 50 million for 90 consecutive days


3. ETF Selection Methodology

3.1 Framework for Comparing ETFs of the Same Category

The same index often has multiple ETFs; selection steps:

Step 1: 规模筛选 → 剔除 < 5亿的小规模产品
Step 2: 费率比较 → 同等条件下选费率最低
Step 3: 跟踪误差 → 近1年/近3年双维度比较
Step 4: 流动性 → 日均成交额、买卖价差
Step 5: 基金公司 → 指数化投资能力、历史口碑

Quantitative scoring model:

def etf_score(etf_data: dict) -> float:
    """
    ETF 综合评分(越高越好,满分100)。

    Args:
        etf_data: 包含 scale, fee, tracking_error, avg_volume, spread 的字典

    Returns:
        综合评分 0~100
    """
    score = 0.0
    # 规模得分(30分)
    scale = etf_data['scale_billion']
    score += min(30, scale / 10 * 30)

    # 费率得分(25分):费率越低越高分
    fee = etf_data['total_fee_pct']  # 年费率百分比
    score += max(0, 25 - fee * 50)

    # 跟踪误差得分(30分):误差越小越高分
    te = etf_data['tracking_error_annual_pct']
    score += max(0, 30 - te * 60)

    # 流动性得分(15分)
    vol = etf_data['avg_daily_volume_million']
    score += min(15, vol / 10 * 15)

    return round(score, 2)

3.2 Quantitative Analysis of the Impact of Fees on Long-Term Returns

import numpy as np

def fee_drag_analysis(annual_return: float, years: int, fee_rates: list[float]) -> dict:
    """
    分析不同费率对长期收益的拖累效果。

    Args:
        annual_return: 指数年化收益率(小数,如0.08)
        years: 投资年限
        fee_rates: 待比较的费率列表(小数,如[0.002, 0.005, 0.015])

    Returns:
        各费率下的终值倍数和相对拖累字典
    """
    results = {}
    base_value = (1 + annual_return) ** years
    for fee in fee_rates:
        net_return = annual_return - fee
        end_value = (1 + net_return) ** years
        drag = (base_value - end_value) / base_value * 100
        results[f'{fee*100:.2f}%'] = {
            'end_value_multiple': round(end_value, 4),
            'drag_pct': round(drag, 2)
        }
    return results

# 示例:8% 指数收益,20年期
# fee_drag_analysis(0.08, 20, [0.002, 0.005, 0.015])

3.3 Market Maker Quality Assessment

High-quality market makers are reflected in:

  • Stable spreads: small spread widening during volatile periods (< 3 times normal level)
  • Sufficient depth: uniform amounts across order book levels
  • Quote continuity: does not frequently cancel and requote
  • Handling of large orders: spreads recover quickly after large trades

Evaluation methods:

# 通过Level2数据计算有效价差
effective_spread = (ask_price - bid_price) / mid_price * 100  # 单位 %

# 价格冲击成本(Impact Cost)
# 买入N万元所需均价相对于中间价的偏离
impact_cost = (avg_buy_price - mid_price) / mid_price * 100

3.4 Fund Company Strength Assessment

Dimension Evaluation points
ETF management scale Whole-market ranking, expertise in index investing
Tracking error history Stability over the long term (3 years+)
Product line completeness Breadth of coverage in broad-based, sector, and cross-border
Subscription and redemption efficiency T+0 in-kind subscription and redemption processing capability
Quality of market maker cooperation Stability of cooperation with leading brokerage market makers

Leading domestic ETF management companies (by scale): ChinaAMC, E Fund, Huatai-PineBridge, Southern, Harvest, Bosera


4. ETF Strategy Applications

4.1 Core-Satellite Strategy (Core-Satellite)

总组合 = 核心仓位(70~80%)+ 卫星仓位(20~30%)

核心仓位:宽基ETF(沪深300/中证500/全A)
  → 获取市场beta,低费率,长期持有,减少交易摩擦

卫星仓位:行业ETF/主题ETF/Smart Beta ETF
  → 增强收益,主动暴露特定因子,允许更高换手

Rebalancing Trigger Conditions:

  • Time trigger: quarterly/semi-annually
  • Deviation trigger: a single asset deviates from target weight > 5%

4.2 Sector Rotation ETF Strategy

Momentum rotation:

def sector_momentum_rotation(etf_returns: pd.DataFrame, lookback: int = 20, top_n: int = 3) -> list[str]:
    """
    基于动量的行业ETF轮动选择。

    Args:
        etf_returns: 各行业ETF日收益率 DataFrame,列为ETF代码
        lookback: 回看窗口(交易日数)
        top_n: 持有ETF数量

    Returns:
        本期持有的ETF代码列表
    """
    momentum = etf_returns.tail(lookback).sum()
    selected = momentum.nlargest(top_n).index.tolist()
    return selected

Macro cycle rotation:

Economic Cycle Recommended Sector ETFs
Recovery phase (low growth → high growth, low inflation) Consumer, Technology, Small/Mid-cap
Overheating phase (high growth, high inflation) Energy, Materials, Industrials
Stagflation phase (low growth, high inflation) Energy, Utilities, Consumer
Recession phase (high growth → low growth) Healthcare, Utilities, Bond ETFs

4.3 Smart Beta ETF Factor Exposure Analysis

Main factors and corresponding ETFs:

Factor Representative ETF Historical Effectiveness (A-shares)
Value (low valuation) CSI 300 Value ETF Moderate, affected by style rotation
Dividend (high dividend yield) Dividend ETF (510880) Strong, especially defensive in bear markets
Low Volatility CSI Low Volatility ETF Strong, Sharpe ratio superior to broad-based
Quality (high ROE) CSI Quality ETF Strong, good long-term compounding effect
Momentum Currently few A-share products Effective in short-to-medium term, mean reversion in long term
Small-cap CSI 1000 ETF (512100) Strong, but high liquidity risk

Factor Exposure Analysis Code:

import pandas as pd
import numpy as np
from scipy import stats

def factor_exposure_analysis(etf_returns: pd.Series, factor_returns: dict[str, pd.Series]) -> pd.DataFrame:
    """
    分析ETF对各因子的暴露程度(单因子回归)。

    Args:
        etf_returns: ETF日收益率序列
        factor_returns: 各因子收益率字典 {因子名: 收益率序列}

    Returns:
        包含 beta, t_stat, r_squared 的 DataFrame
    """
    results = []
    for factor_name, factor_ret in factor_returns.items():
        aligned = pd.concat([etf_returns, factor_ret], axis=1).dropna()
        x = aligned.iloc[:, 1].values
        y = aligned.iloc[:, 0].values
        slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)
        results.append({
            'factor': factor_name,
            'beta': round(slope, 4),
            't_stat': round(slope / std_err, 2),
            'r_squared': round(r_value ** 2, 4),
            'p_value': round(p_value, 4)
        })
    return pd.DataFrame(results).set_index('factor')

4.4 Decay Effect of Leveraged/Inverse ETFs

Beta Decay (Volatility Decay) Principle:

每日恒定杠杆 N 倍 → 复合效应导致长期收益 ≠ N × 指数收益

衰减量(近似)= N²(N-1)/2 × σ² × T
其中 σ 为指数日波动率,T 为持有天数

Numerical Example:

  • Index annualized volatility 20%, daily volatility ≈ 1.26%
  • 2x leveraged ETF, held for 1 year: decay loss ≈ 2² × (2-1)/2 × (0.2)² × 1 ≈ 4%

Applicable Scenarios:

  • Leveraged ETF: short-term tool in strong trend markets (holding < 1 month)
  • Inverse ETF: market hedging, short-term bearish bets (not suitable for long-term holding)
  • Strictly Prohibited: Using leveraged/inverse ETFs for long-term allocation positions

4.5 ETF Arbitrage Strategies

Premium/Discount Arbitrage(Requires physical creation/redemption qualification, typically threshold 1 million units):

溢价套利:
  ETF市价 > IOPV + 交易成本
  → 买入一篮子成分股 → 申购ETF份额 → 卖出ETF
  → 套利利润 ≈ 溢价率 - 冲击成本 - 佣金

折价套利:
  ETF市价 < IOPV - 交易成本
  → 买入ETF份额 → 赎回一篮子成分股 → 卖出成分股
  → 套利利润 ≈ 折价率 - 冲击成本 - 佣金

Cross-Market Arbitrage (ETF vs Futures):

IF(沪深300股指期货)基差 = 期货价格 - 沪深300指数
当基差 > 合理基差(无风险利率×剩余期限)时:
  → 卖期货 + 买ETF(正向套利)
当基差 < 合理基差时:
  → 买期货 + 卖ETF(反向套利,需融券)

Statistical Arbitrage (Pairs Trading):

# 同类ETF(如不同公司发行的沪深300ETF)之间的价差均值回归
# 价差 = 价格差 或 价格比
# 当价差偏离历史均值2个标准差时建仓,回归时平仓
spread = etf_a_price / etf_b_price
z_score = (spread - spread.rolling(60).mean()) / spread.rolling(60).std()
signal = pd.Series(0, index=z_score.index)
signal[z_score > 2] = -1   # ETF_A 相对贵,卖A买B
signal[z_score < -2] = 1   # ETF_A 相对便宜,买A卖B

5. Characteristics of China's ETF Market

5.1 On-Exchange ETF vs Off-Exchange Feeder Fund

Dimension On-Exchange ETF Off-Exchange Feeder Fund
Purchase Channel Securities account, real-time trading Bank/fund direct sales, T+1 subscription/redemption
Subscription/Redemption Method Physical creation/redemption (institutional) or secondary market (individual) Cash creation/redemption
Premium/discount Exists (has arbitrage mechanism) Does not exist
Minimum trading unit 100 units (about 10–100 yuan) Minimum investment of 1 yuan
Fees Relatively low (management fee + trading commission) Slightly higher (subscription fee + management fee)
Suitable scenarios Swing trading, large allocations Regular investment plans, small long-term holdings

5.2 Special considerations for cross-border ETFs (QDII)

Reasons for premium formation:

  • QDII quota limits: after the fund company's QDII quota is used up, subscriptions are suspended, and the arbitrage mechanism ceases to function
  • Exchange rate impact: when the renminbi depreciates, the net asset value of ETFs holding overseas assets rises, triggering chasing of gains
  • Time zone impact: when the A-share market closes, overseas markets have not yet opened, so the IOPV reference price lags

Premium rate warning lines:

  • < 2%: normal range, can be allocated normally
  • 2%–5%: premium is obvious, entry requires caution, wait for it to fall back
  • 5%: high premium, significant buying risk exists (net asset value falls while the premium narrows, a double hit)

Currency hedging:

  • Some QDII ETFs offer hedged versions (such as S&P 500 hedged ETFs)
  • Hedging cost ≈ China-US interest rate differential (about 1.5–2.5%/year in 2025), significantly reducing returns

5.3 Historical experience of LOFs and structured funds

LOF (Listed Open-Ended Fund):

  • Tradable both on and off the exchange; discount arbitrage path: buy at an on-exchange discount → transfer custody → redeem off-exchange
  • Custody transfer takes T+2 to T+3, with risk of net asset value changes

Structured funds (all fully transformed; historical reference before 2020):

  • Class A shares: agreed-return type, similar to bonds
  • Class B shares: leveraged type, linked to Class A's agreed return
  • Important lesson: the downward conversion mechanism caused large losses for Class B shares; high-premium arbitrage was squeezed out
  • Current status: regulators require all to be transformed into ordinary ETFs, with no new issuance

5.4 China's main ETF index systems

Broad-based indices:

Index Constituent stocks Characteristics
CSI 300 The 300 largest by market capitalization on the Shanghai and Shenzhen exchanges Large-cap blue chips, rich derivatives (IF futures/CSI 300 options)
CSI 500 Mid-cap stocks ranked 300–800 Mid-cap growth, complementary to the CSI 300
CSI 1000 Small-cap stocks ranked 800–1800 Small-cap factor, relatively high volatility
SSE 50 The 50 largest on the Shanghai Stock Exchange Ultra-large-cap, with high weightings in finance and real estate
ChiNext Index Top 100 on ChiNext Technology growth, high volatility
STAR 50 Top 50 on the STAR Market Hard technology, short time since listing
BSE 50 Top 50 on the Beijing Stock Exchange Emerging market, weak liquidity
CSI All Share / Wind All A Whole market The broadest benchmark

Index adjustment rules:

  • CSI 300/CSI 500: adjusted once each in June and December every year
  • Before/after adjustment: included stocks rise, excluded stocks fall (short term), providing event-driven opportunities

6. ETF Portfolio Construction

6.1 Implementation of ETF-Based Asset Allocation

Classic Allocation Frameworks (Implementable with ETFs):

股债 60/40 中国版:
  沪深300ETF 30% + 中证500ETF 20% + 中债ETF 40% + 黄金ETF 10%

全天候组合(中国版):
  股票ETF(沪深300)25%
  长期国债ETF        40%
  中期国债ETF        15%
  黄金ETF            7.5%
  商品ETF            12.5%

哑铃策略:
  宽基ETF(低风险核心)50%
  行业/主题ETF(高弹性进攻)50%

6.2 ETF Tool Selection for Global Allocation

A股:沪深300ETF 510300 / 中证500ETF 510500
美股:纳指ETF 159632 / 标普500ETF 513500
港股:恒生ETF 159920 / 恒生科技ETF 513130
欧洲:德国DAX ETF / 欧洲50ETF(规模较小)
日本:日经225ETF 513880 / 东证ETF
新兴:越南ETF / 印度ETF(部分有QDII溢价)

固定收益:
  国内:国债ETF 511010 / 政金债ETF
  美国:美债ETF(QDII)

商品:
  黄金ETF 518880
  原油ETF 162411
  CRB商品指数ETF(国内较少)

6.3 Trade-off Between Rebalancing Frequency and Trading Costs

Rebalancing Costs:

单次再平衡成本 ≈ 交易金额 × (佣金率 + 价差/2 + 冲击成本)
≈ 交易金额 × 0.05%~0.15%(宽基ETF)

年化再平衡成本 = 单次成本 × 年均调仓次数

Recommended Optimal Rebalancing Frequency:

  • Pure passive allocation (low volatility): twice a year (June/December)
  • Sector rotation (high volatility): monthly or quarterly
  • Threshold-triggered method: triggered when deviation from target weight > 5%, usually better than fixed frequency

Commission-Free Rebalancing Techniques:

  • Use new capital to top up underweight positions in a targeted manner, reducing sell operations
  • Allocate dividend income preferentially to underweight assets

6.4 Tax Efficiency Considerations

China ETF Tax Rules:

  • Individual Investors:
    • Capital gains on equity ETFs are tax-exempt (during holding period)
    • ETF dividends: cash dividends are tax-exempt, dividend reinvestment is not taxed
    • Money market ETF interest income: temporarily exempt from individual income tax
  • Institutional Investors:
    • Capital gains must be included in corporate income tax (25%)
    • Dividends during holding period: tax-exempt if held > 12 months

Tax Efficiency Strategies:

  • Place high-turnover sector rotation strategies in individual accounts as much as possible (leveraging capital gains tax exemption)
  • Regular fixed-amount long-term holding, reducing the frequency of realizing short-term capital gains

7. Data Analysis Methods

7.1 Using Tushare to Obtain ETF Data

import tushare as ts
import pandas as pd

def get_etf_list(pro: ts.pro_api) -> pd.DataFrame:
    """
    获取全市场ETF列表。

    Args:
        pro: tushare pro_api 实例

    Returns:
        ETF基本信息 DataFrame
    """
    df = pro.fund_basic(market='E', status='L')  # E=ETF, L=上市中
    return df[['ts_code', 'name', 'management', 'found_date', 'issue_date']]


def get_etf_nav(pro: ts.pro_api, ts_code: str, start_date: str, end_date: str) -> pd.DataFrame:
    """
    获取ETF净值数据(IOPV)。

    Args:
        pro: tushare pro_api 实例
        ts_code: ETF代码,如 '510300.SH'
        start_date: 开始日期 'YYYYMMDD'
        end_date: 结束日期 'YYYYMMDD'

    Returns:
        包含 trade_date, nav, accum_nav 的 DataFrame
    """
    df = pro.fund_nav(ts_code=ts_code, start_date=start_date, end_date=end_date)
    return df.sort_values('end_date').reset_index(drop=True)


def get_etf_daily(pro: ts.pro_api, ts_code: str, start_date: str, end_date: str) -> pd.DataFrame:
    """
    获取ETF场内日行情(市价)。

    Args:
        pro: tushare pro_api 实例
        ts_code: ETF代码
        start_date: 开始日期
        end_date: 结束日期

    Returns:
        包含 trade_date, open, high, low, close, vol, amount 的 DataFrame
    """
    df = pro.fund_daily(ts_code=ts_code, start_date=start_date, end_date=end_date)
    return df.sort_values('trade_date').reset_index(drop=True)


def get_index_daily(pro: ts.pro_api, index_code: str, start_date: str, end_date: str) -> pd.DataFrame:
    """
    获取基准指数日行情(用于计算跟踪误差)。

    Args:
        pro: tushare pro_api 实例
        index_code: 指数代码,如 '000300.SH'(沪深300)
        start_date: 开始日期
        end_date: 结束日期

    Returns:
        包含 trade_date, close 的 DataFrame
    """
    df = pro.index_daily(ts_code=index_code, start_date=start_date, end_date=end_date)
    return df[['trade_date', 'close', 'pct_chg']].sort_values('trade_date').reset_index(drop=True)

7.2 Tracking Error Calculation Code Template

import numpy as np
import pandas as pd


def calc_tracking_error(
    etf_prices: pd.Series,
    index_prices: pd.Series,
    annualize: bool = True
) -> dict:
    """
    计算ETF对标的指数的跟踪误差。

    Args:
        etf_prices: ETF净值序列(以date为索引)
        index_prices: 指数价格序列(以date为索引)
        annualize: 是否年化,默认True

    Returns:
        包含 tracking_error, avg_daily_diff, max_daily_diff 的字典
    """
    # 对齐数据
    aligned = pd.concat([etf_prices, index_prices], axis=1).dropna()
    aligned.columns = ['etf', 'index']

    # 计算日收益率差值
    etf_ret = aligned['etf'].pct_change().dropna()
    idx_ret = aligned['index'].pct_change().dropna()
    daily_diff = etf_ret - idx_ret

    # 跟踪误差 = 差值的标准差
    te_daily = daily_diff.std()
    te = te_daily * np.sqrt(252) if annualize else te_daily

    return {
        'tracking_error': round(te * 100, 4),       # 百分比
        'avg_daily_diff': round(daily_diff.mean() * 100, 4),  # 平均日偏差 %
        'max_daily_diff': round(daily_diff.abs().max() * 100, 4),  # 最大单日偏差 %
        'annualized': annualize
    }


def compare_etfs_same_index(
    etf_codes: list[str],
    index_code: str,
    pro,
    start_date: str,
    end_date: str
) -> pd.DataFrame:
    """
    比较追踪同一指数的多只ETF的跟踪表现。

    Args:
        etf_codes: ETF代码列表
        index_code: 基准指数代码
        pro: tushare pro_api 实例
        start_date: 开始日期
        end_date: 结束日期

    Returns:
        各ETF的跟踪误差比较 DataFrame
    """
    index_df = get_index_daily(pro, index_code, start_date, end_date)
    index_prices = index_df.set_index('trade_date')['close']

    results = []
    for code in etf_codes:
        nav_df = get_etf_nav(pro, code, start_date, end_date)
        etf_prices = nav_df.set_index('end_date')['nav']
        te_result = calc_tracking_error(etf_prices, index_prices)
        te_result['ts_code'] = code
        results.append(te_result)

    return pd.DataFrame(results).set_index('ts_code').sort_values('tracking_error')

7.3 Premium/Discount Rate Monitoring

def calc_premium_discount(
    market_price: float,
    iopv: float
) -> dict:
    """
    计算ETF折溢价率及套利信号。

    Args:
        market_price: ETF场内市价
        iopv: 实时净值(IOPV)

    Returns:
        包含 premium_pct, signal, arbitrage_feasible 的字典
    """
    premium_pct = (market_price - iopv) / iopv * 100

    if premium_pct > 0.3:
        signal = 'PREMIUM_HIGH'   # 溢价:卖出ETF或申购套利
        feasible = premium_pct > 0.5  # 扣除成本后是否可套利
    elif premium_pct < -0.3:
        signal = 'DISCOUNT_HIGH'  # 折价:买入ETF或赎回套利
        feasible = premium_pct < -0.5
    else:
        signal = 'NORMAL'
        feasible = False

    return {
        'premium_pct': round(premium_pct, 4),
        'signal': signal,
        'arbitrage_feasible': feasible
    }


def monitor_qdii_premium(pro, qdii_codes: list[str], date: str) -> pd.DataFrame:
    """
    监控QDII ETF溢价率(溢价过高时发出预警)。

    Args:
        pro: tushare pro_api 实例
        qdii_codes: QDII ETF代码列表
        date: 查询日期 'YYYYMMDD'

    Returns:
        各QDII ETF的溢价率和风险等级 DataFrame
    """
    results = []
    for code in qdii_codes:
        # 获取市价
        price_df = pro.fund_daily(ts_code=code, trade_date=date)
        # 获取净值
        nav_df = pro.fund_nav(ts_code=code, end_date=date)

        if not price_df.empty and not nav_df.empty:
            market_price = price_df.iloc[0]['close']
            nav = nav_df.iloc[0]['nav']
            premium_pct = (market_price - nav) / nav * 100
            risk_level = (
                'HIGH' if premium_pct > 5
                else 'MEDIUM' if premium_pct > 2
                else 'LOW'
            )
            results.append({
                'ts_code': code,
                'market_price': market_price,
                'nav': nav,
                'premium_pct': round(premium_pct, 2),
                'risk_level': risk_level
            })

    return pd.DataFrame(results).sort_values('premium_pct', ascending=False)

7.4 Capital Inflow and Outflow Analysis

def etf_fund_flow_analysis(
    pro,
    ts_code: str,
    start_date: str,
    end_date: str
) -> pd.DataFrame:
    """
    分析ETF规模变化与资金净流入/流出。

    Args:
        pro: tushare pro_api 实例
        ts_code: ETF代码
        start_date: 开始日期
        end_date: 结束日期

    Returns:
        包含规模变化和资金流向估算的 DataFrame
    """
    nav_df = get_etf_nav(pro, ts_code, start_date, end_date)
    nav_df['end_date'] = pd.to_datetime(nav_df['end_date'])
    nav_df = nav_df.sort_values('end_date')

    # 规模(单位亿元)
    nav_df['scale'] = nav_df['unit_nav'] * nav_df['fund_share'] / 1e8

    # 净值变动引起的规模变化(被动)
    nav_df['nav_return'] = nav_df['unit_nav'].pct_change()
    nav_df['passive_change'] = nav_df['scale'].shift(1) * nav_df['nav_return']

    # 资金净流入 ≈ 规模变化 - 净值带来的被动变化
    nav_df['net_flow'] = nav_df['scale'].diff() - nav_df['passive_change']

    # 统计区间
    summary = {
        'total_net_flow': nav_df['net_flow'].sum(),       # 区间总净流入(亿元)
        'avg_daily_flow': nav_df['net_flow'].mean(),      # 日均净流入
        'inflow_days': (nav_df['net_flow'] > 0).sum(),    # 净流入天数
        'outflow_days': (nav_df['net_flow'] < 0).sum(),   # 净流出天数
        'current_scale': nav_df['scale'].iloc[-1]          # 最新规模
    }

    return nav_df[['end_date', 'unit_nav', 'scale', 'net_flow']], summary


def cross_etf_flow_comparison(
    pro,
    etf_codes: list[str],
    start_date: str,
    end_date: str
) -> pd.DataFrame:
    """
    比较同类ETF的资金流向,判断资金偏好。

    Args:
        pro: tushare pro_api 实例
        etf_codes: 同类ETF代码列表
        start_date: 开始日期
        end_date: 结束日期

    Returns:
        各ETF资金流向汇总对比 DataFrame
    """
    rows = []
    for code in etf_codes:
        _, summary = etf_fund_flow_analysis(pro, code, start_date, end_date)
        summary['ts_code'] = code
        rows.append(summary)
    return pd.DataFrame(rows).set_index('ts_code').sort_values('total_net_flow', ascending=False)

8. Common Analysis Scenarios and Prompt Templates

Scenario 1: Screening for the Best ETF in the Same Category

分析追踪 [沪深300/中证500/xxx] 指数的所有ETF,
维度:规模、费率、近1年跟踪误差、日均成交额、买卖价差。
给出综合评分排名,并推荐最适合[长期持有/波段操作/大额配置]的产品。

Scenario 2: Sector ETF Rotation Signals

基于过去 [20/60] 日动量,在以下行业ETF中选出前3名:
[消费、医疗、科技、能源、金融、工业、材料、公用事业]
同时排除近30日跌幅超过15%的ETF。

Scenario 3: ETF Portfolio Backtesting

构建以下ETF组合并回测 [2020-01-01 至 2025-12-31]:
- 沪深300ETF 40%
- 中证500ETF 20%
- 国债ETF 30%
- 黄金ETF 10%
每季度再平衡,计算年化收益、夏普比率、最大回撤、与沪深300的相关性。

Scenario 4: QDII Premium Risk Monitoring

监控以下QDII ETF的实时折溢价率:[纳指ETF 159632、标普500 513500、日经225 513880]
溢价 > 3% 时发出预警,建议等待回落后再入场。

9. Key Considerations

  1. Trading Suspension Substitution: If a sector ETF has a large number of suspended stocks, IOPV becomes distorted, and the reference value of premium/discount declines
  2. QDII Quota: When the quota is exhausted, subscriptions are suspended, and the premium may persist for months, making it unsuitable for arbitrage
  3. Constituent Stock Adjustment: There are certain regular opportunities 1~2 weeks before and after the June/December index adjustments each year
  4. Leveraged ETFs Prohibited for Long-Term Holding: The decay effect is extremely pronounced in oscillating markets; strictly limit the holding period
  5. Money Market ETFs: Essentially money market funds, with logic different from ordinary ETFs; they are liquidity management tools rather than investment tools
  6. ETFs with Poor Liquidity: Large trades should be split across multiple days to avoid self-impact
  7. Tax Treatment: If ETF fund dividends include dividend income, the taxation rules differ from those for capital gains; be careful to distinguish them