返回列表 发布新帖

量化研究---简单粗暴的大qmt动量模型

558 0
发表于 2024-10-28 23:37:35 | 显示全部楼层 阅读模式

量化研究---简单粗暴的大qmt动量模型

文章链接https://mp.weixin.qq.com/s/8T-FT67lgtzlEch1HNHq4w

量化研究---简单粗暴的大qmt动量模型

策略设置的原理

c.trade_code_list=['513100.SH', '513350.SH', '159915.SZ','159937.SZ','511130.SH']
  c.trade_code_name=['纳斯达克ETF', '标普油气ETF', '创业板ETF','黄金ET','30年国债ETF']

选择5个标的相关性低的标的['纳斯达克ETF', '标普油气ETF', '创业板ETF','黄金ET','30年国债ETF']

利用5日收益做为因子,买入因子值最大的那个,卖出其他的持股,当收益最高的标的收益小于0,不启动买入模型,直接卖出空仓

收益因子

c.df=pd.DataFrame()
  c.df['证券代码']=c.trade_code_list
  c.df['名称']=c.trade_code_name
  print(c.df)
  #动量因子天数
  c.n=5
  c.start_tarder_return=0

因子的轮动算法

df['收益']=return_list
  df['时间']=today_1
  df=df.sort_values(by='收益',ascending=True)
  max_stock=df['证券代码'].tolist()[-1]
  stock=max_stock
  max_name=df['名称'].tolist()[-1]
  max_return=df['收益'].tolist()[-1]
  print('收益最高的标的{} {} 收益{}'.format(max_name,max_stock,max_return))
  if max_return>c.start_tarder_return:
    if max_stock in hold_stock_list:
      print('最高收益标的在{}持股不调仓'.format(stock))
      buy_df=pd.DataFrame()
      sell_df=pd.DataFrame()
    else:
      print('最高收益标的不在{}持股调仓,卖出全部持股,买入最高收益'.format(stock))
      buy_df=pd.DataFrame()
      buy_df['证券代码']=[max_stock]
      buy_df['名称']=[max_stock]
      buy_df['收益']=[max_return]
      sell_df=hold_stock
  else:
    print('收益最高的标的{} {} 收益{}小于0 卖出全部空仓'.format(max_name,max_stock,max_return))
    buy_df=pd.DataFrame()
    sell_df=hold_stock

  if sell_df.shape[0]>0:
    for stock in sell_df['证券代码'].tolist():
      order_target_percent(stock, 0, c, c.account)
      print('{} 卖出标的{}'.format(today_1,stock))
  else:
    print('{} 没有卖出标的'.format(today_1))
  if buy_df.shape[0]>0:
    for stock in buy_df['证券代码'].tolist():
      order_target_percent(stock, 1, c, c.account)
      print('{} 买入收益最高的标的{}'.format(today_1,stock))
  else:
    print('{} 没有买入标的'.format(today_1))

全部的源代码

#encoding:gbk
'''
全球动量模型策略回测
'''
import pandas as pd
import numpy as np
import talib
def init(c):
    #账户
    c.account='55011947'
    #账户类型
    c.account_type='STOCK'
    #开始时间
    c.start='20200101 00:00:00'
    #结束时间
    c.end='20500101 00:00:00'
    #测试资金
    c.capital=200000
    #交易股票池
    c.trade_code_list=['513100.SH', '513350.SH', '159915.SZ','159937.SZ','511130.SH']
    c.trade_code_name=['纳斯达克ETF', '标普油气ETF', '创业板ETF','黄金ET','30年国债ETF']
    c.df=pd.DataFrame()
    c.df['证券代码']=c.trade_code_list
    c.df['名称']=c.trade_code_name
    print(c.df)
    #动量因子天数
    c.n=5
    c.start_tarder_return=0
    #老版本的回测需要设定股票池,配合历史数据使用
    #c.set_universe(c.trade_code_list)
