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 :

고마워, 내가 본이 예제는 작동합니다.

나는 다른 것에 대해 조금.


position_get - TradePosition 목록이 나에게 반환됩니다. 원칙적으로 팬더를 던지면 잘 작동합니다.

그러나 모든 것이 하나의 팬더에 국한되지 않으며 다음과 같은 것을 얻어야 하는 경우:

당신은 어떻게 든 팬더 또는 ... 어떻게 든 추가 신체 움직임을 많이 구성해야합니다.

_asdict()를 사용하면 훨씬 더 편리해졌습니다. 작성하는 사람이 MQL5 프로그램이 아니지만 pythonist ... 또는 datasynetist라고 가정해 보겠습니다. 그러면 list / dict는 다음과 같습니다.

python의 기본 요소 중 많은 것들이 list/dict에 데이터 전송을 구축하고 있습니다.

튜플은 너무 자주 그리고 많이 사용되지만 이동 하는 데이터 유형 을 엄격하게 제어해야 하는 경우에만 사용됩니다.

또한 제대로 사용되지 않거나 할당되지 않은 경우 오류 처리기를 중단합니다. 글쎄, 어딘가에 ... :) 내가 틀릴 수 있습니다.

좋아, 나는 이제 이 감정에 완전히 동의하고 사전 대신 명명된 튜플로 데이터를 반환하는 것은 API에 대해 너무 독단적이라고 생각합니다. 명명된 튜플을 피클하는 것이 불가능하기 때문에 최근에 이 디자인에 문제가 있었습니다. 다음 동시 복사기 스크립트를 고려하십시오. ProcessPoolExectutor를 사용하기 위해 모든 이름이 지정된 튜플을 사전으로 변환하는 것이 얼마나 번거로운지 알 수 있습니까?


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