MetaTrader 5 Python User Group - the summary - page 11

 
Дмитрий Прокопьев:

Are these the effects of yesterday's market storm? ;)

No :) I haven't used python in a while so I thought I'd convert one my my popular close-all scripts to python using pythonic abstractions. 


I still cannot get the symbol of the chart that the script was dropped on. More importantly we should be able to get a list of all available symbols to the current account.  Perhaps there is an undocumented function that I am unaware of, but as of right now I can only check if pairs and previously traded symbols exist and nothing else. This is a hack that I'd like to avoid by using something similar to MQL's SymbolsTotal and SymbolsName. 

 

import MetaTrader5 as mt5
from datetime import datetime
from itertools import permutations
from contextlib import contextmanager

class MetatraderConnectionError(Exception):
    pass

@contextmanager
def metatrader_connection():
    try:
        if not mt5.initialize():
            print("Failed to initialize python MT5")
            raise MetatraderConnectionError
        yield
    finally:
        mt5.shutdown()


def get_pair_symbols():
    base_currencies = "USD JPY GBP AUD EUR CHF NZD".split()
    possibles = map(''.join, permutations(base_currencies, 2))
    infos = [(s, mt5.symbol_info(s)) for s in possibles]
    symbol_map = {s: si for s, si in infos if si is not None}
    return symbol_map


def get_prev_traded_symbols():
    begin = datetime(2018, 1, 1)
    end = datetime.now()
    deal_symbols = set(d.symbol for d in mt5.history_deals_get(begin, end))
    order_symbols = set(d.symbol for d in mt5.history_orders_get(begin, end))
    pos_symbols = set(d.symbol for d in mt5.positions_get())
    symbols = deal_symbols | order_symbols | pos_symbols
    symbol_map = {s: mt5.symbol_info(s) for s in symbols if s}
    return symbol_map


def get_symbols():
    return {**get_pair_symbols(), **get_prev_traded_symbols()}


def main():
    for symbol, info in get_symbols().items():
        print(symbol, info)


if __name__ == "__main__":
    with metatrader_connection():
        main()
Current Account - economic indicator from the United Kingdom
Current Account - economic indicator from the United Kingdom
  • www.mql5.com
The Current Account reflects the balance of transactions between UK residents and the rest of the world. It is the sum of net trade balance (the difference between exported and imported goods and services), the net factor income of UK residents (such as interest, dividends, etc.) and net transfer payments (e.g. foreign donations) to UK...
 
nicholi shen:

No :) I haven't used python in a while so I thought I'd convert one my my popular close-all scripts to python using pythonic abstractions. 


I still cannot get the symbol of the chart that the script was dropped on. More importantly we should be able to get a list of all available symbols to the current account.  Perhaps there is an undocumented function that I am unaware of, but as of right now I can only check if pairs and previously traded symbols exist and nothing else. This is a hack that I'd like to avoid by using something similar to MQL's SymbolsTotal and SymbolsName. 

 

in the neighboring threading it`s discussed ... in russian (URL: https://www.mql5.com/ru/forum/306688/page56)

Small translation :) from me

Symbols_total (), symbols_get ([group = "EURUSD," USDGBP ", * RU *"]) are added in release 5.0.29.

it`s required to install the latest beta version of the Terminal.

Also, in all the functions orders_get (), positions_get (), history_orders_get (), history_deals_get (), the ability to filter by group is added - group = "EURUSD," USDGBP ", * RU *".
The methods order_check (), order_send () - return the original request in the request field.


look at threading, are many examples, etc, only russian ... + google translate ^)

MetaTrader 5 Python User Group - как использовать Python в Метатрейдере
MetaTrader 5 Python User Group - как использовать Python в Метатрейдере
  • 2020.03.23
  • www.mql5.com
Мы готовим модуль MetaTrader 5 для Python...
 
Дмитрий Прокопьев:

in the neighboring threading it`s discussed ... in russian (URL: https://www.mql5.com/ru/forum/306688/page56)

Small translation :) from me

Symbols_total (), symbols_get ([group = "EURUSD," USDGBP ", * RU *"]) are added in release 5.0.29.

it`s required to install the latest beta version of the Terminal.

