بنقرة واحدة
etf-analysis
ETF分析:产品筛选、费率对比、跟踪误差、流动性评估、策略应用与中国市场ETF量化配置框架。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
ETF分析:产品筛选、费率对比、跟踪误差、流动性评估、策略应用与中国市场ETF量化配置框架。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Candlestick pattern recognition engine, pure pandas vectorized implementation of 15 classic candlestick patterns (5 single-candle + 5 double-candle + 4 triple-candle + 1 trend confirmation), generating a composite signal from bullish/bearish pattern scores.
基于缠论(缠中说禅)的形态识别引擎,使用czsc库自动检测K线分型、笔、中枢,并生成一买/一卖/二买/二卖/三买/三卖等买卖点信号。支持多周期分析和形态分类(3/5/7/9/11笔形态)。
A股可转债分析——转股/纯债/期权三维估值、下修/强赎/回售博弈、双低策略与转债轮动选债框架
公司事件驱动分析:并购套利价差计算、大股东增减持信号、股权激励解读、定增配股影响评估、A股ST/退市预警
Data source selection — VN-only. All data comes from vnstock (fundamentals + OHLCV) and VietFin DNSE (OHLCV fallback).
Elliott Wave Theory signal engine. Detects swing points through Zigzag, matches 5-wave impulse and 3-wave corrective structures, validates them with Fibonacci wave relationships, and generates trend-top / correction-complete signals. Pure in-house pandas implementation.
| name | etf-analysis |
| description | ETF分析:产品筛选、费率对比、跟踪误差、流动性评估、策略应用与中国市场ETF量化配置框架。 |
| category | asset-class |
ETF(交易所交易基金)是被动投资与资产配置的核心工具。本 skill 覆盖 ETF 产品分析、选择方法论、策略应用、中国市场特色以及数据驱动的量化分析方法,为构建基于 ETF 的量化策略与组合提供完整框架。
| 类型 | 代表产品 | 特点 |
|---|---|---|
| 宽基 ETF | 沪深300ETF (510300)、中证500ETF (510500)、创业板ETF (159915)、科创50ETF (588000) | 流动性最好,交易成本最低,适合核心仓位 |
| 行业 ETF | 消费ETF (159928)、医疗ETF (512170)、半导体ETF (512480)、银行ETF (512800) | 行业轮动工具,持仓集中度高 |
| 主题 ETF | 新能源ETF (516160)、碳中和ETF、元宇宙ETF | 主题炒作属性强,生命周期短 |
| 策略ETF / Smart Beta | 红利ETF (510880)、低波ETF、质量ETF、动量ETF | 因子暴露明确,费率通常略高于宽基 |
| 商品 ETF | 黄金ETF (518880)、豆粕ETF (159985)、原油ETF (162411) | 实物/期货支撑,注意展期损耗 |
| 债券 ETF | 国债ETF (511010)、信用债ETF、可转债ETF (511380) | 利率敏感,久期管理关键 |
| 跨境 ETF (QDII) | 纳指ETF (159632)、标普500ETF (513500)、日经225ETF (513880) | 汇率风险+溢价风险双重叠加 |
| 货币 ETF | 华宝添益 (511990)、银华日利 (511880) | T+0 申赎,流动性管理工具 |
衡量 ETF 复制指数能力的最核心指标。
日跟踪误差 = std(ETF日收益率 - 指数日收益率)
年化跟踪误差 = 日跟踪误差 × √252
评级标准(A股宽基ETF):
跟踪误差来源:
IR = (ETF年化收益率 - 指数年化收益率) / 年化跟踪误差
对 ETF 来说 IR 通常为负(因费率拖累),IR 越接近 0 越好。
折溢价率 = (ETF市价 - ETF净值IOPV) / ETF净值IOPV × 100%
| 指标 | 含义 | 参考阈值 |
|---|---|---|
| 日均成交额 | 买卖方便程度 | 宽基 > 1亿,行业 > 2000万 |
| 买卖价差(Spread) | 即时交易成本 | < 0.05% 为优质 |
| 盘口深度 | 单笔大额交易冲击 | 买卖各5档累计 > 500万为佳 |
| 换手率 | 活跃程度 | 过低则流动性风险高 |
综合费率 = 管理费 + 托管费 + 指数使用费
(不含交易佣金、印花税、申赎费)
长期费率影响公式:
N年费率复利损耗 = (1 - 年费率)^N
例:年费率0.5% vs 0.15%,10年差距 ≈ 3.5%,20年差距 ≈ 6.8%
主流宽基 ETF 费率对比(2025年):
规模门槛:
10亿:流动性充足,做市商活跃
100亿:旗舰 ETF,机构首选
清盘风险信号:规模持续下滑、连续90天日均规模 < 5000万
同一指数往往有多只 ETF,选择步骤:
Step 1: 规模筛选 → 剔除 < 5亿的小规模产品
Step 2: 费率比较 → 同等条件下选费率最低
Step 3: 跟踪误差 → 近1年/近3年双维度比较
Step 4: 流动性 → 日均成交额、买卖价差
Step 5: 基金公司 → 指数化投资能力、历史口碑
量化评分模型:
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)
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])
优质做市商体现在:
评估方法:
# 通过Level2数据计算有效价差
effective_spread = (ask_price - bid_price) / mid_price * 100 # 单位 %
# 价格冲击成本(Impact Cost)
# 买入N万元所需均价相对于中间价的偏离
impact_cost = (avg_buy_price - mid_price) / mid_price * 100
| 维度 | 评估要点 |
|---|---|
| ETF 管理规模 | 全市场排名,指数化投资专业度 |
| 跟踪误差历史 | 长期维度(3年+)稳定性 |
| 产品线完整性 | 宽基、行业、跨境覆盖广度 |
| 申赎效率 | T+0 实物申赎处理能力 |
| 做市商合作质量 | 与头部券商做市商的合作稳定性 |
国内 ETF 管理头部公司(规模口径):华夏、易方达、华泰柏瑞、南方、嘉实、博时
总组合 = 核心仓位(70~80%)+ 卫星仓位(20~30%)
核心仓位:宽基ETF(沪深300/中证500/全A)
→ 获取市场beta,低费率,长期持有,减少交易摩擦
卫星仓位:行业ETF/主题ETF/Smart Beta ETF
→ 增强收益,主动暴露特定因子,允许更高换手
再平衡触发条件:
动量轮动:
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
宏观周期轮动:
| 经济周期 | 推荐行业 ETF |
|---|---|
| 复苏期(低增长→高增长,低通胀) | 消费、科技、中小盘 |
| 过热期(高增长,高通胀) | 能源、材料、工业 |
| 滞胀期(低增长,高通胀) | 能源、公用事业、消费 |
| 衰退期(高增长→低增长) | 医疗、公用事业、债券ETF |
主要因子及对应ETF:
| 因子 | 代表ETF | 历史有效性(A股) |
|---|---|---|
| 价值(低估值) | 沪深300价值ETF | 中等,受风格切换影响 |
| 红利(高股息) | 红利ETF (510880) | 较强,尤其熊市防御 |
| 低波动 | 中证低波ETF | 较强,夏普比优于宽基 |
| 质量(高ROE) | 中证质量ETF | 较强,长期复合效果好 |
| 动量 | 目前A股产品少 | 中短期有效,长期均值回归 |
| 小盘 | 中证1000ETF (512100) | 强,但流动性风险高 |
因子暴露分析代码:
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')
Beta 衰减(Volatility Decay)原理:
每日恒定杠杆 N 倍 → 复合效应导致长期收益 ≠ N × 指数收益
衰减量(近似)= N²(N-1)/2 × σ² × T
其中 σ 为指数日波动率,T 为持有天数
数值示例:
适用场景:
折溢价套利(需要有实物申赎资格,通常门槛100万份):
溢价套利:
ETF市价 > IOPV + 交易成本
→ 买入一篮子成分股 → 申购ETF份额 → 卖出ETF
→ 套利利润 ≈ 溢价率 - 冲击成本 - 佣金
折价套利:
ETF市价 < IOPV - 交易成本
→ 买入ETF份额 → 赎回一篮子成分股 → 卖出成分股
→ 套利利润 ≈ 折价率 - 冲击成本 - 佣金
跨市场套利(ETF vs 期货):
IF(沪深300股指期货)基差 = 期货价格 - 沪深300指数
当基差 > 合理基差(无风险利率×剩余期限)时:
→ 卖期货 + 买ETF(正向套利)
当基差 < 合理基差时:
→ 买期货 + 卖ETF(反向套利,需融券)
统计套利(配对交易):
# 同类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
| 维度 | 场内 ETF | 场外联接基金 |
|---|---|---|
| 购买渠道 | 证券账户,实时交易 | 银行/基金直销,T+1申赎 |
| 申赎方式 | 实物申赎(机构)或二级市场(个人) | 现金申赎 |
| 折溢价 | 存在(有套利机制) | 不存在 |
| 最小交易单位 | 100份(约10~100元) | 1元起投 |
| 费率 | 较低(管理费+交易佣金) | 略高(申购费+管理费) |
| 适合场景 | 波段操作、大额配置 | 定投、小额长期持有 |
溢价形成原因:
溢价率警戒线:
5%:高溢价,存在显著买入风险(净值回落但溢价收窄双杀)
汇率对冲:
LOF(上市开放式基金):
分级基金(已全面转型,2020年前历史参考):
宽基指数:
| 指数 | 成分股 | 特点 |
|---|---|---|
| 沪深300 | 沪深两市市值最大300只 | 大盘蓝筹,衍生品丰富(IF期货/300期权) |
| 中证500 | 300~800名中盘股 | 中盘成长,与300互补 |
| 中证1000 | 800~1800名小盘股 | 小盘因子,波动较大 |
| 上证50 | 沪市最大50只 | 超大盘,金融地产权重高 |
| 创业板指 | 创业板前100名 | 科技成长,波动大 |
| 科创50 | 科创板前50名 | 硬科技,上市时间短 |
| 北证50 | 北交所前50名 | 新兴市场,流动性弱 |
| 中证全指 / 万得全A | 全市场 | 最宽泛的基准 |
指数调整规律:
经典配置框架(可用ETF实现):
股债 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%
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(国内较少)
再平衡成本:
单次再平衡成本 ≈ 交易金额 × (佣金率 + 价差/2 + 冲击成本)
≈ 交易金额 × 0.05%~0.15%(宽基ETF)
年化再平衡成本 = 单次成本 × 年均调仓次数
最优再平衡频率建议:
免佣金再平衡技巧:
中国 ETF 税务规则:
税务效率策略:
from vnstock import Vnstock
import pandas as pd
stock = Vnstock().stock(symbol="VNM", source="KBS")
# 获取基金列表
def get_vn_fund_list() -> pd.DataFrame:
"""
获取越南市场基金列表。
"""
df = stock.listing.funds()
return df[['symbol', 'name', 'fund_type', 'management_company']]
# 获取基金净值历史
def get_fund_nav(symbol: str, start_date: str, end_date: str) -> pd.DataFrame:
"""
获取基金净值历史。
Args:
symbol: 基金代码 (e.g., "FUEVFVND")
start_date, end_date: YYYY-MM-DD
"""
stock = Vnstock().stock(symbol=symbol, source="KBS")
df = stock.funds.nav_history(symbol, start=start_date, end=end_date)
return df[['date', 'nav', 'accum_nav']]
# 获取基金持仓
def get_fund_holdings(symbol: str, report_date: str) -> pd.DataFrame:
"""
获取基金持仓明细。
Args:
symbol: 基金代码
report_date: 报告日期 YYYY-MM-DD
"""
df = stock.funds.holdings(symbol, report_date=report_date)
return df[['symbol', 'stock_name', 'volume', 'market_value', 'ratio']]
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_symbol: str,
start_date: str,
end_date: str
) -> pd.DataFrame:
"""
比较追踪同一指数的多只越南ETF的跟踪表现。
Args:
etf_codes: ETF代码列表 (e.g., ["FUEVFVND", "FUESSVFL"])
index_symbol: 基准指数代码 (e.g., "VNINDEX")
start_date, end_date: YYYY-MM-DD
Returns:
各ETF的跟踪误差比较 DataFrame
"""
from app.services.dnse.intraday_tool import get_intraday_tool
from datetime import datetime, timezone, timedelta
tool = get_intraday_tool()
# Fetch index data
TZ_VN = timezone(timedelta(hours=7))
from_dt = datetime.strptime(start_date, "%Y-%m-%d").replace(tzinfo=TZ_VN)
to_dt = datetime.strptime(end_date, "%Y-%m-%d").replace(tzinfo=TZ_VN)
index_candles = tool.fetch(index_symbol, resolution="1D",
from_ts=int(from_dt.timestamp()),
to_ts=int(to_dt.timestamp()))
index_prices = pd.Series({c["time"][:10]: float(c["close"]) for c in index_candles})
results = []
for code in etf_codes:
fund_candles = tool.fetch(code, resolution="1D",
from_ts=int(from_dt.timestamp()),
to_ts=int(to_dt.timestamp()))
fund_prices = pd.Series({c["time"][:10]: float(c["close"]) for c in fund_candles})
te_result = calc_tracking_error(fund_prices, index_prices)
te_result['symbol'] = code
results.append(te_result)
return pd.DataFrame(results).set_index('symbol').sort_values('tracking_error')
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'
feasible = premium_pct > 0.5
elif premium_pct < -0.3:
signal = 'DISCOUNT_HIGH'
feasible = premium_pct < -0.5
else:
signal = 'NORMAL'
feasible = False
return {
'premium_pct': round(premium_pct, 2),
'signal': signal,
'arbitrage_feasible': feasible
}
from vnstock import Vnstock
import pandas as pd
def get_fund_nav_history(
symbol: str,
start_date: str,
end_date: str
) -> pd.DataFrame:
"""
获取越南基金净值历史数据。
Args:
symbol: 基金代码 (e.g., "FUEVFVND", "FUESSVFL")
start_date: 开始日期
end_date: 结束日期
Returns:
DataFrame 包含日期、净值、累计净值
"""
stock = Vnstock().stock(symbol=symbol, source="KBS")
df = stock.funds.nav_history(symbol, start=start_date, end=end_date)
return df[['date', 'nav', 'accum_nav']]
def list_vn_funds() -> pd.DataFrame:
"""
列出越南市场所有基金。
Returns:
DataFrame 包含基金代码、名称、类型、管理公司
"""
from vnstock import Vnstock
stock = Vnstock().stock(symbol="VNM", source="KBS")
return stock.listing.funds()
分析追踪 [沪深300/中证500/xxx] 指数的所有ETF,
维度:规模、费率、近1年跟踪误差、日均成交额、买卖价差。
给出综合评分排名,并推荐最适合[长期持有/波段操作/大额配置]的产品。
基于过去 [20/60] 日动量,在以下行业ETF中选出前3名:
[消费、医疗、科技、能源、金融、工业、材料、公用事业]
同时排除近30日跌幅超过15%的ETF。
构建以下ETF组合并回测 [2020-01-01 至 2025-12-31]:
- 沪深300ETF 40%
- 中证500ETF 20%
- 国债ETF 30%
- 黄金ETF 10%
每季度再平衡,计算年化收益、夏普比率、最大回撤、与沪深300的相关性。
监控以下QDII ETF的实时折溢价率:[纳指ETF 159632、标普500 513500、日经225 513880]
溢价 > 3% 时发出预警,建议等待回落后再入场。