Skip to content

Account Info

CAccountInfo

Source code in strategytester5\trade_classes\AccountInfo.py
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
class CAccountInfo:
    def __init__(self, terminal: Union[OverLoadedMetaTrader5API|MetaTrader5]):

        """
        A lightweight Python wrapper that resembles the MQL5 Standard Library class
        `CAccountInfo` and provides convenient, read-only access to the properties of
        the currently connected MetaTrader 5 trading account.

        This class caches the result of `mt5.account_info()` at construction time.
        The returned values reflect the account state at the time of initialization
        (balance, equity, margin, etc.). If you need up-to-date values after trading
        activity or price changes, re-instantiate the class or implement a refresh.

        [MQL5 Reference](https://www.mql5.com/en/docs/standardlibrary/tradeclasses/caccountinfo)

        Args
        ----------
        terminal : MetaTrader5 module-like or simulated/overloaded MetaTrader5 instance.

        Raises
        ------
        RuntimeError
            If account information cannot be retrieved (i.e., `account_info()` returns None).

        Notes
        -----
        Method groups mirror the MQL5 layout:
        - Integer properties: Login, TradeMode, Leverage, StopoutMode, MarginMode, etc.
        - Double properties: Balance, Equity, Margin, FreeMargin, etc.
        - String properties: Name, Server, Currency, Company
        - Checks / calculations: MarginCheck, OrderProfitCheck, FreeMarginCheck, MaxLotCheck
        """

        self.terminal = terminal

        self._account_info = self.terminal.account_info()
        if self._account_info is None:
            raise RuntimeError("Failed to retrieve account info: ", self.terminal.last_error())

    # --- Integer properties

    @property
    def login(self) -> int:
        """Gets the account number (Login)."""

        return int(self._account_info.login)

    @property
    def trade_mode(self) -> int:
        """Gets the trade mode (ACCOUNT_TRADE_MODE_*)."""

        return int(self._account_info.trade_mode)

    @property
    def trade_mode_description(self) -> str:
        """Gets the trade mode as a human-readable string."""

        mode_map = {
            self.terminal.ACCOUNT_TRADE_MODE_DEMO: "Demo",
            self.terminal.ACCOUNT_TRADE_MODE_CONTEST: "Contest",
            self.terminal.ACCOUNT_TRADE_MODE_REAL: "Real",
        }

        return mode_map.get(self._account_info.trade_mode, "Unknown")

    @property
    def leverage(self) -> int:
        """Gets the account leverage."""

        return int(self._account_info.leverage)

    @property
    def stopout_mode(self) -> int:
        """Gets the stop-out mode (ACCOUNT_STOPOUT_MODE_*)."""

        return int(self._account_info.margin_so_mode)

    @property
    def stopout_mode_description(self) -> str:
        """Gets the stop-out mode as a human-readable string."""

        mode_map = {
            self.terminal.ACCOUNT_STOPOUT_MODE_PERCENT: "Percent",
            self.terminal.ACCOUNT_STOPOUT_MODE_MONEY: "Money",
        }

        return mode_map.get(self._account_info.margin_so_mode, "Unknown")

    @property
    def margin_mode(self) -> int:
        """Gets the margin calculation mode (ACCOUNT_MARGIN_MODE_*)."""

        return int(self._account_info.margin_mode)

    @property
    def margin_mode_description(self) -> str:
        """Gets the margin calculation mode as a human-readable string."""

        mode_map = {
            self.terminal.ACCOUNT_MARGIN_MODE_RETAIL_NETTING: "Retail Netting",
            self.terminal.ACCOUNT_MARGIN_MODE_EXCHANGE: "Exchange",
            self.terminal.ACCOUNT_MARGIN_MODE_RETAIL_HEDGING: "Retail Hedging",
        }
        return mode_map.get(self._account_info.margin_mode, "Unknown")

    @property
    def trade_allowed(self) -> bool:
        """Returns True if trading is allowed for the account."""
        return bool(self._account_info.trade_allowed)

    @property
    def trade_expert(self) -> bool:
        """Returns True if automated trading is allowed for the account."""
        return bool(self._account_info.trade_expert)

    @property
    def limit_orders(self) -> int:
        """Gets the maximum number of allowed pending orders."""
        return int(self._account_info.limit_orders)

    # --- Double properties

    @property
    def balance(self) -> float:
        """Gets the account balance."""
        return float(self._account_info.balance)

    @property
    def credit(self) -> float:
        """Gets the account credit."""
        return float(self._account_info.credit)

    @property
    def profit(self) -> float:
        """Gets the current profit for the account."""
        return float(self._account_info.profit)

    @property
    def equity(self) -> float:
        """Gets the account equity."""
        return float(self._account_info.equity)

    @property
    def margin(self) -> float:
        """Gets the reserved margin."""
        return float(self._account_info.margin)

    @property
    def free_margin(self) -> float:
        """Gets the free margin."""
        return float(self._account_info.margin_free)

    @property
    def margin_level(self) -> float:
        """Gets the margin level."""
        return float(self._account_info.margin_level)

    @property
    def margin_call(self) -> float:
        """Gets the margin call level."""
        return float(self._account_info.margin_so_call)

    @property
    def margin_stopout(self) -> float:
        """Gets the stop-out level."""
        return float(self._account_info.margin_so_so)

    # --- String properties

    @property
    def name(self) -> str:
        """Gets the client name."""
        return str(self._account_info.name)

    @property
    def server(self) -> str:
        """Gets the trade server name."""
        return str(self._account_info.server)

    @property
    def currency(self) -> str:
        """Gets the deposit currency."""
        return str(self._account_info.currency)

    @property
    def company(self) -> str:
        """Gets the broker/company name."""
        return str(self._account_info.company)

    # --- Checks

    def order_profit_check(self, symbol: str, order_type: int, volume: float, price_open: float, price_close: float) -> float:

        """Evaluates profit for the given open/close prices (approximate, ignores commissions/swaps)."""

        profit = self.terminal.order_calc_profit(order_type, symbol, volume, price_open, price_close)
        return float(profit) if profit is not None else 0.0

    def free_margin_check(self, symbol: str, order_type: int, volume: float, price: float) -> Optional[float]:

        """Returns free margin left after opening the position, or None if margin check fails."""

        required_margin = self.margin_check(symbol, order_type, volume, price)
        return None if required_margin is None else (self.free_margin - required_margin)

    def margin_check(self, symbol: str, order_type: int, volume: float, price: float) -> Optional[float]:

        """Gets the amount of margin required to execute trade operation"""

        margin = self.terminal.order_calc_margin(order_type, symbol, volume, price)
        return margin if margin is not None else 0.0

    def max_lot_check(self, symbol: str, order_type: int, price: float, percent: float = 100.0) -> Optional[float]: 
        """ Estimates the maximum tradable volume based on available margin. 

        Args
        ---------- 
        percent : float Percentage of free margin to use (0..100). 

        Returns 
        ------- 
        Optional[float] Estimated maximum lot size, or None if margin cannot be estimated. """ 

        required_margin_per_lot = self.margin_check(symbol, order_type, 1.0, price)
        if required_margin_per_lot in (None, 0.0): 
            return None 

        margin_available = self.free_margin * (percent / 100.0)
        return margin_available / required_margin_per_lot


    def print_all(self) -> None:
        """Print all @property values of the class."""

        for name, attr in vars(type(self)).items():
            if isinstance(attr, property):
                try:
                    value = getattr(self, name)
                except Exception as e:
                    value = f"<error: {e}>"

                print(f"{name:20} : {value}")

