2349.年化62%的动量策略 39838

策略名称:动量轮动策略

策略说明:

本策略基于动量效应,通过筛选过去一段时间内表现优异的股票进行投资。策略的核心思想是捕捉市场中的趋势,利用股票的短期动量获取超额收益。

策略核心逻辑:

  1. 股票池筛选

    • 筛选主板和中小板股票,排除科创板、北交所股票。

    • 排除上市未满250天的次新股。

    • 排除停牌、ST股和退市标签的股票。

  2. 动量计算

    • 计算每只股票过去91天的收益率(动量)。

    • 筛选动量最大的10只股票作为投资标的。

  3. 交易决策

    • 每日开盘前,根据动量筛选出目标股票。

    • 每日开盘时,卖出不在目标股票列表中的持仓股票,买入新筛选的目标股票。

  4. 风险控制

    • 排除股价低于5元的股票,避免低价股的高波动风险。

    • 限制持仓数量为10只,分散投资风险。

策略特点:

  • 动量效应:通过捕捉股票的短期趋势,获取超额收益。

  • 动态调仓:每日根据动量筛选结果调整持仓,保持组合的时效性。

  • 风险分散:限制持仓数量,避免过度集中风险。

适用场景:

  • 适用于A股市场,能够有效捕捉市场中的短期趋势。

  • 适合短线交易者,通过快速交易获取收益。

风险提示:

  • 动量策略在震荡市中可能表现不佳,需注意市场风险。

  • 策略依赖于历史数据的有效性,需定期优化参数以适应市场变化。


