2

I'm trying to create a trading bot that makes orders instead of making them manually from the MetaTrader5 App, I make the function below

Note: BoS: Buy or Sell | sl: Stop Loss | tp: Take Profit | lot: Volume

def MetaTrader_Order(symbol, BoS, price, sl, tp, lot):

    # connect to MetaTrader 5
    if not mt5.initialize():
        print("initialize() failed")
        mt5.shutdown()

    

    # prepare the buy request structure
    symbol_info = mt5.symbol_info(symbol)
    if symbol_info is None:
        print(symbol, " not found, can not call order_check()")

    
    # if the symbol is unavailable in MarketWatch, add it
    if not symbol_info.visible:
        print(symbol, " is not visible, trying to switch on")
        if not mt5.symbol_select(symbol,True):
            print("symbol_select({}) failed, exit",symbol)


    
    deviation = 20


    if BoS == "SELL":    
        request = {
        "action": mt5.TRADE_ACTION_DEAL,
        "symbol": symbol,
        "volume": lot,
        "type": mt5.ORDER_TYPE_SELL,
        "price": price,
        "sl": sl,
        "tp": tp,
        "deviation": deviation,
        "magic": 234000,
        "comment": "python script open",
        "type_time": mt5.ORDER_TIME_GTC,
        "type_filling": mt5.ORDER_FILLING_RETURN,
        }   

    elif BoS == "BUY":
        request = {
        "action": mt5.TRADE_ACTION_DEAL,
        "symbol": symbol,
        "volume": lot,
        "type": mt5.ORDER_TYPE_BUY,
        "price": price,
        "sl": sl,
        "tp": tp,
        "deviation": deviation,
        "magic": 234000,
        "comment": "python script open",
        "type_time": mt5.ORDER_TIME_GTC,
        "type_filling": mt5.ORDER_FILLING_RETURN,
        } 


    else:
        request = None

    
    # send a trading request
    result = mt5.order_send(request)


    # check the execution result
    print("1. order_send(): {} {} at price {}, with lot {}, with deviation {}".format(BoS, symbol, price, lot, deviation))

    if result.retcode != mt5.TRADE_RETCODE_DONE:
        print("2. order_send failed, retcode={}".format(result.retcode))

        # request the result as a dictionary and display it element by element
        result_dict=result._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: 
        print("2. order_send done, ", result)

when I try to pass arguments to function like that:

MetaTrader_Order("GBPUSD", "SELL", 1.40001, 1.5, 1.3, 0.1)

it gives me an output like this:

1. order_send(): SELL GBPUSD at price 1.40001, with lot 0.01, with deviation 20
2. order_send failed, retcode=10021
   retcode=10021
   deal=0
   order=0
   volume=0.0
   price=0.0
   bid=0.0
   ask=0.0
   comment=No prices
   request_id=0
   retcode_external=0
   request=TradeRequest(action=1, magic=234000, order=0, symbol='GBPUSD', volume=0.01, price=1.40001, stoplimit=0.0, sl=1.5, tp=1.3, deviation=20, type=1, type_filling=2, type_time=0, expiration=0, comment='python script open', position=0, position_by=0)
       traderequest: action=1
       traderequest: magic=234000
       traderequest: order=0
       traderequest: symbol=GBPUSD
       traderequest: volume=0.01
       traderequest: price=1.40001
       traderequest: stoplimit=0.0
       traderequest: sl=1.5
       traderequest: tp=1.3
       traderequest: deviation=20
       traderequest: type=1
       traderequest: type_filling=2
       traderequest: type_time=0
       traderequest: expiration=0
       traderequest: comment=python script open
       traderequest: position=0
       traderequest: position_by=0 

if I try to put price automatically like this: price = mt5.symbol_info_tick(symbol).ask it works and sends the order to MetaTrader5 with no problems

but really I wont to send order with a specific price that I entered, not the market price

.
.
.
MT5 Documentation: https://www.mql5.com/en/docs/integration/python_metatrader5 MT5
order_send: https://www.mql5.com/en/docs/integration/python_metatrader5/mt5ordersend_py
MT5 Return Codes: https://www.mql5.com/en/docs/constants/errorswarnings/enum_trade_return_codes

also see TRADE_ACTION_PENDING on this page: https://www.mql5.com/en/docs/constants/structures/mqltraderequest (it's in another language)

1 Answers1

3

I solved the problem by writing this part of the code like that:

if BoS == "SELL": 
        if price < mt5.symbol_info_tick(symbol).bid:
            price = mt5.symbol_info_tick(symbol).bid

        request = {
        "action": mt5.TRADE_ACTION_PENDING,
        "symbol": symbol,
        "volume": lot,
        "type": mt5.ORDER_TYPE_SELL_LIMIT,
        "price": price,
        "sl": sl,
        "tp": tp,
        "deviation": deviation,
        "magic": 234000,
        "comment": "python script open",
        "type_time": mt5.ORDER_TIME_GTC,
        "type_filling": mt5.ORDER_FILLING_RETURN,
        }   

    elif BoS == "BUY":
        if price > mt5.symbol_info_tick(symbol).ask:
            price = mt5.symbol_info_tick(symbol).ask

        request = {
        "action": mt5.TRADE_ACTION_PENDING,
        "symbol": symbol,
        "volume": lot,
        "type": mt5.ORDER_TYPE_BUY_LIMIT,
        "price": price,
        "sl": sl,
        "tp": tp,
        "deviation": deviation,
        "magic": 234000,
        "comment": "python script open",    ## may delete some items
        "type_time": mt5.ORDER_TIME_GTC,
        "type_filling": mt5.ORDER_FILLING_RETURN,
        } 

Notice: "action": mt5.TRADE_ACTION_PENDING,
And: "type": mt5.ORDER_TYPE_SELL_LIMIT,

  • can you give some little explanation between ACTION_PENDING and ACTION_DEAL – Code with Benji Sep 12 '22 at 09:12
  • 1
    thanks this worked for me. @TumwesigyeBenjamin check this for a description https://www.mql5.com/en/docs/constants/tradingconstants/enum_trade_request_actions – Karl Oct 19 '22 at 14:01
  • by the way, another way I solved the "no prices" error was to load the history data of the symbols I trade on the mt5 platform .... like opening up the graphs of the symbol(GBPUSD) for it to load some data in memory after that I have not experienced this issue again, @Karl – Code with Benji Oct 20 '22 at 08:30