Also, in all the functions orders_get (), positions_get (), history_orders_get (), history_deals_get (), the ability to filter by group is added - group = "EURUSD," USDGBP ", * RU *".
The methods order_check (), order_send () - return the original request in the request field.


look at threading, are many examples, etc, only russian ... + google translate ^)

I don't speak Russian so would it be possible for you to communicate the following to that thread on my behalf?


The symbols_get function should return a generator of SymbolInfo named tuples. A call to symbols_get without args should return all symbols available in the terminal. The function should take a callback which would be passed in a SymbolInfo namedtuple to be processed using the filter function. Here are some examples. 

import MetaTrader5 as mt5
from contextlib import contextmanager
import re


@contextmanager
def metatrader_connection(**kw):
    try:
        if not mt5.initialize(**kw):
            print("Failed to initialize python MT5")
            raise Exception
        yield
    finally:
        mt5.shutdown()


def symbols_get(function=None):
    """
    No function passed in will result in all symbols returned to the caller.
    If a callable function is passed in then the function is passed a SymbolInfo tuple for filtering
    :param function: callback function to filter the symbols
    """
    all_symbols_in_terminal_info = map(
        mt5.symbol_info,
        ['EURUSD', 'USDJPY', 'GBPJPY', 'EURGBP'] # *example only* this would represent all symbols available to the terminal
    )
    if function is not None:
        return filter(function, all_symbols_in_terminal_info)
    return all_symbols_in_terminal_info


if __name__ == "__main__":
    with metatrader_connection():
        all_terminal_symbols = symbols_get()
        jpy_symbols = symbols_get(lambda s: "JPY" in s.name)
        jpy_symbols_using_re = symbols_get(lambda s: re.match(r'\w*JPY\w*', s.name))
        visible_symbols = symbols_get(lambda s: s.visible)
        selected_symbols = symbols_get(lambda s: s.select)


        def my_criteria(symbol_info):
            return 'USD' in symbol_info.name and symbol_info.session_deals > 0


        usd_symbols_with_session_deals = symbols_get(my_criteria)
 
nicholi shen:

I don't speak Russian so would it be possible for you to communicate the following to that thread on my behalf?


OK, no problem ...

You can write to this thread, many speak English and the developers are reading the exact same thread.

 
nicholi shen:

No :) I haven't used python in a while so I thought I'd convert one my my popular close-all scripts to python using pythonic abstractions. 


I still cannot get the symbol of the chart that the script was dropped on. More importantly we should be able to get a list of all available symbols to the current account.  Perhaps there is an undocumented function that I am unaware of, but as of right now I can only check if pairs and previously traded symbols exist and nothing else. This is a hack that I'd like to avoid by using something similar to MQL's SymbolsTotal and SymbolsName. 

 

With version 5.0.29 and latest beta version of Terminal, you can use symbols_get() method to retrieve all available symbols.

 

Im dorry for the delkay in reply. Im running MT5 on linux (Fedora) with a wine installation. The error I get is:

ERROR: Could not find a version that satisfies the requirement MetaTrader5 (from versions: none)
ERROR: No matching distribution found for MetaTrader5


jaffer wilson:

What is the error you are getting?

 
alkam_ai:

Im dorry for the delkay in reply. Im running MT5 on linux (Fedora) with a wine installation. The error I get is:

ERROR: Could not find a version that satisfies the requirement MetaTrader5 (from versions: none)
ERROR: No matching distribution found for MetaTrader5


Uhhh ... you use of MT5 (Wine) + python (Wine)?!

cool ... I could not get to make such a configuration :(

 

Is it possible to send a request to set a stop loss on an existing order?

I have a code that works in my python ea, which can set and open trades. however I need to know the syntax for mt5.Buy(), mt5.Sell(), and what values they accept. for example how can i set a stop loss and take profit value when sending a buy? or a sell?

and how can I update the order? (i can't send a request to update a stoploss) i get an invalid request 10016 error


my ea actually works to connect buy and sell but i don't see any examples or documentation for buy and sell.

import MetaTrader5 as mt5
import time

# connect to MetaTrader 5
if not mt5.initialize():
    print("initialize() failed")
    mt5.shutdown()
 
# request connection status and parameters
print(mt5.terminal_info())
# get data on MetaTrader 5 version
print(mt5.version())

info = mt5.terminal_info()
if info.trade_allowed == False:
    print( "Auto-trading disabled in Terminal, enable it" )
    quit()

symbol = "XAUUSD"       # set to whatever symbol or currency
lot = 0.01              # buy/sell lot
slminprofit = 20 * lot  # number pips * lotsize


positions=mt5.positions_get(symbol=symbol)
    if positions==None:
        print("No positions, error code={}".format(mt5.last_error()))
    if len(positions)>0:
        print("Total positions on", symbol,":",len(positions))
        # display all active orders
        for position in positions:
            if position.type == 0:
                ptype = "Buy"
            elif position.type == 1:
                ptype = "Sell"
            print("id:", position.identifier, ptype, position.profit, position.ORDER_VOLUME_CURRENT)

            
            #stoploss
            position_id=position.identifier
            if position.type == 1 and position.profit > slminprofit: #if ordertype sell 
                request={
                    "action": mt5.TRADE_ACTION_SLTP,
                    "position": position_id,
                    "sl": v_ask - 100 * lot,
                    "comment": "python trailing sl",
                    "deviation": 20,
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_RETURN,
                    "volume": position.ORDER_VOLUME_CURRENT
                }
                # send a trading request
                result=mt5.order_send(request)
                # check the execution result
                print("3. SL SELL update sent on position #{}: {} {} lots".format(position_id,symbol,lot));
                if result.retcode != mt5.TRADE_RETCODE_DONE:
                    print("4. order_send failed, retcode={}".format(result.retcode))
                    print("   result",result)
                else:
                    print("4. position #{} SL Updated, {}".format(position_id,result))
            elif position.type == 0 and position.profit > slminprofit: #if ordertype buy 
                request={
                    "action": mt5.TRADE_ACTION_SLTP,
                    "position": position_id,
                    "sl": v_bid + 100 * lot,
                    "comment": "python trailing sl",
                    "deviation": 20,
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_RETURN,
                    "volume": position.ORDER_VOLUME_CURRENT
                }
                # send a trading request
                result=mt5.order_send(request)
                # check the execution result
                print("3. SL BUY update sent on position #{}: {} {} lots".format(position_id,symbol,lot));
                if result.retcode != mt5.TRADE_RETCODE_DONE:
                    print("4. order_send failed, retcode={}".format(result.retcode))
                    print("   result",result)
                else:
                    print("4. position #{} SL Updated, {}".format(position_id,result))
            
    else:
        print("Positions on", symbol,"not found.")

my buy code (i save the order number to a variable called "ticket" so i can use it later to see if the order was successful)
r = mt5.Buy(symbol, lot)

        time.sleep( 1 )
        if r.retcode != mt5. TRADE_RETCODE_DONE :
            print( "Buy failed: " , r)
        else :
            ticket = r.order
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Order Properties
  • www.mql5.com
Requests to execute trade operations are formalized as orders. Each order has a variety of properties for reading. Information on them can be obtained using functions Position identifier that is set to an order as soon as it is executed. Each executed order results in a deal that opens or modifies an already existing position. The...
 
Azeem Hussein:

Is it possible to send a request to set a stop loss on an existing order?

I have a code that works in my python ea, which can set and open trades. however I need to know the syntax for mt5.Buy(), mt5.Sell(), and what values they accept. for example how can i set a stop loss and take profit value when sending a buy? or a sell?

and how can I update the order? (i can't send a request to update a stoploss) i get an invalid request 10016 error


my ea actually works to connect buy and sell but i don't see any examples or documentation for buy and sell.

my buy code (i save the order number to a variable called "ticket" so i can use it later to see if the order was successful)
r = mt5.Buy(symbol, lot)

You can set the tp/sl when you send the order as well as modifying it. Here is a quick example. 

import MetaTrader5 as mt5
from contextlib import contextmanager


@contextmanager
def mt5_connection(**kw):
    try:
        if not mt5.initialize(**kw):
            raise Exception("Failed to initialize python MT5")
        yield
    finally:
        mt5.shutdown()


def raw_order(**kwargs):
    return mt5.order_send(kwargs)


def buy(symbol, volume, sl=0.0, tp=0.0):
    price = mt5.symbol_info_tick(symbol).ask
    res = raw_order(
        action=mt5.TRADE_ACTION_DEAL,
        type=mt5.ORDER_TYPE_BUY,
        symbol=symbol,
        volume=float(volume),
        price=price,
        sl=sl,
        tp=tp,
    )
    return res


def mod_sl_tp(position, sl=None, tp=None):
    res = raw_order(
        action=mt5.TRADE_ACTION_SLTP,
        position=position.ticket,
        symbol=position.symbol,
        sl=(sl or position.sl),
        tp=(tp or position.tp),
    )
    return res


def position_from_result(result):
    try:
        deal = mt5.history_deals_get(ticket=result.deal)[0]
        pos = mt5.positions_get(ticket=deal.position_id)[0]
        return pos
    except:
        return None


def main():
    symbol = "EPM20"
    result = buy(symbol, volume=1)
    print(result)
    if position := position_from_result(result):
        new_stop = position.price_open - 25
        new_take = position.price_open + 50
        result = mod_sl_tp(position, sl=new_stop, tp=new_take)
        print(result)


if __name__ == "__main__":
    with mt5_connection():
        main()
 
nicholi shen:

I don't speak Russian so would it be possible for you to communicate the following to that thread on my behalf?


The symbols_get function should return a generator of SymbolInfo named tuples. A call to symbols_get without args should return all symbols available in the terminal. The function should take a callback which would be passed in a SymbolInfo namedtuple to be processed using the filter function. Here are some examples. 

See sample in symbols_get please

Example:

import MetaTrader5 as mt5
# display data on the MetaTrader 5 package
print("MetaTrader5 package author: ",mt5.__author__)
print("MetaTrader5 package version: ",mt5.__version__)
 
# establish connection to the MetaTrader 5 terminal
if not mt5.initialize():
    print("initialize() failed, error code =",mt5.last_error())
    quit()
 
# get all symbols
symbols=mt5.symbols_get()
print('Symbols: 'len(symbols))
count=0
# display the first five ones
for s in symbols:
    count+=1
    print("{}. {}".format(count,s.name))
    if count==5: break
print()
 
# get symbols containing RU in their names
ru_symbols=mt5.symbols_get("*RU*")
print('len(*RU*): 'len(ru_symbols))
for s in ru_symbols:
    print(s.name)
print()
 
# get symbols whose names do not contain USD, EUR, JPY and GBP
group_symbols=mt5.symbols_get(group="*,!*USD*,!*EUR*,!*JPY*,!*GBP*")
print('len(*,!*USD*,!*EUR*,!*JPY*,!*GBP*):'len(group_symbols))
for s in group_symbols:
    print(s.name,":",s)
 
# shut down connection to the MetaTrader 5 terminal
mt5.shutdown()
 
Result:
MetaTrader5 package author:  MetaQuotes Software Corp.
MetaTrader5 package version:  5.0.29
Symbols:  84
1. EURUSD
2. GBPUSD
3. USDCHF
4. USDJPY
5. USDCNH
 
len(*RU*):  8
EURUSD
USDRUB
USDRUR
EURRUR
EURRUB
FORTS.RUB.M5
EURUSD_T20
EURUSD4
 
len(*,!*USD*,!*EUR*,!*JPY*,!*GBP*):  13
AUDCAD : SymbolInfo(custom=False, chart_mode=0, select=True, visible=True, session_deals=0, session_buy_orders=0, session...
AUDCHF : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
AUDNZD : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
CADCHF : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
NZDCAD : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
NZDCHF : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
NZDSGD : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
CADMXN : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
CHFMXN : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
NZDMXN : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
FORTS.RTS.M5 : SymbolInfo(custom=True, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, ...
FORTS.RUB.M5 : SymbolInfo(custom=True, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, ...
FOREX.CHF.M5 : SymbolInfo(custom=True, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, ...

Documentation on MQL5: Integration / MetaTrader for Python / symbols_get
Documentation on MQL5: Integration / MetaTrader for Python / symbols_get
  • www.mql5.com
AUDCAD : SymbolInfo(custom=False, chart_mode=0, select=True, visible=True, session_deals=0, session_buy_orders=0, session... AUDCHF : SymbolInfo(custom=False, chart_mode=0, select=False, visible=False, session_deals=0, session_buy_orders=0, sessi...
Reason: