Trading con Python - pagina 2

 
Malik Arykov copy_rates_from non è sufficiente per un'analisi completa dei dati. Se fosse possibile estrarre i dati degli indicatori (compresi gli indicatori personalizzati), l'anello di analisi sarebbe chiuso.

IMHO, il trading via Python è una mossa di PR di MQL5.

Chi vi impedisce di calcolare i dati degli indicatori? O di passare i dati degli indicatori personalizzati a python da mql?

 
Sergey Deev #:

Chi vi impedisce di calcolare i dati degli indicatori? O passare i dati degli indicatori personalizzati a python da mql

Puoi fare un esempio, almeno in pseudocodice. Creiamo uno script in python. Voglio ricevere i dati di Bollinger (Ishimoku, ecc.) per un certo periodo di tempo. Come si fa?

 
Sergey Zhilinskiy inserisci il codice nella finestra pop-up.
Grazie
 
Sergey Deev #:

Scambiare con un pitone è buono...

...


Python memorizza quotazioni e indicatori su SQLite. Comunicazione MQL-python via socket, file o database (socket è meglio).


Hai ragione, naturalmente. Ma voglio aiutare le persone che non hanno familiarità con i database, le prese di qualche tipo ad entrare nel trading algoritmico...

Quindi rendiamolo semplice - attraverso i file. Chiaramente, e abbastanza per lavorare.

 

Propongo di fare tre file:

Classes.py - per metterci dentro tutti i tipi di classi, non necessariamente tutte, solo quelle che ne hanno bisogno, in modo che non ci sia un inutile ingombro di codice nel file principale;

Functions.py - per memorizzare lì tutti i tipi di funzioni, non necessariamente tutte, solo quelle che hanno bisogno di non ingombrare il codice nel file principale;

TradeLogic.py - file principale.


Metterò le classi di timing, bar e trade nel file Classes.py (una classe trade vuota):

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__() 
        


Non ci sono ancora spiegazioni, le spiegazioni saranno fornite man mano che andremo avanti.

 
Malik Arykov #:

Puoi farmi un esempio, almeno in pseudocodice? Creare uno script in python. Voglio ottenere i dati di Bolinger (Ishimoku, ecc.) per un dato tempo. Come si fa?

Cioè, dare un esempio di come salvare i dati di qualsiasi indicatore in un file csv o SQLite e poi leggerli in python? Non sarà divertente?

 

Nel file TradeLogic.py suggerisco di scrivere questo per iniziare:

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'] 

Qui ci sono alcune importazioni di ciò che sarà necessario in seguito, e il programma vero e proprio inizia con la linea N=1000. L'indirizzo "work_catalog" è la directory dove ho intenzione di salvare i file con i prezzi e, se necessario, altri. L'indirizzo è così strano, perché io uso Metatrader in macchina virtuale e per questa dimostrazione Python - anche lì, strumenti - l'elenco degli strumenti su cui abbiamo intenzione di commercio.

 
Sergey Deev #:

cioè dare un esempio di salvataggio dei dati di qualsiasi indicatore in un file csv o SQLite e poi leggerli in python? Non sarà divertente?

No, non sarà divertente. Ci sono molte persone che possono iniziare rapidamente il trading algoritmico con Python, ma attualmente non hanno alcuna familiarità con Python, e hanno la sensazione di non aver bisogno di MQL, non sono pronti a spendere tempo per imparare uno strumento che ha un'applicazione estremamente limitata. Non parlate nemmeno di sintassi simile al C, ci sono troppe persone che non conoscono affatto il C/C++.

Lo scopo di questo ramo è quello di dare istruzioni specifiche alle persone che non sanno da dove dovrebbero iniziare con il trading algoritmico. Un calcio d'inizio. Senza complicazioni inutili.

 

La libreria metatrader5 sarà utilizzata per gestire il terminale Metatrader5.

Biblioteca qui:https://pypi.org/project/MetaTrader5

Documentazione qui: https: //www.mql5.com/ru/docs/integration/python_metatrader5

 

Utilizzando le funzioni descritte nella libreria, implementate le funzioni per iniziare una connessione al terminale e per terminare una connessione al terminale. Abbiamo intenzione di farlo in un ciclo infinito ogni 5 minuti.


Scrivete anche la funzione dt_stamp_from_M5_view che creerà un conteggio di data-ora(oggetto di classe date_time) dalla stringa di tipo '202112101635' (la chiamo M5_view).


Mettiamo questo codice nel file 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)

Questo codice è già funzionale. Cioè, si avvia, determina il multiplo uguale più vicino di 5 minuti, + 10 secondi (per assicurare che le barre del server si chiudano, vogliamo salvare le quotazioni), dorme fino a questo momento, si sveglia, si connette al terminale, negozia (nel senso che non fa nulla), termina la connessione al terminale, dorme per 5 minuti - e il ciclo si ripete.


Funzionamento del programma: