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...
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()
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". -----
バージョン5.0.30がリリースされました
ありがとうございました。
バージョン5.0.31がリリースされました
大きな変化はありますか?
いいえ、https://www.mql5.com/en/forum/306742/page13#comment_15699363 のいくつかの修正だけです。
https://pypi.org/project/pymt5adapter/
https://github.com/nicholishen/pymt5adapter
ありがとうございます、私が見たこの例では、うまくいきました。
私は、ちょっと別のことで。
positions_get - TradePositionのリストが返されます。原理的には、パンダを放り込んでも問題なく動作します。
しかし、すべてはパンダ一匹に限らず、必要なものがあれば、そのようなものを手に入れることができます。
どうにかして、パンダを合成するか、それとも...。なんというか、余計な体の動きが多い。
MQL5のプログラマーでなく、例えばpythonistが書くのであれば、_asdict()でかなり便利になりましたね ...またはデータシーネティストの場合、list / dict は
Pythonの基本的な要素は、多くはリスト/ディクショナリ上のデータ転送を構築しています。
タプルは、あまりにも頻繁に、たくさん使われますが、その中で移動する データの種類を 厳密に制御する必要がある場合にのみ使用します。
を使用するか、適切に割り当てないと、エラーハンドラもハングアップします。まあ、どこかで・・・。:)間違っているかもしれません。
また、データを辞書ではなくnamedtupleで返すのは、APIとしては意見が分かれすぎると思います。最近、この設計で問題になったのは、namedtupleのpickleができないことです。次のような同時進行のトレードコピーのスクリプトを考えてみましょう。ProcessPoolExectutorを使用するために、すべてのnamedtupleを辞書に変換することがいかに面倒であるか、お気づきでしょうか。
trade_copier.py
terminal_config.json
特に,OrderSendResult.requestのように,namedtupleの中にnamedtupleがネストしている場合は難しいです.そのため、pickle可能なデータ型に戻すためだけに、独自の変換関数を作成する必要があります。すべてを再帰的関数に通してネイティブなデータ型に戻すこともできるが、計算量が多くなる。
https://pypi.org/project/pymt5adapter/
https://github.com/nicholishen/pymt5adapter
インストールに失敗しました
Win10、Py3.6.10、WinPy3.7.7です。