115 lines
4.6 KiB
Python
115 lines
4.6 KiB
Python
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)
|