A 股、美股、港股到底谁影响谁?用 Python 做一次分析

用户头像sh_*2176oo
2026-06-23 发布

A 股、美股、港股到底谁影响谁?用 Python 做一次跨市场相关性分析

每天早上打开行情软件,很多人会先看隔夜美股。

纳斯达克大涨,大家会期待 A 股科技股高开;恒生科技下跌,很多人会担心港股互联网和 A 股成长板块承压;美股半导体走强,又会有人去看 A 股芯片股。

这些判断听起来很合理,但问题是:它们到底有多可靠?

市场之间确实会互相影响,但影响不是一句“美股涨,A 股就涨”这么简单。不同市场有时同向,有时背离;有时隔夜影响明显,有时完全被本地政策和资金面覆盖。

这篇文章用 AlphaFeed 做一个跨市场相关性分析:把 A 股 ETF、美股 ETF、港股标的放到同一个 DataFrame 里,计算收益率相关性、滞后相关性和滚动相关性。我们不靠感觉判断市场联动,而是用数据看关系到底强不强。

1. 为什么要做跨市场分析

如果你只交易 A 股,为什么还要看美股和港股?

因为市场不是孤立的。

  1. 美股影响全球风险偏好;
  2. 港股和 A 股有大量共同行业和共同公司;
  3. 美元、利率、科技股、商品价格都会跨市场传导;
  4. ETF 和指数产品让资金流动更加全球化;
  5. 重大事件发生时,开盘时间更早的市场会先反映信息。

但跨市场分析最容易犯的错误是过度简化。

比如:

常见说法 需要验证的问题
美股大涨,A 股第二天会涨 哪个指数?多大涨幅?胜率多少?
港股科技能预判 A 股科技 相关性稳定吗?有没有阶段失效?
A 股跟美股关系不大 是全市场不大,还是某些行业不大?
全球市场越来越同步 同步性是长期提高,还是只在危机时提高?

这些问题都可以用数据检验。

2. AlphaFeed 为什么适合做这个实验

跨市场分析最麻烦的不是相关性公式,而是数据对齐。

你需要处理:

  1. A 股代码格式;
  2. 美股代码格式;
  3. 港股代码格式;
  4. 不同市场交易日不同;
  5. 时区和收盘时间不同;
  6. 字段命名不同;
  7. 批量获取和复权方式。

AlphaFeed 的优势是用同一套 Python SDK 暴露 A 股、ETF、美股、港股数据。代码格式也相对统一:

市场 示例
A 股 ETF 510300.SH
A 股股票 600519.SH
美股 AAPL.US
港股 00700.HK

这让我们可以把跨市场标的放进同一个列表里处理。

3. 准备标的池

为了降低个股噪音,跨市场分析通常优先用指数 ETF 或代表性大盘标的。

示例标的池:

SYMBOLS = {
    "hs300": "510300.SH",   # 沪深300 ETF 示例
    "zz500": "510500.SH",   # 中证500 ETF 示例
    "cyb": "159915.SZ",     # 创业板 ETF 示例
    "nasdaq": "QQQ.US",     # 纳斯达克100 ETF 示例
    "sp500": "SPY.US",      # 标普500 ETF 示例
    "tencent": "00700.HK",  # 腾讯控股示例
}

注意:不同账户和数据权限下,具体可用标的请以接口返回为准。如果某个美股 ETF 或港股标的不可用,可以换成你账户可用的代表性标的。

4. 获取跨市场 K 线

安装:

pip install alphafeed pandas

初始化:

from alphafeed import AlphaFeed

af = AlphaFeed(api_key="your-api-key")

或者使用环境变量:

export ALPHAFEED_API_KEY="your-api-key"

拉取 K 线:

import pandas as pd
from alphafeed import AlphaFeed

af = AlphaFeed()

SYMBOLS = {
    "hs300": "510300.SH",
    "zz500": "510500.SH",
    "cyb": "159915.SZ",
    "nasdaq": "QQQ.US",
    "sp500": "SPY.US",
    "tencent": "00700.HK",
}

dfs = af.klines.batch(
    list(SYMBOLS.values()),
    period="1d",
    count=800,
    adjust="forward",
    to_dataframe=True,
    show_progress=True,
)

把收盘价拼成矩阵:

def build_close_matrix(dfs: dict[str, pd.DataFrame], name_map: dict[str, str]) -> pd.DataFrame:
    reverse_map = {symbol: name for name, symbol in name_map.items()}
    series = []

    for symbol, df in dfs.items():
        name = reverse_map[symbol]
        one = df.sort_values("trade_date").copy()
        one["trade_date"] = pd.to_datetime(one["trade_date"])
        s = one.set_index("trade_date")["close"]
        s.name = name
        series.append(s)

    close = pd.concat(series, axis=1).sort_index()
    return close


close = build_close_matrix(dfs, SYMBOLS)
print(close.tail())

