Send order in MetaTrader5 using Python - page 2

nicholish en
2726
nicholish en  
luisaoisdead:

LOG FILE

ORDER_SEND

and metatrader capture

if i make a manual trade....

thanks for your time!!!

No offense, but there are many errors in your code. The first major issue is obvious because the logs in both MT and python are screaming at you that the volume is invalid, and it's invalid because you have to pass the MetaTrader5.order_send must have a float value passed for volume and you are passing an int. It's also invalid because you are setting incorrect sl and tp because /ES tick-size is .25 not .01.  Next, you are trading a futures contract and treating it like a forex lot and you are passing invalid args for the request. Finally, pytmt5adapter is a replacement for MetaTrader5. Do not use them at the same time. pymt5adapter also does a lot of processing in the background to correct little mistakes automatically, like converting int volumes to floats before passing on the request to MT. It seems like you are new to this so my recommendation is stick to pymt5adapter and use an IDE like pycharm so you can get real time type checking and documentation. Here is roughly how your code should look. Note that the terminal connection is managed by the connected context manager and I have gotten a different logger from the logging module which will output the debugging info to the console to you can avoid all the print statements everywhere. 

import logging
import time

import pymt5adapter as mt5

MAGIC = 234000


def position_from_order_send_result(r: mt5.OrderSendResult):
    deal = mt5.history_deals_get(ticket=r.deal)[0]
    pos = mt5.positions_get(ticket=deal.position_id)[0]
    return pos


def close_position(position: mt5.TradePosition) -> mt5.OrderSendResult:
    order_type = mt5.ORDER_TYPE.BUY if position.type == mt5.ORDER_TYPE.SELL else mt5.ORDER_TYPE.SELL
    r = mt5.order_send(action=mt5.TRADE_ACTION.DEAL, type=order_type, symbol=position.symbol,
                       volume=position.volume, position=position.ticket)
    return r


def market_order(symbol, volume, type_, sl=None, tp=None):
    r = mt5.order_send(action=mt5.TRADE_ACTION.DEAL, type=type_, symbol=symbol, volume=volume, sl=sl, tp=tp)
    return r


def buy(symbol, volume: float, sl_ticks: int = None, tp_ticks: int = None) -> mt5.TradePosition:
    tick = mt5.symbol_info_tick(symbol)
    tick_size = getattr(symbol, 'trade_tick_size', mt5.symbol_info(symbol).trade_tick_size)
    sl = tick.ask - sl_ticks * tick_size if sl_ticks else None
    tp = tick.ask + tp_ticks * tick_size if tp_ticks else None
    r = market_order(symbol, volume, sl=sl, tp=tp, type_=mt5.ORDER_TYPE.BUY)
    pos = position_from_order_send_result(r)
    return pos


def main():
    symbol = mt5.symbol_info('EPU20')
    pos = buy(symbol, volume=1.0, sl_ticks=10, tp_ticks=10)
    assert pos and pos.sl and pos.tp and pos.volume == 1.0
    time.sleep(2)
    r = close_position(pos)
    assert r.retcode == mt5.TRADE_RETCODE.DONE
    assert not mt5.positions_get(symbol=symbol)


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    logger = logging.getLogger()
    with mt5.connected(raise_on_errors=True, logger=logger):
        main()
luisaoisdead
46
luisaoisdead  
nicholish en:

No offense, but there are many errors in your code. The first major issue is obvious because the logs in both MT and python are screaming at you that the volume is invalid, and it's invalid because you have to pass the MetaTrader5.order_send must have a float value passed for volume and you are passing an int. It's also invalid because you are setting incorrect sl and tp because /ES tick-size is .25 not .01.  Next, you are trading a futures contract and treating it like a forex lot and you are passing invalid args for the request. Finally, pytmt5adapter is a replacement for MetaTrader5. Do not use them at the same time. pymt5adapter also does a lot of processing in the background to correct little mistakes automatically, like converting int volumes to floats before passing on the request to MT. It seems like you are new to this so my recommendation is stick to pymt5adapter and use an IDE like pycharm so you can get real time type checking and documentation. Here is roughly how your code should look. Note that the terminal connection is managed by the connected context manager and I have gotten a different logger from the logging module which will output the debugging info to the console to you can avoid all the print statements everywhere. 

Thanks!!!

So i shouldn´t use MetaTrader5 and i will study pymt5adapter.

thanks!!!

luisaoisdead
46
luisaoisdead  

just in case, to get market data.

i should do it, this way?

https://www.mql5.com/es/articles/5691

thanks again!

luisaoisdead
46
luisaoisdead  
luisaoisdead:

just in case, to get market data.

i should do it, this way?

https://www.mql5.com/es/articles/5691

thanks again!

def price(symbol):

    for i in list(range(200)):

        time.sleep(1)

        tick = mt5.symbol_info_tick(symbol)

        print(tick)

Fxstrzelecka
10
Fxstrzelecka  

I am new to python and MT5 so please apologize for a beginner question. 

I want to place a Stop Entry Order from python to MT5. 

with 'type_time' mt5.ORDER_TIME_GTC and mt5.ORDER_TIME_DAY the Trade Request works perfectly but using a expiration limit for your order (mt5.ORDER_TIME_SPECIFIED, 'expiration': Date) the order is not passed to the broker. No error message simply ignored. I know that you have to convert numbers in python from type numpy.int64 to int() that MT5 excepts integers passed from python. But what to do with datetime python formats? I tried to hard code the 'expiration': Date as well as pass it via a variable, no result.

Can somebody help me please.

Thanks

nicholish en
2726
nicholish en  
Fxstrzelecka:

I am new to python and MT5 so please apologize for a beginner question. 

I want to place a Stop Entry Order from python to MT5. 

with 'type_time' mt5.ORDER_TIME_GTC and mt5.ORDER_TIME_DAY the Trade Request works perfectly but using a expiration limit for your order (mt5.ORDER_TIME_SPECIFIED, 'expiration': Date) the order is not passed to the broker. No error message simply ignored. I know that you have to convert numbers in python from type numpy.int64 to int() that MT5 excepts integers passed from python. But what to do with datetime python formats? I tried to hard code the 'expiration': Date as well as pass it via a variable, no result.

Can somebody help me please.

Thanks

You have to check last_error() and it will likely be complaining that the expiration time is invalid. It's expecting a UNIX timestamp. Also, not all broker/instruments support custom expiration... You could make a python function to get the timestamp which will satisfy the type for the expected arg, however, it doesn't guarantee that the order will be accepted as a valid expiration time. 

def expiration_time(**delta_kwargs):
    import datetime as dt
    expire = dt.datetime.now() + dt.timedelta(**delta_kwargs)
    timestamp = int(expire.timestamp())
    return timestamp
Fxstrzelecka
10
Fxstrzelecka  
nicholish en:

You have to check last_error() and it will likely be complaining that the expiration time is invalid. It's expecting a UNIX timestamp. Also, not all broker/instruments support custom expiration... You could make a python function to get the timestamp which will satisfy the type for the expected arg, however, it doesn't guarantee that the order will be accepted as a valid expiration time. 

Thank you.

The UNIX timestamp was the solution.

iNeurons MFZ
39
iNeurons MFZ  

Hi Everyone, I have been trying to use a wrapper published/ made by nicholish en and try to test with several codes posted in this forum - as I am new with Python. It worked great with buy/sell limit, however I have a problem whenever I tried to send a market order - returning 'Unsupported Filling Mode' error -- for this I used codes posted in #11.  Below is the log:

INFO:root:Order Request: BUY    {"type":"order_request","request":{"action":1,"magic":0,"order":0,"symbol":"USDJPY","volume":1.0,"price":0.0,"stoplimit":0.0,"sl":103.31099999999999,"tp":103.331,"deviation":0,"type":0,"type_filling":0,"type_time":0,"expiration":0,"comment":"","position":0,"position_by":0}}
INFO:root:Order Response: INVALID_FILL  {"type":"order_response","latency_ms":0.074,"response":{"retcode":10030,"deal":0,"order":0,"volume":0.0,"price":0.0,"bid":0.0,"ask":0.0,"comment":"Unsupported filling mode","request_id":0,"retcode_external":0}}
WARNING:root:Order Fail: INVALID_FILL   {"type":"order_fail","retcode":10030,"description":"INVALID_FILL"}
DEBUG:root:Function Debugging: history_deals_get        {"type":"function_debugging","latency_ms":0.073,"last_error":[-2,"Terminal: Invalid params"],"call_signature":{"function":"history_deals_get","args":[],"kwargs":{"ticket":0}}}
CRITICAL:root:UNCAUGHT EXCEPTION: INVALID_PARAMS: Terminal: Invalid params(){'ticket': 0}       {"type":"exception","last_error":[-2,"Terminal: Invalid params"],"exception":{"type":"MT5Error","message":"INVALID_PARAMS: Terminal: Invalid params(){'ticket': 0}"}}

I wonder if anyone has ever encountered this/ would able to help me on this please?

Thanks in advance :)

nicholish en
2726
nicholish en  
iNeurons MFZ:

Hi Everyone, I have been trying to use a wrapper published/ made by nicholish en and try to test with several codes posted in this forum - as I am new with Python. It worked great with buy/sell limit, however I have a problem whenever I tried to send a market order - returning 'Unsupported Filling Mode' error -- for this I used codes posted in #11.  Below is the log:

I wonder if anyone has ever encountered this/ would able to help me on this please?

Thanks in advance :)

It means your broker doesn't support "fill or kill" orders. 

Guilherme Santana
9
Guilherme Santana  
Hi, im trying to place an order in MT5 using Python. When i use EURUSD, i have sucess, but when i use, for example, EURJPY, it return an error. Can someone help me?
Here is my code:

***