Le trading avec Python - page 2

 
Malik Arykov copy_rates_from n'est pas suffisant pour une analyse complète des données. S'il était possible d'extraire les données des indicateurs (y compris les indicateurs personnalisés), l'anneau d'analyse serait fermé.

À mon avis, le trading via Python est une opération de relations publiques de MQL5.

Qui vous empêche de calculer les données des indicateurs ? ou de passer les données des indicateurs personnalisés à python depuis mql ?

 
Sergey Deev #:

Qui vous empêche de calculer les données des indicateurs ? ou de passer les données des indicateurs personnalisés à python depuis mql.

Pouvez-vous donner un exemple, au moins en pseudocode. Nous créons un script en python. Je veux recevoir les données de Bollinger (Ishimoku, etc.) pour une certaine période de temps. Comment dois-je m'y prendre ?

 
Sergey Zhilinskiy insérez le code dans la fenêtre pop-up.
Merci
 
Sergey Deev #:

Echanger avec un python, c'est bien...

...


Python stocke les cotations et les indicateurs sur SQLite. Communication MQL-python via socket, fichiers ou base de données (socket est préférable).


Vous avez raison, bien sûr. Mais je veux aider les gens qui ne sont pas familiers avec les bases de données, les sockets d'un certain type à entrer dans le trading algorithmique...

Faisons donc simple - par le biais de fichiers. Clairement, et suffisamment pour travailler avec.

 

Je propose de faire trois dossiers :

Classes.py - pour y mettre toutes sortes de classes, pas nécessairement toutes, juste celles qui en ont besoin, afin qu'il n'y ait pas de code inutile qui encombre le fichier principal;

Functions.py - pour y stocker toutes sortes de fonctions, pas nécessairement toutes, juste celles qui ne doivent pas être encombrées de code dans le fichier principal ;

TradeLogic.py - fichier principal.


Je mettrai les classes de timing, bar et trade dans le fichier Classes.py (une classe de trade vide) :

import datetime as dt 


