第四讲 玩转双均线策略

  • Leo
  • 发布于 10小时前
  • 阅读 30

什么是双均线策略双均线策略是金融市场中一种经典的趋势跟踪策略,其核心思想是利用两条不同周期的移动平均线的交叉来识别市场趋势的转向。当较短周期的均线(如5日均线)自下向上穿过较长周期的均线(如20日均线)时,形成“金叉”,被视为买入信号,表明短期趋势转强,可能开启上涨行情;反之,当短期均线自上向下

什么是双均线策略

双均线策略是金融市场中一种经典的趋势跟踪策略,其核心思想是利用两条不同周期的移动平均线的交叉来识别市场趋势的转向。

当较短周期的均线(如5日均线)自下向上穿过较长周期的均线(如20日均线)时,形成“金叉”,被视为买入信号,表明短期趋势转强,可能开启上涨行情;反之,当短期均线自上向下穿过长期均线,形成“死叉”,则被视为卖出信号,表明趋势可能反转下跌。

该策略通过捕捉趋势的启动和结束,帮助交易者跟随市场主要方向,但也可能在震荡行情中因频繁的交叉信号产生虚假交易信号。

国外有一个团队,还专门做过这么一个实验,让十几个完全不懂股票的人去操作交易,严格执行“金叉”买入,“死叉”卖出的交易规则。他们的收益竟然能跑赢大盘。

验证双均线

既然了解了双均线的一些基本原理,我们就随机挑选几支股票进行双均线的测试。当然挑选的股票,我们从上节课得到候选股票中进行筛选。

股票代码 股票名称 所属板块
300502.SZ 新易盛 通信行业
300533.SZ 冰川网络 传媒,游戏行业
605098.SH 行动教育 社会服务,教育行业

双均线策略代码

我在这轮测试中,会使用到backtrade作为我的测试工具,backTrade呢作为一款经典的交易回测工具,常常被用于股票,期货,加密货币领域的回测。后面我会单独开一个章节介绍backTrade的用法,大家可以先了解有这么一个东西。

主体功能

if __name__ == '__main__':
    stock_code = '300502.SZ'
    start_date = '2025-01-01'
    end_date = '2025-12-31'

    # 1. 从MySQL加载数据
    df = load_stock_data(stock_code, start_date, end_date)
    print(f"股票: {stock_code}")
    print(f"数据: {df.index[0].strftime('%Y-%m-%d')} ~ {df.index[-1].strftime('%Y-%m-%d')}  共{len(df)}个交易日")

    # 2. 创建 Cerebro 大脑 - Backtrader的核心引擎
    cerebro = bt.Cerebro()

    # 3. 添加策略
    cerebro.addstrategy(DoubleMAStrategy)

    # 4. 添加数据(将DataFrame转为Backtrader的数据格式)
    cerebro.adddata(bt.feeds.PandasData(dataname=df))

    # 5. 设置回测参数(从.env读取)
    cerebro.broker.setcash(INITIAL_CASH)                          # 初始资金
    cerebro.broker.setcommission(commission=COMMISSION)           # 手续费
    cerebro.addsizer(bt.sizers.PercentSizer, percents=POSITION_PCT)  # 仓位比例

    # 6. 添加分析器(用于计算绩效指标)
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe', riskfreerate=0.02)
    cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
    cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades')

    # 7. 运行回测
    results = cerebro.run()
    strat = results[0]

    # 8. 输出结果
    final_value = cerebro.broker.getvalue()
    total_return = (final_value - INITIAL_CASH) / INITIAL_CASH

    sharpe = strat.analyzers.sharpe.get_analysis()
    sharpe_ratio = sharpe.get('sharperatio', 0) or 0

    dd = strat.analyzers.drawdown.get_analysis()
    max_drawdown = dd.get('max', {}).get('drawdown', 0) / 100

    ta = strat.analyzers.trades.get_analysis()
    trade_count = ta.get('total', {}).get('total', 0)
    won = ta.get('won', {}).get('total', 0)
    win_rate = won / trade_count if trade_count > 0 else 0

    print(f"\n{'='*50}")
    print(f"初始资金:  {INITIAL_CASH:>14,.2f}")
    print(f"手续费:    {COMMISSION*10000:>11.1f} (万分之)")
    print(f"仓位比例:  {POSITION_PCT:>13d}%")
    print(f"最终资金:  {final_value:>14,.2f}")
    print(f"总收益率:  {total_return*100:>13.2f}%")
    print(f"最大回撤:  {max_drawdown*100:>13.2f}%")
    print(f"夏普比率:  {sharpe_ratio:>14.4f}")
    print(f"交易次数:  {trade_count:>14d}")
    print(f"胜率:      {win_rate*100:>13.2f}%")
    print(f"{'='*50}")

    run_and_report(DoubleMAStrategy, stock_code, '2025-01-01', '2025-12-31', label='双均线策略', plot=True)

策略逻辑

class DoubleMAStrategy(bt.Strategy):
    """双均线金叉/死叉策略"""
    params = (('fast', 10), ('slow', 30))

    def __init__(self):
        self.ma_fast = bt.indicators.SMA(self.data.close, period=self.p.fast)
        self.ma_slow = bt.indicators.SMA(self.data.close, period=self.p.slow)
        self.crossover = bt.indicators.CrossOver(self.ma_fast, self.ma_slow)

    def next(self):
        if not self.position:
            if self.crossover > 0:
                self.buy()
        elif self.crossover < 0:
            self.close()

整个策略逻辑,其实非常简单,就是金叉买入,死叉卖出

对测试结果进行分析

新易盛

image.png

冰川网络

image.png

行动教育

image.png

数据分析

股票 总收益 最大回撤 交易次数 胜率 对比买入持有
新易盛 311.30% 35.24% 3 1 433.73%
冰川网络 41.10% 23.00% 4 1 88.55%
行动教育 20.69% 5.81% 2 1 24.17%

从三支股票的结果上来进行分析,看得出来,这三支股票的整体收益还是不错,但是打脸的是,所有三支都比不上一直持有来得收益高。但是这是在我们事后诸葛亮的情况下,对比出来的。如果是人为进行操作的话,很大的可能在没有吃掉大肉的时候就直接跑掉了。

不过虽说总体的收益率不差,但是它也有一个比较大的局限性,通常。它的信号通常会滞后几天,这是由双均线的特性决定的。因此有没有更好的手段可以更早一步的感知市场情绪的变化呢? 当然是有的,就会在下一讲中提到,MACD策略。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Leo
Leo
江湖只有他的大名,没有他的介绍。