欢迎使用CSDN-markdown编辑器

来源:互联网 发布:ubuntu添加中文输入法 编辑:程序博客网 时间:2024/06/05 02:04
# 导入函数库import jqdataimport pandas as pdimport numpy as npimport datetimefrom sklearn.ensemble import RandomForestClassifierfrom sklearn import svm#————————————————————————————————————————————————初始化函数————————————————————————————————————def initialize(context):    set_params()      # 1设置策参数    set_variables()   # 2设置中间变量    set_backtest()    # 3设置回测条件    #设置策略参数def set_params():    g.frequency = 5    # 设置调仓天数    g.stock_number = 20  # 选择股票的个数,(默认20,可能会修改)    g.factors = ['open', 'close','low','high','volume','money']#自己选取的技术指标    g.interval = g.frequency + 1 #间隔日期数    g.trees = 15   #随机森林的树量#设置中间变量def set_variables():    g.total = 0                # 记录回测运行的天数    g.if_trade = False     # 当天是否交易#设置回测条件def set_backtest():    set_option('use_real_price',True) # 用真实价格交易    log.set_level('order','error')    # 设置报错等级#————————————————————————————————————————————————初始化函数——————————————————————————————————————
#————————————————————————————————————————————开盘前——————————————————————————————————————————————def before_trading_start(context):    if g.total % g.frequency == 0:        #每g.tc天,交易一次        g.if_trade = True         # 设置手续费与手续费        set_slip_fee(context)         # 设置可行股票池:获得当前开盘的沪深300股票池并剔除当前或者计算样本期间停牌的股票        g.stocks = set_feasible_stocks(get_index_stocks('000300.XSHG'),g.interval,context)    g.total += 1# 设置可行股票池:# 过滤掉当日停牌的股票,且筛选出前days天未停牌股票def set_feasible_stocks(stock_list,days,context):    suspened_info_df = get_price(list(stock_list), start_date=context.current_dt, end_date=context.current_dt, frequency='daily', fields='paused')['paused'].T    unsuspened_index = suspened_info_df.iloc[:,0]<1    unsuspened_stocks = suspened_info_df[unsuspened_index].index    feasible_stocks=[]    for stock in unsuspened_stocks:        if sum(attribute_history(stock, days, unit='1d',fields=('paused'),skip_paused=False))[0]==0:            feasible_stocks.append(stock)    return feasible_stocks# 根据不同的时间段设置滑点与手续费def set_slip_fee(context):    set_slippage(FixedSlippage(0))     # 根据不同的时间段设置手续费    dt=context.current_dt    if dt>datetime.datetime(2013,1, 1):        set_commission(PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))     elif dt>datetime.datetime(2011,1, 1):        set_commission(PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5))    elif dt>datetime.datetime(2009,1, 1):        set_commission(PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5))    else:        set_commission(PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5))       '''    run_daily(before_market_open, time='before_open', reference_security='000300.XSHG')       # 开盘时运行    run_daily(market_open, time='open', reference_security='000300.XSHG')      # 收盘后运行    run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')    '''#——————————————————————————————————————————开盘前————————————————————————————————————————————
#—————————————————————————————————————开盘中,交易股票————————————————————————————————————————## 开盘时运行函数def handle_data(context, data):    #在实际日进行交易    if g.if_trade==True:        df = get_price(g.stocks,frequency='daily',end_date=context.current_dt-datetime.timedelta(days=1),fields=g.factors, skip_paused=False, fq='pre', count=g.interval)            #获取函数运行当天要买入的股票列表        buy_list = []        for i in range(0,len(g.stocks)):            tempdf = df.ix[:,:,i]            #解决SVM和随机forest遇到的NaN缺失值问题            tempdf.fillna(method='pad').fillna(method='bfill')            try:                if svm_buy(tempdf)==True and forest_buy(tempdf)==True:                    buy_list.append(g.stocks[i])            except:                pass        #获取分配给每支股票的金额        g.stock_number = len(buy_list)        #交易函数,卖出所有股票,再买入buy_list内的股票        order_sell(context,buy_list)        g.everystock = context.portfolio.available_cash / max(g.stock_number,1)        order_buy(buy_list)           #清仓所有已持有的股票        #order_target_value(context.portfolio.positions.keys(),0)        #购买buy_list中的股票        #order_target_value(buy_list, g.everystock)    g.if_trade = False
#随机森林选股函数def forest_buy(df):    df['return']=False    for i in range(1,len(df)):        df.iloc[i,6] = ( (df.iloc[i,0]-df.iloc[i-1,0])/df.iloc[i-1,0] > 0 )    x_train = []    for i in df.index:        x_train.append(list(df.loc[i,g.factors]))    x_test = x_train[-1]    x_train = x_train[1:g.interval-1]    x_test = array(x_test).reshape((1,-1)) #为后来sklearn需要的数据形式做准备    y_train = []    for i in df.index:        y_train.append(df.loc[i,'return'])    y_train = y_train[2:g.interval]    #括号里面的n_estimators就是森林中包含的树的数目    clf_forest = RandomForestClassifier(n_estimators=g.trees)    #训练的代码    clf_forest.fit(x_train, y_train)    #得到测试结果的代码    prediction_forest = clf_forest.predict(x_test)    return prediction_forest
#支持向量机选股函数def svm_buy(df):    df['return']=False    for i in range(1,len(df)):        #df.iloc[i,6]=df.iloc[i,0]>df.iloc[i-1,0]        df.iloc[i,6] = ( (df.iloc[i,0]-df.iloc[i-1,0])/df.iloc[i-1,0] > 0 )    x_train = []    for i in df.index:        x_train.append(list(df.loc[i,g.factors]))    x_test = x_train[-1]    x_train = x_train[1:g.interval-1]    x_test = array(x_test).reshape((1,-1)) #为后来sklearn需要的数据形式做准备    y_train = []    for i in df.index:        y_train.append(df.loc[i,'return'])    y_train = y_train[2:g.interval]    clf_svm = svm.SVC()    clf_svm.fit(x_train, y_train)    prediction_svm = clf_svm.predict(x_test)    prediction_svm    return prediction_svm
#copy辅助交易的买卖函数def indexOf(key,A):    for i in range(0,len(A)):        if key<=A[i]:            return i    return -1#交易函数,卖出def order_sell(context,toBuy):    #如果现有持仓股票不在股票池,清空    list_position = context.portfolio.positions.keys()    #有持仓,但是不在要买的名单里    for i in range(0,len(g.stocks)):        if indexOf(g.stocks[i],toBuy)==-1 and indexOf(g.stocks[i],list_position)>-1:            order_target_value(g.stocks[i], 0)#交易函数,买入def order_buy(toBuy):    # 如果股票在待持仓列表,按所分配的份额持仓    for i in range(0,len(g.stocks)):        if indexOf(g.stocks[i],toBuy)>-1:            order_target_value(g.stocks[i], g.everystock)
## 收盘后运行函数  def after_market_close(context):    log.info(str('函数运行时间(after_market_close):'+str(context.current_dt.time())))    #得到当天所有成交记录    trades = get_trades()    for _trade in trades.values():        log.info('成交记录:'+str(_trade))    log.info('一天结束')    log.info('##############################################################')