Grupo de usuarios de MetaTrader 5 Python - cómo utilizar Python en Metatrader - página 66

 
Vladimir Karputov:

¿Cuáles son los precios actuales (Bid y Ask)? ¿Cuál era el nivel de congelación (SYMBOL_TRADE_FREEZE_LEVEL)?

¿No está seguro de los niveles de congelación?

El precio de compra se utiliza para mis compras y el precio de venta para mis ventas.

He probado a codificar mi sl y tp ahora.

Es extraño que compre y venda perfectamente durante horas y luego se detenga.

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:

Escribe Still:

si r.retcode != TRADE_RETCODE_REQUOTE y r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: El objeto 'NoneType' no tiene el atributo 'retcode'


Rashid Umarov:
Ejemplo de ayuda a la carrera para https://www.mql5.com/ru/docs/integration/python_metatrader5/mt5ordersend_py

El ejemplo de la ayuda funciona.
Utilicé un ejemplo en mi función y escribí:

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

 
IvanDorofeev:

Sigue escribiendo:

El ejemplo de la ayuda funciona.

Aplicando el ejemplo de mi función, dice:

¡si result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: El objeto 'NoneType' no tiene el atributo 'retcode'

¿Así que obtuviste result_buy==None, no comprobaste el valor e intentaste obtener el retcode de None?

 

La nueva beta de la terminal MT5 junto con la MetaTrader5 5.0.31 sólo puede sostener unas 7700 llamadas a copy_rates_from_pos() antes de que se bloquee completamente el hilo. Para demostrar este bug he implementado un timeout usando asyncio. El tiempo de espera funciona en el control, sin embargo, no funciona para copy_rates_from_pos porque el hilo se congela completamente debido al error.

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()
 

Ni siquiera apagar y reiniciar la conexión ayuda.

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:

Hay un error en las tasas de copia. He publicado esto varias veces pero nadie lo ha reconocido.

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

Pregunta: ¿Para qué sirve este ciclo?

 
Vladimir Perervenko:

Pregunta: ¿Por qué este ciclo?

Estaba obteniendo fallos al solicitar barras máximas como parámetro "count", así que escribí una rutina sencilla que hace crecer el número de barras solicitadas en cada iteración como prueba unitaria para probar la función. Esto debería completarse sin problemas, pero dado que sólo se puede llamar un número finito de veces hace que no sea fiable.

 
nicholi shen:

Estaba obteniendo fallos al solicitar barras máximas como parámetro "count", así que escribí una rutina sencilla que hace crecer el número de barras solicitadas en cada iteración como prueba unitaria para probar la función. Esto debería completarse sin problemas, pero dado que sólo se puede llamar un número finito de veces hace que no sea fiable.

Este problema se solucionó en la versión 5.0.33, que fue lanzada sin liberar automáticamente los arrays de numpy.
 
IvanDorofeev:

Escribe Still:

si r.retcode != TRADE_RETCODE_REQUOTE y r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: El objeto 'NoneType' no tiene el atributo 'retcode'


El ejemplo de la ayuda funciona.
Aplicando un ejemplo en mi función, dice

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

Actualice a 5.0.33, el script Buy/Close está arreglado allí, todavía devolverá el error como None, pero ahora puede llamar a mt5.last_error() sin excepción y ver el código de error.
 

ckeiderling:

...

Tengo el mismo problema usando mt5.copy_ticks_range () y mt5.copy_rates_range (). Tengo que reiniciar el kernel para borrar la memoria.

...
Esto se ha solucionado en la versión 5.0.33