机器之心专栏

作者:Cerulean

本文介绍了多个监督学习和强化学习模型在金融商场的运用,作者首要描绘了多个论文的中心思维与完成,而且全面归纳了其在Gipub上保护的项目。

项目地址链接

现在,在本项目中:

完成了4个强化学习模型。

完成了3个监督学习模型。

完成了1个简略的生意所,供给根本的买入、持有、卖出操作(卖空仍在开发中),标的物可所以股票组合或许期货合约组合。

关于监督学习模型的数据集:

咱们选用2008年1月1日到2018年1月1日这个区间内,

招商银行(600036)

交通银行(601328)

中信银行(601998)

工商银行(601389)

这四只银行股在第T天的,

开盘价(Open)

收盘价(Close)

最高价(High)

最低价(Low)

生意量(Volume)

作为输入数据,第T+1天的收盘价(Close)作为输出数据,进行练习,其间,这个区间前70%的数据作为练习数据,后30%作为测验数据,现在没有设置验证集数据。

下图是现在的试验成果,就现在的试验成果来看,监督学习的体现要好于强化学习。

图例:蓝色的折线是测验数据集,其他色彩的折线是三种不同的监督学习模型在测验集上的猜测。

美国股市实时行情(上海精锐)

接下来,咱们将会顺次对这3个监督学习模型与4个强化学习模型做一个简略的介绍。

1.Naive-LSTM(LSTM)

该模型是依据LSTM和Dense(全衔接)的根本模型,输入是序列长度为5,即第T到第T+4天的OCHLV数据,输出是一个实数,代表了第T+5的猜测收盘价格。

arXiv:1506.02078:VisualizingandUnderstandingRecurrentNetwork

模型核算图:

以下是构建模型的中心代码:

def_init_nn(self):self.rnn=self.add_rnn(1,self.hidden_size)self.rnn_output,_=tf.nn.dynamic_rnn(self.rnn,self.x,dtype=tf.float32)self.rnn_output=self.rnn_output[:,-1]self.rnn_output_dense=self.add_fc(self.rnn_output,16)self.y=self.add_fc(self.rnn_output_dense,self.y_space)

能够看出,榜首行代码调用了项目中封装的用于构建LSTM层的API,第二行代码用于核算该层输出和状况序列,第四行和第五行结构了一个全衔接层并核算终究的输出。

2.TreNet(HNN)

IJCAI2017.HybridNeuralNetworksforLearningpeTrendinTimeSeries

上述引证的论文提出了一种混合神经络的结构,一起用RNN与CNN提取序列特征,然后将输出拼接作为全衔接层的输入,终究输出终究的猜测成果。

模型核算图:

以下是构建模型的中心代码:

def_init_nn(self):self.rnn=self.add_rnn(1,self.hidden_size)self.rnn_output,_=tf.nn.dynamic_rnn(self.rnn,self.rnn_x,dtype=tf.float32)self.rnn_output=self.rnn_output[:,-1]#selfn_x_inputisa[-1,5,20,1]tensor,aftercnn,peshapewillbe[-1,5,20,5].selfn=self.add_cnn(selfn_x,filters=2,kernel_size=[2,2],pooling_size=[2,2])selfn_output=tf.reshape(selfn,[-1,self.seq_lengp*self.x_space*2])self.y_concat=tf.concat([self.rnn_output,selfn_output],axis=1)self.y_dense=self.add_fc(self.y_concat,16)self.y=self.add_fc(self.y_dense,self.y_space)

能够看出,榜首到第三行结构了LSTM层并核算成果,第四到第五行用项目封装的结构CNN的API结构了CNN层并核算了成果。终究拼接了RNN和CNN的成果,作为全衔接层的输入,然后得到终究的核算成果。

3.DA-RNN(DualAttnRNN)

arXiv:1704.02971:ADual-StageAttention-BasedRecurrentNeuralNetworkforTimeSeriesPrediction

上述引证的论文提出了一种依据注意力机制(AttentionBasedModel)的与Seq-to-Seq模型的络结构,其立异点在于该模型接连两次运用注意力机制,在对原始序列运用注意力机制求权重后再次运用注意力机制对编码后的序列求权重,然后经解码与全衔接层后输出成果。

模型核算图:

以下是构建模型的中心代码:

def_init_nn(self):#FirstAttnwiptf.variable_scope("1st_encoder"):self.f_encoder_rnn=self.add_rnn(1,self.hidden_size)self.f_encoder_outputs,_=tf.nn.dynamic_rnn(self.f_encoder_rnn,self.x,dtype=tf.float32)self.f_attn_inputs=self.add_fc(self.f_encoder_outputs,self.hidden_size,tf.tanh)self.f_attn_outputs=tf.nn.softmax(self.f_attn_inputs)wiptf.variable_scope("1st_decoder"):self.f_decoder_input=tf.multiply(self.f_encoder_outputs,self.f_attn_outputs)self.f_decoder_rnn=self.add_rnn(1,self.hidden_size)self.f_decoder_outputs,_=tf.nn.dynamic_rnn(self.f_decoder_rnn,self.f_decoder_input,dtype=tf.float32)#SecondAttnwiptf.variable_scope("2nd_encoder"):self.s_attn_input=self.add_fc(self.f_decoder_outputs,self.hidden_size,tf.tanh)self.s_attn_outputs=tf.nn.softmax(self.s_attn_input)wiptf.variable_scope("2nd_decoder"):self.s_decoder_input=tf.multiply(self.f_decoder_outputs,self.s_attn_outputs)self.s_decoder_rnn=self.add_rnn(2,self.hidden_size)self.f_decoder_outputs,_=tf.nn.dynamic_rnn(self.s_decoder_rnn,self.s_decoder_input,dtype=tf.float32)self.f_decoder_outputs_dense=self.add_fc(self.f_decoder_outputs[:,-1],16)self.y=self.add_fc(self.f_decoder_outputs_dense,self.y_space)

能够看出,别离对应于四个变量命名空间,具有2组4个编解码层,在每一个编解码层都运用了一次注意力机制,求出当时序列的权重,然后与序列相乘后进行下一步的编解码作业,这是一种Seq-to-Seq的机制,更广泛地用于自然语言处理。终究解码的输出成果作为全衔接层的输入,然后核算终究的成果。

以上是关于项目中监督学习模型的简略介绍,其间,一切模型的详细完成能够在项目链接中看到。

接下来是关于3个强化学习模型的介绍,但是在介绍强化学习模型前,咱们首要对强化学习的数据和环境一个简略的概述。

FinancialMarket

这个文件完成了三个中心类,别离是:

Market

Trader

Position

他们别离代表了商场、生意员、持仓信息,终究Market类作为Agent(强化学习模型)的Environment(环境),承受Agent的Action(动作),一起给出NextState(下一状况)和Reward(奖赏),并进行迭代。

关于强化学习运用的数据,

咱们运用这四只银行股在第T天的,

开盘价(Open)

收盘价(Close)

最高价(High)

最低价(Low)

生意量(Volume)

和生意员在第T天的,

现金(Cash)

持仓价值(HoldingValue)

各持仓量(HoldingAmount)

作为State(状况),运用生意指令,

买入(Buy)

卖出(Sell)

持有(Hold)

作为Agent(智能体)的Action(动作),其间,RewardFunc(奖赏函数)有2个版别,的核算代码如下:

def_update_reward(self,action_code,action_status,position):ifaction_code==ActionCode.Buy:ifaction_status==ActionStatus.Success:ifposition.pro_value>position.cur_value:self.reward+=70else:self.reward-=50else:self.reward-=100elifaction_code==ActionCode.Sell:ifaction_statu@staticmepoddef_calculate_reward_v1(action_code,action_status,position):ifaction_status==ActionStatus.Failed:reward=-100else:ifposition.pro_value>=position.cur_value:ifaction_code==ActionCode.Hold:reward=50else:reward=100else:reward=-50returnreward@staticmepoddef_calculate_reward_v2(_,action_status,position):ifaction_status==ActionStatus.Success:reward=position.pro_value-position.cur_valueelse:reward=-200returnrewards==ActionStatus.Success:ifposition.pro_value>position.cur_value:self.reward-=70else:self.reward+=50else:self.reward-=100else:ifaction_status==ActionStatus.Success:ifposition.pro_value>position.cur_value:self.reward+=70else:self.reward-=50else:self.reward-=100

接下来是关于试验成果与强化学习模型的介绍:

图例-横坐标是时刻,纵坐标是赢利,其间蓝色折线是基准线,其他色彩的折线是强化学习模型体现

能够看出,除了PolicyGradient能够跑赢基准收益外,其他强化学习模型的收益乃至不如基准,这儿十分值得评论,现在笔者也在测验从参数、输入特征、输出特征、奖赏函数等多个视点考虑处理该问题。

接下来是关于强化学习模型的介绍:

1.PolicyGradient

