MetaTrader 5 Python User Group - Comment utiliser Python dans Metatrader - page 66

 
Vladimir Karputov:

Quels étaient les prix actuels (Bid et Ask) ? Quel était le niveau de gel (SYMBOL_TRADE_FREEZE_LEVEL) ?

Vous n'êtes pas sûr des niveaux de FREEZE ?

Le cours vendeur est utilisé pour mon achat et le cours acheteur pour mes ventes.

J'ai essayé de coder en dur mes sl et tp maintenant.

C'est juste étrange qu'il achète et vende parfaitement pendant des heures, puis s'arrête.

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:

Il écrit encore :

if r.retcode != TRADE_RETCODE_REQUOTE and r.retcode != TRADE_RETCODE_PRICE_OFF :
AttributeError : L'objet 'NoneType' n'a pas d'attribut 'retcode'
.


Rashid Umarov:
Exemple d'aide à l'exécution pour https://www.mql5.com/ru/docs/integration/python_metatrader5/mt5ordersend_py

Exemple de travaux d'aide.
J'ai utilisé un exemple dans ma fonction et j'ai écrit :

if result_buy.retcode != mt5.TRADE_RETCODE_DONE :
AttributeError : L'objet 'NoneType' n'a pas d'attribut 'retcode'.

 
IvanDorofeev:

Il écrit toujours :

L'exemple de l'aide fonctionne.

En appliquant l'exemple de ma fonction, il est dit :

if result_buy.retcode != mt5.TRADE_RETCODE_DONE :
AttributeError : L'objet 'NoneType' n'a pas d'attribut 'retcode'
.

Vous avez donc obtenu result_buy==None, n'avez pas vérifié la valeur et avez essayé de récupérer le retcode de None ?

 

Le nouveau terminal MT5 bêta avec la version MetaTrader5 5.0.31 ne peut supporter qu'environ 7700 appels à copy_rates_from_pos() avant de bloquer complètement le thread. Afin de démontrer ce bug, j'ai implémenté un timeout en utilisant asyncio. Le délai d'attente fonctionne sur le contrôle, mais il ne fonctionne pas pour les taux de copie_from_pos parce que le thread se bloque complètement à cause du bogue.

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

Même le fait d'arrêter et de réinitialiser la connexion n'aide pas.

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:

Il y a un bug dans les taux de copie. J'ai posté ceci plusieurs fois mais personne ne l'a reconnu.

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

Question : A quoi sert ce cycle ?

 
Vladimir Perervenko:

Question : Pourquoi ce cycle ?

J'ai donc écrit une routine simple qui augmente le nombre de barres demandées à chaque itération en tant que test unitaire pour tester la fonction. Cette opération devrait se dérouler sans problème, mais étant donné que vous ne pouvez l'appeler qu'un nombre limité de fois, elle n'est pas fiable.

 
nicholi shen:

J'ai donc écrit une routine simple qui augmente le nombre de barres demandées à chaque itération comme un test unitaire pour tester la fonction. Cela devrait fonctionner sans problème, mais étant donné que vous ne pouvez l'appeler qu'un nombre fini de fois, ce n'est pas fiable.

Ce problème a été corrigé dans la version 5.0.33, qui ne libérait pas automatiquement les tableaux numpy.
 
IvanDorofeev:

Il écrit encore :

if r.retcode != TRADE_RETCODE_REQUOTE and r.retcode != TRADE_RETCODE_PRICE_OFF :
AttributeError : L'objet 'NoneType' n'a pas d'attribut 'retcode'
.


Exemple tiré de l'ouvrage d'aide.
En appliquant cet exemple dans ma fonction, il est dit que

if result_buy.retcode != mt5.TRADE_RETCODE_DONE :
AttributeError : L'objet 'NoneType' n'a pas d'attribut 'retcode'.

Mise à jour vers 5.0.33, le script Buy/Close est corrigé là, ils retourneront toujours l'erreur comme None, mais maintenant vous pouvez appeler mt5.last_error() sans exception et voir le code d'erreur.
 

ckeiderling:

...

J'obtiens le même problème en utilisant mt5.copy_ticks_range () et mt5.copy_rates_range (). Je dois réinitialiser le noyau pour effacer la mémoire.

...
Ce problème est corrigé dans la version 5.0.33
Raison: