From a2a261769bcd1bd5bf017034a5100edf621ffb10 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Wed, 28 Jan 2026 09:54:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E9=A3=8E?= =?UTF-8?q?=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backtest.py | 47 +++++++++---------------------------- strategies/macd_strategy.py | 13 +++++----- 2 files changed, 17 insertions(+), 43 deletions(-) diff --git a/backtest.py b/backtest.py index a653a87..b48fc6b 100644 --- a/backtest.py +++ b/backtest.py @@ -135,40 +135,19 @@ def parse_arguments(): 返回: args: 命名空间对象 """ - parser = argparse.ArgumentParser( - description="量化回测工具", formatter_class=argparse.RawDescriptionHelpFormatter - ) + parser = argparse.ArgumentParser(description="量化回测工具", formatter_class=argparse.RawDescriptionHelpFormatter) # 必需参数 - parser.add_argument( - "--code", type=str, required=True, help="股票代码 (如: 000001.SZ)" - ) - parser.add_argument( - "--start-date", type=str, required=True, help="回测开始日期 (格式: YYYY-MM-DD)" - ) - parser.add_argument( - "--end-date", type=str, required=True, help="回测结束日期 (格式: YYYY-MM-DD)" - ) - parser.add_argument( - "--strategy-file", - type=str, - required=True, - help="策略文件路径 (如: strategy.py)", - ) + parser.add_argument("--code", type=str, required=True, help="股票代码 (如: 000001.SZ)") + parser.add_argument("--start-date", type=str, required=True, help="回测开始日期 (格式: YYYY-MM-DD)") + parser.add_argument("--end-date", type=str, required=True, help="回测结束日期 (格式: YYYY-MM-DD)") + parser.add_argument("--strategy-file", type=str, required=True, help="策略文件路径 (如: strategy.py)", ) # 可选参数 - parser.add_argument( - "--cash", type=float, default=100000, help="初始资金 (默认: 100000)" - ) - parser.add_argument( - "--commission", type=float, default=0.002, help="手续费率 (默认: 0.002)" - ) - parser.add_argument( - "--output", type=str, default=None, help="HTML 输出文件路径 (可选)" - ) - parser.add_argument( - "--warmup-days", type=int, default=365, help="预热天数 (默认: 365,约一年)" - ) + parser.add_argument("--cash", type=float, default=100000, help="初始资金 (默认: 100000)") + parser.add_argument("--commission", type=float, default=0.002, help="手续费率 (默认: 0.002)") + parser.add_argument("--output", type=str, default=None, help="HTML 输出文件路径 (可选)") + parser.add_argument("--warmup-days", type=int, default=365, help="预热天数 (默认: 365,约一年)") return parser.parse_args() @@ -255,21 +234,17 @@ def main(): data = load_data_from_db(args.code, args.start_date, args.end_date) print(f"数据加载完成,共 {len(data)} 条记录") - # 截取预热数据 - warmup_data = data.iloc[-args.warmup_days:] - print(f"使用预热数据范围: {warmup_data.index[0]} ~ {warmup_data.index[-1]}") - # 加载策略 calculate_indicators, strategy_class = load_strategy(args.strategy_file) # 计算指标 - warmup_data = calculate_indicators(warmup_data) + data = calculate_indicators(data) # 执行回测 from backtesting import Backtest bt = Backtest( - warmup_data, + data, strategy_class, cash=args.cash, commission=args.commission, diff --git a/strategies/macd_strategy.py b/strategies/macd_strategy.py index 4f77bf5..773648e 100644 --- a/strategies/macd_strategy.py +++ b/strategies/macd_strategy.py @@ -38,7 +38,7 @@ def calculate_indicators(data): 返回: DataFrame, 添加了指标列: - - dif: MACD 线 (dif) + - macd: MACD 线 (macd) - signal: MACD 信号线 (DEA) - hist: MACD 柱状图 (Histogram) - ema: 日指数移动平均线 @@ -49,7 +49,7 @@ def calculate_indicators(data): # talib.MACD 返回三个值: (macd, macdsignal, macdhist) macd, macdsignal, macdhist = talib.MACD(data["Close"], fastperiod=10, slowperiod=20, signalperiod=9) - data["dif"] = macd + data["macd"] = macd data["signal"] = macdsignal data["hist"] = macdhist @@ -92,10 +92,10 @@ class MacdTrendStrategy(Strategy): 注册指标到 backtesting 框架 """ # 注册 MACD 线 - self.macd = self.I(lambda x: x, self.data.dif) + self.macd = self.I(lambda x: x, self.data.macd) # 注册 MACD 信号线 - self.macd_signal = self.I(lambda x: x, self.data.signal) + self.signal = self.I(lambda x: x, self.data.signal) # 注册 EMA 趋势线 self.ema = self.I(lambda x: x, self.data.ema) @@ -113,12 +113,11 @@ class MacdTrendStrategy(Strategy): - 或价格 < EMA (趋势转向,强制平仓) """ # 买入条件: MACD 金叉 AND 价格 > EMA - if crossover(self.macd, self.macd_signal) and self.data.Close[-1] > self.ema[-1]: - self.position.close() # 先平掉现有仓位 + if crossover(self.macd, self.signal) and self.data.Close[-1] > self.ema[-1]: self.buy() # 开多仓 # 卖出条件: MACD 死叉 OR 价格 < EMA - elif crossover(self.macd_signal, self.macd) or self.data.Close[-1] < self.ema[-1]: + elif crossover(self.signal, self.macd) or self.data.Close[-1] < self.ema[-1]: self.position.close() # 平掉多仓