量化交易策略之均线策略

0
回复
3389
查看
[复制链接]

209

主题

26

回帖

1424

积分

超级版主

积分
1424
来源: 2019-7-18 07:02:11 显示全部楼层 |阅读模式




收益风险











源码:

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

  10. import random
  11. import numpy as np
  12. import pandas as pd
  13. from pandas import Series,DataFrame
  14. import scipy.stats as stats
  15. import math
  16. def initialize(context):
  17.     #初始化沪深300
  18.     g.stocks_ttl = get_index_stocks('000300.XSHE')
  19.     set_universe(g.stocks_ttl)
  20.     set_commission(PerTrade(buy_cost=0.0005, sell_cost=0.0013, min_cost=5))
  21.     #初始化可用股票池(不停牌的股票池)
  22.     g.stocks_trading=[]
  23.     #初始化有历史数据的股票池
  24.     g.stocks_hist=[]
  25.     #初始化持仓股票池
  26.     g.stocks_hold=[]
  27.     #初始化备选股票池
  28.     g.stocks_toChoose=[]
  29.     #将要买入的股票池
  30.     g.stocks_toBuy=[]
  31.     #将要卖出的股票池
  32.     g.stocks_toSell=[]
  33.     #长短均线的间隔
  34.     g.shortMA=1
  35.     g.longMA=60
  36.     #持仓持有股票数量的最大上限
  37.     g.numHoldmax=100
  38.     # 坑满时每次调仓量
  39.     g.num_of_change=4
  40.     #设置计算几日收益率
  41.     g.period=10

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

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

  71.     #得到发出信号的卖出池
  72.     g.stocks_toSell=[]
  73.     length=len(g.stocks_hold)
  74.     if length>0:
  75.         current_hold=get_current_data(g.stocks_hold)
  76.         for i in range(0,length):
  77.             #如果当天股票不停牌,则进行下一步计算
  78.             if not current_hold[g.stocks_hold[i]].paused:
  79.                 temp_hist= attribute_history(g.stocks_hold[i],g.longMA+1, '1d', ('close'),skip_paused=True)
  80.                 signal=cal_signal(temp_hist)
  81.                 if signal==-1:
  82.                     g.stocks_toSell.append(g.stocks_hold[i])
  83.                
  84.    
  85. #输入某只股票的hist数据,然后判断是否发出买入卖出信号,输入为dataframe,输出为
  86. #数字1:买入,-1卖出,0表示不变
  87. def cal_signal(data_withHist):
  88.     length=len(data_withHist.iloc[:,0])
  89.     MA_shortYesterday=calMA(data_withHist,g.shortMA)
  90.     MA_shortBeforeYesterday=calMA(data_withHist.head(length-1),g.shortMA)
  91.     MA_longYesterday=calMA(data_withHist,g.longMA)
  92.     MA_longBeforeYesterday=calMA(data_withHist.head(length-1),g.longMA)
  93.     signal=0
  94.     if MA_shortBeforeYesterdayMA_longYesterday:
  95.         signal=1
  96.     elif MA_shortYesterday
  97.         signal=-1
  98.     return signal
  99.    
  100. #输入某只股票的hist数据,计算MA,返回一个数
  101. def calMA(data_withHist,num):
  102.     ma=data_withHist.tail(num).mean()
  103.     ma=ma.values[0]
  104.     return ma

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

  126. def handle_data(context,data):
  127.     #首先卖出持仓中该卖出的股票
  128.     for i in range(0,len(g.stocks_toSell)):
  129.         order_target(g.stocks_toSell[i],0, LimitOrderStyle(0.01))
  130.     g.stocks_hold=list(set(g.stocks_hold).difference(set(g.stocks_toSell)))
  131.     # 计算还剩下的坑位
  132.     num_canBuy=g.numHoldmax-len(g.stocks_hold)
  133.    
  134.     # 如果坑满了,剔除坑中持有的一部分收益不好的股票,买入备选池中收益率较好的股票
  135.     if num_canBuy == 0 and len(g.stocks_toBuy)>0:
  136.         stocks_holdreturnup=calreturn(g.stocks_hold)
  137.         stocks_tobuyreturnup=calreturn(g.stocks_toBuy)
  138.         for i in range(0,min(len(g.stocks_toBuy),g.num_of_change)):
  139.             order_target(stocks_holdreturnup.index[i],0, LimitOrderStyle(0.01))
  140.             g.stocks_hold.remove(stocks_holdreturnup.index[i])
  141.         num_canBuy=g.numHoldmax-len(g.stocks_hold)
  142.         cash_ttl=context.portfolio.cash
  143.         cash_perShare=cash_ttl/num_canBuy
  144.         for i in range(0,num_canBuy):
  145.             order_target_value(stocks_tobuyreturnup.index[len(stocks_tobuyreturnup)-i-1],cash_perShare,LimitOrderStyle(9999))
  146.    
  147.     # 如果坑没满
  148.     elif num_canBuy>0:
  149.         cash_ttl=context.portfolio.cash
  150.         cash_perShare=cash_ttl/num_canBuy
  151.         #如果备选股票池中的股票数量小于可买的股票,则全部买入
  152.         if len(g.stocks_toBuy)<=num_canBuy:
  153.             for i in range(0,len(g.stocks_toBuy)):
  154.                 order_target_value(g.stocks_toBuy[i],cash_perShare,LimitOrderStyle(9999))
  155.    
  156.         #如果备选池的股票大于可买数量,则按照收益率买入
  157.         elif len(g.stocks_toBuy)>num_canBuy:
  158.             stocks_tobuyreturnup=calreturn(g.stocks_toBuy)
  159.             for i in range (0,num_canBuy):
  160.                  order_target_value(stocks_tobuyreturnup.index[len(stocks_tobuyreturnup)-i-1],cash_perShare,LimitOrderStyle(9999))
  161.                 #成功下单完了以后更新g.stocks_hold
  162.    
  163.     #记录一下实际持仓:
  164. def after_trading_end(context):
  165.     g.stocks_hold=context.portfolio.positions.keys()
  166.     #log.info("一天结束后的持仓")
  167.     #log.info(g.stocks_hold)
  168.    
复制代码
美元-上涨.jpg



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 免费注册
关注微信