NIPS.Vol.99.1999:Policygradientmepodsforreinforcementlearningwipfunctionapproximation

模型核算图:

BasicPolicyGradient的思维很朴素,重复及或许多的采样,关于一次采样的一切动作中,依据奖赏函数值的正负决议梯度下降的方向,然后进步或许下降这些动作呈现的概率。

以下是构建模型的中心代码:

def_init_nn(self):#Initializepredictactorandcritic.w_init,b_init=tf.random_normal_initializer(.0,.3),tf.constant_initializer(0.1)wiptf.variable_scope('nn'):first_dense=tf.layers.dense(self.s,50,tf.nn.relu,kernel_initializer=w_init,bias_initializer=b_init)second_dense=tf.layers.dense(first_dense,50,tf.nn.relu,kernel_initializer=w_init,bias_initializer=b_init)action_prob=tf.layers.dense(second_dense,self.a_space,tf.nn.tanh,kernel_initializer=w_init,bias_initializer=b_init)self.a_prob=action_probself.a_s_prob=tf.nn.softmax(action_prob)def_init_op(self):wiptf.variable_scope('loss'):#a_one_hot=tf.one_hot(self.a,self.a_space)#negative_cross_entropy=-tf.reduce_sum(tf.log(self.a_prob)*a_one_hot)negative_cross_entropy=tf.nn.sparse_softmax_cross_entropy_wip_logits(logits=self.a_prob,labels=self.a)self.loss_fn=tf.reduce_mean(negative_cross_entropy*self.r)wiptf.variable_scope('train'):self.train_op=tf.train.RMSPropOptimizer(self.learning_rate*2).minimize(self.loss_fn)self.session.run(tf.global_variables_initializer())

本完成简略地选用两次全衔接后输出Softmax后各个动作的概率,终究希望最小化采样动作的概率与实在概率乘以奖赏函数的值的穿插熵。

2.DoubleDQN

arXiv:1509.06461:DeepReinforcementLearningwipDoubleQ-learning

模型核算图:

Double-DQN选用评价络与方针络彼此限制,希望防止传统DQN中简单呈现的过度估量问题。首要运用评价络猜测下一个状况的状况-动作函数值,然后选取取得最大值的动作,计做a_,接着用方针络猜测下一状况与选用a_的状况值核算标签,然后希望最小化标签与评价络对当时状况的状况-动作函数和当时动作的Q的均方差。

以下是构建模型的中心代码:

def_init_op(self):self.loss=tf.reduce_mean(tf.squared_difference(self.q_next,self.q_eval))self.train_op=tf.train.RMSPropOptimizer(self.learning_rate).minimize(self.loss)self.e_params=tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,scope='q_eval')self.t_params=tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,scope='q_target')self.update_q_target_op=[tf.assign(t,e)fort,einzip(self.t_params,self.e_params)]self.session.run(tf.global_variables_initializer())deftrain(self):#1.Ifbufferlengpislesspanbuffersize,return.ifself.buffer_lengp<self.buffer_size:return#2.UpdateQ-Targetifneed.ifself.total_step%self.update_q_target_step==0:self.session.run(self.update_q_target_op)#3.Gettransitionbatch.s,a,r,s_next=self.get_transition_batch()#4.Calculateq_eval_next.q_eval_next=self.session.run(self.q_eval,)#5.Getactionindicesandmakebatchindices.a_indices=np.argmax(q_eval_next,axis=1)b_indices=np.arange(self.batch_size,dtype=np.int)#6.Calculateq_target_nextselectedbyactions.q_target_next=self.session.run(self.q_target,)q_target_next_wip_a=q_target_next[b_indices,a_indices]#7.Calculatelabels.q_eval=self.session.run(self.q_eval,)q_next=q_eval.copy()q_next[b_indices,a.astype(np.int)]=r+self.gamma*q_target_next_wip_a#8.Calculateloss._,self.critic_loss=self.session.run([self.train_op,self.loss],)#9.Increasetotalstep.self.total_step+=1

Double-DQN的完成代码中,注释现已十分翔实,在这儿就不再过多赘述。

3.DeepDeterministicPolicyGradient(DDPG)

arXiv:1509.02971:Continuouscontrolwipdeepreinforcementlearning

模型核算图:

DDPG用于接连动作空间,在本问题中,关于四只股票的生意持有的动作被映射到区间[0,11],其间,DDPG运用Actor-CriticModel,引进评价Actor,方针Actor模型与评价Critic,方针Critic模型两组四个络,其间Actor模型用于猜测动作,Critic模型用于评价当时状况与动作的分数(状况-动作值函数),该办法希望最小化:评价Critic与评价Actor对当时状况-动作函数值与方针Critic和方针Actor对下一状况-动作函数值的均方差(如算法图所示),顺次迭代改善方针Critic和方针Actor。

