Trading with Python - page 2

 
Malik Arykov copy_rates_from is not sufficient for complete data analysis. If it were possible to extract indicator data (including custom indicators), the analysis ring would be closed.

IMHO, trading via Python is a PR move by MQL5.

Who prevents you from calculating the indicator data? Or pass the data of custom indicators to python from mql?

 
Sergey Deev #:

Who prevents you from calculating indicator data? Or pass data of custom indicators to python from mql

Can you give an example, at least in pseudocode. We create a script in python. I want to receive the Bollinger's data (Ishimoku, etc.) for a certain time period. How do I do it?

 
Sergey Zhilinskiy insert the code in the pop-up window.
Thanks
 
Sergey Deev #:

Trading with a python is good...

...


Python stores quotes and indicators on SQLite. MQL-python communication via socket, files or database (socket is better).


You are right of course. But I want to help people who are not familiar with databases, sockets of some kind to enter algorithmic trading...

So let's make it simple - through files. Clearly, and enough to work with.

 

I propose to make three files:

Classes.py - to put all sorts of classes in there, not necessarily all of them, just the ones that need it, so that there is no unnecessary cluttering code in the main file;

Functions.py - for storing there all sorts of functions, not necessarily all of them, just the ones that need not to be cluttered code in the main file;

TradeLogic.py - main file.


I will put classes of timing, bar, and trade in the Classes.py file (a blank trade class):

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


No explanations yet, explanations will be provided as we go along.

 
Malik Arykov #:

Can you give me an example, at least in pseudocode? Create a script in python. I want to get Bolinger (Ishimoku, etc.) data for a given time. How do I do it?

I.e., give an example of how to save data of any indicators in csv-file or SQLite and then read it in python? It will not be funny?

 

In the file TradeLogic.py I suggest writing this to start with:

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

Here are some imports of what will be needed later, and the program itself starts with line N=1000. The address "work_catalog" is the directory where I plan to save files with prices and, if necessary, others. The address is so strange, because I use Metatrader in virtual machine and for this demonstration Python - also there, instruments - the list of instruments on which we plan to trade.

 
Sergey Deev #:

i.e. give an example of saving any indicator data to a csv file or SQLite and then reading it into python? It will not be funny?

No, it won't be funny. There are a lot of people who can quickly start algorithmic trading with Python, but are currently not familiar with Python at all, and have a feeling that they don't need MQL, are not ready to spend time learning a tool that has extremely narrow application. Don't speak about C-like syntax either, there are too many people unfamiliar with C/C++ at all.

The purpose of this branch is to give specific instructions to people who do not know where they should start with algorithmic trading. A starter kick. Without any unnecessary complications.

 

The metatrader5 library will be used to manage the Metatrader5 terminal.

Library here:https://pypi.org/project/MetaTrader5

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

 

Using the functions described in the library, implement the functions for initiating a connection to the terminal and for terminating a connection to the terminal. We plan to do it in infinite loop every 5 minutes.


Also write the dt_stamp_from_M5_view function that will create a count of date-time(object of class date_time) from the '202112101635' type string (I call it M5_view).


Let's put this code into TradeLogic.py file:

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)

This code is already functional. I.e., it starts up, determines the nearest equal multiple of 5 minutes, + 10 seconds (to ensure that server bars will close, we want to save quotes), sleeps to this moment, wakes up, connects to the terminal, trades (in the sense that it does nothing), ends connection to the terminal, sleeps for 5 minutes - and the cycle repeats.


Program operation: