MetaTrader 5 Python User Group - как использовать Python в Метатрейдере - страница 66

 
Vladimir Karputov:

А какие были текущие цены (Bid и Ask)? Какой был уровень заморозки (SYMBOL_TRADE_FREEZE_LEVEL)?

Not sure about the FREEZE levels?

Ask price is being used for my buy and bid price for my shorts.

I have tried hardcoding my sl and tp now. 

Just strange that it will Buy and Sell perfect for hours and then stop.

price_ask = mt5.symbol_info_tick(symbol).ask # Buying    

####################

##cONDITION FOR buy

if close_past < close_current and position_type(symbol) != 0 or position_type(symbol) == None:
        mt5.Close(symbol)
        buy(symbol, lot, price_ask, point, digits)
        print('{} LONG Postition bought!'.format(symbol))

####################

##### Function to BUY
def buy(symbol, lot, price, point, digits):
    request_buy = {
        "action": mt5.TRADE_ACTION_DEAL,
        "symbol": symbol,
        "volume": lot,
        "type": mt5.ORDER_TYPE_BUY,
        "price": round(price, digits),
        "sl": round((price - 100 * point),digits),
        "tp": round((price + 300 * point),digits),
        "magic": 234000,
        "comment": "{} Buy.".format(symbol),
        "type_time": mt5.ORDER_TIME_GTC,
        }
    # send a trading request
    result_buy = mt5.order_send(request_buy)
    # check the execution result
    print("1.BUY order send(): by {} {} lots at {}".format(symbol,lot,price));
    if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
        print("2. order_send failed, retcode={}".format(result_buy.retcode))
        # request the result as a dictionary and display it element by element
        result_dict=result_buy._asdict()
        for field in result_dict.keys():
            print("   {}={}".format(field,result_dict[field]))
            # if this is a trading request structure, display it element by element as well
            if field=="request":
                traderequest_dict=result_dict[field]._asdict()
                for tradereq_filed in traderequest_dict:
                    print("       traderequest: {}={}".format(tradereq_filed,traderequest_dict[tradereq_filed]))
    else:
        return result_buy
#########
 
nicholi shen:

Всё равно пишет:

if r.retcode != TRADE_RETCODE_REQUOTE and r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: 'NoneType' object has no attribute 'retcode'


Rashid Umarov:
Запустите пример из справки для https://www.mql5.com/ru/docs/integration/python_metatrader5/mt5ordersend_py

Пример из справки работает. 
Применяю пример у себя в функции, пишет:

    if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: 'NoneType' object has no attribute 'retcode'

 
IvanDorofeev:

Всё равно пишет:

Пример из справки работает. 

Применяю пример у себя в функции, пишет:

    if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: 'NoneType' object has no attribute 'retcode'

То есть вы получили result_buy==None, не проверили значение и попытались получить retcode  от None?

 

The new MT5-terminal beta along with the MetaTrader5 5.0.31 can only sustain about ~7700 calls to copy_rates_from_pos() before it completely locks up the thread. In order to demonstrate this bug I have implemented a timeout using asyncio. The timeout works on the control, however, it does not work for copy_rates_from_pos because the thread completely freezes due to the bug. 

import asyncio
import time

import MetaTrader5 as mt5


async def proof_timeout_works_on_blocking_call():
    loop = asyncio.get_running_loop()
    future = loop.run_in_executor(None, time.sleep, 5.0)
    try:
        await asyncio.wait_for(future, timeout=0.5)
    except asyncio.TimeoutError:
        print("Timeout works as expected for blocking calls!")


async def async_copy_rates(*args, timeout):
    loop = asyncio.get_running_loop()
    future = loop.run_in_executor(None, mt5.copy_rates_from_pos, *args)
    try:
        return await asyncio.wait_for(future, timeout=timeout)
    except asyncio.TimeoutError:
        print(f"async_copy_rates timed out")
        print('mql errors =', *mt5.last_error())
        raise


async def async_last_error():
    loop = asyncio.get_running_loop()
    err = await loop.run_in_executor(None, mt5.last_error)
    return err


async def main():
    await proof_timeout_works_on_blocking_call()
    maxbars = mt5.terminal_info().maxbars
    for i in range(1, maxbars):
        r = await async_copy_rates('EURUSD', mt5.TIMEFRAME_M1, 0, i, timeout=0.5)
        if r is not None:
            print(f'{i} -> {len(r)}')


if __name__ == '__main__':
    mt5.initialize()
    print(mt5.__version__)
    asyncio.run(main())
    mt5.shutdown()
 

Even shutting down and re-initializing the connection doesn't help. 

import time

import MetaTrader5 as mt5


def main():
    maxbars = mt5.terminal_info().maxbars
    for i, count in enumerate(range(1000, maxbars), 1):
        for retry in range(5):
            r = mt5.copy_rates_from_pos('EURUSD', mt5.TIMEFRAME_M1, 0, count)
            errno, strerr = mt5.last_error()
            if errno != mt5.RES_S_OK:
                print(strerr)
                print('Reinitialing connection')
                mt5.shutdown()
                time.sleep(1)
                print('Reinitialing connection =', mt5.initialize())
            else:
                print(f"{i} -> {len(r)}")
                break
        else:
            print('maxium retry exceed')
            mt5.shutdown()
            quit()


if __name__ == '__main__':
    mt5.initialize()
    print(mt5.__version__)
    main()
    mt5.shutdown()
 
nicholi shen:

There is a bug in copy rates. I posted this several times but nobody has acknowledged it. 

for count in range(maxbars):
    rates = mt5.copy_rates_from_pos('EURUSD', mt5.TIMEFRAME_M1, 0, count)
    errno, strerror = mt5.last_error()
    if errno != mt5.RES_S_OK:
        print(f"Failed on count={count} with strerror={strerror}")
        break

Вопрос: Этот цикл зачем?

 
Vladimir Perervenko:

Question: Why this cycle?

I was getting failures requesting maxbars as the "count" parameter so I wrote a simple routine that grows the number of bars requested on each iteration as a unit-test to test the function. This should complete without issues, but given that you can only call it a finite number of times makes it unreliable.  

 
nicholi shen:

I was getting failures requesting maxbars as the "count" parameter so I wrote a simple routine that grows the number of bars requested on each iteration as a unit-test to test the function. This should complete without issues, but given that you can only call it a finite number of times makes it unreliable.  

This issue fixed in 5.0.33, it was releated with not automatically freeing numpy arrays.
 
IvanDorofeev:

Всё равно пишет:

if r.retcode != TRADE_RETCODE_REQUOTE and r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: 'NoneType' object has no attribute 'retcode'


Пример из справки работает. 
Применяю пример у себя в функции, пишет:

    if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: 'NoneType' object has no attribute 'retcode'

Обновитесь до 5.0.33, там исправлен скрипт Buy/Close, они все равно вам вернут ошибку в виде None, но сейчас вы сможете вызвать mt5.last_error() без exception и посмотреть код ошибки.
 

ckeiderling:

...

I get the same problem using mt5.copy_ticks_range () and mt5.copy_rates_range (). I have to reset the kernel in order to clear out the memory. 

...
This is fixed in 5.0.33