Handel mit Python - Seite 2

 
Malik Arykov copy_rates_from ist für eine vollständige Datenanalyse nicht ausreichend. Wenn es möglich wäre, Indikatordaten (einschließlich benutzerdefinierter Indikatoren) zu extrahieren, würde sich der Analysering schließen.

IMHO ist der Handel über Python eine PR-Maßnahme von MQL5.

Wer hindert Sie daran, die Daten der Indikatoren zu berechnen oder die Daten der benutzerdefinierten Indikatoren von mql an python zu übergeben?

 
Sergey Deev #:

Wer hindert Sie daran, Indikatordaten zu berechnen? Oder Daten von benutzerdefinierten Indikatoren von mql an Python zu übergeben

Können Sie ein Beispiel geben, zumindest in Pseudocode. Wir erstellen ein Skript in Python. Ich möchte die Bollinger-Daten (Ishimoku, etc.) für einen bestimmten Zeitraum erhalten. Wie kann ich das tun?

 
Sergey Zhilinskiy fügen Sie dann den Code in das Pop-up-Fenster ein.
Danke
 
Sergey Deev #:

Der Handel mit einer Python ist gut...

...


Python speichert Anführungszeichen und Indikatoren in SQLite. MQL-Python-Kommunikation über Socket, Dateien oder Datenbank (Socket ist besser).


Sie haben natürlich Recht. Aber ich möchte Menschen, die sich nicht mit Datenbanken auskennen, helfen, in den algorithmischen Handel einzusteigen...

Machen wir es uns also einfach - durch Dateien. Eindeutig, und genug, um damit zu arbeiten.

 

Ich schlage vor, drei Dateien zu erstellen:

Classes.py - um dort alle möglichen Klassen unterzubringen, nicht notwendigerweise alle, nur die, die es brauchen, so dass es keinen unnötigen überladenen Code in der Hauptdatei gibt;

Functions.py - um dort alle möglichen Funktionen zu speichern, nicht unbedingt alle, nur die, die nicht in der Hauptdatei überladen werden müssen;

TradeLogic.py - Hauptdatei.


Ich werde die Klassen Timing, Bar und Trade in die Classes.py-Datei aufnehmen (eine leere Trade-Klasse):

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


Es gibt noch keine Erklärungen, diese werden im Laufe der Zeit nachgereicht.

 
Malik Arykov #:

Können Sie mir ein Beispiel geben, zumindest in Pseudocode? Erstellen Sie ein Skript in Python. Ich möchte Bolinger-Daten (Ishimoku usw.) für einen bestimmten Zeitpunkt erhalten. Wie kann ich das tun?

D.h., geben Sie ein Beispiel dafür, wie man Daten beliebiger Indikatoren in einer csv-Datei oder in SQLite speichert und sie dann in Python liest? Es wird nicht lustig sein?

 

In der Datei TradeLogic.py schlage ich vor, zunächst folgendes zu schreiben:

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

Hier sind einige Importe von Dingen, die später benötigt werden, und das Programm selbst beginnt mit der Zeile N=1000. Die Adresse "work_catalog" ist das Verzeichnis, in dem ich die Dateien mit den Preisen und ggf. weitere Dateien speichern möchte. Die Adresse ist so seltsam, weil ich Metatrader in einer virtuellen Maschine verwende und für diese Demonstration Python - auch dort, Instrumente - die Liste der Instrumente, auf denen wir planen, zu handeln.

 
Sergey Deev #:

Geben Sie ein Beispiel für das Speichern von Indikatordaten in einer csv-Datei oder in SQLite und das anschließende Einlesen in Python? Es wird nicht lustig sein?

Nein, es wird nicht lustig sein. Es gibt viele Leute, die mit Python schnell in den algorithmischen Handel einsteigen können, aber derzeit überhaupt nicht mit Python vertraut sind und das Gefühl haben, dass sie MQL nicht brauchen, und nicht bereit sind, Zeit in das Erlernen eines Tools zu investieren, dessen Anwendungsbereich sehr begrenzt ist. Sprechen Sie auch nicht von einer C-ähnlichen Syntax, es gibt zu viele Leute, die mit C/C++ überhaupt nicht vertraut sind.

Der Zweck dieses Zweigs ist es, Menschen, die nicht wissen, wo sie mit dem algorithmischen Handel beginnen sollen, spezifische Anweisungen zu geben. Ein Startschuss. Ohne unnötige Komplikationen.

 

Die metatrader5-Bibliothek wird für die Verwaltung des Metatrader5-Terminals verwendet.

Bibliothek hier:https://pypi.org/project/MetaTrader5

Dokumentation hier: https: //www.mql5.com/ru/docs/integration/python_metatrader5

 

Implementieren Sie mit Hilfe der in der Bibliothek beschriebenen Funktionen die Funktionen zum Initiieren einer Verbindung zum Terminal und zum Beenden einer Verbindung zum Terminal. Wir planen, dies in einer Endlosschleife alle 5 Minuten zu tun.


Schreiben Sie auch die Funktion dt_stamp_from_M5_view, die aus der Zeichenkette des Typs '202112101635' (ich nenne sie M5_view) eine Zählung der Datumszeit(Objekt der Klasse date_time) erstellt.


Fügen wir diesen Code in die Datei TradeLogic.py ein:

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)

Dieser Code ist bereits funktionsfähig. D.h. er startet, ermittelt das nächstgelegene Vielfache von 5 Minuten + 10 Sekunden (um sicherzustellen, dass die Serverbars geschlossen werden, wollen wir die Kurse speichern), schläft bis zu diesem Zeitpunkt, wacht auf, verbindet sich mit dem Terminal, handelt (in dem Sinne, dass er nichts tut), beendet die Verbindung zum Terminal, schläft 5 Minuten - und der Zyklus wiederholt sich.


Betrieb des Programms: