全部版块 我的主页
论坛 金融投资论坛 六区 金融实务版
91 1
2025-12-04

在 JoinQuant 平台上使用 Python 实现 MACD 金叉与死叉交易策略

本文将详细介绍如何基于 JoinQuant(聚宽)量化平台,利用 Python 编程语言实现经典的 MACD 技术指标策略。通过识别 MACD 的“金叉”和“死叉”信号,自动触发买入与卖出操作。文中包含完整可运行的代码示例,帮助您快速掌握策略开发流程。

策略核心逻辑说明

技术指标设置

采用标准 MACD 参数配置:快线周期为 12,慢线周期为 26,信号线周期为 9。

交易信号定义

  • 金叉(买入信号):当 DIF 线(差离值)从下方穿越 DEA 线(讯号线)时,判定为买入时机,执行全仓买入操作。
  • 死叉(卖出信号):当 DIF 线从上方穿过 DEA 线向下时,视为卖出信号,立即清空持仓。

数据处理方式

每个交易日获取目标股票过去 100 个交易日的收盘价数据,确保有足够的历史信息用于稳定计算 MACD 指标值。

计算工具支持

借助高效的第三方技术分析库进行指标运算,提升计算性能与准确性。

talib

完整策略代码实现

# -*- coding: utf-8 -*-
# 导入所需函数库
from jqdata import *
import talib
import numpy as np

def initialize(context):
    """
    初始化函数,配置基准、复权模式、标的股票及交易成本等参数
    """
    # 设定沪深300指数作为业绩基准
    set_benchmark('000300.XSHG')

    # 启用真实价格的动态复权模式
    set_option('use_real_price', True)

    # 指定操作的个股,此处以平安银行为例
    g.security = '000001.XSHE'

    # 定义MACD参数
    g.fast_period = 12   # 快线周期
    g.slow_period = 26   # 慢线周期
    g.signal_period = 9  # 信号线周期

    # 设置股票类交易的手续费与印花税
    set_order_cost(
        OrderCost(
            close_tax=0.001,           # 卖出印花税千分之一
            open_commission=0.0003,    # 买入佣金万分之三
            close_commission=0.0003,   # 卖出佣金万分之三
            min_commission=5           # 每笔最低5元
        ),
        type='stock'
    )

    # 每日开盘时执行 market_open 函数
    run_daily(market_open, time='every_bar')

def market_open(context):
    """
    日内交易逻辑主函数
    """
    security = g.security

    # 获取最近100天的日线收盘价数据
    close_data = attribute_history(security, 100, '1d', ['close'])

    # 转换为 numpy 数组格式以适配 talib 输入要求
    close_array = close_data['close'].values

    # 利用 talib 计算 MACD 三项输出:DIF, DEA, 柱状图
    macd_dif, macd_dea, macd_hist = talib.MACD(
        close_array,
        fastperiod=g.fast_period,
        slowperiod=g.slow_period,
        signalperiod=g.signal_period
    )

    # 提取当前及前一时刻的 DIF 与 DEA 值
    current_dif = macd_dif[-1]
    current_dea = macd_dea[-1]
    prev_dif = macd_dif[-2]
    prev_dea = macd_dea[-2]

    # 查询当前是否持有该股票
    current_position = context.portfolio.positions[security].closeable_amount

    # 获取账户可用现金
    cash = context.portfolio.available_cash

    # 判断交易条件并执行相应操作
    # 金叉判断:前一期 DIF 小于 DEA,当前期 DIF 大于 DEA
    if prev_dif < prev_dea and current_dif > current_dea:
        if cash > 0:
            order_value(security, cash)  # 使用全部可用资金买入
            log.info("MACD金叉,买入 %s" % security)

    # 死叉判断:前一期 DIF 大于 DEA,当前期 DIF 小于 DEA
    elif prev_dif > prev_dea and current_dif < current_dea:
        if current_position > 0:
            order_target(security, 0)  # 清仓卖出所有持股
            log.info("MACD死叉,卖出 %s" % security)
# 代码关键点解析

talib.MACD
该函数是一个高效的技术分析工具,能够返回三个数组:DIF(快线)、DEA(慢线)以及MACD柱状图。这些数据是判断买卖信号的核心依据。
attribute_history
在调用历史数据时,我们选取了过去100天的数据长度。尽管MACD的标准参数为12和26,但为了确保EMA(指数移动平均)计算的稳定性和准确性,通常需要提供比最长周期多出2-3倍的数据量,以便让指标充分收敛。 # 交叉判断逻辑 通过对比前一日与当日的DIF和DEA值,可以识别金叉或死叉信号: - 若昨日 DIF < DEA,而今日 DIF > DEA,则形成**金叉**,视为买入信号。 - 若昨日 DIF > DEA,而今日 DIF < DEA,则形成**死叉**,视为卖出信号。 elif prev_dif > prev_dea and current_dif < current_dea: # 当出现死叉信号时执行清仓操作 if current_position > 0: order_target(security, 0) log.info("MACD死叉,卖出 %s" % security)
[-1]
[-2]
# 核心交易指令说明
order_value(security, cash)
此命令表示使用当前账户中全部可用现金买入指定证券,实现满仓操作。
order_target(security, 0)
该指令将目标证券的持仓调整为零,即执行彻底的清仓卖出动作,不留余股。
order_value
order_target
# 常见问题解答(Q&A) Q: 为什么获取历史数据时不采用26天,而是选择100天? A: 因为MACD依赖EMA进行计算,而EMA具有递归特性,初始值对后续结果影响较大。若仅取26天数据,前期EMA尚未收敛,会导致指标失真。获取更长时间段(如100天以上)的数据可使EMA趋于稳定,从而保证回测中指标值与实际行情软件显示一致。 Q: 如何将此策略扩展为多只股票轮动模式? A: 可将
g.security
替换为一个股票代码列表,例如
g.stocks = ['000001.XSHE', '600519.XSHG']
。随后在
market_open
函数中,利用
for security in g.stocks:
循环逐一处理每只股票,分别完成数据提取、指标计算与下单操作。同时需考虑资金分配策略,比如将总资金均分为N份,每只股票使用1/N的资金量进行交易。 Q: 策略中的
set_option('use_real_price', True)
有何作用?
A: 此行启用了动态复权模式(即真实价格处理)。在实际市场中,股票会因分红、配股、拆合股等事件导致价格跳变。启用该选项后,聚宽平台会在回测过程中自动进行复权处理,确保所使用的股价序列连续无断点,避免因价格异常波动造成技术指标误判(例如股价除权后骤降被误认为死叉触发条件)。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
3 小时前
聚寬收费
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群