quant001 发表于 2019-7-18 07:02:11

量化交易策略之均线策略

http://s8.sinaimg.cn/mw690/001uapR3zy75g4urUh107&690



收益风险
http://s8.sinaimg.cn/mw690/001uapR3zy75g4vpMJpe7&690

http://s7.sinaimg.cn/mw690/001uapR3zy75g4vvlFY76&690

http://s8.sinaimg.cn/mw690/001uapR3zy75g4vy1oPe7&690

http://s4.sinaimg.cn/mw690/001uapR3zy75g4vA69J43&690

http://s11.sinaimg.cn/mw690/001uapR3zy75g4vBL4u9a&690


源码:

#股票池需要如下:
#沪深300池,
#当前不停牌的股票池,
#有历史数据的股票池,
#两者的交集得到可用股票池
#持仓股票池
#可用股票池中剔除持仓股票得到的股票池(可以进行买入操作的股票池)
#将要买入的股票池:即上述股票池中发出买入信号得到的股票池
#将要卖出的股票池:持仓股票池中,没有停牌的,发出卖出信号的股票池

import random
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import scipy.stats as stats
import math
def initialize(context):
    #初始化沪深300
    g.stocks_ttl = get_index_stocks('000300.XSHE')
    set_universe(g.stocks_ttl)
    set_commission(PerTrade(buy_cost=0.0005, sell_cost=0.0013, min_cost=5))
    #初始化可用股票池(不停牌的股票池)
    g.stocks_trading=[]
    #初始化有历史数据的股票池
    g.stocks_hist=[]
    #初始化持仓股票池
    g.stocks_hold=[]
    #初始化备选股票池
    g.stocks_toChoose=[]
    #将要买入的股票池
    g.stocks_toBuy=[]
    #将要卖出的股票池
    g.stocks_toSell=[]
    #长短均线的间隔
    g.shortMA=1
    g.longMA=60
    #持仓持有股票数量的最大上限
    g.numHoldmax=100
    # 坑满时每次调仓量
    g.num_of_change=4
    #设置计算几日收益率
    g.period=10

def before_trading_start(context):
    #得到当前的可用的股票池
    g.stocks_ttl = get_index_stocks('000300.XSHE')
    set_universe(g.stocks_ttl)
    current_data = get_current_data(g.stocks_ttl)
    g.stocks_trading=[]
    length=len(current_data)
    #得到有历史数据的股票池,并且得到有历史数据
    operate_buy={}
    g.stocks_hist=[]
    for i in range(0,length):
      #得到当前的不停牌股票
      if not current_data].paused:
            #取出有历史数据的股票,如果历史数据能够支撑运算,顺便也把买入的信号一做
            temp_hist= attribute_history(g.stocks_ttl,g.longMA+1, '1d', ('close'),skip_paused=True)
            temp_hist=temp_hist.dropna()
            if len(temp_hist['close'])>=g.longMA:
                g.stocks_hist.append(g.stocks_ttl)
                signal=cal_signal(temp_hist)
                operate_buy.update({g.stocks_ttl:signal})

    #得到最后的备选池
    g.stocks_toChoose=list(set(g.stocks_hist).difference(set(g.stocks_hold)))
   
    #得到最终的可执行池:即发出信号的买入池
    g.stocks_toBuy=[]
    length=len(g.stocks_toChoose)
    for i in range(0,length):
      if operate_buy]==1:
            g.stocks_toBuy.append(g.stocks_toChoose)

    #得到发出信号的卖出池
    g.stocks_toSell=[]
    length=len(g.stocks_hold)
    if length>0:
      current_hold=get_current_data(g.stocks_hold)
      for i in range(0,length):
            #如果当天股票不停牌,则进行下一步计算
            if not current_hold].paused:
                temp_hist= attribute_history(g.stocks_hold,g.longMA+1, '1d', ('close'),skip_paused=True)
                signal=cal_signal(temp_hist)
                if signal==-1:
                  g.stocks_toSell.append(g.stocks_hold)
               
   
#输入某只股票的hist数据,然后判断是否发出买入卖出信号,输入为dataframe,输出为
#数字1:买入,-1卖出,0表示不变
def cal_signal(data_withHist):
    length=len(data_withHist.iloc[:,0])
    MA_shortYesterday=calMA(data_withHist,g.shortMA)
    MA_shortBeforeYesterday=calMA(data_withHist.head(length-1),g.shortMA)
    MA_longYesterday=calMA(data_withHist,g.longMA)
    MA_longBeforeYesterday=calMA(data_withHist.head(length-1),g.longMA)
    signal=0
    if MA_shortBeforeYesterdayMA_longYesterday:
      signal=1
    elif MA_shortYesterday
      signal=-1
    return signal
   
#输入某只股票的hist数据,计算MA,返回一个数
def calMA(data_withHist,num):
    ma=data_withHist.tail(num).mean()
    ma=ma.values
    return ma

#构成一个列索引为股票名,收益率一行的索引为
#'return'的dataframe,并返回这个dataframe
def calreturn(stocklist):
    #取出每只股票period天的收盘价格
    stocks_info=history(g.period,'1d','close',security_list=stocklist)
    #去除信息不全的数据
    stocks_info.dropna(axis=0,how='any',thresh=None)
    #取出昨天和period天之前的收盘价,计算收益率
    a1=list(stocks_info.iloc)
    a2=list(stocks_info.iloc)
    a1=np.array(a1)
    a2=np.array(a2)
    #用一个dataframe来保存所有股票的收益率信息
    stocks_return=DataFrame(a2/a1,columns=['return'],index=stocks_info.columns)
    stocks_info=stocks_info.T
    #把收益率的数据加到相应的列
    stocks_info=pd.concat(,axis=1)
    #将股票信息按照收益率从小到大来存储
    stocks_info=stocks_info.sort(columns=['return'],ascending=)
    #返回处理好的dataframe
    return stocks_info   

def handle_data(context,data):
    #首先卖出持仓中该卖出的股票
    for i in range(0,len(g.stocks_toSell)):
      order_target(g.stocks_toSell,0, LimitOrderStyle(0.01))
    g.stocks_hold=list(set(g.stocks_hold).difference(set(g.stocks_toSell)))
    # 计算还剩下的坑位
    num_canBuy=g.numHoldmax-len(g.stocks_hold)
   
    # 如果坑满了,剔除坑中持有的一部分收益不好的股票,买入备选池中收益率较好的股票
    if num_canBuy == 0 and len(g.stocks_toBuy)>0:
      stocks_holdreturnup=calreturn(g.stocks_hold)
      stocks_tobuyreturnup=calreturn(g.stocks_toBuy)
      for i in range(0,min(len(g.stocks_toBuy),g.num_of_change)):
            order_target(stocks_holdreturnup.index,0, LimitOrderStyle(0.01))
            g.stocks_hold.remove(stocks_holdreturnup.index)
      num_canBuy=g.numHoldmax-len(g.stocks_hold)
      cash_ttl=context.portfolio.cash
      cash_perShare=cash_ttl/num_canBuy
      for i in range(0,num_canBuy):
            order_target_value(stocks_tobuyreturnup.index,cash_perShare,LimitOrderStyle(9999))
   
    # 如果坑没满
    elif num_canBuy>0:
      cash_ttl=context.portfolio.cash
      cash_perShare=cash_ttl/num_canBuy
      #如果备选股票池中的股票数量小于可买的股票,则全部买入
      if len(g.stocks_toBuy)<=num_canBuy:
            for i in range(0,len(g.stocks_toBuy)):
                order_target_value(g.stocks_toBuy,cash_perShare,LimitOrderStyle(9999))
   
      #如果备选池的股票大于可买数量,则按照收益率买入
      elif len(g.stocks_toBuy)>num_canBuy:
            stocks_tobuyreturnup=calreturn(g.stocks_toBuy)
            for i in range (0,num_canBuy):
               order_target_value(stocks_tobuyreturnup.index,cash_perShare,LimitOrderStyle(9999))
                #成功下单完了以后更新g.stocks_hold
   
    #记录一下实际持仓:
def after_trading_end(context):
    g.stocks_hold=context.portfolio.positions.keys()
    #log.info("一天结束后的持仓")
    #log.info(g.stocks_hold)
   


页: [1]
查看完整版本: 量化交易策略之均线策略