LSTM跑demo时,替换变量,程序报错

策略分享
标签: #<Tag:0x00007f8c6211de88>

(kajimage) #1
克隆策略

LSTM Networks应用于股票市场探究之Sequential Model

  • 整个模型只有一个input(6 features * 30 time series)
  • LSTM future_return_5作为output(time series=30,features=['close','open','high','low','amount','volume'])
In [44]:
# 导入包
import matplotlib.pyplot as plt
from sklearn.preprocessing import scale
from keras.layers import Input, Dense, LSTM, merge
from keras.models import Model
In [45]:
# 基础参数配置
class conf:
    instrument = '600690.SHA'  #股票代码
    #设置用于训练和回测的开始/结束日期
    start_date = '2014-01-01'
    split_date = '2017-06-01'
    end_date = '2018-06-01'
    fields = ['ta_sma_10_0',]
    seq_len = 30 #每个input的长度
    batch = 100 #整数,指定进行梯度下降时每个batch包含的样本数,训练时一个batch的样本会被计算一次梯度下降,使目标函数优化一步
In [46]:
# 数据导入以及初步处理
data = D.history_data(conf.instrument, conf.start_date, conf.end_date, conf.fields)
data['return'] = data['close'].shift(-5) / data['open'].shift(-1) - 1 #计算未来5日收益率(未来第五日的收盘价/明日的开盘价)
data=data[data.amount>0]
data.dropna(inplace=True)
datatime = data['date'][data.date>=conf.split_date]  #记录predictions的时间,回测要用
data['return'] = data['return'].apply(lambda x:np.where(x>=0.2,0.2,np.where(x>-0.2,x,-0.2)))  #去极值
data['return'] = data['return']*10  # 适当增大return范围,利于LSTM模型训练
data.reset_index(drop=True, inplace=True)
scaledata = data[conf.fields]
traindata = data[data.date<conf.split_date]
In [47]:
# 数据处理:设定每个input(30time series×6features)以及数据标准化
train_input = []
train_output = []
test_input = []
test_output = []
for i in range(conf.seq_len-1, len(traindata)):
    a = scale(scaledata[i+1-conf.seq_len:i+1])
    train_input.append(a)
    c = data['return'][i]
    train_output.append(c)
for j in range(len(traindata), len(data)):
    b = scale(scaledata[j+1-conf.seq_len:j+1])
    test_input.append(b)
    c = data['return'][j]
    test_output.append(c)

# LSTM接受数组类型的输入
train_x = np.array(train_input)
train_y = np.array(train_output)
test_x = np.array(test_input) 
test_y = np.array(test_output)
In [48]:
# 自定义激活函数
import tensorflow as tf
def atan(x): 
    return tf.atan(x)
In [49]:
# 构建神经网络层 1层LSTM层+3层Dense层
# 用于1个输入情况
lstm_input = Input(shape=(30,6), name='lstm_input')
lstm_output = LSTM(128, activation=atan, dropout_W=0.2, dropout_U=0.1)(lstm_input)
Dense_output_1 = Dense(64, activation='linear')(lstm_output)
Dense_output_2 = Dense(16, activation='linear')(Dense_output_1)
predictions = Dense(1, activation=atan)(Dense_output_2)

model = Model(input=lstm_input, output=predictions)

model.compile(optimizer='adam', loss='mse', metrics=['mse'])
    
model.fit(train_x, train_y, batch_size=conf.batch, nb_epoch=10, verbose=2)
Epoch 1/10
3s - loss: 0.2762 - mean_squared_error: 0.2762
Epoch 2/10
2s - loss: 0.2659 - mean_squared_error: 0.2659
Epoch 3/10
2s - loss: 0.2727 - mean_squared_error: 0.2727
Epoch 4/10
2s - loss: 0.2659 - mean_squared_error: 0.2659
Epoch 5/10
2s - loss: 0.2690 - mean_squared_error: 0.2690
Epoch 6/10
2s - loss: 0.2652 - mean_squared_error: 0.2652
Epoch 7/10
2s - loss: 0.2629 - mean_squared_error: 0.2629
Epoch 8/10
2s - loss: 0.2606 - mean_squared_error: 0.2606
Epoch 9/10
2s - loss: 0.2570 - mean_squared_error: 0.2570
Epoch 10/10
2s - loss: 0.2582 - mean_squared_error: 0.2582
Out[49]:
<keras.callbacks.History at 0x7f376a6775f8>
In [50]:
# 预测
predictions = model.predict(test_x)
In [51]:
# 预测值和真实值的关系
data1 = test_y
data2 = predictions
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(data2,data1, 'o', label="data")
ax.legend(loc='best')
Out[51]:
<matplotlib.legend.Legend at 0x7f376a197358>
In [52]:
# 如果预测值>0,取为1;如果预测值<=0,取为-1.为回测做准备
for i in range(len(predictions)):
    if predictions[i]>0:
        predictions[i]=1
    elif predictions[i]<=0:
        predictions[i]=-1
In [53]:
# 将预测值与时间整合作为回测数据
cc = np.reshape(predictions,len(predictions), 1)
databacktest = pd.DataFrame()
databacktest['date'] = datatime
databacktest['direction']=np.round(cc)
In [54]:
def initialize(context):
    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    # 传入预测数据和真实数据
    context.predictions=databacktest
    
    context.hold=conf.split_date

# 回测引擎:每日数据处理函数,每天执行一次
def handle_data(context, data):
    current_dt = data.current_dt.strftime('%Y-%m-%d') 
    sid = context.symbol(conf.instrument)
    cur_position = context.portfolio.positions[sid].amount    # 持仓
    if cur_position==0:
        if databacktest['direction'].values[databacktest.date==current_dt]==1:
            context.order_target_percent(sid, 0.9)
            context.date=current_dt
            
    else:
        if databacktest['direction'].values[databacktest.date==current_dt]==-1:
            if context.trading_calendar.session_distance(pd.Timestamp(context.date), pd.Timestamp(current_dt))>=5:
                context.order_target(sid, 0)

# 调用回测引擎
m8 = M.backtest.v6(
    instruments=conf.instrument,
    start_date=conf.split_date,
    end_date=conf.end_date,
    initialize=initialize,
    handle_data=handle_data,
    order_price_field_buy='open',       # 表示 开盘 时买入
    order_price_field_sell='close',     # 表示 收盘 前卖出
    capital_base=10000, 
    benchmark='000300.SHA', 
    m_cached=False
)    
[2018-06-28 14:36:16.211619] INFO: bigquant: backtest.v6 开始运行..
[2018-06-28 14:36:16.307313] INFO: algo: set price type:backward_adjusted
[2018-06-28 14:36:17.231992] INFO: Performance: Simulated 247 trading days out of 247.
[2018-06-28 14:36:17.233100] INFO: Performance: first open: 2017-06-01 01:30:00+00:00
[2018-06-28 14:36:17.233965] INFO: Performance: last close: 2018-06-01 07:00:00+00:00
  • 收益率42.2%
  • 年化收益率43.22%
  • 基准收益率7.95%
  • 阿尔法0.36
  • 贝塔0.89
  • 夏普比率1.52
  • 胜率0.75
  • 盈亏比0.741
  • 收益波动率25.48%
  • 信息比率1.58
  • 最大回撤14.95%
[2018-06-28 14:36:18.646889] INFO: bigquant: backtest.v6 运行完成[2.435297s].

(iQuant) #2

ta_sma_10_0是特征因子,不能用D.history_data获取,尝试一下D.features


(kajimage) #3

已经解决,感谢解答~