Python point value in account currency

 

So I want to calculate lot size and in order to do that I need the point value in account currency.

How do I do this using the MT5 Python API?

 

This is what I've got now:

mt5.symbol_select(symbol, True)
symbol_info_tick = mt5.symbol_info_tick(symbol)
symbol_info = mt5.symbol_info(symbol)

current_price = (symbol_info_tick.bid + symbol_info_tick.ask) / 2
contract_size = symbol_info.trade_contract_size
point_size = symbol_info.point

quote_currency = symbol_info.currency_profit
qc_usd_symbol_info_tick = mt5.symbol_info_tick(quote_currency + "USD")
qc_usd_rate = (qc_usd_symbol_info_tick.bid + qc_usd_symbol_info_tick.ask) / 2

point_value_qc = (contract_size * (current_price + point_size)) - (contract_size * current_price)
point_value_usd = point_value_qc * qc_usd_rate

account_currency = mt5.account_info().currency
ac_usd_symbol_info_tick = mt5.symbol_info_tick(account_currency + "USD")
ac_usd_rate = (ac_usd_symbol_info_tick.bid + ac_usd_symbol_info_tick.ask) / 2

point_value_ac = point_value_usd * ac_usd_rate

Let me know if there's any mistakes or better ways to do this.

Well, not every quote currency hase a pair with it as base and usd as quote so I'll need to find a way to deal with those edge cases now, but I feel like there should be a better way.

 

Think I've figured it out:

def calculate_position_size(symbol, tradeinfo):
    print(symbol)

    mt5.symbol_select(symbol, True)
    symbol_info_tick = mt5.symbol_info_tick(symbol)
    symbol_info = mt5.symbol_info(symbol)

    current_price = (symbol_info_tick.bid + symbol_info_tick.ask) / 2
    sl = tradeinfo[2]
    tick_size = symbol_info.trade_tick_size

    balance = mt5.account_info().balance
    risk_per_trade = 0.01
    ticks_at_risk = abs(current_price - sl) / tick_size
    tick_value = symbol_info.trade_tick_value

    position_size = (balance * risk_per_trade) / (ticks_at_risk * tick_value)

    return position_size
 
jdevoldere:

Think I've figured it out:

Pretty good. As you have figured out the symbol.trade_tick_value calculates the tick_value in your deposit currency. Just a couple of constructive criticisms if I may... I wouldn't hard-code the balance and the risk percentage and I would also work directly with the trade request dict or create paramters that shadow the request keywords so you can unpack a request in the function call. Also don't forget to normalize your lot size and check it against the min and max volume size....

import logging
import math

import MetaTrader5 as mt5

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')


class MT5Error(Exception): pass








def size_by_risk(symbol, price, sl, risk_percent=0.01, of_amount=None, enforce_restrictions=True, **kwargs) -> float: symbol = mt5.symbol_info(getattr(symbol, 'name', symbol)) risk_capital = (of_amount or mt5.account_info().balance) * risk_percent risk_ticks = abs(price - sl) / symbol.trade_tick_size size = risk_capital / (risk_ticks * symbol.trade_tick_value) floor_size = (size // symbol.volume_min) * symbol.volume_min if not enforce_restrictions or (symbol.volume_min <= floor_size <= symbol.volume_max): return floor_size raise MT5Error(f'Cannot compute lot size for risk_capital={risk_capital}')

def main():     symbol = mt5.symbol_info('EURUSD')     tick = mt5.symbol_info_tick(symbol.name)     req = dict(         action=mt5.TRADE_ACTION_DEAL,         type=mt5.ORDER_TYPE_BUY,         symbol=symbol.name,         price=tick.ask,         sl=tick.ask - 1575 * symbol.trade_tick_size,         tp=tick.ask + 1000 * symbol.trade_tick_size,     )     try:         req['volume'] = size_by_risk(**req)         r = mt5.order_check(req)         if r is None:             raise MT5Error     except MT5Error as e:         logging.warning(f'Order Failed: {symbol.name}: {e}')         logging.warning(f'Failed Request: {req}')         logging.warning(f'Last Error: {mt5.last_error()}')     else:         res = r._asdict()         req = res.pop('request')._asdict()         logging.info(f'Request: {req}')         logging.info(f'Response: {res}') if __name__ == '__main__':     try:         if not mt5.initialize():             raise MT5Error(f'Failed to initialize: {mt5.last_error()}')         logging.info('MT5 initialized')         main()     except Exception as e:         logging.exception(e)     finally:         mt5.shutdown()         logging.info('MT5 shutdown')
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
//| Expert initialization function                                   | //| Expert deinitialization function                                 | //| Expert tick function                                             | //| test1                                                            |...
Reason: