用Python进行交易 - 页 2

 
Malik Arykov copy_rates_from 对于完整的数据分析是不够的。如果有可能提取指标数据(包括自定义指标),分析环就会被关闭。

IMHO,通过Python进行交易是MQL5的一个公关举措。

谁能阻止你计算指标数据? 或者把自定义指标的数据从mql传给python?

 
Sergey Deev #:

谁能阻止你计算指标数据? 或者从mql将自定义指标的数据传递给python

你能不能举个例子,至少用伪代码。我们用python创建一个脚本。我想接收某一时间段的布林线数据(Ishimoku,等等)。我怎么做呢?

 
Sergey Zhilinskiy 插入代码。
谢谢
 
Sergey Deev #:

与蟒蛇交易是好事...

...


Python在SQLite上存储报价和指标。通过套接字、文件或数据库(套接字更好)进行MQL-python通信。


当然,你是对的。但我想帮助那些不熟悉数据库、套接字的人进入算法交易...

因此,让我们把它变得简单--通过文件。很明显,而且有足够的工作能力。

 

我提议制作三个文件。

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 #:

你能给我一个例子吗,至少在伪代码中?在python中创建一个脚本。我想获得某个时间段的博林格(石木等)数据。我怎么做呢?

也就是说,请举例说明如何将任何指标的数据保存在csv-file或SQLite中,然后用python读取?这不会很有趣吗?

 

在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 "是我计划保存有价格的文件的目录,如果有必要,还有其他的。这个地址很奇怪,因为我在虚拟机 中使用Metatrader,为了这个演示,Python - 也在那里,仪器 - 我们计划交易的仪器列表。

 
Sergey Deev #:

即举个例子,把任何指标数据保存到csv文件或SQLite中,然后再读到python中?这不会很有趣吗?

不,这不会是有趣的。有很多人可以用Python快速开始算法交易,但目前对Python一点都不熟悉,而且感觉自己不需要MQL,不准备花时间学习一个应用范围极窄的工具。也不要讲类似C的语法,有太多的人根本不熟悉C/C++。

这个分支的目的是给那些不知道应该从哪里开始进行算法交易的人提供具体指导。一个首发踢球。没有任何不必要的并发症。

 

metatrader5库将被用来管理Metatrader5终端。

这里的图书馆: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分钟--循环重复。


程序操作。