Торговля с Python - страница 2

 
Malik Arykov #:

Питон - только для анализа данных с богатой возможностью отображать результаты анализа в виде 2d(3d) графиков.

copy_rates_from для полного анализа данных недостаточно. Если можно было извлекать данные индикаторов (в т.ч. пользовательских), то кольцо анализа замкнулось бы.

А торговать через питон, ИМХО - пиар ход MQL5

А кто мешает посчитать данные индикаторов? или передать данные пользовательских индикаторов в питон из mql

 
Sergey Deev #:

А кто мешает посчитать данные индикаторов? или передать данные пользовательских индикаторов в питон из mql

А можете пример привести, хотя бы на псевдокоде. Создаем скрипт на питоне. Хочу получить данные Болинджера(Ишимоку и т.д) на заданное время. Каким образом? 

 
Sergey Zhilinskiy #:
А какое будет преимущество по сравнению с реализацией на MQL?

Возможность начать алгоритмическую торговлю людям, которым не хочется тратить время на вникание в премудрости MQL, которые не видят смысла изучать язык, у которого чрезвычайно узкое применение, вместо языка, который применим везде и всюду.

Vladimir Karputov #:

Вставляйте, пожалуйста, код правильно: сначала нажимаете кнопку  , а затем во всплывающее окно вставляете код.

Благодарю
 
Sergey Deev #:

Торговля с питон - это гуд..

...


В питоне хранение котировок и индикаторов на SQLite. Связь MQL-питон через сокет, файлы или БД (лучше сокет).


Вы, конечно, правы. Но мне хотелось бы посодействовать входу в алгоритмический трейдинг людям, которые не знакомы вот так сразу с тем, как обращаться с базами данных, сокетами какими-то...

так что сделаем просто - через файлы. Наглядно, и достаточно для работы.

 

Предлагаю сделать три файла:

Classes.py - для того, чтобы складывать туда всякие разные классы, не обязательно все, просто те, которые просятся, чтобы не было лишнего загромождающего кода в основном файле;

Functions.py - для того, чтобы складывать туда всякие разные функции, не обязательно все, просто те, которые просятся, чтобы не было лишнего загромождающего кода в основном файле;

TradeLogic.py - основной файл.


Положу в файл Classes.py классы отсчёта времени, бара, и сделки (заготовку класса сделки):

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


Никаких пояснений пока что не даю, пояснения будут по ходу дела.

 
Malik Arykov #:

А можете пример привести, хотя бы на псевдокоде. Создаем скрипт на питоне. Хочу получить данные Болинджера(Ишимоку и т.д) на заданное время. Каким образом? 

т.е. привести пример сохранения данных любых индикаторов  в csv- файл или SQLite с последующим чтением их на питон? Это не смешно будет?

 

В файле TradeLogic.py предлагаю написать для начала такое:

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

Здесь некоторые импорты того, что потом понадобится, и собственно программа начинается со строки N=1000. Адрес "work_catalog" - это каталог, куда предполагаю сохранять файлы с ценами, и, если нужно будет, другие. Адрес такой странный, потому что пользую Метатрейдер в виртуальной машине, и для этой демонстрации Python - тоже там же, instruments - список инструментов, по которым планируем вести торговлю.

 
Sergey Deev #:

т.е. привести пример сохранения данных любых индикаторов  в csv- файл или SQLite с последующим чтением их на питон? Это не смешно будет?

Нет, не будет смешно. Очень много людей, способных быстро начать алгоритмическую торговлю с Python, но на данный момент не знакомых с Python совсем, и при этом испытывающих какое-то ощущение ненужности им MQL, неготовности тратить время на изучение инструмента, имеющего чрезвычайно узкое применение. Про С-подобный синтаксис тоже не надо, очень много людей незнакомы с С/С++ совсем.

Цель ветки - представить конкретные инструкции людям, не знающим, с какой стороны им вообще начать алготрейдинг. Стартовый пинок. Без лишних сложностей.

 

Будет использоваться библиотека metatrader5, для управления терминалом Метатрейдер5.

Библиотека здесь:https://pypi.org/project/MetaTrader5

Документация тут: https://www.mql5.com/ru/docs/integration/python_metatrader5

 

Пользуясь описанными в библиотеке функциями, реализуем функции для инициации соединения с терминалом, и для завершения соединения с терминалом. Планируем делать это в бесконечном цикле каждые 5 минут.


Также напишем функцию dt_stamp_from_M5_view, которая будет из строки вида '202112101635' (я называю такой вид M5_view) создавать отсчёт даты-времени (объект класса date_time). 


Поместим в файл 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)

Этот код уже функционален. В том смысле, что он запускается, определяет ближайший "ровный", кратный 5 минутам отсчёт времени, + 10 секунд к нему (чтобы бары на сервере гарантированно закрылись, нам ведь надо сохранить котировки будет), спит до этого момента, просыпается, соединяется с терминалом, делает торговлю (в том смысле, что ничего не делает), завершает соединение с терминалом, засыпает на 5 минут, - и цикл повторяется. 


Работа программы:


Причина обращения: