init: stock buddy v5 完整回测系统

三版本 A/B/C 止损策略对比回测
- A: 固定止损 12%
- B: ATR x2.5 动态止损
- C: 混合自适应(低波动固定8%/中波动ATR×2.5/高波动ATR×2.0)

含仓位分级、成交量确认、CSV缓存机制
已验证三只港股持仓:01833 / 09886 / 09982

待补全:data/1833.csv 和 data/9886.csv(在外网运行 download_data.py)
This commit is contained in:
Stock Buddy
2026-03-22 12:57:47 +08:00
commit bd7d85817a
10 changed files with 1887 additions and 0 deletions

57
download_data.py Normal file
View File

@@ -0,0 +1,57 @@
"""
download_data.py — 在外网环境运行此脚本下载数据缓存
下载完成后将 data/ 目录推送到 repo内网环境直接读缓存
用法:
python3 download_data.py
"""
import yfinance as yf
import pandas as pd
import os, time, warnings
warnings.filterwarnings('ignore')
STOCKS = {
"平安好医生": "1833.HK",
"叮当健康": "9886.HK",
"中原建业": "9982.HK",
}
PERIOD = "2y"
CACHE_DIR = "data"
os.makedirs(CACHE_DIR, exist_ok=True)
print("📥 Stock Buddy — 数据下载工具")
print(f" 目标目录: {CACHE_DIR}/\n")
for i, (name, ticker) in enumerate(STOCKS.items()):
sym = ticker.replace(".HK", "")
fp = os.path.join(CACHE_DIR, f"{sym}.csv")
if os.path.exists(fp):
df = pd.read_csv(fp, index_col=0, parse_dates=True)
print(f"{name} ({ticker}): 已有缓存 {len(df)} 行,跳过")
continue
print(f" 🌐 {name} ({ticker}): 下载中...")
try:
df = yf.download(ticker, period=PERIOD, auto_adjust=True, progress=False)
if df.empty:
print(f"{name}: 下载失败(可能仍限速,稍后重试)")
continue
if isinstance(df.columns, pd.MultiIndex):
df.columns = df.columns.droplevel(1)
df.to_csv(fp)
print(f"{name}: {len(df)} 行 → {fp}")
print(f" 范围: {df.index[0].date()} ~ {df.index[-1].date()}")
print(f" 最新收盘: {float(df['Close'].iloc[-1]):.4f}")
except Exception as e:
print(f"{name}: 失败 - {e}")
if i < len(STOCKS) - 1:
time.sleep(5)
print("\n完成!将 data/ 目录推送到 repo 后,内网环境即可读取缓存。")
print("推送命令:")
print(" git add data/")
print(" git commit -m 'chore: add data cache'")
print(" git push")