这里有一个严谨点:不同市场交易日不同,所以 close 里会有缺失值。不要急着随便填充,先明确你的研究问题。

5. 处理不同市场交易日

跨市场相关性最容易踩坑的地方,就是日期对齐。

如果你直接 dropna(),只保留所有市场都交易的日期,样本会变少,但比较干净。

close_aligned = close.dropna()
ret = close_aligned.pct_change().dropna()

如果你用前值填充:

close_ffill = close.ffill().dropna()
ret_ffill = close_ffill.pct_change().dropna()

这样样本更多,但会把某些市场休市日的收益率变成 0,可能影响相关性。

所以我建议:

  1. 做严谨统计时,先用 dropna()
  2. 做展示或长周期曲线时,可以考虑 ffill()
  3. 两种方法都跑一遍,看结论是否稳定。

本文先使用 dropna()

6. 计算收益率相关性矩阵

最基础的分析是相关性矩阵:

corr = ret.corr()
print(corr.round(3))

输出会类似:

          hs300  zz500   cyb  nasdaq  sp500  tencent
hs300     1.000  0.780 0.720   0.210  0.190    0.430
zz500     0.780  1.000 0.760   0.180  0.160    0.390
cyb       0.720  0.760 1.000   0.260  0.230    0.450
nasdaq    0.210  0.180 0.260   1.000  0.880    0.350
sp500     0.190  0.160 0.230   0.880  1.000    0.300
tencent   0.430  0.390 0.450   0.350  0.300    1.000

上面只是示意,不代表真实结果。你应该以自己运行结果为准。

看相关性矩阵时,要注意三点:

  1. 同市场内部相关性通常更高;
  2. 跨市场相关性往往不稳定;
  3. 相关性不等于因果关系。

如果纳斯达克和创业板相关性为 0.25,只能说明它们在样本期内日收益有一定同步性,不能说明纳斯达克上涨会“导致”创业板上涨。

7. 研究隔夜影响:滞后相关性

很多人真正关心的是:美股今晚涨跌,对 A 股明天有没有影响?

这就需要做滞后相关性。

由于美股收盘在北京时间次日凌晨,粗略研究时可以把美股收益向后移动一天,再和 A 股当天收益比较。

lead_lag = pd.DataFrame({
    "nasdaq_prev_day_vs_hs300": ret["nasdaq"].shift(1).corr(ret["hs300"]),
    "nasdaq_prev_day_vs_cyb": ret["nasdaq"].shift(1).corr(ret["cyb"]),
    "sp500_prev_day_vs_hs300": ret["sp500"].shift(1).corr(ret["hs300"]),
    "sp500_prev_day_vs_zz500": ret["sp500"].shift(1).corr(ret["zz500"]),
}, index=["corr"])

print(lead_lag.T.round(3))

更系统一点,可以写函数:

def lag_corr(source: pd.Series, target: pd.Series, max_lag=5) -> pd.DataFrame:
    rows = []
    for lag in range(-max_lag, max_lag + 1):
        rows.append({
            "lag": lag,
            "corr": source.shift(lag).corr(target),
        })
    return pd.DataFrame(rows)


lag_table = lag_corr(ret["nasdaq"], ret["cyb"], max_lag=5)
print(lag_table)

这里的 lag 要结合你的定义解释清楚。不要只打印表格不解释,否则很容易误读。

8. 相关性不是常数:做滚动相关性

市场之间的关系会变。

危机时期,全球市场可能一起下跌,相关性上升;平稳时期,各市场可能更多受本地因素影响,相关性下降。

所以只看全样本相关性不够,还要看滚动相关性:

rolling_corr = ret["nasdaq"].rolling(60).corr(ret["cyb"])

print(rolling_corr.dropna().tail())
print("最近60日相关性:", rolling_corr.dropna().iloc[-1])
print("历史平均相关性:", rolling_corr.mean())
print("历史最高相关性:", rolling_corr.max())
print("历史最低相关性:", rolling_corr.min())

你还可以把结果保存下来:

rolling_corr.to_csv("nasdaq_cyb_rolling_corr.csv", encoding="utf-8-sig")

如果你发现相关性长期在 0.1 到 0.6 之间波动,就不能简单说“它们高度相关”。更准确的表述应该是:它们在某些阶段同步性较强,在某些阶段相关性较弱。

9. 验证一个常见说法:美股大涨后,A 股更容易上涨吗

我们可以做一个条件统计。

比如:当纳斯达克前一交易日涨幅超过 1% 时,创业板 ETF 当天上涨概率是多少?平均收益是多少?

condition = ret["nasdaq"].shift(1) > 0.01
sample = ret.loc[condition, "cyb"]

stats = {
    "sample_size": len(sample),
    "win_rate": (sample > 0).mean(),
    "avg_return": sample.mean(),
    "median_return": sample.median(),
}

print(stats)

再比较基准:

