新建回测系统,并提交

This commit is contained in:
2026-01-17 21:37:42 +08:00
commit fe50ea935a
68 changed files with 108208 additions and 0 deletions

231
config/settings.py Normal file
View File

@@ -0,0 +1,231 @@
"""全局配置:路径、日期、资金、策略参数等。
所有路径尽量通过 BASE_DIR 派生,避免硬编码。
"""
from pathlib import Path
from utils.logger import setup_logger
logger = setup_logger(__name__)
# 项目根目录:假设本文件位于 strategy_backtest/config/settings.py
BASE_DIR: Path = Path(__file__).resolve().parent.parent.parent
# 数据与结果目录
DATA_DAY_DIR: Path = BASE_DIR / "data" / "day"
DATA_INDEX_DIR: Path = BASE_DIR / "data" / "index" # 指数数据目录
CODE_DIR: Path = BASE_DIR / "data" / "code"
RESULTS_DIR: Path = BASE_DIR / "strategy_backtest" / "results"
# 股票代码列表文件(如果存在,可以作为股票池来源)
STOCK_CODE_FILE: Path = CODE_DIR / "all_stock_codes.txt"
# 基准指数配置
BENCHMARK_FILE: Path = DATA_INDEX_DIR / "000001.SH.txt" # 上证指数
BENCHMARK_NAME: str = "上证指数" # 基准指数名称
# 回测时间区间含首尾格式YYYYMMDD
START_DATE: str = "20220101"
END_DATE: str = "20251231"
# 初始资金
INITIAL_CASH: float = 1000000.0
# ==================== 策略参数配置 ====================
# 每个策略都有自己独立的一套参数
# 均线交叉策略参数
MACROSS_MA_SHORT: int = 5 # 快速均线周期
MACROSS_MA_LONG: int = 15 # 慢速均线周期
MACROSS_HOLD_DAYS: int = 3 # 持有天数
MACROSS_MAX_POSITIONS: int = 2 # 最多持仓股票数
MACROSS_POSITION_PCT_PER_STOCK: float = 0.2 # 每只个股占总资金的比例0.2 = 20%
# 均线交叉策略风控参数
MACROSS_RISK_CONTROL = {
"stop_loss": {
"method": "fixed_pct", # 止损方法fixed_pct / atr / trailing
"stop_pct": 0.05, # 固定百分比止损5%
"atr_period": 14, # ATR周期
"atr_multiplier": 2.0, # ATR倍数
"trailing_pct": 0.10, # 跟踪止损回撤比例
},
"take_profit": {
"method": "fixed_pct", # 止盈方法fixed_pct / atr / trailing
"stop_pct": 0.10, # 固定百分比止盈10%
"atr_period": 14,
"atr_multiplier": 3.0,
"trailing_pct": 0.15, # 跟踪止盈回撤比例
},
}
# OCZ策略参数
OCZ_N: int = 30 # 阻力回望长度
OCZ_B: float = 60.0 # 实体占比门槛(%)
OCZ_V1: float = 1.5 # 放量倍数
OCZ_TOL: float = 1.5 # 回踩容错(%)
OCZ_R: float = 6.0 # 收盘涨幅门槛(%)
OCZ_HOLD_DAYS: int = 5 # 持有天数
OCZ_MAX_POSITIONS: int = 2 # 最多持仓股票数
OCZ_POSITION_PCT_PER_STOCK: float = 0.2 # 每只个股占总资金的比例
OCZ_VOLATILITY_MIN: float = 2.5 # 最小波动率(%)
OCZ_VOLATILITY_MAX: float = 8.0 # 最大波动率(%)
# OCZ策略风控参数突破回踩策略特点特殊止损止盈逻辑
# 注意OCZ策略使用策略内部的特殊止损止盈逻辑不使用通用风控模块
# 止损位 = 突破的阻力位,止盈位 = 买入价 + (买入价 - 阻力位) * 2 (盈亏比1:2)
OCZ_RISK_CONTROL = {
"stop_loss": {
"method": "custom", # 使用策略自定义逻辑,不使用通用风控模块
"stop_pct": 0, # 占位参数,实际不使用
},
"take_profit": {
"method": "custom", # 使用策略自定义逻辑
"stop_pct": 0, # 占位参数,实际不使用
},
}
# ==================== 策略配置 ====================
# 所有策略定义(统一管理)
STRATEGIES = {
"MaCrossStrategy": {
"module": "strategies.ma_cross",
"params": {
"ma_short": MACROSS_MA_SHORT,
"ma_long": MACROSS_MA_LONG,
"hold_days": MACROSS_HOLD_DAYS,
"max_positions": MACROSS_MAX_POSITIONS,
"position_pct_per_stock": MACROSS_POSITION_PCT_PER_STOCK,
},
"risk_control": MACROSS_RISK_CONTROL, # 每个策略独立的风控配置
},
"OczStrategy": {
"module": "strategies.ocz_strategy",
"params": {
"N": OCZ_N,
"B": OCZ_B,
"V1": OCZ_V1,
"TOL": OCZ_TOL,
"R": OCZ_R,
"hold_days": OCZ_HOLD_DAYS,
"volatility_min": OCZ_VOLATILITY_MIN,
"volatility_max": OCZ_VOLATILITY_MAX,
"max_positions": OCZ_MAX_POSITIONS,
"position_pct_per_stock": OCZ_POSITION_PCT_PER_STOCK,
},
"risk_control": OCZ_RISK_CONTROL, # 每个策略独立的风控配置
},
}
# 策略开关0=不回测, 1=回测)
# 作用:控制哪些策略需要回测,无需注释代码
STRATEGY_SWITCHES = {
"MaCrossStrategy": 1, # 1=开启均线交叉策略回测
"OczStrategy": 0, # 1=开启OCZ策略回测
}
# 为了兼容旧代码保留STRATEGY变量指向首个开启的策略
STRATEGY = None
for strategy_name, switch in STRATEGY_SWITCHES.items():
if switch == 1 and strategy_name in STRATEGIES:
STRATEGY = {
"name": strategy_name,
"module": STRATEGIES[strategy_name]["module"],
"params": STRATEGIES[strategy_name]["params"],
}
break
# 如果没有任何策略开启,默认使用第一个策略
if STRATEGY is None and STRATEGIES:
first_strategy_name = list(STRATEGIES.keys())[0]
STRATEGY = {
"name": first_strategy_name,
"module": STRATEGIES[first_strategy_name]["module"],
"params": STRATEGIES[first_strategy_name]["params"],
}
# 回测相关其他参数(预留)
TRADING_DAYS_PER_YEAR: int = 252
# 股票过滤规则
MIN_LISTING_DAYS: int = 60 # 最小上市天数,过滤新股(默认 60 天)
# Tushare 配置(仅用于获取交易日历)
# 注意:不要在公共仓库中提交真实 token可在本地修改此值
# 或设置环境变量 TUSHARE_TOKEN 来提供。
TUSHARE_TOKEN: str = "9343e641869058684afeadfcfe7fd6684160852e52e85332a7734c8d" # 在这里填写你的 Tushare token或留空使用环境变量
TUSHARE_CALENDAR_EXCHANGE: str = "SSE" # 交易所代码SSE 上交所SZSE 深交所
# ==================== 参数优化配置 ====================
OPTIMIZATION_N_JOBS: int = 4 # 并行进程数
OPTIMIZATION_TOP_N: int = 10 # 保存前N个最优结果
OPTIMIZATION_METRIC: str = "sharpe" # 排序指标sharpe / total_return / max_drawdown / annual_return
# 参数空间定义(根据策略配置不同的参数范围)
# 格式:{参数名: [最小值, 最大值, 步长]} 或 {参数名: [离散值列表]}
PARAM_SPACES: dict = {
# 均线交叉策略参数空间
"ma_cross": {
"ma_short": [5, 10, 2], # 短期均线3-20步長2 -> [3,5,7,9,11,13,15,17,19]
"ma_long": [15, 30, 5], # 长期均线20-60步長5 -> [20,25,30,35,40,45,50,55]
"hold_days": [3, 10, 1], # 持有天数3-10步長1 -> [3,4,5,6,7,8,9]
"position_pct_per_stock": [0.2, 0.4, 0.5], # 单股仓位比例(离散值)
},
# OCZ策略参数空间
"ocz": {
"N": [20, 40, 5], # 阻力回望长度20-40步長5
"B": [50, 70, 10], # 实体占比门槛50-70%步長10
"V1": [1.2, 1.8, 0.2], # 放量倍数1.2-1.8步長0.2
"TOL": [1.0, 2.0, 0.5], # 回踩容错1.0-2.0%步長0.5
"R": [3, 5, 1], # 涨幅门槛3-5%步長1
"hold_days": [3, 10, 1], # 持有天数3-10步長1
"position_pct_per_stock": [0.2, 0.3, 0.5], # 单股仓位比例
},
# 可以添加其他策略的参数空间
# "other_strategy": {
# "param1": [1, 10, 1],
# "param2": [0.1, 0.5, 0.1],
# },
}
# 参数约束条件(避免无意义的参数组合)
# 格式lambda params: 返回True表示合法False表示过滤
PARAM_CONSTRAINTS: dict = {
"ma_cross": lambda params: (
# 约束1短期均线必须小于长期均线
params.get("ma_short", 0) < params.get("ma_long", 999)
# 可以添加更多约束,例如:
# and params.get("hold_days", 0) >= 3
# and params.get("position_pct_per_stock", 0) <= 0.6
),
"ocz": lambda params: (
# 约束1N 必须大于持有天数(确保有足够历史数据)
params.get("N", 30) > params.get("hold_days", 0)
# 约束2实体占比必须大于0且小于100
and 0 < params.get("B", 60) < 100
# 约束3放量倍数必须大于1
and params.get("V1", 1.5) > 1.0
),
}
# ==================== 风险控制配置 ====================
# 止损止盈方法fixed_pct / atr / trailing
STOP_LOSS_METHOD: str = "fixed_pct"
STOP_LOSS_PCT: float = 0.05 # 固定百分比止损5%
TAKE_PROFIT_PCT: float = 0.10 # 固定百分比止盈15%
ATR_PERIOD: int = 14 # ATR周期
ATR_MULTIPLIER: float = 2.0 # ATR倍数
TRAILING_PCT: float = 0.10 # 跟踪止盈回撤比例10%
# ==================== 持仓规模优化配置 ====================
# 持仓方法equal_weight / kelly / volatility_target
POSITION_METHOD: str = "equal_weight"
KELLY_RISK_FREE: float = 0.03 # Kelly公式无风险利率
KELLY_MAX_FRACTION: float = 0.25 # Kelly最大仓位比例防止过度杠杆
VOLATILITY_TARGET: float = 0.15 # 目标波动率年化15%
VOLATILITY_WINDOW: int = 20 # 计算波动率的窗口期(天)
logger.info("settings.py 已加载配置")