[PYTHON] J'ai étudié l'algorithme d'apprentissage de renforcement du trading d'algorithmes

[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.

Matériel de référence

Aperçu de l'enquête

Signification de l'utilisation de l'apprentissage par renforcement (voir référence 4)

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.

Différence entre la fonction de valeur RL et Direct RL

■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

Évaluation de l'agent

Utilisez le rapport de Sharpe différentiel (DSR). Utilisé lors de la mise à jour du poids.

Précautions pour le fonctionnement réel

Algorithme (voir référence 1)

[Détermination de la position au temps t (long ou court)]

F_t=sign(\sum_{i=0}^{M}w_{i,t}r_{t-i}+w_{M+1,t}F_{t-1}+v_t) F_t ∈ [-1,1]; (short=-1, long=1) w_t: weight vector v_t: threshold of the neural network $ r_t $: $ p_t --p_ {t-1} $ (retour en série chronologique)

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.

[Bénéfice au moment T]

P_t=\sum_{t=0}^{T}R_t R_t:=F_{t-1}r_t-δ|F_t-F_{t-1}| δ: coût de transaction

[Valeur d'évaluation optimisée]

■sharpe ratio \hat{S}(t):=\frac{A_t}{B_t} A_t=A_{t-1}+η(R_t-A_{t-1}), A_0=0 B_t=B_{t-1}+η(R_t^2-B_{t-1}), B_0=0 η: adaptation parameter

■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. D_t:=\frac{d\hat{S}}{dη}|_{η=0}

=\frac{B_{t-1}\Delta A_t-\frac{1}{2}A_{t-1}\Delta B_t}{(B_{t-1}-A_{t-1}^2)^\frac{3}{2}} \Delta A_t=R_t-A_{t-1} \Delta B_t=R_t^2-B_{t-1}

Considérez $ D_t $ comme une mesure de performance immédiate et mettez à jour le poids pour le maximiser.

[Mettre à jour le poids]

w_{i,t}=w_{i,t-1}+\rho \Delta w_{i,t} \Delta w_{i,t}=\frac{dD_t}{dw_i}     \approx \frac{dD_t}{dR_t}{ \frac{dR_t}{dF_t}\frac{dF_t}{dw_{i,t}} + \frac{dR_t}{dF_{t-1}}\frac{dF_{t-1}}{dw_{i,t-1}}}

\frac{dF_t}{dw_{i,t}}\approx\frac{\partial F_t}{\partial w_{i,t}}+\frac{\partial F_t}{\partial F_{t-1}}\frac{dF_{t-1}}{dw_{i,t-1}}

\frac{dD_t}{dR_t}=\frac{B_{t-1}-A_{t-1}R_t}{(B_{t-1}-A_{t-1}^2)^{3/2}} \frac{dR_t}{dF_t}=-\delta \frac{dR_t}{dF_{t-1}}=r_t-\delta

[Coupe de perte, seuil de réglage du signal, jugement d'anomalie du système]

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. ..

Code de référence

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)
    

Expérience

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.

Résultat expérimental

Taux USD / yen

USD.png

Bénéfice cumulé (lors de l'achat d'une seule unité par jour)

profit.png

DSR DSR_.png

SR SR.png

commentaire

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

J'ai étudié l'algorithme d'apprentissage de renforcement du trading d'algorithmes
J'ai étudié le mécanisme de connexion flask!
Renforcement de l'apprentissage 2 Installation de chainerrl
Apprentissage par renforcement profond 2 Mise en œuvre de l'apprentissage par renforcement
J'ai évalué la stratégie de négociation du système boursier avec Python.
J'ai essayé d'implémenter l'algorithme FloodFill avec TRON BATTLE de CodinGame
Essayez l'algorithme Variational-Quantum-Eigensolver (VQE) avec Blueqat
Essayez le serveur Taxii (2. Paramètres de service / collecte)
J'ai étudié l'algorithme d'apprentissage de renforcement du trading d'algorithmes
À propos de la commande de service
Essayez de modéliser une distribution multimodale à l'aide de l'algorithme EM
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
J'ai appris les bases de l'apprentissage intensif et joué avec Cart Pole (implémentation simple de Q Learning)
Explorez le labyrinthe avec l'apprentissage augmenté
J'ai étudié la méthode X-means qui estime automatiquement le nombre de clusters
J'ai étudié à quoi ressemble la lunette
J'ai essayé l'apprentissage par renforcement avec PyBrain
J'ai étudié le comportement de la différence entre lien dur et lien symbolique
J'ai étudié la superposition de l'arborescence des appareils
Notez que je comprends l'algorithme du classificateur Naive Bayes. Et je l'ai écrit en Python.
J'ai essayé d'appeler l'API de prédiction du modèle d'apprentissage automatique de WordPress
J'ai fait GAN avec Keras, donc j'ai fait une vidéo du processus d'apprentissage.
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
J'ai essayé l'histoire courante de prédire la moyenne Nikkei à l'aide du Deep Learning (backtest)
[Renforcer l'apprentissage] J'ai implémenté / expliqué R2D3 (Keras-RL)
J'ai vérifié les options de copyMakeBorder d'OpenCV
Othello-De la troisième ligne de "Implementation Deep Learning" (3)
Notes d'apprentissage depuis le début de Python 1
La structure des dossiers de Flask est résumée
Je ne connaissais pas les bases de Python
Algorithme d'apprentissage automatique (implémentation de la classification multi-classes)
Visualisez les effets de l'apprentissage profond / de la régularisation
Le modèle de projet Python auquel je pense.
Notes d'apprentissage depuis le début de Python 2
Essayez l'algorithme d'apprentissage amélioré standard d'OpenAI PPO
[Renforcer l'apprentissage] Rechercher le meilleur itinéraire
Othello-De la troisième ligne de "Implementation Deep Learning" (2)
[Examen d'ingénieur d'information de base] J'ai écrit l'algorithme de la méthode de division mutuelle euclidienne en Python.
J'ai essayé d'exécuter le didacticiel de détection d'objets en utilisant le dernier algorithme d'apprentissage en profondeur
J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
L'histoire de l'apprentissage profond avec TPU
J'ai essayé l'analyse par grappes de la carte météo
L'histoire selon laquelle le coût d'apprentissage de Python est faible
J'ai résolu le problème le plus profond d'Hiroshi Yuki.
J'ai vérifié la liste des touches de raccourci de Jupyter
J'ai essayé de corriger la forme trapézoïdale de l'image
Essayez Progate Free Edition [Python I]
J'ai vérifié la période de rétention de session de django
J'ai vérifié la vitesse de traitement de la numpy unidimensionnelle
À propos du contenu de développement de l'apprentissage automatique (exemple)
J'ai touché certaines des nouvelles fonctionnalités de Python 3.8 ①
Visualisez le comportement de l'algorithme de tri avec matplotlib
J'ai lu et implémenté les variantes de UKR
Je souhaite personnaliser l'apparence de zabbix
J'ai essayé d'utiliser le filtre d'image d'OpenCV
[Mac] J'ai essayé de renforcer l'apprentissage avec Open AI Baselines
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
[CodeIQ] J'ai écrit la distribution de probabilité des dés (du cours de mathématiques CodeIQ pour l'apprentissage automatique [Distribution de probabilités])