baseline = {
    "sample_size": len(ret["cyb"]),
    "win_rate": (ret["cyb"] > 0).mean(),
    "avg_return": ret["cyb"].mean(),
    "median_return": ret["cyb"].median(),
}

print("条件样本:", stats)
print("全样本基准:", baseline)

如果条件样本胜率只是略高于基准,而且样本数量不大,就不能得出很强的结论。

这就是数据分析的价值:它会逼你把“感觉很明显”变成“到底提高了多少”。

10. 再加一个反向条件:美股大跌后呢

只看上涨是不够的,还要看下跌冲击:

condition_down = ret["nasdaq"].shift(1) < -0.01
sample_down = ret.loc[condition_down, "cyb"]

down_stats = {
    "sample_size": len(sample_down),
    "win_rate": (sample_down > 0).mean(),
    "avg_return": sample_down.mean(),
    "median_return": sample_down.median(),
    "worst_return": sample_down.min(),
}

print(down_stats)

很多跨市场影响并不是对称的。

有时美股大涨,对 A 股提振有限;但美股大跌,会显著影响开盘情绪。这种非对称性比简单相关性更有研究价值。

11. 输出一份跨市场分析报告

可以把核心结果整理成 Markdown:

def format_pct(x):
    return f"{x:.2%}" if pd.notna(x) else "N/A"


report_lines = []
report_lines.append("# 跨市场相关性分析报告")
report_lines.append("")
report_lines.append("## 收益率相关性矩阵")
report_lines.append("")
report_lines.append(corr.round(3).to_markdown())
report_lines.append("")
report_lines.append("## 纳斯达克前日涨超 1% 后,创业板表现")
report_lines.append("")
report_lines.append(f"- 样本数量:{stats['sample_size']}")
report_lines.append(f"- 上涨概率:{format_pct(stats['win_rate'])}")
report_lines.append(f"- 平均收益:{format_pct(stats['avg_return'])}")
report_lines.append(f"- 中位数收益:{format_pct(stats['median_return'])}")
report_lines.append("")
report_lines.append("## 纳斯达克前日跌超 1% 后,创业板表现")
report_lines.append("")
report_lines.append(f"- 样本数量:{down_stats['sample_size']}")
report_lines.append(f"- 上涨概率:{format_pct(down_stats['win_rate'])}")
report_lines.append(f"- 平均收益:{format_pct(down_stats['avg_return'])}")
report_lines.append(f"- 最差收益:{format_pct(down_stats['worst_return'])}")
report_lines.append("")
report_lines.append("数据来源:AlphaFeed (https://alphafeed.org/)")

with open("cross_market_report.md", "w", encoding="utf-8") as f:
    f.write("\n".join(report_lines))

如果没有 to_markdown,安装:

pip install tabulate

12. 这个分析能用来交易吗

谨慎一点说:不能直接用。

相关性分析不是交易策略,它只是研究的第一步。它可以告诉你市场之间是否存在同步性、滞后关系和阶段变化,但不能直接给出买卖点。

如果你想进一步做成策略,至少还需要考虑:

  1. 开盘价是否已经反映隔夜信息;
  2. 交易成本和滑点;
  3. 信号是否稳定;
  4. 样本外是否有效;
  5. 极端行情下是否失效;
  6. 是否存在数据窥探和过拟合。

例如,“纳斯达克前日涨超 1%,创业板次日平均收益更高”不代表你可以无脑买入。因为 A 股开盘价可能已经跳空反映了这部分预期,真正可交易的收益可能小很多。

量化研究必须从“统计关系”走到“可交易规则”,中间还有很长一段路。

13. AlphaFeed 在跨市场研究里的价值

跨市场研究真正麻烦的是数据工程,而不是相关性公式。

AlphaFeed 在这里提供了几个关键能力:

  1. A 股、ETF、美股、港股统一代码格式;
  2. 同一套 SDK 获取历史 K 线;
  3. 支持批量拉取多标的数据;
  4. K 线可以直接返回 DataFrame;
  5. 复权方式可以明确指定;
  6. 同一套数据还能继续接实时行情、盘口和标的信息。

这让你可以把更多精力放在研究问题本身:市场之间到底有没有关系?关系是否稳定?有没有滞后?有没有非对称性?

而不是花大量时间处理“这个市场的代码怎么写、那个市场的字段叫什么”。

结语

市场之间确实会互相影响,但这种影响不能只靠感觉判断。

“美股涨,A 股就涨”“港股科技能预判创业板”“全球市场越来越同步”这些说法,都需要用数据拆开验证。相关性、滞后相关性、滚动相关性和条件统计,能帮你把模糊经验变成可检验的问题。

AlphaFeed 的意义在于,让跨市场数据接入变得足够简单。你可以用同一套 Python SDK 拉 A 股、ETF、美股、港股 K 线,把它们放进同一个 DataFrame,然后开始真正的研究。

不要迷信结论,先学会验证。

参考文献:

评论