class date_time(dt.datetime): 
    
    '''
    Класс описывает отсчёт даты и времени. 
    Представляет собой расширение класса datetime библиотеки datetime.  
    '''
    
    @property 
    def M5_view(self): 
        minute = (self.minute//5)*5 
        if minute < 10: 
            _minute = '0'+str(minute) 
        else: 
            _minute = str(minute) 
        return self.strftime('%Y%m%d%H')+_minute
    
    @property 
    def nice_view(self): 
        return self.strftime('%Y.%m.%d %H:%M:%S')
    
    def __str__(self): 
        return self.M5_view
    
    def __repr__(self): 
        return self.__str__() 



class Bar: 
    
    '''
    Класс описывает бар, то есть структуру данных, 
    удобную для описания изменения цен финансовых инструментов на интервалах времени.  
    '''
    
    def __init__(self, instrument, time_frame, time_close, price_open, price_low, price_high, price_close, pips_value): 
        self.instrument = instrument 
        self.time_frame = time_frame   
        self.time_close = time_close 
        self.time_open = self.time_close - dt.timedelta(minutes=self.time_frame) 
        self.price_open = price_open 
        self.price_low = price_low 
        self.price_high = price_high 
        self.price_close = price_close 
        self.w = pips_value 
    
    def __str__(self): 
        str1 = '(Bar: instrument={} time_frame={} time_open={} time_close={}\n'
        str2 = 'open={} low={} high={} close={} pips_value={})'
        return (str1+str2).format(self.instrument, self.time_frame, self.time_open.M5_view, self.time_close.M5_view, 
                                  self.price_open, self.price_low, self.price_high, self.price_close, self.w) 
    
    def __repr__(self): 
        return self.__str__()



class Sdelka: 
    
    '''
    Класс описывает сделку. 
    Используется для описания cделок по финансовым инструментам. 
    '''
    
    def __init__(self, instrument, buysell, dt_stamp, price_in, price_SL, price_TP, pips_value): 
        self.instrument = instrument 
        self.buysell = buysell 
        self.dt_stamp = dt_stamp 
        self.price_in = price_in 
        self.price_SL = price_SL 
        self.price_TP = price_TP
        self.w = pips_value 
    
    @property 
    def bs(self): 
        if self.buysell == 'buy': 
            return 1 
        elif self.buysell == 'sell': 
            return -1 
    
    @property 
    def SL(self): 
        return abs(round((self.price_SL - self.price_in)/self.w, 1)) 
    
    @property 
    def TP(self): 
        return abs(round((self.price_TP - self.price_in)/self.w, 1)) 
        
    def __str__(self): 
        str1 = '(Sdelka: instrument={} buysell={} dt_stamp={} price_in={} SL={} TP={} price_SL={} price_TP={} w={})'
        return str1.format(self.instrument, self.buysell, self.dt_stamp.M5_view, self.price_in, self.SL, self.TP, 
                           self.price_SL, self.price_TP, self.w) 
    
    def __repr__(self): 
        return self.__str__() 
        


Pas encore d'explications, des explications seront fournies au fur et à mesure.

 
Malik Arykov #:

Pouvez-vous me donner un exemple, au moins en pseudocode ? Créez un script en python. Je veux obtenir les données de Bolinger (Ishimoku, etc.) pour un temps donné. Comment dois-je m'y prendre ?

En d'autres termes, donnez un exemple de la manière de sauvegarder les données de n'importe quel indicateur dans un fichier csv ou SQLite et de les lire ensuite dans python ? Ce ne sera pas drôle ?

 

Dans le fichier TradeLogic.py, je suggère d'écrire ceci pour commencer :

import os, time 
import datetime as dt 
from json import loads, dump 
from random import randint   
from numpy import log10 
import Classes 
import Functions  
import MetaTrader5 as mt5


N = 1000 # количество отсчётов, сохраняемых в файлах котировок 
N_sd_sell_max = 3 # максимальное количество сделок типа sell по одному инструменту 
N_sd_buy_max = 3 # максимальное количество сделок типа buy по одному инструменту 
volume = 0.01 # объём сделок  
account_demo = ['Alpari-MT5-Demo', 12345678, 'password'] 
work_account = account_demo  
work_catalog = 'Z:\\fx_for_forum\\fx\\'
instruments = ['EURUSD_i', 'GBPUSD_i', 'EURGBP_i', 'USDCHF_i', 'USDCAD_i', 'USDJPY_i'] 

Voici quelques importations de ce qui sera nécessaire plus tard, et le programme lui-même commence à la ligne N=1000. L'adresse "work_catalog" est le répertoire où je prévois de sauvegarder les fichiers avec les prix et, si nécessaire, d'autres. L'adresse est si étrange, car j'utilise Metatrader dans une machine virtuelle et pour cette démonstration Python - également là, instruments - la liste des instruments sur lesquels nous prévoyons de trader.

 
Sergey Deev #:

Par exemple, donnez un exemple de sauvegarde des données d'un indicateur dans un fichier csv ou SQLite, puis de lecture dans python ? Ce ne sera pas drôle ?

Non, ce ne sera pas drôle. Il y a beaucoup de gens qui peuvent rapidement commencer le trading algorithmique avec Python, mais qui ne sont pas du tout familiers avec Python, et qui ont le sentiment qu'ils n'ont pas besoin de MQL, ne sont pas prêts à passer du temps à apprendre un outil qui a une application extrêmement étroite. Ne parlez pas non plus de syntaxe de type C, il y a trop de gens qui ne connaissent pas du tout le C/C++.

L'objectif de cette branche est de donner des instructions spécifiques aux personnes qui ne savent pas par où commencer avec le trading algorithmique. Un coup de pied de démarrage. Sans complications inutiles.

 

La bibliothèque metatrader5 sera utilisée pour gérer le terminal Metatrader5.

Bibliothèque ici: https://pypi.org/project/MetaTrader5

Documentation ici : https://www.mql5.com/ru/docs/integration/python_metatrader5

 

A l'aide des fonctions décrites dans la bibliothèque, implémentez les fonctions d'initiation de connexion au terminal et de terminaison de connexion au terminal. Nous prévoyons de le faire en boucle infinie toutes les 5 minutes.


Ecrivez aussi la fonction dt_stamp_from_M5_view qui va créer un compte de date-heure(objet de la classe date_time) à partir de la chaîne de type '202112101635' (je l'appelle M5_view).


Mettons ce code dans le fichier TradeLogic.py :

import os, time 
import datetime as dt 
from json import loads, dump 
from random import randint   
from numpy import log10 
from Classes import date_time  
import Functions  
import MetaTrader5 as mt5


N = 1000 # количество отсчётов, сохраняемых в файлах котировок 
N_sd_sell_max = 3 # максимальное количество сделок типа sell по одному инструменту 
N_sd_buy_max = 3 # максимальное количество сделок типа buy по одному инструменту 
volume = 0.01 # объём сделок  
account_demo = ['Alpari-MT5-Demo', 12345678, 'password'] 
work_account = account_demo  
work_catalog = 'Z:\\fx_for_forum\\fx\\'
instruments = ['EURUSD_i', 'GBPUSD_i', 'EURGBP_i', 'USDCHF_i', 'USDCAD_i', 'USDJPY_i'] 



def terminal_init(path_to_terminal, account):
    '''
    Функция осуществляет соединение с терминалом MT5
    '''
    if mt5.initialize(path_to_terminal, server=account[0], login=account[1], password=account[2]): 
        str1 = ' - соединение с терминалом {} билд {} установлено' 
        print(date_time.now().nice_view, str1.format(mt5.terminal_info().name, mt5.version()[1])) 
        return True 
    else: 
        print(date_time.now().nice_view, ' - соединение с терминалом установить не удалось') 
        return False 


def terminal_done():
    '''
    Функция завершает соединение с терминалом MT5
    '''     
    try: 
        mt5.shutdown() 
        print('\n' + date_time.now().nice_view, ' - соединение с терминалом успешно завершено') 
    except: 
        print('\n' + date_time.now().nice_view, ' - соединение с терминалом завершить не удалось') 


def dt_stamp_from_M5_view(M5_view): 
    return date_time(int(M5_view[0:4]), int(M5_view[4:6]), int(M5_view[6:8]), int(M5_view[8:10]), int(M5_view[10:12]))  





def main(N): 
    
    '''
    Главная функция, обеспечивающая в бесконечном цикле связь с терминалом, 
    сохранение котировок, и запуск функции, осуществляющей торговлю
    '''    
    
    dt_start = date_time.now() 
    dt_write = dt_stamp_from_M5_view(dt_start.M5_view) + dt.timedelta(minutes=5, seconds=10) 
    print('\n' + dt_start.nice_view, ' - начал работу, бездействую до ' + dt_write.nice_view + '\n') 
    timedelta_sleep = dt_write - date_time.now() 
    time.sleep(timedelta_sleep.seconds) 
    
    while True:
        
        # установка соединения с MetaTrader5 
        if terminal_init(os.path.join('C:\\', 'Program Files', 'Alpari MT5', 'terminal64.exe'), work_account): 
        
            # пауза 10 секунд: временная заглушка, имитирующая анализ цен, принятие и выполнение решений 
            print('\nосуществляю торговлю: анализирую котировки, открываю и/или закрываю сделки')
            time.sleep(10)
            
            # завершение соединения с MetaTrader5 
            terminal_done() 
        
            # определение параметров ожидания до следующего выполнения тела цикла 
            dt_start = date_time.now()  
            dt_write = dt_stamp_from_M5_view(dt_start.M5_view) + dt.timedelta(minutes=5, seconds=10) 
            timedelta_sleep = dt_write - dt_start 
            print(date_time.now().nice_view + '  - засыпаю до {}\n\n\n\n\n'.format(dt_write.nice_view))  
            time.sleep(timedelta_sleep.seconds) 
        


if __name__ == '__main__':
    main(N)

Ce code est déjà fonctionnel. C'est-à-dire qu'il démarre, détermine le multiple égal le plus proche de 5 minutes, + 10 secondes (pour s'assurer que les barres du serveur se fermeront, nous voulons sauvegarder les cotations), dort jusqu'à ce moment, se réveille, se connecte au terminal, négocie (dans le sens où il ne fait rien), termine la connexion au terminal, dort pendant 5 minutes - et le cycle se répète.


Fonctionnement du programme :