Refactor code structure for improved readability and maintainability

This commit is contained in:
tigerenwork 2026-06-07 22:52:48 +08:00
parent b03a8f7dda
commit 5f7537a01d
6 changed files with 2164 additions and 27 deletions

View File

@ -0,0 +1,37 @@
============================================================
数据质量报告 / Data Quality Report
生成时间: 2026-06-07T16:05:29.175368
数据源: AKShare (fund_etf_hist_em)
============================================================
159995 (芯片ETF):
日期范围: 2021-02-04 ~ 2025-05-30 (1043 天)
原始缺失: 265 天 (17.1%)
日均收益率: +0.000172
日波动率: 0.021145
最大日涨幅: +10.01%
最大日跌幅: -9.05%
159819 (人工智能ETF):
日期范围: 2021-02-04 ~ 2025-05-30 (1043 天)
原始缺失: 421 天 (27.1%)
日均收益率: +0.000163
日波动率: 0.019471
最大日涨幅: +10.07%
最大日跌幅: -9.95%
516160 (新能源ETF):
日期范围: 2021-02-04 ~ 2025-05-30 (1043 天)
原始缺失: 510 天 (32.8%)
日均收益率: -0.000343
日波动率: 0.020161
最大日涨幅: +10.07%
最大日跌幅: -9.98%
159928 (消费ETF):
日期范围: 2021-02-04 ~ 2025-05-30 (1043 天)
原始缺失: 0 天 (0.0%)
日均收益率: -0.000380
日波动率: 0.015514
最大日涨幅: +10.01%
最大日跌幅: -9.94%

File diff suppressed because it is too large Load Diff

1044
data/etf_returns_panel.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -32,12 +32,20 @@ from datetime import datetime, timedelta
import time
import os
# ── 绕过系统代理,直连东方财富 ──
# macOS 上的 Clash/小火箭等代理工具的出口 IP 容易被东方财富反爬封禁。
# 设置环境变量让 requests 库对 eastmoney.com 不走代理。
os.environ["NO_PROXY"] = os.environ.get("NO_PROXY", "") + ",eastmoney.com,eastmoneyfutures.com,10jqka.com.cn"
os.environ["no_proxy"] = os.environ["NO_PROXY"]
# ── 检查 akshare 是否安装 ──
try:
import akshare as ak
print(f"✓ AKShare 版本: {ak.__version__}")
except ImportError:
print("请先安装 AKShare: pip install akshare")
print("❌ AKShare 未安装。请在 trading conda 环境中执行:")
print(" conda activate trading")
print(" pip install akshare")
raise
print("=" * 68)
@ -118,18 +126,26 @@ def fetch_etf_safe(code: str, start: str, end: str, max_retries: int = 3):
end_date=end,
adjust="qfq", # 前复权
)
time.sleep(0.5) # 礼貌限速,避免被封 IP
return df
except Exception as e:
print(f"{code}{attempt+1} 次获取失败: {e}")
err_msg = str(e)
if "ProxyError" in err_msg or "RemoteDisconnected" in err_msg:
wait = (attempt + 1) * 5 # 代理/连接问题,等更久
print(f"\n{code} 连接被拒绝 (代理/反爬){wait}s 后重试...")
else:
wait = 2.0
print(f"\n{code}{attempt+1} 次获取失败: {e}")
if attempt < max_retries - 1:
time.sleep(2.0)
print(f"{code} 全部 {max_retries} 次获取失败,跳过")
time.sleep(wait)
print(f"\n{code} 全部 {max_retries} 次获取失败,跳过")
return None
etf_data = {}
for code, name in ETF_UNIVERSE.items():
for i, (code, name) in enumerate(ETF_UNIVERSE.items()):
if i > 0:
# 请求间隔 + 随机抖动,避免触发东方财富反爬
time.sleep(2.0 + np.random.uniform(0, 1.5))
print(f" 获取 {code} ({name})...", end=" ")
df = fetch_etf_safe(code, START_DATE, END_DATE)
if df is not None:
@ -234,26 +250,17 @@ if index_data:
print("\n[§4] 获取北向资金数据")
try:
# 北向资金日频净流入
north_flow = ak.stock_hsgt_north_net_flow_in_em(symbol="北上")
if north_flow is not None and len(north_flow) > 0:
print(f" 北向资金净流入: {north_flow.shape}")
print(f" 列名: {list(north_flow.columns)}")
# 标准化为通用格式
if "date" in north_flow.columns and "value" in north_flow.columns:
north_flow = north_flow.rename(columns={"date": "日期", "value": "净流入_亿"})
print(f" 最新数据:\n{north_flow.tail(3)}")
else:
print(" 未获取到北向资金数据 (接口可能已变更)")
time.sleep(0.5)
# 沪深港通历史资金流向 (更详细)
hsgt = ak.stock_hsgt_hist_em(symbol="沪股通")
if hsgt is not None and len(hsgt) > 0:
print(f"\n 沪深港通历史资金: {hsgt.shape}")
print(f" 列名: {list(hsgt.columns)}")
print(f" 最新 3 行:\n{hsgt.tail(3)}")
# 北向资金: stock_hsgt_hist_em 获取沪股通/深股通历史资金流向
for market, label in [("沪股通", "沪股通(北向)"), ("深股通", "深股通(北向)")]:
try:
hsgt = ak.stock_hsgt_hist_em(symbol=market)
if hsgt is not None and len(hsgt) > 0:
print(f" {label}: {hsgt.shape}")
print(f" 列名: {list(hsgt.columns)}")
print(f" 最新 3 行:\n{hsgt.tail(3)}")
time.sleep(1.5) # 避免触发反爬
except Exception as e:
print(f" {label} 获取失败: {e}")
except Exception as e:
print(f" 北向资金获取失败: {e}")

View File

@ -47,7 +47,9 @@ try:
import tushare as ts
print(f"✓ Tushare 版本: {ts.__version__}")
except ImportError:
print("请先安装 Tushare: pip install tushare")
print("❌ Tushare 未安装。请在 trading conda 环境中执行:")
print(" conda activate trading")
print(" pip install tushare")
raise
print("=" * 68)

View File

@ -2,3 +2,6 @@ numpy
pandas
matplotlib
scipy
scikit-learn
akshare
tushare