策略代码结构:

  1. 初始化函数(initialize

    • 设定基准指数(沪深300)。

    • 配置交易手续费和滑点。

    • 定义每日运行的函数(开盘前、开盘时、收盘后)。

  2. 开盘前运行函数(before_market_open

    • 筛选符合条件的股票,计算动量,更新目标股票列表。

  3. 开盘时运行函数(market_open

    • 根据目标股票列表调整持仓,卖出不在目标列表中的股票,买入新筛选的目标股票。

  4. 动量计算函数(get_momentum

    • 计算每只股票过去91天的收益率,筛选动量最大的10只股票。

  5. 过滤函数

    • filter_trade_stock:筛选主板和中小板股票。

    • filter_new_stock:排除上市未满250天的次新股。

    • filter_paused_stock:排除停牌股票。

    • filter_st_stock:排除ST股和退市标签的股票。

  6. 复盘函数(print_trade_info

    • 打印每日成交记录和持仓信息,便于复盘分析。


策略优化建议:

  1. 参数优化

    • 可对动量计算周期(如91天)进行优化,以适应不同的市场周期。

    • 调整持仓数量(如10只),以平衡风险与收益。

  2. 风险控制

    • 增加最大回撤限制,当回撤超过一定比例时暂停交易。

    • 设置单笔交易的最大亏损比例,避免单笔交易亏损过大。

  3. 多因子结合

    • 可结合其他技术指标(如成交量、MACD等)进行综合筛选,提高策略的稳定性。


总结:

本策略通过动量效应捕捉市场中的短期趋势,适合短线交易者在A股市场中获取收益。策略逻辑清晰,适合有一定编程基础的投资者进行进一步优化和实盘测试。

策略代码

#  年化62%的动量策略

#导入函数库
from jqdata import *
from jqfactor import get_factor_values
import numpy as np
import pandas as pd
from heapq import nlargest

#初始化函数 
def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 用真实价格交易
    set_option('use_real_price', True)
    # 打开防未来函数
    set_option("avoid_future_data", True)
    # 将滑点设置为0
    set_slippage(FixedSlippage(0))
    # 设置交易成本万分之三
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5),type='fund')
    # 过滤order中低于error级别的日志
    log.set_level('order', 'error')
    #选股参数
    g.stock_num = 10 #持仓数
    g.day_count = 91 #动量计算参数
    g.stock_price = 5 #股价筛选参数
    # 开盘前运行
    run_daily(before_market_open, time='before_open', reference_security='000300.XSHG')
    # 开盘时运行
    run_daily(market_open, time='open', reference_security='000300.XSHG')
    run_daily(print_trade_info, time='15:30', reference_security='000300.XSHG')

## 开盘前运行函数
def before_market_open(context):
    # 输出运行时间
    log.info('函数运行时间(before_market_open):'+str(context.current_dt.time()))

    # 要操作的股票:(g.为全局变量)
    initial_list = get_all_securities().index.tolist()
    initial_list = filter_trade_stock(context, initial_list)
    initial_list = filter_new_stock(context,initial_list)
    initial_list = filter_paused_stock(initial_list)
    initial_list = filter_st_stock(initial_list)
    #接下来预持有的代码
    next_holding_codes = get_momentum(context, initial_list)
    #持有的代码
    holding_codes=list(context.portfolio.positions.keys())
    #在昨日持仓列表中而不在今日预持仓列表中
    g.security1 = [x for x in holding_codes if x not in next_holding_codes]  
    #在今日预持仓列表中而不在昨日持仓列表中
    g.security2 = [y for y in next_holding_codes if y not in holding_codes]  
        
    # 给微信发送消息(添加模拟交易,并绑定微信生效)
    # send_message('美好的一天~')

## 开盘时运行函数
def market_open(context):
    log.info('函数运行时间(market_open):'+str(context.current_dt.time()))
    security1 = g.security1
    security2 = g.security2
    #平仓
    for stock in security1:
        order_target(stock, 0)
    #开仓
    cash = context.portfolio.available_cash / len(security2)
    for stock in security2:
        order_value(stock, cash)
    

关键函数解锁后查看:


#1 过滤模块-选取主板、中小板
#输入股票列表,返回选取主板、中小板后的列表
def filter_trade_stock(context, stock_list):
    return [stock for stock in stock_list  if stock[0:2] == '60' or stock[0:2] == '00']
    
#2 过滤次新股
#输入股票列表,返回剔除上市日期不足250日股票后的列表
def filter_new_stock(context,stock_list):
    yesterday = context.previous_date
    return [stock for stock in stock_list if not yesterday - get_security_info(stock).start_date < datetime.timedelta(days=250)]

#3 过滤模块-过滤停牌股票
#输入选股列表,返回剔除停牌股票后的列表
def filter_paused_stock(stock_list):
    current_data = get_current_data()
    return [stock for stock in stock_list if not current_data[stock].paused]

#4 过滤模块-过滤ST及其他具有退市标签的股票
#输入选股列表,返回剔除ST及其他具有退市标签股票后的列表
def filter_st_stock(stock_list):
    current_data = get_current_data()
    return [stock for stock in stock_list
            if not current_data[stock].is_st
            and 'ST' not in current_data[stock].name
            and '*' not in current_data[stock].name
            and '退' not in current_data[stock].name]



#复盘模块-打印
#打印每日持仓信息
def print_trade_info(context):
    #打印当天成交记录
    trades = get_trades()
    for _trade in trades.values():
        print('成交记录:'+str(_trade))
    #打印账户信息
    for position in list(context.portfolio.positions.values()):
        securities=position.security
        cost=position.avg_cost
        price=position.price
        ret=100*(price/cost-1)
        value=position.value
        amount=position.total_amount    
        print('代码:{}'.format(securities))
        print('成本价:{}'.format(format(cost,'.2f')))
        print('现价:{}'.format(price))
        print('收益率:{}%'.format(format(ret,'.2f')))
        print('持仓(股):{}'.format(amount))
        print('市值:{}'.format(format(value,'.2f')))
        print('———————————————————————————————————')
    print('———————————————————————————————————————分割线————————————————————————————————————————')
2025-02-23
⚠️
本站资源大多来自网络,仅供网友学习交流,未经作者或上传书面授权,请勿作他用。
站长 vx: xiangyin615 或者 留言反馈 ,我们将尽快处理。
Notice: When you of the legal rights be violate, please stir to vx: xiangyin615
个人中心
购物车
优惠劵
搜索