is a wrapper and drop-in replacement for the python package by MetaQuotes. The API functions return the same values from the functions, but adds the following functionality: Typing hinting has been added to all functions and return objects for linting and IDE integration. Intellisense will now work now matter how nested the objects are...
Danke, dieses Beispiel habe ich gesehen, es funktioniert.
Mir geht es um etwas anderes.
positions_get - die Liste der TradePosition wird an mich zurückgegeben. Im Prinzip kann man Pandas einbauen und gut arbeiten.
Aber alles ist nicht auf einen Panda beschränkt, und wenn Sie etwas wie:
Sie müssen irgendwie komponieren, Pandas oder für... irgendwie eine Menge zusätzlicher Körperbewegungen.
Mit _asdict () ist es viel bequemer geworden, wenn derjenige, der schreibt, kein MQL5-Prog ist, sondern, sagen wir, ein Pythonist ... oder ein Datennetzbetreiber, dann ist list / dict
Die grundlegenden Elemente von Python, viele bauen eine Datenübertragung auf Liste / dict.
Tupel werden zu oft und viel verwendet, aber nur, wenn Sie die Datentypen, die sich darin bewegen, genau kontrollieren müssen.
und auch einen Fehler-Handler aufhängen, wenn er nicht richtig verwendet oder zugewiesen wird. Nun, irgendwo ... :) Ich könnte mich irren.
Ok, ich stimme dieser Meinung jetzt völlig zu, und ich denke auch, dass die Rückgabe von Daten als Namedtupel anstelle von Wörterbüchern zu eigenwillig für eine API ist. Kürzlich hatte ich Probleme mit diesem Design, weil es unmöglich ist, namedtuples zu picken. Betrachten Sie das folgende Skript zum Kopieren von gleichzeitigem Handel. Haben Sie bemerkt, wie mühsam es ist, alle Namedtupel in Dictionaries umzuwandeln, um den ProcessPoolExectutor zu nutzen?
trade_copier.py
import json
import time
from concurrent.futures.process import ProcessPoolExecutor
from typing import List
import pymt5adapter as mt5
from pymt5adapter.order import Order
from pymt5adapter.symbol import Symbol
def result_to_dict(result):
res = result._asdict()
res['request'] = res['request']._asdict()
return res
def p2d(positions):
return [p._asdict() for p in positions]
def get_position_map(positions: List[dict]):
position_map = {}
for p in positions:
position_map.setdefault(p['symbol'], {}).setdefault('positions', []).append(p)
v = -p['volume'] if p['type'] else p['volume']
inner = position_map[p['symbol']]
inner['net_volume'] = inner.get('net_volume', 0.0) + v
return position_map
def match_positions(terminal, positions):
result_positions = []
incoming = get_position_map(positions)
with mt5.connected(**terminal):
my_pos_map = get_position_map(p2d(mt5.positions_get()))
for symbol, d in incoming.items():
if symbol not in my_pos_map:
volume = d['net_volume']
else:
volume = d['net_volume'] - my_pos_map[symbol]['net_volume']
if volume == 0.0:
continue
symbol = Symbol(symbol)
order = Order.as_buy() if volume > 0.0else Order.as_sell()
order(volume=abs(volume), symbol=symbol.name)
for _ in range(5):
symbol.refresh_rates()
price = symbol.ask if volume > 0.0else symbol.bid
res = order(price=price).send()
if res.retcode == mt5.TRADE_RETCODE_DONE:
result_positions.append(result_to_dict(res))
breakreturn result_positions
def main():
with open('terminal_config.json') as f:
terminals = json.load(f)
master = terminals['master']
slaves = terminals['slaves']
with mt5.connected(**master), ProcessPoolExecutor() as pool:
while True:
positions = [p2d(mt5.positions_get())] * len(slaves)
results = list(pool.map(match_positions, slaves, positions))
for result in results:
for sub in result:
if sub:
print(sub)
time.sleep(0.01)
if __name__ == "__main__":
main()
Besonders schwierig ist es, wenn Namedtupel in Namedtupel verschachtelt sind, wie es bei OrderSendResult.request der Fall ist. Sie müssen also eigene Konvertierungsfunktionen erstellen, nur um sie wieder in abrufbare Datentypen umzuwandeln. Sie könnten alles durch eine rekursive Funktion laufen lassen, um es wieder in native Datentypen zu konvertieren, aber das ist sehr rechenintensiv.
def as_dict(data: Any):
try:
return as_dict(data._asdict())
except AttributeError:
T = type(data)
if T is list or T is tuple:
return T(as_dict(i) for i in data)
if T is dict:
return {k: as_dict(v) for k, v in data.items()}
return data
----- Установка "pymt5adapter" -----
ERROR: Could not find a version that satisfies the requirement pymt5adapter (from versions: none)
ERROR: No matching distribution found for pymt5adapter
----- Не удалось установить "pymt5adapter". -----
----- Установка "pymt5adapter==0.1.11" -----
ERROR: Could not find a version that satisfies the requirement pymt5adapter==0.1.11 (from versions: none)
ERROR: No matching distribution found for pymt5adapter==0.1.11
----- Не удалось установить "pymt5adapter==0.1.11". -----
----- Установка "pymt5adapter" -----
ERROR: Could not find a version that satisfies the requirement pymt5adapter (from versions: none)
ERROR: No matching distribution found for pymt5adapter
----- Не удалось установить "pymt5adapter". -----
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Erlauben Sie die Verwendung von Cookies, um sich auf der Website MQL5.com anzumelden.
Bitte aktivieren Sie die notwendige Einstellung in Ihrem Browser, da Sie sich sonst nicht einloggen können.
Sie sind angemeldet. Die Zwei-Faktor-Authentifizierung wurde deaktiviert. Richten Sie sie erneut ein und scannen Sie einen neuen QR-Code oder fahren Sie mit deaktivierter Zwei-Faktor-Authentifizierung fort.
Version 5.0.30 ist erschienen
Ich danke Ihnen!
Version 5.0.31 ist erschienen
Irgendwelche größeren Änderungen?
Nein, nur einige Korrekturen für https://www.mql5.com/en/forum/306742/page13#comment_15699363
https://pypi.org/project/pymt5adapter/
https://github.com/nicholishen/pymt5adapter
Danke, dieses Beispiel habe ich gesehen, es funktioniert.
Mir geht es um etwas anderes.
positions_get - die Liste der TradePosition wird an mich zurückgegeben. Im Prinzip kann man Pandas einbauen und gut arbeiten.
Aber alles ist nicht auf einen Panda beschränkt, und wenn Sie etwas wie:
Sie müssen irgendwie komponieren, Pandas oder für... irgendwie eine Menge zusätzlicher Körperbewegungen.
Mit _asdict () ist es viel bequemer geworden, wenn derjenige, der schreibt, kein MQL5-Prog ist, sondern, sagen wir, ein Pythonist ... oder ein Datennetzbetreiber, dann ist list / dict
Die grundlegenden Elemente von Python, viele bauen eine Datenübertragung auf Liste / dict.
Tupel werden zu oft und viel verwendet, aber nur, wenn Sie die Datentypen, die sich darin bewegen, genau kontrollieren müssen.
und auch einen Fehler-Handler aufhängen, wenn er nicht richtig verwendet oder zugewiesen wird. Nun, irgendwo ... :) Ich könnte mich irren.
Ok, ich stimme dieser Meinung jetzt völlig zu, und ich denke auch, dass die Rückgabe von Daten als Namedtupel anstelle von Wörterbüchern zu eigenwillig für eine API ist. Kürzlich hatte ich Probleme mit diesem Design, weil es unmöglich ist, namedtuples zu picken. Betrachten Sie das folgende Skript zum Kopieren von gleichzeitigem Handel. Haben Sie bemerkt, wie mühsam es ist, alle Namedtupel in Dictionaries umzuwandeln, um den ProcessPoolExectutor zu nutzen?
trade_copier.py
terminal_config.json
{ "master": { "path":"C:\\Users\\nicho\\Desktop\\terminal1\\terminal64.exe", "portable": true }, "slaves": [ { "path": "C:\\Users\\nicho\\Desktop\\terminal2\\terminal64.exe", "portable": true },{ "path": "C:\\Users\\nicho\\Desktop\\terminal3\\terminal64.exe", "portable": true } ] }Besonders schwierig ist es, wenn Namedtupel in Namedtupel verschachtelt sind, wie es bei OrderSendResult.request der Fall ist. Sie müssen also eigene Konvertierungsfunktionen erstellen, nur um sie wieder in abrufbare Datentypen umzuwandeln. Sie könnten alles durch eine rekursive Funktion laufen lassen, um es wieder in native Datentypen zu konvertieren, aber das ist sehr rechenintensiv.
https://pypi.org/project/pymt5adapter/
https://github.com/nicholishen/pymt5adapter
Installation fehlgeschlagen
Win10, Py3.6.10 und WinPy3.7.7.