balance property

Gets the account balance.

company property

Gets the broker/company name.

credit property

Gets the account credit.

currency property

Gets the deposit currency.

equity property

Gets the account equity.

free_margin property

Gets the free margin.

leverage property

Gets the account leverage.

limit_orders property

Gets the maximum number of allowed pending orders.

login property

Gets the account number (Login).

margin property

Gets the reserved margin.

margin_call property

Gets the margin call level.

margin_level property

Gets the margin level.

margin_mode property

Gets the margin calculation mode (ACCOUNT_MARGIN_MODE_*).

margin_mode_description property

Gets the margin calculation mode as a human-readable string.

margin_stopout property

Gets the stop-out level.

name property

Gets the client name.

profit property

Gets the current profit for the account.

server property

Gets the trade server name.

stopout_mode property

Gets the stop-out mode (ACCOUNT_STOPOUT_MODE_*).

stopout_mode_description property

Gets the stop-out mode as a human-readable string.

trade_allowed property

Returns True if trading is allowed for the account.

trade_expert property

Returns True if automated trading is allowed for the account.

trade_mode property

Gets the trade mode (ACCOUNT_TRADE_MODE_*).

trade_mode_description property

Gets the trade mode as a human-readable string.

__init__(terminal)

A lightweight Python wrapper that resembles the MQL5 Standard Library class CAccountInfo and provides convenient, read-only access to the properties of the currently connected MetaTrader 5 trading account.

This class caches the result of mt5.account_info() at construction time. The returned values reflect the account state at the time of initialization (balance, equity, margin, etc.). If you need up-to-date values after trading activity or price changes, re-instantiate the class or implement a refresh.

MQL5 Reference

Args

terminal : MetaTrader5 module-like or simulated/overloaded MetaTrader5 instance.

Raises

RuntimeError If account information cannot be retrieved (i.e., account_info() returns None).

Notes

Method groups mirror the MQL5 layout: - Integer properties: Login, TradeMode, Leverage, StopoutMode, MarginMode, etc. - Double properties: Balance, Equity, Margin, FreeMargin, etc. - String properties: Name, Server, Currency, Company - Checks / calculations: MarginCheck, OrderProfitCheck, FreeMarginCheck, MaxLotCheck

Source code in strategytester5\trade_classes\AccountInfo.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def __init__(self, terminal: Union[OverLoadedMetaTrader5API|MetaTrader5]):

    """
    A lightweight Python wrapper that resembles the MQL5 Standard Library class
    `CAccountInfo` and provides convenient, read-only access to the properties of
    the currently connected MetaTrader 5 trading account.

    This class caches the result of `mt5.account_info()` at construction time.
    The returned values reflect the account state at the time of initialization
    (balance, equity, margin, etc.). If you need up-to-date values after trading
    activity or price changes, re-instantiate the class or implement a refresh.

    [MQL5 Reference](https://www.mql5.com/en/docs/standardlibrary/tradeclasses/caccountinfo)

    Args
    ----------
    terminal : MetaTrader5 module-like or simulated/overloaded MetaTrader5 instance.

    Raises
    ------
    RuntimeError
        If account information cannot be retrieved (i.e., `account_info()` returns None).

    Notes
    -----
    Method groups mirror the MQL5 layout:
    - Integer properties: Login, TradeMode, Leverage, StopoutMode, MarginMode, etc.
    - Double properties: Balance, Equity, Margin, FreeMargin, etc.
    - String properties: Name, Server, Currency, Company
    - Checks / calculations: MarginCheck, OrderProfitCheck, FreeMarginCheck, MaxLotCheck
    """

    self.terminal = terminal

    self._account_info = self.terminal.account_info()
    if self._account_info is None:
        raise RuntimeError("Failed to retrieve account info: ", self.terminal.last_error())

free_margin_check(symbol, order_type, volume, price)

Returns free margin left after opening the position, or None if margin check fails.

Source code in strategytester5\trade_classes\AccountInfo.py
204
205
206
207
208
209
def free_margin_check(self, symbol: str, order_type: int, volume: float, price: float) -> Optional[float]:

    """Returns free margin left after opening the position, or None if margin check fails."""

    required_margin = self.margin_check(symbol, order_type, volume, price)
    return None if required_margin is None else (self.free_margin - required_margin)

margin_check(symbol, order_type, volume, price)

Gets the amount of margin required to execute trade operation

Source code in strategytester5\trade_classes\AccountInfo.py
211
212
213
214
215
216
def margin_check(self, symbol: str, order_type: int, volume: float, price: float) -> Optional[float]:

    """Gets the amount of margin required to execute trade operation"""

    margin = self.terminal.order_calc_margin(order_type, symbol, volume, price)
    return margin if margin is not None else 0.0

max_lot_check(symbol, order_type, price, percent=100.0)

Estimates the maximum tradable volume based on available margin.

Args

percent : float Percentage of free margin to use (0..100).

Returns

Optional[float] Estimated maximum lot size, or None if margin cannot be estimated.

Source code in strategytester5\trade_classes\AccountInfo.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
def max_lot_check(self, symbol: str, order_type: int, price: float, percent: float = 100.0) -> Optional[float]: 
    """ Estimates the maximum tradable volume based on available margin. 

    Args
    ---------- 
    percent : float Percentage of free margin to use (0..100). 

    Returns 
    ------- 
    Optional[float] Estimated maximum lot size, or None if margin cannot be estimated. """ 

    required_margin_per_lot = self.margin_check(symbol, order_type, 1.0, price)
    if required_margin_per_lot in (None, 0.0): 
        return None 

    margin_available = self.free_margin * (percent / 100.0)
    return margin_available / required_margin_per_lot

order_profit_check(symbol, order_type, volume, price_open, price_close)

Evaluates profit for the given open/close prices (approximate, ignores commissions/swaps).

Source code in strategytester5\trade_classes\AccountInfo.py
197
198
199
200
201
202
def order_profit_check(self, symbol: str, order_type: int, volume: float, price_open: float, price_close: float) -> float:

    """Evaluates profit for the given open/close prices (approximate, ignores commissions/swaps)."""

    profit = self.terminal.order_calc_profit(order_type, symbol, volume, price_open, price_close)
    return float(profit) if profit is not None else 0.0

print_all()

Print all @property values of the class.

Source code in strategytester5\trade_classes\AccountInfo.py
237
238
239
240
241
242
243
244
245
246
247
def print_all(self) -> None:
    """Print all @property values of the class."""

    for name, attr in vars(type(self)).items():
        if isinstance(attr, property):
            try:
                value = getattr(self, name)
            except Exception as e:
                value = f"<error: {e}>"

            print(f"{name:20} : {value}")