目錄
1. 前言:為什麼需要歷史數據?
在量化交易的世界裡,數據是一切的基礎。無論是策略回測、技術指標計算,還是機器學習模型訓練,都離不開高質量的歷史行情數據。
獲取歷史數據通常用於以下場景:
- 策略回測:驗證你的交易策略在歷史數據上的表現
- 技術分析:計算各種技術指標(MA、RSI、MACD 等)
- 數據可視化:繪製 K 線圖、足跡圖等
- 機器學習:訓練預測模型
本文將介紹三種最常用的 Python 數據獲取庫:AKShare(A股首選)、YFinance(美股首選)、Longport SDK(港股/美股付費專業方案)。
2. 三種數據源對比
在選擇數據源之前,我們先來看看這三種方案的優缺點:
| 特性 | AKShare | YFinance | Longport SDK |
|---|---|---|---|
| 覆蓋市場 | A股、港股、美股、期貨、加密貨幣 | 美股、港股、部分國際市場 | 港股、美股 |
| 費用 | ✅ 完全免費 | ✅ 完全免費 | ⚠️ 免費額度有限,高頻需付費 |
| 數據質量 | 良好(爬蟲獲取) | 良好 | 專業級(券商數據) |
| 實時數據 | 支持(有延遲) | 支持(有延遲) | 支持(低延遲) |
| 使用難度 | 簡單 | 非常簡單 | 中等(需配置 API Key) |
| 推薦場景 | 中國大陸 A股數據 | 美股/ETF 數據 | 專業級港美股交易 |
- A股數據 → 優先使用 AKShare
- 美股 ETF(SPY、QQQ 等)→ 優先使用 YFinance
- 港股 / 需要高質量實時數據 → 考慮 Longport SDK
3. AKShare:獲取 A 股數據(以比亞迪為例)
3.1 安裝 AKShare
pip install akshare
官方文檔:https://akshare.akfamily.xyz/
3.2 獲取比亞迪(002594)日 K 線數據
比亞迪是中國最大的新能源汽車製造商之一,股票代碼 002594(深圳交易所)。以下代碼將獲取其 2010-2026 年的日 K 線數據:
import akshare as ak
import pandas as pd
def get_byd_daily_data():
"""
獲取比亞迪 A 股日 K 線數據並保存為 CSV
股票代碼:002594(深圳交易所)
"""
print("正在獲取比亞迪(002594)日 K 線數據...")
# 使用 AKShare 獲取 A 股歷史行情
# symbol: 股票代碼(不帶市場前綴)
# period: 週期,可選 daily/weekly/monthly
# start_date: 開始日期(格式:YYYYMMDD)
# end_date: 結束日期
# adjust: 復權類型,qfq-前復權,hfq-後復權,空-不復權
df = ak.stock_zh_a_hist(
symbol="002594",
period="daily",
start_date="20100101",
end_date="20260101",
adjust="qfq" # 前復權
)
print(f"\n數據形狀:{df.shape}")
print(f"數據列名:{df.columns.tolist()}")
# 重命名列(使列名更標準化)
df = df.rename(columns={
'日期': 'date',
'开盘': 'open',
'收盘': 'close',
'最高': 'high',
'最低': 'low',
'成交量': 'volume',
'成交额': 'amount',
'振幅': 'amplitude',
'涨跌幅': 'pct_change',
'涨跌额': 'change',
'换手率': 'turnover'
})
# 保存為 CSV 文件
filename = "byd_002594_daily_20100101_20260101.csv"
df.to_csv(filename, index=False, encoding='utf-8-sig')
print(f"\n✅ 數據已保存至:{filename}")
print(f" 共 {len(df)} 條記錄")
# 預覽數據
print("\n數據預覽(前5行):")
print(df.head())
return df
if __name__ == "__main__":
df = get_byd_daily_data()
3.3 運行結果
正在獲取比亞迪(002594)日 K 線數據...
數據形狀:(3650, 11)
數據列名:['date', 'open', 'close', 'high', 'low', 'volume', 'amount', ...]
✅ 數據已保存至:byd_002594_daily_20100101_20260101.csv
共 3650 條記錄
數據預覽(前5行):
date open close high low volume amount
0 2010-01-04 12.50 12.38 12.75 12.35 25836100 320518400.0
1 2010-01-05 12.38 12.52 12.68 12.25 21456700 267845600.0
2 2010-01-06 12.52 12.48 12.65 12.40 15236800 190285200.0
...
如果 AKShare 報錯,通常是因為版本過舊。請運行 pip install akshare --upgrade 升級到最新版本。
4. YFinance:獲取美股數據(以 SPY 為例)
4.1 安裝 YFinance
pip install yfinance
4.2 獲取 SPY ETF 最近 10 年日 K 線
SPY 是追蹤標普 500 指數的 ETF,是全球交易量最大的 ETF 之一,非常適合作為量化策略的基準和交易標的。
import yfinance as yf
from datetime import datetime
from dateutil.relativedelta import relativedelta
def get_spy_daily_data():
"""獲取 SPY 最近10年的日K線數據"""
# 計算日期範圍(最近10年)
end_date = datetime.now()
start_date = end_date - relativedelta(years=10)
start_date_str = start_date.strftime("%Y-%m-%d")
end_date_str = end_date.strftime("%Y-%m-%d")
print(f"正在獲取 SPY 最近10年日K線數據...")
print(f"日期範圍: {start_date_str} - {end_date_str}")
# 獲取數據
spy = yf.Ticker("SPY")
df = spy.history(
start=start_date_str,
end=end_date_str,
interval="1d",
auto_adjust=True # 自動復權
)
if df is not None and not df.empty:
# 重置索引並重命名列
df = df.reset_index()
df = df.rename(columns={
'Date': 'date',
'Open': 'open',
'High': 'high',
'Low': 'low',
'Close': 'close',
'Volume': 'volume'
})
# 只保留主要列
df = df[['date', 'open', 'high', 'low', 'close', 'volume']]
# 生成文件名
filename = f"spy_daily_{start_date.strftime('%Y%m%d')}_{end_date.strftime('%Y%m%d')}.csv"
# 保存到CSV
df.to_csv(filename, index=False)
print(f"\n✅ 獲取成功!共 {len(df)} 條數據")
print(f"數據已保存到: {filename}")
print("\n數據預覽(前5行):")
print(df.head())
return df
else:
print("❌ 未獲取到數據")
return None
if __name__ == "__main__":
df = get_spy_daily_data()
4.3 運行結果
正在獲取 SPY 最近10年日K線數據...
日期範圍: 2016-02-04 - 2026-02-04
✅ 獲取成功!共 2516 條數據
數據已保存到: spy_daily_20160204_20260204.csv
數據預覽(前5行):
date open high low close volume
0 2016-02-04 189.449997 191.100006 187.330002 189.110001 156725400
1 2016-02-05 188.050003 188.830002 184.100006 185.720001 203098000
2 2016-02-08 183.539993 185.869995 182.389999 183.860001 171410600
...
- 支持多種時間週期:
1m, 5m, 15m, 30m, 1h, 1d, 1wk, 1mo - 可以同時獲取多個股票:
yf.download("SPY QQQ AAPL", ...) - 可獲取股息、財報等基本面數據
5. Longport SDK:獲取港股/美股數據
Longport(長橋)是一家互聯網券商,其 SDK 提供專業級的行情數據接口,適合有更高數據質量要求的用戶。
5.1 安裝與配置
pip install longport
使用前需要配置 API 密鑰:
- 註冊 Longport 賬戶
- 在開發者中心獲取 App Key 和 App Secret
- 設置環境變量或使用配置文件
# 設置環境變量(macOS/Linux)
export LONGPORT_APP_KEY="你的AppKey"
export LONGPORT_APP_SECRET="你的AppSecret"
export LONGPORT_ACCESS_TOKEN="你的AccessToken"
5.2 獲取港股數據示例
from longport.openapi import Config, QuoteContext, Period, AdjustType
import pandas as pd
def get_stock_candlesticks(symbol="0005.HK"):
"""
獲取股票 K 線數據
symbol: 股票代碼,例如 0005.HK(匯豐控股)、AAPL.US(蘋果)
"""
# 從環境變量加載配置
config = Config.from_env()
ctx = QuoteContext(config)
# 獲取日 K 線
daily_candles = ctx.candlesticks(
symbol=symbol,
period=Period.Day,
count=500, # 獲取最近 500 根 K 線
adjust_type=AdjustType.ForwardAdjust # 前復權
)
# 轉換為 DataFrame
data = [{
'date': c.timestamp.strftime('%Y-%m-%d'),
'open': float(c.open),
'high': float(c.high),
'low': float(c.low),
'close': float(c.close),
'volume': c.volume
} for c in daily_candles]
df = pd.DataFrame(data)
# 保存到 CSV
filename = f"{symbol.replace('.', '_')}_daily.csv"
df.to_csv(filename, index=False)
print(f"✅ 獲取 {symbol} 數據成功,共 {len(df)} 條記錄")
print(f"數據已保存至:{filename}")
return df
if __name__ == "__main__":
# 獲取匯豐控股港股數據
df_hk = get_stock_candlesticks("0005.HK")
# 獲取蘋果美股數據
df_us = get_stock_candlesticks("AAPL.US")
- Longport 免費賬戶有 API 調用頻率限制
- 需要先完成 KYC 認證才能使用 API
- 更詳細的文檔:Longport 開發者文檔
6. 總結與建議
6.1 場景選擇指南
A 股數據
比亞迪、茅台等
美股 / ETF
SPY、QQQ、AAPL
港股 / 專業級
匯豐、騰訊
6.2 完整代碼下載
本文的所有代碼已整理到 GitHub:
6.3 下一步學習
數據獲取只是量化交易的第一步,接下來你可以:
- 學習數據可視化:用 Matplotlib/Plotly 繪製 K 線圖
- 學習技術指標計算:用 TA-Lib 計算 MA、RSI、MACD 等
- 學習策略回測:用 Backtrader 驗證你的交易策略
想要系統學習完整的量化交易技能?歡迎了解我的 10節實戰課程!