MetaTrader 5 Python用户组 - 如何在Metatrader中使用Python - 页 60

 
5.0.30版已出
 
MetaQuotes:
5.0.30版已出

谢谢你!

 
MetaTrader 5 Python User Group - the summary
MetaTrader 5 Python User Group - the summary
  • 2020.03.30
  • www.mql5.com
The Main Study MetaTrader Python online documentation Python Releases for Windows - website MetaTrader5 : Python Package - website...
 
5.0.31版已出
 
MetaQuotes:
5.0.31版已出
有什么重大变化吗?
 
MetaTrader 5 Python User Group - the summary
MetaTrader 5 Python User Group - the summary
  • 2020.04.02
  • www.mql5.com
The Main Study MetaTrader Python online documentation Python Releases for Windows - website MetaTrader5 : Python Package - website...
 
Kiran Sawant:
有什么重大变化吗?

不,只是对https://www.mql5.com/en/forum/306742/page13#comment_15699363 的一些修复。

MetaTrader 5 Python User Group - the summary
MetaTrader 5 Python User Group - the summary
  • 2020.03.30
  • www.mql5.com
The Main Study MetaTrader Python online documentation Python Releases for Windows - website MetaTrader5 : Python Package - website...
 
pymt5adapter
pymt5adapter
  • 2020.04.02
  • pypi.org
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...
 
Dmitry Prokopyev :

谢谢,我看到的这个例子,它是有效的。

我有点关于别的东西。


positions_get - 列表中的TradePosition将返回给我。原则上说,你可以扔进熊猫,而且工作得很好。

但一切并不局限于一只熊猫,如果你需要得到类似的东西。

你必须以某种方式构成,熊猫或为...莫名其妙地做了很多额外的身体运动。

有了_asdict(),就变得更加方便了,如果写作的人不是MQL5程序,而是比方说一个Pythonist ...或者是一个数据网络主义者,那么列表/数据就是

在Python的基本元素中,有很多是建立在列表/Dict上的数据传输。

图元的使用,太频繁了,而且很多,但只有当你需要严格控制在其中移动的 数据类型 时才会使用。

并挂起一个错误处理程序,如果没有正确使用或分配。嗯,在某个地方...:)我可能是错的。

好吧,我现在完全同意这种观点,我也认为以命名图元而不是字典的方式返回数据对于一个API来说太有意见了。我最近在这个设计上遇到了问题,因为它不可能腌制命名的图元。考虑以下并发的交易复制器脚本。注意到为了使用ProcessPoolExectutor,将所有命名的图元转换为字典是多么的麻烦?


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.0 else Order.as_sell()
            order(volume=abs(volume), symbol=symbol.name)
            for _ in range(5):
                symbol.refresh_rates()
                price = symbol.ask if volume > 0.0 else symbol.bid
                res = order(price=price).send()
                if res.retcode == mt5.TRADE_RETCODE_DONE:
                    result_positions.append(result_to_dict(res))
                    break
    return 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()

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

当有命名的图元嵌套在命名的图元中时,尤其困难,例如OrderSendResult.request的情况。所以你必须创建独特的转换函数,只是为了将它们转换回可摘取的数据类型。你可以通过一个递归函数来运行所有的东西,将其转换为本地数据类型,但这在计算上很昂贵。

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". -----

Win10,Py3.6.10和WinPy3.7.7。