MetaTrader 5 Python User Group - Come usare Python in Metatrader - pagina 66

 
Vladimir Karputov:

Quali erano i prezzi attuali (Bid e Ask)? Qual era il livello di congelamento (SYMBOL_TRADE_FREEZE_LEVEL)?

Non sei sicuro dei livelli di FREEZE?

Il prezzo di domanda viene usato per il mio acquisto e il prezzo di offerta per il mio short.

Ho provato a codificare i miei sl e tp ora.

È strano che compri e venda perfettamente per ore e poi si fermi.

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:

Scrive ancora:

se r.retcode != TRADE_RETCODE_REQUOTE e r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: l'oggetto 'NoneType' non ha attributo 'retcode'


Rashid Umarov:
Esempio di aiuto all'esecuzione per https://www.mql5.com/ru/docs/integration/python_metatrader5/mt5ordersend_py

L'esempio dell'aiuto funziona.
Ho usato un esempio nella mia funzione e ho scritto:

if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: l'oggetto 'NoneType' non ha attributo 'retcode'

 
IvanDorofeev:

Scrive ancora:

L'esempio della guida funziona.

Applicando l'esempio nella mia funzione, si dice:

se result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: l'oggetto 'NoneType' non ha attributo 'retcode'

Quindi hai ottenuto result_buy==None, non hai controllato il valore e hai cercato di ottenere il retcode da None?

 

Il nuovo MT5-terminal beta insieme a MetaTrader5 5.0.31 può sostenere solo circa 7700 chiamate a copy_rates_from_pos() prima che si blocchi completamente il thread. Per dimostrare questo bug ho implementato un timeout usando asyncio. Il timeout funziona sul controllo, tuttavia, non funziona per copy_rates_from_pos perché il thread si blocca completamente a causa del 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()
 

Anche spegnere e reinizializzare la connessione non aiuta.

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:

C'è un bug nei tassi di copia. L'ho postato diverse volte ma nessuno l'ha riconosciuto.

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

Domanda: A cosa serve questo ciclo?

 
Vladimir Perervenko:

Domanda: Perché questo ciclo?

Stavo ottenendo dei fallimenti richiedendo maxbars come parametro "count", così ho scritto una semplice routine che cresce il numero di barre richieste ad ogni iterazione come unit-test per testare la funzione. Questo dovrebbe essere completato senza problemi, ma dato che potete chiamarlo solo un numero finito di volte lo rende inaffidabile.

 
nicholi shen:

Stavo ottenendo dei fallimenti richiedendo maxbars come parametro "count", così ho scritto una semplice routine che cresce il numero di barre richieste ad ogni iterazione come unit-test per testare la funzione. Questo dovrebbe completare senza problemi, ma dato che si può chiamare solo un numero finito di volte lo rende inaffidabile.

Questo problema è stato risolto in 5.0.33, è stato rilasciato senza liberare automaticamente gli array numpy.
 
IvanDorofeev:

Scrive ancora:

se r.retcode != TRADE_RETCODE_REQUOTE e r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: l'oggetto 'NoneType' non ha attributo 'retcode'


L'esempio dell'aiuto funziona.
Applicando questo esempio nella mia funzione, si dice

if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: l'oggetto 'NoneType' non ha attributo 'retcode'

Aggiornamento alla 5.0.33, lo script Buy/Close è fissato lì, restituiranno ancora l'errore come None, ma ora è possibile chiamare mt5.last_error() senza eccezione e vedere il codice di errore.
 

ckeiderling:

...

Ottengo lo stesso problema usando mt5.copy_ticks_range () e mt5.copy_rates_range (). Devo resettare il kernel per cancellare la memoria.

...
Questo è fissato in 5.0.33
Motivazione: