[Python] Essayez d'optimiser les paramètres de la systole FX avec une recherche aléatoire

Optimisation des paramètres du système FX en Python J'ai donc essayé toutes les combinaisons de paramètres du système commercial pour trouver la solution optimale.

Si le nombre de combinaisons est petit, il n'y a pas de problème avec le round robin, mais si le nombre de combinaisons est grand, cela devient assez difficile. L'algorithme d'optimisation pour cela est [Metahuristics](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E3%83%92%E3%83%A5% E3% 83% BC% E3% 83% AA% E3% 82% B9% E3% 83% 86% E3% 82% A3% E3% 82% AF% E3% 82% B9). Je voulais implémenter un algorithme génétique bien connu, mais avant cela, j'ai écrit une recherche aléatoire plus simple en Python.

Préparation

Mettez la fonction pour convertir les données d'une minute en une autre période et la fonction d'index technique dans indicateurs.py, et le backtest précédent et la fonction pour l'évaluer dans backtest.py. La source peut être trouvée sur GitHub. Le code suivant créera des données d'une heure dans ʻohlc`.

import numpy as np
import pandas as pd
import indicators as ind #indicators.Importation de py
from backtest import Backtest,BacktestReport

dataM1 = pd.read_csv('DAT_ASCII_EURUSD_M1_2015.csv', sep=';',
                     names=('Time','Open','High','Low','Close', ''),
                     index_col='Time', parse_dates=True)
dataM1.index += pd.offsets.Hour(7) #Décalage de 7 heures
ohlc = ind.TF_ohlc(dataM1, 'H') #Création de données horaires

Paramètres du système commercial à optimiser

Dans l'optimisation précédente, nous avons optimisé en modifiant deux paramètres dans une certaine plage comme suit.

SlowMAperiod = np.arange(10, 61) #Gamme de période moyenne mobile à long terme
FastMAperiod = np.arange(5, 31)  #Gamme de période moyenne mobile à court terme

À ce rythme, il n'y a que 1066 façons, mais je changerai le nombre de combinaisons plus tard.

Recherche aléatoire

Dans une recherche aléatoire simple, les valeurs des paramètres doivent être générées aléatoirement dans l'ordre et celle avec l'évaluation de backtest la plus élevée doit être adoptée, mais ici, une fois afin qu'elle puisse être appliquée aux algorithmes génétiques. J'ai essayé environ 20 combinaisons de paramètres dans chaque génération et essayé de le répéter pendant plusieurs générations.

def Optimize(ohlc, SlowMAperiod, FastMAperiod):
    def shift(x, n=1): return np.concatenate((np.zeros(n), x[:-n])) #Fonction Shift

    SlowMA = np.empty([len(SlowMAperiod), len(ohlc)]) #Moyenne mobile à long terme
    for i in range(len(SlowMAperiod)):
        SlowMA[i] = ind.iMA(ohlc, SlowMAperiod[i])

    FastMA = np.empty([len(FastMAperiod), len(ohlc)]) #Moyenne mobile à court terme
    for i in range(len(FastMAperiod)):
        FastMA[i] = ind.iMA(ohlc, FastMAperiod[i])
    
    M = 20 #Nombre d'individus
    Eval = np.zeros([M, 6])  #Élément d'évaluation
    Param = np.zeros([M, 2], dtype=int) #Paramètres
    RandomSearch(Param, Eval[:,0], SlowMAperiod, FastMAperiod) #Initialisation des paramètres
    gens = 0 #Nombre de générations
    while gens < 100:
        for k in range(M):
            i = Param[k,0]
            j = Param[k,1]
            #Acheter le signal d'entrée
            BuyEntry = (FastMA[j] > SlowMA[i]) & (shift(FastMA[j]) <= shift(SlowMA[i]))
            #Vendre un signal d'entrée
            SellEntry = (FastMA[j] < SlowMA[i]) & (shift(FastMA[j]) >= shift(SlowMA[i]))
            #Acheter un signal de sortie
            BuyExit = SellEntry.copy()
            #Vendre un signal de sortie
            SellExit = BuyEntry.copy()
            #Backtest
            Trade, PL = Backtest(ohlc, BuyEntry, SellEntry, BuyExit, SellExit) 
            Eval[k] = BacktestReport(Trade, PL)
        #Changement de génération
        Param = RandomSearch(Param, Eval[:,0], SlowMAperiod, FastMAperiod)
        gens += 1
    Slow = SlowMAperiod[Param[:,0]]
    Fast = FastMAperiod[Param[:,1]]
    return pd.DataFrame({'Slow':Slow, 'Fast':Fast, 'Profit': Eval[:,0], 'Trades':Eval[:,1],
                         'Average':Eval[:,2],'PF':Eval[:,3], 'MDD':Eval[:,4], 'RF':Eval[:,5]},
                         columns=['Slow','Fast','Profit','Trades','Average','PF','MDD','RF'])

La différence avec la dernière fois est que nous avons préparé un tableau «Param» pour stocker la combinaison de paramètres pour chaque génération. Ensuite, l'ensemble de paramètres avec la valeur d'évaluation la plus élevée (profit / perte total dans ce cas) est sauvegardé (sauvegarde élite) pour chaque génération, et les paramètres restants sont générés de manière aléatoire à plusieurs reprises.

Une fonction qui génère de manière aléatoire des paramètres avec un stockage élite peut être écrite comme suit:

#Recherche aléatoire avec sauvegarde élite
def RandomSearch(Param, Eval, SlowMAperiod, FastMAperiod):
    Param = Param[np.argsort(Eval)[::-1]] #Trier
    NewParam = np.vstack((np.random.randint(len(SlowMAperiod), size=len(Eval)),
                          np.random.randint(len(FastMAperiod), size=len(Eval)))).T
    NewParam[0] = Param[0] #Sauvegarde élite
    return NewParam

La méthode consiste à trier les valeurs d'évaluation et à redéfinir le paramètre 0. Lorsque vous faites cela, vous obtenez:

result = Optimize(ohlc, SlowMAperiod, FastMAperiod)
result.sort_values('Profit', ascending=False)
Slow Fast Profit Trades Average PF MDD RF
0 27 8 2507.1 264.0 9.496591 1.423497 485.1 5.168213
15 18 5 944.1 428.0 2.205841 1.110187 693.1 1.362141
19 48 14 825.4 238.0 3.468067 1.131883 927.7 0.889727
16 42 29 720.4 308.0 2.338961 1.094974 1011.8 0.711998
8 44 25 589.3 246.0 2.395528 1.089205 1141.1 0.516432
6 60 25 588.8 120.0 4.906667 1.126946 1025.0 0.574439
4 22 5 493.5 124.0 3.979839 1.105354 1106.3 0.446082
11 26 7 391.2 206.0 1.899029 1.069326 1099.8 0.355701
17 13 7 343.2 152.0 2.257895 1.069697 990.9 0.346352
18 45 20 174.5 160.0 1.090625 1.032210 1118.4 0.156026
12 38 20 169.8 170.0 0.998824 1.029754 939.8 0.180677
3 21 11 148.6 460.0 0.323043 1.016830 1203.1 0.123514
5 34 13 -342.0 170.0 -2.011765 0.939258 1160.8 -0.294624
7 42 22 -374.4 156.0 -2.400000 0.933744 1189.6 -0.314728
1 51 20 -441.4 160.0 -2.758750 0.922788 1089.9 -0.404991
9 58 27 -1485.5 222.0 -6.691441 0.787506 2394.0 -0.620510
10 19 25 -1620.0 234.0 -6.923077 0.775828 1845.7 -0.877716
13 33 16 -1625.0 400.0 -4.062500 0.827957 2307.7 -0.704164
2 44 24 -1885.7 508.0 -3.712008 0.828287 2652.2 -0.710995
14 55 12 -2048.3 398.0 -5.146482 0.776908 2813.6 -0.728000

De cette manière, la solution optimale a été recherchée, mais elle est naturelle car nous avons essayé 20 individus pendant 100 générations, soit près de 2000 fois.

Puisqu'il n'y a que deux paramètres cette fois, le nombre de combinaisons n'augmente pas tellement,

SlowMAperiod = np.arange(10, 161) #Gamme de période moyenne mobile à long terme
FastMAperiod = np.arange(5, 131)  #Gamme de période moyenne mobile à court terme

Augmentons-le à 19 026 façons comme ça. Le résultat est

Slow Fast Profit Trades Average PF MDD RF
0 52 48 2003.4 190.0 10.544211 1.426773 1106.4 1.810738
5 125 26 1312.6 58.0 22.631034 1.513939 896.4 1.464302
16 49 47 1203.9 62.0 19.417742 1.448046 773.0 1.557439
11 56 55 989.6 116.0 8.531034 1.245266 922.0 1.073319
14 52 34 704.0 62.0 11.354839 1.261632 527.2 1.335357
13 152 36 545.5 75.0 7.273333 1.133198 936.5 0.582488
2 140 58 457.4 196.0 2.333673 1.085960 867.1 0.527505
18 40 109 308.1 88.0 3.501136 1.073977 1435.0 0.214704
6 75 107 255.1 78.0 3.270513 1.066815 1145.1 0.222775
3 158 85 172.7 122.0 1.415574 1.036899 1530.6 0.112832
12 68 32 -622.3 90.0 -6.914444 0.836838 1629.9 -0.381803
10 120 111 -638.0 37.0 -17.243243 0.787057 1233.4 -0.517269
8 153 30 -667.3 35.0 -19.065714 0.776284 1558.8 -0.428086
7 43 74 -749.0 39.0 -19.205128 0.770245 1766.8 -0.423930
15 63 104 -774.3 92.0 -8.416304 0.835339 1692.6 -0.457462
9 154 56 -1296.9 58.0 -22.360345 0.675945 1733.3 -0.748226
1 152 24 -1315.2 74.0 -17.772973 0.664627 2130.3 -0.617378
19 155 27 -1363.8 60.0 -22.730000 0.672006 1474.4 -0.924986
17 109 40 -1478.5 62.0 -23.846774 0.651379 1784.5 -0.828523
4 148 122 -1957.4 100.0 -19.574000 0.626400 2171.4 -0.901446
Par conséquent, la solution optimale n'a pas pu être trouvée. Cependant, si vous répétez cette opération plusieurs fois, la solution optimale sera trouvée. Eh bien, si la combinaison peut être gérée par round robin, il sera possible de trouver une solution raisonnable par recherche aléatoire.

Recommended Posts

[Python] Essayez d'optimiser les paramètres de la systole FX avec une recherche aléatoire
[Python] Essayez d'optimiser les paramètres de systole FX avec un algorithme génétique
Essayez de gratter avec Python.
Recherche séquentielle avec Python
Dichotomie avec python
Dichotomie avec Python 3
Essayez la sortie Python avec Haxe 3.2
Recherche de bits complète avec Python
Backtesting FX Systre avec Python (2)
Essayez d'exécuter Python avec Try Jupyter
Les moteurs de recherche fonctionnent avec python
Rechercher des tweets Twitter avec Python
Essayez la reconnaissance faciale avec Python
Rationalisez la recherche Web avec Python
Essayez de gratter avec Python + Beautiful Soup
Tester avec des nombres aléatoires en Python
Essayez d'exploiter Facebook avec Python
générateur de nombres aléatoires français avec python
Essayez la décomposition de valeurs singulières avec Python
Essayez la reconnaissance faciale avec python + OpenCV
Essayez la simulation de contrôle de fréquence avec Python
Essayez de reproduire un film couleur avec Python
Essayez de vous connecter à qiita avec Python
Essayez une formule utilisant Σ avec python
Essayez de travailler avec des données binaires en Python
Rechercher le labyrinthe avec l'algorithme python A *
Essayez d'utiliser Python avec Google Cloud Functions
Convertissez des données FX 1 minute en données 5 minutes avec Python
Essayez le scraping HTML avec la bibliothèque Python
Essayez d'appeler Python depuis Ruby avec une économie
Essayez de dessiner une carte avec python + cartopy 0.18.0
[Suite] Essayez l'accès au registre PLC avec Python
Essayez d'attribuer ou de changer avec Python: lambda
[Pour les débutants] Essayez le web scraping avec Python
Essayez Python
Essayez de prédire FX avec LSTM en utilisant Keras + Tensorflow Partie 3 (essayez d'atteindre tous les paramètres)
nginxparser: essayez d'analyser le fichier de configuration nginx avec Python
Sortie CSV de la recherche Google avec [Python]! 【Facile】
Rechercher et télécharger automatiquement des vidéos YouTube avec Python
Raisonnement causal et recherche causale par Python (pour les débutants)
Essayez-le avec JupyterLab en Python japonais Word Cloud.
Essayez d'exécuter Google Chrome avec Python et Selenium
Essayez de résoudre le diagramme homme-machine avec Python
Essayez de dessiner une courbe de vie avec python
Essayez de créer un code de "décryptage" en Python
Essayez de générer automatiquement des documents Python avec Sphinx
Essayez de travailler avec Mongo en Python sur Mac
[Python3] [Ubuntu16] [Docker] Essayez la reconnaissance faciale avec OpenFace
Essayez de créer un groupe de dièdre avec Python
Essayez de détecter les poissons avec python + OpenCV2.4 (inachevé)
Effectuez une recherche Twitter à partir de Python et essayez de générer des phrases avec la chaîne de Markov.
Essayez de mettre en œuvre une recherche complète de la séquence qui apparaît souvent chez les pros de la concurrence avec python