Negociando com Python - página 2

 
Malik Arykov copy_rates_from não é suficiente para uma análise completa dos dados. Se fosse possível extrair dados indicadores (incluindo indicadores personalizados), o anel de análise seria fechado.

IMHO, o comércio via Python é um movimento de relações públicas da MQL5.

Quem o impede de calcular os dados dos indicadores? Ou passar os dados dos indicadores personalizados para python a partir de mql?

 
Sergey Deev #:

Quem o impede de calcular dados indicadores? Ou passar dados de indicadores personalizados para python a partir de mql

Você pode dar um exemplo, pelo menos em pseudo-código. Criamos um roteiro em python. Quero receber os dados do Bollinger (Ishimoku, etc.) por um determinado período de tempo. Como eu faço isso?

 
Sergey Zhilinskiy insira o código na janela pop-up.
Obrigado
 
Sergey Deev #:

Negociar com uma pitão é bom...

...


Python armazena citações e indicadores no SQLite. Comunicação MQL-python via socket, arquivos ou banco de dados (socket é melhor).


Você está certo, é claro. Mas quero ajudar as pessoas que não estão familiarizadas com bancos de dados, soquetes de algum tipo para entrar em comércio algorítmico...

Portanto, vamos simplificar - através de arquivos. Claramente, e o suficiente para trabalhar com ele.

 

Proponho a criação de três arquivos:

Classes.py - para colocar todos os tipos de classes ali, não necessariamente todas, apenas aquelas que precisam, para que não haja um código desordenado desnecessário no arquivo principal;

Functions.py - para armazenar ali todo tipo de funções, não necessariamente todas, apenas aquelas que não precisam ser desordenadas no arquivo principal;

TradeLogic.py - arquivo principal.


Colocarei as classes de tempo, barra e comércio no arquivo Classes.py (uma classe de comércio em branco):

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


Ainda sem explicações, serão fornecidas explicações à medida que formos avançando.

 
Malik Arykov #:

Você pode me dar um exemplo, pelo menos em pseudo-código? Criar um roteiro em python. Quero obter dados de Bolinger (Ishimoku, etc.) por um determinado tempo. Como eu faço isso?

Ou seja, dê um exemplo de como salvar dados de qualquer indicador em arquivo csv ou SQLite e depois leia-o em python? Não vai ser engraçado?

 

No arquivo TradeLogic.py, sugiro escrever isto para começar:

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

Aqui estão algumas importações do que será necessário mais tarde, e o programa em si começa com a linha N=1000. O endereço "work_catalog" é o diretório onde pretendo salvar arquivos com preços e, se necessário, outros. O endereço é tão estranho, porque eu uso Metatrader em máquina virtual e para esta demonstração Python - também ali, instrumentos - a lista de instrumentos sobre os quais planejamos negociar.

 
Sergey Deev #:

ou seja, dar um exemplo de como salvar qualquer dado indicador em um arquivo csv ou SQLite e depois lê-lo em python? Não vai ser engraçado?

Não, não vai ser engraçado. Há muitas pessoas que podem iniciar rapidamente o comércio algorítmico com Python, mas atualmente não estão familiarizadas com Python, e têm a sensação de que não precisam de MQL, não estão prontas para gastar tempo aprendendo uma ferramenta que tem aplicação extremamente estreita. Também não fale sobre a sintaxe tipo C, há muitas pessoas que não estão familiarizadas com C/C++.

O objetivo deste ramo é dar instruções específicas às pessoas que não sabem por onde devem começar com o comércio algorítmico. Um pontapé inicial. Sem nenhuma complicação desnecessária.

 

A biblioteca Metatrader5 será utilizada para gerenciar o terminal Metatrader5.

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

Documentação aqui: https: //www.mql5.com/ru/docs/integration/python_metatrader5

 

Usando as funções descritas na biblioteca, implementar as funções para iniciar uma conexão com o terminal e para terminar uma conexão com o terminal. Planejamos fazer isso em loop infinito a cada 5 minutos.


Também escreva a função dt_stamp_from_M5_view que criará uma contagem de data/hora(objeto de classe date_time) a partir da string do tipo '202112101635' (chamo-lhe M5_view).


Vamos colocar este código no arquivo 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)

Este código já está funcional. Isto é, ele inicia, determina o múltiplo igual mais próximo de 5 minutos, + 10 segundos (para garantir que as barras do servidor fecharão, queremos salvar cotações), dorme até esse momento, acorda, se conecta ao terminal, negocia (no sentido de que não faz nada), termina a conexão com o terminal, dorme por 5 minutos - e o ciclo se repete.


Operação do programa: