量化交易策略之均线策略
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]