MetaTrader 5 Python User Group - como usar o Python no Metatrader - página 66

 
Vladimir Karputov:

Quais eram os preços actuais (Bid and Ask)? Qual foi o nível de congelamento (SYMBOL_TRADE_FREEZE_LEVEL)?

Não tem a certeza sobre os níveis FREEZE?

O preço de pedido está a ser utilizado para a minha compra e o preço de oferta dos meus calções.

Tentei agora codificar a minha sl e tp.

É estranho que compre e venda perfeito durante horas e depois pare.

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:

Ainda escreve:

se r.retcode != TRADE_RETCODE_REQUOTE e r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: objecto 'NoneType' não tem atributo 'retcode'
.


Exemplo de trabalhos de ajuda.
Utilizei um exemplo na minha função e escrevi:

if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: objecto 'NoneType' não tem atributo 'retcode'.

 
IvanDorofeev:

Continua a escrever:

O exemplo da ajuda funciona.

Aplicando o exemplo na minha função, diz:

if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: objecto 'NoneType' não tem atributo 'retcode'
.

Então obteve result_buy==None, não verificou o valor e tentou obter o código retcode de None?

 

O novo MT5-terminal beta juntamente com o MetaTrader5 5.0.31 só pode suportar cerca de 7700 chamadas para copiar_taxas_de_pos() antes de trancar completamente o fio. A fim de demonstrar este bug, implementei um timeout utilizando asyncio. O tempo limite funciona no controlo, contudo, não funciona para copy_rates_from_pos porque o fio congela por completo devido ao 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()
 

Mesmo o encerramento e a reinicialização da ligação não ajuda.

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:

Há um erro nas taxas de cópia. Afixei isto várias vezes, mas ninguém o reconheceu.

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

Pergunta: Para que serve este ciclo?

 
Vladimir Perervenko:

Pergunta: Porquê este ciclo?

Estava a receber falhas solicitando maxbars como parâmetro de "contagem", por isso escrevi uma rotina simples que aumenta o número de barras solicitadas em cada iteração como um teste de unidade para testar a função. Isto deve ser concluído sem problemas, mas dado que só se pode chamar-lhe um número finito de vezes, torna-o pouco fiável.

 
nicholi shen:

Estava a receber falhas solicitando maxbars como parâmetro de "contagem", por isso escrevi uma rotina simples que aumenta o número de barras solicitadas em cada iteração como um teste unitário para testar a função. Isto deve terminar sem problemas, mas dado que só se pode chamar-lhe um número finito de vezes, torna-o pouco fiável.

Esta edição corrigida em 5.0.33, foi lançada sem libertar automaticamente as matrizes numéricas.
 
IvanDorofeev:

Ainda escreve:

se r.retcode != TRADE_RETCODE_REQUOTE e r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: objecto 'NoneType' não tem atributo 'retcode'
.


Exemplo de trabalhos de ajuda.
Aplicando um exemplo na minha função, diz

if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: objecto 'NoneType' não tem atributo 'retcode'.

Actualização para 5.0.33, Buy/Close script é corrigido lá, eles ainda retornarão erro como None, mas agora pode chamar mt5.last_error() sem excepção e ver código de erro.
 

ckeiderling:

...

Tenho o mesmo problema usando mt5.copy_ticks_range () e mt5.copy_rates_range (). Tenho de reiniciar o núcleo a fim de limpar a memória.

...
Isto é fixado em 5.0.33