【量化】基于聚宽实现MACD均线择时策略

本文介绍了一种基于MACD指标的均线择时交易策略,该策略筛选出市盈率、市净率等财务指标良好的股票,并利用MACD的金叉和死叉信号决定买卖时机,每十天调整一次仓位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MACD均线择时策略是十分基础的策略,适合咱们这种新手学习,这篇博客就分享一下基于聚宽实现MACD均线择时策略。

代码:

注:需要到聚宽的量化平台去运行。

# MACD均线择时策略
'''
筛选出符合:
10<市盈率(pe_ratio)<40, 市净率(pb_ratio)<3, 净利润环比增长率(inc_net_profit_annual)>0.3,净资产收益率(roe)>15的股票,按照销售毛利率进行降序排列,选取前50只
买入:DIF从下而上穿过DEA,即形成金叉
卖出:DIF从上往下穿过DEA,即形成死叉
十天一次调仓
'''
import pandas as pd
import numpy as np
import talib  ## 使用talib计算MACD的参数
def initialize(context):
    g.days=0#计算持有天数
    g.refresh_rate=10#调仓的频率
    set_benchmark('000300.XSHG')#设置参考指数
    set_option('use_real_price', True)
    log.set_level('order', 'error')#过滤日志错误
    run_daily(trade, 'every_bar')
    
def before_trading_start(context):
    set_slip_fee(context)

#设置下滑,交易费率
def set_slip_fee(context):
    set_slippage(FixedSlippage(0.02)) 
    dt=context.current_dt
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    # if dt>datetime.datetime(2013,1, 1):
    #     set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')
    # else:
    #     set_order_cost(OrderCost(open_tax=0, open_commission=0.003,close_commission=0.003, close_tax=0.001,min_commission=5), type='stock')

#过滤停牌股票 
def paused_filter(security_list):
    current_data=get_current_data()
    security_list = [stock for stock in security_list if not current_data[stock].paused]
    return security_list

#过滤退市股票
def delisted_filter(security_list):
    current_data = get_current_data()
    security_list = [stock for stock in security_list if not '退' in current_data[stock].name]
    return security_list

#过滤ST   
def st_filter(security_list):
    current_data = get_current_data()
    security_list = [stock for stock in security_list if not current_data[stock].is_st]
    return security_list 
    
#对持仓股票每日进行检查,死叉卖出   
def zy_zs(context):
    dqhold = list(context.portfolio.positions.keys())
    for stock in dqhold:
            prices=attribute_history(stock,300,'1d',['close'])
            price=array(prices['close'])
            MACD_tmp=talib.MACD(price,fastperiod=12,slowperiod=26,signalperiod=20)
            DIF=MACD_tmp[0]
            DEA=MACD_tmp[1]
            MACD=MACD_tmp[2]
            if MACD[-1]<0 and MACD[-4]>0:
                order_target_value(stock, 0)
def trade(context):
    zy_zs(context)#卖出死叉个股
    #如果手中不持有股票,则立即进行选股
    if len(context.portfolio.positions.keys())==0:
        g.days=0
    #10<市盈率(pe_ratio)<40,每股盈余(eps)>0.3,净资产收益率(roe)>15,净利润环比增长率>0.3,并按照市净率进行升序排列,取前五十只。
    if g.days%g.refresh_rate==0:
        stock_to_choose=get_fundamentals(query(
                valuation.code,valuation.pe_ratio,valuation.market_cap,
                indicator.eps,indicator.inc_net_profit_annual
                ).filter(
                        valuation.pe_ratio<40,
                        valuation.pe_ratio>10,
                        indicator.eps>0.3,
                        indicator.inc_net_profit_annual>0.3,
                        indicator.roe>15
                        ).order_by(valuation.pb_ratio.asc()
                        ).limit(
                                50),date=None)
        #过滤停牌、退市、ST个股
        stockpool = list(stock_to_choose['code'])
        stockpool = paused_filter(stockpool)
        stockpool = delisted_filter(stockpool)
        stockpool = st_filter(stockpool)
        jx_list=[]#MACD金叉列表
        sx_list=[]#MACD死叉列表
        hold=[]#持有列表
          
        for stock in stockpool:
            prices=attribute_history(stock,300,'1d',['close'])
            price=array(prices['close'])
            MACD_tmp=talib.MACD(price,fastperiod=12,slowperiod=26,signalperiod=20)
            DIF=MACD_tmp[0]
            DEA=MACD_tmp[1]
            MACD=MACD_tmp[2]
            if MACD[-1]>0 and MACD[-4]<0:
                jx_list.append(stock)
            elif MACD[-1]<0 and MACD[-4]>0:
                sx_list.append(stock)
                
        #卖出手中死叉个股          
        stockset = list(context.portfolio.positions.keys())
        for stock in stockset:
            if stock in jx_list:
                hold.append(stock)#如果金叉则持有
            else:
                 order_target_value(stock, 0) #卖出非金叉个股
        #构建买入列表
        buy_list = []
        for stock in jx_list:
            if stock not in hold:
                buy_list.append(stock)#新增的买入股票
              
        #分配资金,购买股票      
        if len(buy_list)==0:
            Cash=context.portfolio.available_cash
        else:
            Cash = context.portfolio.available_cash/len(buy_list)
            for stock in buy_list:
                order_target_value(stock, Cash)        
        g.days = 1
    else:
        g.days += 1

 回测结果:

 

### 聗失的聚宽量化交易平台教程 #### 一、简介 聚宽(JoinQuant)是一个专注于量化投资研究的在线平台,提供了丰富的金融数据接口和强大的回测功能。它支持多种编程语言,尤其是 Python开发环境[^3]。 #### 二、安装与配置 为了使用 JQData 提供的数据服务,开发者可以通过 pip 工具轻松完成库文件的安装。以下是基本的操作命令: ```bash pip install jqdata ``` 此操作适用于 Windows、Mac 和 Linux 多种操作系统,并兼容 Python2 和 Python3 版本。 #### 三、基础 API 使用 JQData 平台的核心优势在于其简单易用的 API 接口设计。仅需少量代码即可获取所需的历史行情数据或其他市场指标。例如,下面展示如何查询某只股票一段时间内的收盘价: ```python import jqdata def get_close_price(stock_code, start_date, end_date): df = jqdata.get_price( security=stock_code, start_date=start_date, end_date=end_date, fields=['close'] ) return df['close'] prices = get_close_price('000001.XSHE', '2023-01-01', '2023-09-01') print(prices) ``` 上述脚本定义了一个函数 `get_close_price` 来提取指定时间段内特定证券的每日收盘价格。 #### 四、动态复权处理 当涉及长期历史数据分析时,考虑到股票可能经历拆分、合并或分红等情况的影响,启用动态复权模式尤为重要。这样可以确保所使用的股价序列保持连贯性和一致性[^4]。 需要注意的是,在实际应用过程中不应保存跨越不同日期间调用此类 API 所返回的结果,因为一旦发生任何改变复权因子的行为,则之前存储的信息可能会变得不准确。 #### 五、费用模拟设定 构建完整的交易策略模型还需要考虑成本因素,比如买卖手续费及印花税率等现实世界中的开支项目。这些参数可以在初始化阶段按照个人需求灵活调整。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值