def handlebar(c):
    #当前K线索引号
    d=c.barpos
    #获取当前K线日期
    today=timetag_to_datetime(c.get_bar_timetag(d),'%Y-%m-%d')
    today_1=''.join(str(today).split('-'))
    '''
    #注意时间格式是20240101
    hist=c.get_market_data_ex(stock_code=c.trade_code_list,period='1d',
    end_time=today_1, count=-1, dividend_type='follow',fill_data=True, subscribe=False)
    print(hist)
    '''
    '''
    get_history_data(len, period, field, dividend_type = 0,skip_paused = True)
    '''
    #
    '''
    默认参数,除复权,默认不复权,可选值包括:
    0:不复权
    1:向前复权
    2:向后复权
    3:等比向前复权
    4:等比向后复权
    '''
    #必须使用前复权
    #hist=c.get_history_data(100,'1d',['open','close','low','high'],1)
    df=c.df
    return_list=[]
    hold_stock=get_position(c,c.account,c.account_type)
    if hold_stock.shape[0]>0:
        hold_stock_list=hold_stock['证券代码'].tolist()
    else:
        hold_stock_list=[]
    for stock,name  in zip(c.trade_code_list,c.trade_code_name):
        try:
            hist=c.get_market_data_ex(
            fields=[], 
            stock_code=[stock], 
            period='1d', 
            start_time=str(c.start)[:8], 
            end_time=today_1, 
            count=-1, 
            fill_data=True, 
            subscribe=True)
            hist=hist[stock]
            close_list=hist['close'].tolist()[-c.n:]
            zdf=((close_list[-1]-close_list[0])/close_list[0])*100
            return_list.append(zdf)
        except:
            pass
            return_list.append(-1)
    df['收益']=return_list
    df['时间']=today_1
    df=df.sort_values(by='收益',ascending=True)
    max_stock=df['证券代码'].tolist()[-1]
    stock=max_stock
    max_name=df['名称'].tolist()[-1]
    max_return=df['收益'].tolist()[-1]
    print('收益最高的标的{} {} 收益{}'.format(max_name,max_stock,max_return))
    if max_return>c.start_tarder_return:
        if max_stock in hold_stock_list:
            print('最高收益标的在{}持股不调仓'.format(stock))
            buy_df=pd.DataFrame()
            sell_df=pd.DataFrame()
        else:
            print('最高收益标的不在{}持股调仓,卖出全部持股,买入最高收益'.format(stock))
            buy_df=pd.DataFrame()
            buy_df['证券代码']=[max_stock]
            buy_df['名称']=[max_stock]
            buy_df['收益']=[max_return]
            sell_df=hold_stock
    else:
        print('收益最高的标的{} {} 收益{}小于0 卖出全部空仓'.format(max_name,max_stock,max_return))
        buy_df=pd.DataFrame()
        sell_df=hold_stock

    if sell_df.shape[0]>0:
        for stock in sell_df['证券代码'].tolist():
            order_target_percent(stock, 0, c, c.account)
            print('{} 卖出标的{}'.format(today_1,stock))
    else:
        print('{} 没有卖出标的'.format(today_1))
    if buy_df.shape[0]>0:
        for stock in buy_df['证券代码'].tolist():
            order_target_percent(stock, 1, c, c.account)
            print('{} 买入收益最高的标的{}'.format(today_1,stock))
    else:
        print('{} 没有买入标的'.format(today_1))

#获取账户总权益m_dBalance
def get_account(c,accountid,datatype):
    '''
    获取账户数据
    '''
    accounts = get_trade_detail_data(accountid, datatype, 'account')
    result={}
    for dt in accounts:
        result['总资产']=dt.m_dBalance
        result['净资产']=dt.m_dAssureAsset
        result['总市值']=dt.m_dInstrumentValue
        result['总负债']=dt.m_dTotalDebit
        result['可用金额']=dt.m_dAvailable
        result['盈亏']=dt.m_dPositionProfit
    return result
#获取持仓信息{code.market:手数}
def get_position(c,accountid,datatype):
    '''
    获取持股数据
    '''
    positions = get_trade_detail_data(accountid,datatype, 'position')
    data=pd.DataFrame()
    if len(positions)>0:
        df=pd.DataFrame()
        for dt in positions:
            df['股票代码']=[dt.m_strInstrumentID]
            df['市场类型']=[dt.m_strExchangeID]
            df['证券代码']=df['股票代码']+'.'+df['市场类型']
            df['证券名称']=[dt.m_strInstrumentName]
            df['持仓量']=[dt.m_nVolume]
            df['可用数量']=[dt.m_nCanUseVolume]
            df['成本价']=[dt.m_dOpenPrice]
            df['市值']=[dt.m_dInstrumentValue]
            df['持仓成本']=[dt.m_dPositionCost]
            df['盈亏']=[dt.m_dPositionProfit]
            data=pd.concat([data,df],ignore_index=True)
    else:
        data=pd.DataFrame()
    return data 







回复

您需要登录后才可以回帖 登录 | 立即注册

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2025 迅投QMT社区 版权所有 All Rights Reserved. 蜀ICP备19002686号-2
关灯 快速发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表