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