Files

115 lines
4.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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_price<down and current_price<mid[num-1]:
#如果股票未停牌
if paused==False:
#将股票卖空
order_target(security,0)
#如果连续num天收口
if boll==4:
#股价超过上轨且价格低于均线时卖
if current_price>up and current_price<mid[num-1]:
if paused==False:
order_target(security,0)
#跌破下轨且价格高于均线时买
elif current_price<down and current_price>mid[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<mid[num-1] and mid[num-1]<mid[num-3]:
if paused==False:
order_target(security,0)