以下是构建模型的中心代码:

def_init_nn(self):#Initializepredictactorandcritic.self.a_predict=self.__build_actor_nn(self.s,"predict/actor",trainable=True)self.q_predict=self.__build_critic(self.s,self.a_predict,"predict/critic",trainable=True)#Initializetargetactorandcritic.self.a_next=self.__build_actor_nn(self.s_next,"target/actor",trainable=False)self.q_next=self.__build_critic(self.s_next,self.a_next,"target/critic",trainable=False)#Savescopesself.scopes=["predict/actor","target/actor","predict/critic","target/critic"]def_init_op(self):#Getactorandcriticparameters.params=[tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,scope)forscopeinself.scopes]zipped_a_params,zipped_c_params=zip(params[0],params[1]),zip(params[2],params[3])#Initializeupdateactorandcriticop.self.update_a=[tf.assign(t_a,(1-self.tau)*t_a+self.tau*p_a)forp_a,t_ainzipped_a_params]self.update_c=[tf.assign(t_c,(1-self.tau)*t_c+self.tau*p_c)forp_c,t_cinzipped_c_params]#Initializeactorlossandtrainop.self.a_loss=-tf.reduce_mean(self.q_predict)self.a_train_op=tf.train.RMSPropOptimizer(self.learning_rate).minimize(self.a_loss,var_list=params[0])#Initializecriticlossandtrainop.self.q_target=self.r+self.gamma*self.q_nextself.c_loss=tf.losses.mean_squared_error(self.q_target,self.q_predict)self.c_train_op=tf.train.RMSPropOptimizer(self.learning_rate*2).minimize(self.c_loss,var_list=params[2])#Initializevariables.self.session.run(tf.global_variables_initializer())

代码首要初始化两组四个络,别离是评价Actor、方针Actor,评价Critic,方针Critic,然后依据DDPG的算法最小化评价Critic与评价Actor对当时状况-动作函数值与方针Critic和方针Actor对下一状况-动作函数值的均方差,顺次迭代更新Actor与Critic直至收敛。

4.Dueling-DQN

arXiv:1511.06581:DuelingNetworkArchitecturesforDeepReinforcementLearning

模型核算图:

算法:

相关于DQN直接输出状况-动作函数值,Dueling-DQN的状况-动作函数值由上式决议,从络结构上能够看出,在输出状况-动作函数值前,Dueling-DQN的结构拆分了原DQN络结构的终究一层,这样的思维很像Actor-Critic模型中的Baseline,由于并不是每个状况都是十分重要的,有些时分关于这些状况,采纳那个动作都不会有很大的影响。

以下是构建模型的中心代码:

def__build_critic_nn(self,s,scope):w_init,b_init=tf.random_normal_initializer(.0,.3),tf.constant_initializer(.1)wiptf.variable_scope(scope):s_first_dense=tf.layers.dense(s,16,activation=tf.nn.relu,kernel_initializer=w_init,bias_initializer=b_init)s_second_dense=tf.layers.dense(s_first_dense,16,tf.nn.relu,kernel_initializer=w_init,bias_initializer=b_init)value=tf.layers.dense(s_second_dense,1,kernel_initializer=w_init,bias_initializer=b_init)advantage=tf.layers.dense(s_second_dense,self.a_space,kernel_initializer=w_init,bias_initializer=b_init)q=value+(advantage-tf.reduce_mean(advantage,axis=1,keep_dims=True))returnq

即终究关于某个状况-动作函数值而言,Advantage的在不同动作维度上的值必定意义上描绘了这个动作关于这个状况的重要性,终究加上Q值,防止了过度估量。

以上是最近关于强化学习和监督学习在金融商场中的一些运用和相关论文办法的完成。

现在仍有以下问题亟待讨论与处理:

强化学习模型奖赏函数的规划

强化学习中依据值迭代的算法难以收敛

监督学习的特征维度怎么扩展

一起,项目中或许有Bug,欢迎各种Issue提出以及欢迎奉献各种代码:)

本文为机器之心编译,转载请联络本大众号取得授权。

------------------------------------------------

参加机器之心(全职记者/实习生):hr@jiqizhixin

投稿或寻求报导:editor@jiqizhixin

广告&商务协作:bd@jiqizhixin