import numpy as np import pandas as pd from pandas import Series,DataFrame def initialize(context): # 设定沪深300作为基准 set_benchmark('000300.XSHG') # 开启动态复权模式(真实价格) set_option('use_real_price', True) # 股票类交易手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱 set_order_cost(OrderCost(open_tax=0, close_tax=0.001, \ open_commission=0.0003, close_commission=0.0003,\ close_today_commission=0, min_commission=5), type='stock') def handle_data(context, data): #获取沪深300股票池 stock_set=get_index_stocks('000300.XSHG') #此处可增加选股条件 q = query( valuation.code, # 股票代码 ).filter( valuation.code.in_(stock_set),#只对设定股票池执行 ) #获取财务数据,指定日期为回测当天 current_date=context.current_dt.strftime('%Y-%m-%d') fdf = get_fundamentals(q,current_date) #取前50只股 fdf=fdf.head(100) #获取股票列表 get_stocks=list(fdf['code']) # 去除ST,*ST st=get_extras('is_st',get_stocks,current_date,current_date, df=True) st=st.loc[current_date] get_stocks=list(st[st==False].index) #考虑5天的历史数据 num=5 #轨线用前面20天数据计算 days=20 #每只股票可用资金为当前资金除以50 cash=context.portfolio.available_cash/100 #获取所有股票前num+days天收盘价数据 price=history(num+days,'1d','close',get_stocks,skip_paused=True) where_are_nan = np.isnan(price) where_are_inf = np.isinf(price) price[where_are_nan] = 0 price[where_are_inf] = 0 #循环每只股 for security in get_stocks: #用数组保存均值,大小为num mid=np.arange(num) #标准差 std=np.arange(num) #定义数组大小 close_data=np.arange(num*days).reshape(num,days) for i in range(0,num): for j in range(0,days): close_data[i][j]=price[security][i+j] #中轨线即均值为days天收盘价数据平均 mid[i]=np.mean(close_data[i]) #计算标准差 std[i]=np.std(close_data[i]) #上轨线=中轨线+两倍的标准差 up=mid[num-1]+2*std[num-1] #下轨线 down=mid[num-1]-2*std[num-1] #保存num天数据,判断开口收口或平口 boll=0 for i in range(0,num-1): if std[i]>std[i+1]: boll=boll+1 else: boll=boll-1 #判断目前股票是否停牌 paused=data[security].paused #取得当前股票价格 current_price=data[security].price #如果连续num天开口 if boll==-4: #如果当前价格超过昨日的上轨且价格高于均线 if current_price>up and current_price>mid[num-1]: #计算可以买多少股票 num_of_shares=int(cash/current_price) #如果可以买的数量超过0并且股票未停牌 if num_of_shares>0 and paused==False: #购买股票 order(security,+num_of_shares) #如果当前价格跌破了昨日的下轨且价格低于均线 elif current_priceup and current_pricemid[num-1]: num_of_shares=int(cash/current_price) if num_of_shares>0 and paused==False: order(security,+num_of_shares) #连续平口 if boll in range(-1,1): #价格在中轨线上且昨日均价高于三天前 if current_price>mid[num-1] and mid[num-1]>mid[num-3]: num_of_shares=int(cash/current_price) if num_of_shares>0 and paused==False: order(security,+num_of_shares) if current_price