[Blog de Nekopuni](http://nekopuni.holy.jp/2014/09/python%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92%EF%BC % 8B% E7% 82% BA% E6% 9B% BF% E3% 83% 88% E3% 83% AC% E3% 83% BC% E3% 83% 89% E6% 88% A6% E7% 95% A5 Inspiré par% E3% 81% 9D% E3% 81% AE2 /), j'ai étudié le trading d'algorithmes en utilisant un apprentissage amélioré pour les loisirs et les avantages pratiques. Je ne suis pas totalement confiant dans ce que j'écris (en particulier le code). Mon utilisation principale est comme mémo pour moi-même, mais j'apprécierais qu'elle puisse être utilisée comme référence pour un matériel d'enquête médiocre.
La différence entre l'apprentissage amélioré et l'apprentissage supervisé est la suivante.
Dans l'apprentissage supervisé, les conditions sont optimisées sans politique commerciale unifiée. D'un autre côté, un apprentissage intensifié permet de construire des algorithmes incluant l'environnement et les politiques, on considère donc que l'efficacité de l'utilisation de l'apprentissage amélioré est élevée.
■Value Function RL La valeur d'action est attribuée par état ou paire d'actions d'état. Sur la base de cette valeur, nous optimisons la politique (la politique d'action à entreprendre lorsqu'un certain état est obtenu). Cela maximisera les récompenses attendues à long terme. Le Q-learning est classé ici. Pour plus de détails sur le Q-learning, voir Reference 5 .
■Direct RL Nous ajusterons directement la fonction de récompense (nombre de valeurs) en fonction de l'expérience (valeur observée) obtenue à partir de l'environnement. Contrairement à Q-learning, Q-table n'est pas nécessaire, donc la quantité de calcul temporel / spatial est faible. Cependant, maximiser les récompenses attendues sera à court terme. L'apprentissage récurrent par renforcement (RRL) est catégorisé ici. Pour plus d'informations sur RRL [Référence 5](http://www.amazon.co.jp/gp/product/4627826613/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4627826613&linkCode=as2&tagao=sh img src = "http://ir-jp.amazon-adsystem.com/e/ir?t=shimashimao06-22&l=as2&o=9&a=4627826613" width = "1" height = "1" border = "0" alt Veuillez vous référer à = "" style = "border: none! Important; margin: 0px! Important;" />. (Cette fois, j'écris le code en utilisant ce RRL.)
RRL Financial Trading Framework
Utilisez le rapport de Sharpe différentiel (DSR). Utilisé lors de la mise à jour du poids.
La forme de la formule est la même qu'un simple réseau neuronal à une couche. En fait, la méthode du réseau de neurones est appliquée, et le seuil $ v_t $ est également inclus dans le vecteur de poids pour l'optimisation.
■sharpe ratio
■Differential Sharpe Ratio(DSR)
Une version améliorée de la moyenne mobile du ratio de sharpe pour l'apprentissage en ligne.
DSR est plus léger dans le calcul et converge plus rapidement (il semble).
Ueno $ \ hat {S} $ est développé par Taylor autour de η = 0 et le premier terme est acquis.
Considérez $ D_t $ comme une mesure de performance immédiate et mettez à jour le poids pour le maximiser.
Il y a une déclaration selon laquelle il devrait être défini comme paramètre, mais il n'y a pas de description spécifique. Il ne semble pas y avoir d'autre choix que de lui attribuer une valeur empirique. ..
La fonction de signe est une fois calculée comme tanh et signalée selon que $ F_t $ est supérieur ou non à 0. Les fonctions telles que la réduction des pertes ne sont pas écrites. C'est un code très suspect, même si je le dis moi-même. S'il vous plaît voir pour référence.
python
# coding: utf-8
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from math import tanh, copysign
class RRLAgentForFX:
TRADING_COST = 0.003
EPS = 1e-6
def __init__(self,M,rho=0.01,eta=0.1,bias=1.0):
np.random.seed(555)
self.M = M # number of lags
self.weights = np.zeros(self.M+3,dtype=np.float64)
self.bias = bias # bias term
self.rho = rho
self.eta = eta
self.price_diff = np.zeros(self.M+1) # r_t
self.pre_price = None
self.pre_signal = 0
self.pre_A = 0.0
self.pre_B = 0.0
self.pre_gradient_F = 0.0
# result store
self.signal_store = []
self.profit_store = []
self.dsr_store = []
self.sr_store = []
self.cumulative_profit = 0.0
def train_online(self, price):
self.calculate_price_diff(price)
signal, self.F_t_value = self.select_signal()
print "signal",signal
self.calculate_return(signal)
self.update_parameters()
self.pre_price = price
self.pre_signal = signal
# store result
self.signal_store.append(signal)
def calculate_price_diff(self,price):
r = price - self.pre_price if self.pre_price is not None else 0
self.price_diff[:self.M] = self.price_diff[1:]
self.price_diff[self.M] = r
def calculate_return(self,signal):
R_t = self.pre_signal*self.price_diff[-1]
R_t -= self.TRADING_COST*abs(signal - self.pre_signal)
self.return_t = R_t
self.cumulative_profit += R_t
self.profit_store.append(self.cumulative_profit)
def select_signal(self):
values_sum = (self.weights[:self.M+1]*self.price_diff).sum()
values_sum += self.weights[-2]*self.pre_signal
values_sum += self.bias*self.weights[-1]
F_t_value = tanh(values_sum)
return copysign(1, F_t_value ), F_t_value
def update_parameters(self):
# update weight
self.weights += self.rho*self.calculate_gradient_weights()
print "weight",self.weights
# update moment R_t
self.update_R_moment()
def calculate_gradient_weights(self):
""" differentiate between D_t and w_t """
denominator = self.pre_B-self.pre_A**2
if denominator!=0:
diff_D_R = self.pre_B-self.pre_A*self.return_t
diff_D_R /= (denominator)**1.5
else:
diff_D_R = 0
gradient_F = self.calculate_gradient_F()
print "gradient_F",gradient_F
#diff_R_F = -self.TRADING_COST
#diff_R_F_{t-1} = self.price_diff[-1] - self.TRADING_COST
delta_weights = -self.TRADING_COST*gradient_F
delta_weights += ( self.price_diff[-1] - self.TRADING_COST) \
*self.pre_gradient_F
delta_weights *= diff_D_R
self.pre_gradient_F = gradient_F
return delta_weights
def calculate_gradient_F(self):
""" differentiate between F_t and w_t """
diff_tnah = 1-self.F_t_value**2
diff_F_w = diff_tnah*( np.r_[ self.price_diff, self.pre_signal, self.bias ] )
diff_F_F = diff_tnah*self.weights[-2]
return diff_F_w + diff_F_F*self.pre_gradient_F
def update_R_moment(self):
delta_A = self.return_t - self.pre_A
delta_B = self.return_t**2 - self.pre_B
A_t = self.pre_A + self.eta*delta_A # A_t. first moment of R_t.
B_t = self.pre_B + self.eta*delta_B # B_t. second moment of R_t.
self.sr_store.append(A_t/B_t)
self.calculate_dsr(delta_A, delta_B)
self.pre_A = A_t
self.pre_B = B_t
def calculate_dsr(self,delta_A,delta_B):
dsr = self.pre_B*delta_A - 0.5*self.pre_A*delta_B
dsr /= (self.pre_B-self.pre_A**2)**1.5
self.dsr_store.append(dsr)
if __name__=='__main__':
M = 8
fx_agent = RRLAgentForFX(M,rho=0.01,eta=0.01,bias=0.25)
ifname = os.getcwd()+'/input/quote.csv'
data = pd.read_csv(ifname)
train_data = data.ix[:3000,'USD']
for price in train_data.values:
fx_agent.train_online(price)
J'ai téléchargé et utilisé le fichier csv des données de date et d'heure du taux de change (/ yen) à partir de la page de Mizuho Bank Historical Data. .. J'ai utilisé USD / Yen à partir du 1er avril 2002 et j'ai appris en utilisant 3000 données.
DSR
SR
Le résultat dépend des valeurs de ρ et η. C'est trop instable. .. Je souhaite mettre à jour le code dès que je remarque l'erreur. Si vous remarquez quelque chose d'étrange, il serait grandement apprécié que vous puissiez commenter.
Recommended Posts