整理 course 目录:原课程归入同名文件夹,新增学习资料/动手练习分类

This commit is contained in:
2026-09-28 11:52:44 +08:00
parent 5629d57ea7
commit cb211da473
51 changed files with 398 additions and 32 deletions
+48
View File
@@ -0,0 +1,48 @@
"""量化练习公共库:数据获取(带缓存+重试) + 常用指标 + 回测指标。"""
import os, time, pandas as pd, numpy as np
CACHE = os.path.join(os.path.dirname(__file__), "..", "data", "cache")
os.makedirs(CACHE, exist_ok=True)
def _fetch(symbol, start, end, adjust, retries=6, wait=2.0):
import akshare as ak
last = None
for i in range(retries):
try:
return ak.stock_zh_a_hist(symbol=symbol, period="daily",
start_date=start, end_date=end, adjust=adjust)
except Exception as e: # 网络间歇性抽风,重试
last = e
time.sleep(wait * (i + 1))
raise last
def get_daily(symbol="000001", start="20200101", end="20241231", adjust="qfq"):
"""拉单只A股日线(前复权),带本地缓存与自动重试。"""
f = os.path.join(CACHE, f"{symbol}_{start}_{end}_{adjust}.csv")
if os.path.exists(f):
return pd.read_csv(f, parse_dates=["日期"])
df = _fetch(symbol, start, end, adjust)
df.to_csv(f, index=False, encoding="utf-8-sig")
return df
def add_returns(df, price_col="收盘"):
df = df.copy()
df["ret"] = df[price_col].pct_change().fillna(0.0)
return df
def net_value(ret):
return (1 + pd.Series(ret).fillna(0.0)).cumprod()
def stats(ret, periods=252):
ret = pd.Series(ret).fillna(0.0)
nv = net_value(ret); total = nv.iloc[-1] - 1
ann = (1 + total) ** (periods / max(len(ret), 1)) - 1
vol = ret.std() * np.sqrt(periods)
sharpe = (ret.mean() * periods) / vol if vol > 0 else np.nan
dd = (nv / nv.cummax() - 1).min()
calmar = ann / abs(dd) if dd < 0 else np.nan
return {"总收益": f"{total:.2%}", "年化": f"{ann:.2%}", "年化波动": f"{vol:.2%}",
"夏普": f"{sharpe:.2f}", "最大回撤": f"{dd:.2%}", "卡玛": f"{calmar:.2f}"}
def max_drawdown(nv):
return (nv / nv.cummax() - 1).min()