PythonMetaTrader5 2.2__tar.gz → 2.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,267 @@
1
+ Metadata-Version: 2.4
2
+ Name: PythonMetaTrader5
3
+ Version: 2.3.2
4
+ Summary: Connect MT5 with Python
5
+ Author-email: Wiktor Jelen <wiktorjn@gmail.com>
6
+ License: CC BY-NC 4.0
7
+ Project-URL: Homepage, https://github.com/Akinzou/MetaTrader5-Python
8
+ Project-URL: Bug Tracker, https://github.com/Akinzou/MetaTrader5-Python/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: MetaTrader5
15
+ Requires-Dist: loguru
16
+ Requires-Dist: pyautogui
17
+
18
+ # PythonMetaTrader5 [![PyPI Publish](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml) ![PyPI](https://img.shields.io/pypi/v/pythonmetatrader5) ![Python](https://img.shields.io/badge/python-3.6%2B-blue?logo=python&logoColor=white) ![License](https://img.shields.io/badge/license-CC_BY--NC_4.0-lightgrey.svg) [![PyPI Downloads](https://static.pepy.tech/badge/pythonmetatrader5)](https://pepy.tech/projects/pythonmetatrader5)
19
+
20
+ [![Discord](https://img.shields.io/badge/Join_us_on-Discord-5865F2?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/BARYa55KS8)
21
+
22
+
23
+ # MetaTrader5 Python Broker Helper
24
+
25
+ Minimal, production‑ready helper around the official **MetaTrader5** Python package,
26
+ with a single market-entry function and clean handling of **SL/TP as absolute prices or offsets in POINTS**.
27
+ Includes utilities to read positions, close them, and manage pending orders.
28
+
29
+ > Works with: `MetaTrader5`, `loguru`, `pyautogui`
30
+
31
+ ---
32
+
33
+ ## Features
34
+
35
+ - ✅ One function to open market positions: `OpenPosition(...)`
36
+ - ✅ SL/TP can be passed **as absolute prices** or **offsets in POINTS**
37
+ - ✅ Automatic price normalization to instrument `digits`
38
+ - ✅ Consistent error handling (common MT5 retcodes mapped to messages)
39
+ - ✅ Backward‑compat wrappers: `Buy`, `Sell`, `BuySL`, `SellSL`
40
+ - ✅ Position helpers: `GetPositions`, `GetPosition`, `GetPositionsBySymbol`
41
+ - ✅ Closing and pending orders helpers: `Close`, `SellLimit`, `BuyLimit`, `CancelOrders`
42
+
43
+ ---
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install MetaTrader5
49
+ ```
50
+
51
+ > Ensure your MetaTrader 5 terminal is running, logged in, and **Algo Trading** is enabled.
52
+
53
+ ---
54
+
55
+ ## Quick Start
56
+
57
+ ```python
58
+ from PythonMetaTrader5 import Broker
59
+ import time
60
+
61
+ # Login to your account
62
+ broker = Broker(96540048, "PASSWORD", "MetaQuotes-Demo")
63
+ time.sleep(1) # small grace period after login
64
+
65
+ # Open BUY with SL/TP given as OFFSETS IN POINTS
66
+ r = broker.OpenPosition(
67
+ "EURUSD", "buy", 0.10,
68
+ sl=1000, sl_type="offset", # 1000 points (≈ 100 pips on 5-digit symbol)
69
+ tp=1500, tp_type="offset"
70
+ )
71
+
72
+ # Read positions for a symbol
73
+ xau_positions = broker.GetPositionsBySymbol("XAUUSD", as_dict=True)
74
+
75
+ # Close all positions on a symbol
76
+ broker.Close("EURUSD")
77
+
78
+ # Cancel pending limit orders on a symbol
79
+ broker.CancelOrders("EURUSD")
80
+
81
+ # Graceful shutdown
82
+ broker.Disconnect()
83
+ ```
84
+
85
+ ---
86
+
87
+ ## SL/TP Semantics (Important)
88
+
89
+ - `sl_type` / `tp_type`:
90
+ - `"absolute"` → you pass **absolute prices** (e.g., `1.23456`)
91
+ - `"offset"` → you pass **offsets in POINTS** (converted using `symbol_info(symbol).point`)
92
+
93
+ - Offsets are applied from the **current tick price** (`ask` for BUY, `bid` for SELL):
94
+ - BUY : `SL = ask - |sl|*point`, `TP = ask + |tp|*point`
95
+ - SELL: `SL = bid + |sl|*point`, `TP = bid - |tp|*point`
96
+
97
+ - All calculated prices (including absolute inputs) are normalized to the instrument `digits`.
98
+
99
+ > If you get `Wrong SL (10016)`, check `symbol_info(symbol).stops_level` and multiply by `point` to know the minimal allowed distance.
100
+
101
+ ---
102
+
103
+ ## API Reference
104
+
105
+ ### `class Broker`
106
+
107
+ #### `__init__(self, log, password, server)`
108
+ Initialize MT5, attempt login, and print account info on success.
109
+
110
+ - **log**: login number (int or str)
111
+ - **password**: account password (str)
112
+ - **server**: broker server name (str)
113
+
114
+ #### `login(self, ToEffect=False) -> bool`
115
+ Retrying login loop. If `ToEffect` is `False`, returns immediately on failure.
116
+
117
+ ---
118
+
119
+ ### Market Entry
120
+
121
+ #### `OpenPosition(self, symbol, side, volume, *, sl=None, tp=None, price=None, comment=None, ticket=None, sl_type="absolute", tp_type="absolute")`
122
+ Open a market position.
123
+
124
+ - **symbol**: e.g., `"EURUSD"`
125
+ - **side**: `"buy" | "sell" | "long" | "short"`
126
+ - **volume**: lot size (float)
127
+ - **sl**/**tp**: number (see `sl_type`/`tp_type`)
128
+ - **sl_type**/**tp_type**: `"absolute"` (prices) or `"offset"` (**POINTS**)
129
+ - **price**: optional direct price; if `None`, uses current tick (ask/bid) and retries on transient errors
130
+ - **comment**: optional MT5 order comment
131
+ - **ticket**: existing position id if needed (rarely used for market entry)
132
+
133
+ **Returns**: result of `order_send` (MT5 `TradeResult`)
134
+
135
+ **Examples**:
136
+ ```python
137
+ # Absolute prices
138
+ broker.OpenPosition("XAUUSD", "sell", 0.10, sl=2400.0, tp=2380.0, sl_type="absolute", tp_type="absolute")
139
+
140
+ # Offsets in POINTS
141
+ broker.OpenPosition("EURUSD", "buy", 0.10, sl=1000, tp=1500, sl_type="offset", tp_type="offset")
142
+ ```
143
+
144
+ ---
145
+
146
+ ### Backward‑Compat Wrappers
147
+
148
+ #### `Buy(self, symbol, volume, price=None, *, comment=None, ticket=None)`
149
+ Market BUY via `OpenPosition`.
150
+
151
+ #### `Sell(self, symbol, volume, price=None, *, comment=None, ticket=None)`
152
+ Market SELL via `OpenPosition`.
153
+
154
+ #### `BuySL(self, symbol, volume, sl, price=None, *, comment=None, ticket=None, sl_type="absolute")`
155
+ BUY with SL specified (absolute or offset in points).
156
+
157
+ #### `SellSL(self, symbol, volume, sl, price=None, *, comment=None, ticket=None, sl_type="absolute")`
158
+ SELL with SL specified (absolute or offset in points).
159
+
160
+ ---
161
+
162
+ ### Close & Pending Orders
163
+
164
+ #### `Close(self, symbol, *, comment=None, ticket=None) -> bool`
165
+ Iteratively closes all positions for a **ticket** or for a **symbol** (same filtering semantics as `positions_get`). Returns `False` if nothing to close.
166
+
167
+ #### `SellLimit(self, symbol, volume, stoplimit, price=None, comment=None, ticket=None)`
168
+ Create a SELL LIMIT order at `stoplimit`. If current `bid >= stoplimit`, executes a market SELL immediately for consistency.
169
+
170
+ #### `BuyLimit(self, symbol, volume, stoplimit, price=None, comment=None, ticket=None)`
171
+ Create a BUY LIMIT order at `stoplimit`. If current `ask <= stoplimit`, executes a market BUY immediately.
172
+
173
+ #### `CancelOrders(self, symbol)`
174
+ Cancel all BUY/SELL LIMIT pending orders on the given symbol.
175
+
176
+ #### `Disconnect(self)`
177
+ Shutdown MT5 connection.
178
+
179
+ ---
180
+
181
+ ### Positions Helpers
182
+
183
+ #### `GetPositionsBySymbol(self, symbol: str, as_dict: bool = False) -> list`
184
+ Return all open positions for a symbol. If `as_dict=True`, returns a list of plain dictionaries (ready for JSON/GUI).
185
+
186
+ #### `GetPositions(self, symbol=None, *, ticket=None, as_dict: bool = False) -> list`
187
+ Return positions with the same filter style as `Close()`:
188
+ - `ticket` provided → that single position
189
+ - else `symbol` provided → all for that symbol
190
+ - else → all positions
191
+
192
+ #### `GetPosition(self, symbol=None, *, ticket=None, as_dict: bool = False)`
193
+ Return the first matching position (or `None`). Useful when at most one position is expected.
194
+
195
+ **Example**:
196
+ ```python
197
+ p = broker.GetPosition(symbol="XAUUSD", as_dict=True)
198
+ if p:
199
+ print("Ticket:", p["ticket"], "Type:", "BUY" if p["type"] == 0 else "SELL", "Profit:", p["profit"])
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Error Handling & Retcodes
205
+
206
+ - Known retcodes are mapped in `RetCodes`:
207
+ - `10027`: Enable Algo Trading in MetaTrader5 app
208
+ - `10018`: Market closed
209
+ - `10016`: Wrong SL
210
+
211
+ - For `10027`, a `Ctrl+E` hotkey is issued via `pyautogui` to toggle Algo Trading.
212
+ - For `10016`, retries are **not** attempted (invalid SL/TP).
213
+
214
+ ---
215
+
216
+ ## Advanced Examples
217
+
218
+ ```python
219
+ # 1) BUY with SL absolute price, TP as offset in points
220
+ broker.OpenPosition(
221
+ "US500", "buy", 1.0,
222
+ sl=5780.0, sl_type="absolute",
223
+ tp=200, tp_type="offset"
224
+ )
225
+
226
+ # 2) SELL with both offsets in points
227
+ broker.OpenPosition(
228
+ "EURUSD", "sell", 0.2,
229
+ sl=800, tp=1200,
230
+ sl_type="offset", tp_type="offset"
231
+ )
232
+
233
+ # 3) Get all positions as dicts and filter by profit
234
+ pos = broker.GetPositions(as_dict=True)
235
+ winners = [p for p in pos if p["profit"] > 0]
236
+
237
+ # 4) Close by ticket
238
+ p = broker.GetPosition(symbol="XAUUSD")
239
+ if p:
240
+ broker.Close("XAUUSD", ticket=p.ticket)
241
+
242
+ # 5) Pending orders
243
+ broker.BuyLimit("EURUSD", 0.10, stoplimit=1.10000)
244
+ broker.SellLimit("EURUSD", 0.10, stoplimit=1.12000)
245
+ broker.CancelOrders("EURUSD")
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Notes
251
+
252
+ - Ensure the symbol is visible/active in MT5 Market Watch.
253
+ - Check `stops_level`/`freeze_level` on your broker if SL/TP are rejected:
254
+ ```python
255
+ info = symbol_info("EURUSD")
256
+ print(info.point, info.digits, info.stops_level, info.freeze_level, info.volume_min, info.volume_step)
257
+ ```
258
+ - `volume` must respect broker `volume_min`/`volume_step`.
259
+
260
+ ---
261
+
262
+ ## License
263
+
264
+ CC-BY-NC 4.0
265
+
266
+
267
+
@@ -0,0 +1,250 @@
1
+ # PythonMetaTrader5 [![PyPI Publish](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml) ![PyPI](https://img.shields.io/pypi/v/pythonmetatrader5) ![Python](https://img.shields.io/badge/python-3.6%2B-blue?logo=python&logoColor=white) ![License](https://img.shields.io/badge/license-CC_BY--NC_4.0-lightgrey.svg) [![PyPI Downloads](https://static.pepy.tech/badge/pythonmetatrader5)](https://pepy.tech/projects/pythonmetatrader5)
2
+
3
+ [![Discord](https://img.shields.io/badge/Join_us_on-Discord-5865F2?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/BARYa55KS8)
4
+
5
+
6
+ # MetaTrader5 Python Broker Helper
7
+
8
+ Minimal, production‑ready helper around the official **MetaTrader5** Python package,
9
+ with a single market-entry function and clean handling of **SL/TP as absolute prices or offsets in POINTS**.
10
+ Includes utilities to read positions, close them, and manage pending orders.
11
+
12
+ > Works with: `MetaTrader5`, `loguru`, `pyautogui`
13
+
14
+ ---
15
+
16
+ ## Features
17
+
18
+ - ✅ One function to open market positions: `OpenPosition(...)`
19
+ - ✅ SL/TP can be passed **as absolute prices** or **offsets in POINTS**
20
+ - ✅ Automatic price normalization to instrument `digits`
21
+ - ✅ Consistent error handling (common MT5 retcodes mapped to messages)
22
+ - ✅ Backward‑compat wrappers: `Buy`, `Sell`, `BuySL`, `SellSL`
23
+ - ✅ Position helpers: `GetPositions`, `GetPosition`, `GetPositionsBySymbol`
24
+ - ✅ Closing and pending orders helpers: `Close`, `SellLimit`, `BuyLimit`, `CancelOrders`
25
+
26
+ ---
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install MetaTrader5
32
+ ```
33
+
34
+ > Ensure your MetaTrader 5 terminal is running, logged in, and **Algo Trading** is enabled.
35
+
36
+ ---
37
+
38
+ ## Quick Start
39
+
40
+ ```python
41
+ from PythonMetaTrader5 import Broker
42
+ import time
43
+
44
+ # Login to your account
45
+ broker = Broker(96540048, "PASSWORD", "MetaQuotes-Demo")
46
+ time.sleep(1) # small grace period after login
47
+
48
+ # Open BUY with SL/TP given as OFFSETS IN POINTS
49
+ r = broker.OpenPosition(
50
+ "EURUSD", "buy", 0.10,
51
+ sl=1000, sl_type="offset", # 1000 points (≈ 100 pips on 5-digit symbol)
52
+ tp=1500, tp_type="offset"
53
+ )
54
+
55
+ # Read positions for a symbol
56
+ xau_positions = broker.GetPositionsBySymbol("XAUUSD", as_dict=True)
57
+
58
+ # Close all positions on a symbol
59
+ broker.Close("EURUSD")
60
+
61
+ # Cancel pending limit orders on a symbol
62
+ broker.CancelOrders("EURUSD")
63
+
64
+ # Graceful shutdown
65
+ broker.Disconnect()
66
+ ```
67
+
68
+ ---
69
+
70
+ ## SL/TP Semantics (Important)
71
+
72
+ - `sl_type` / `tp_type`:
73
+ - `"absolute"` → you pass **absolute prices** (e.g., `1.23456`)
74
+ - `"offset"` → you pass **offsets in POINTS** (converted using `symbol_info(symbol).point`)
75
+
76
+ - Offsets are applied from the **current tick price** (`ask` for BUY, `bid` for SELL):
77
+ - BUY : `SL = ask - |sl|*point`, `TP = ask + |tp|*point`
78
+ - SELL: `SL = bid + |sl|*point`, `TP = bid - |tp|*point`
79
+
80
+ - All calculated prices (including absolute inputs) are normalized to the instrument `digits`.
81
+
82
+ > If you get `Wrong SL (10016)`, check `symbol_info(symbol).stops_level` and multiply by `point` to know the minimal allowed distance.
83
+
84
+ ---
85
+
86
+ ## API Reference
87
+
88
+ ### `class Broker`
89
+
90
+ #### `__init__(self, log, password, server)`
91
+ Initialize MT5, attempt login, and print account info on success.
92
+
93
+ - **log**: login number (int or str)
94
+ - **password**: account password (str)
95
+ - **server**: broker server name (str)
96
+
97
+ #### `login(self, ToEffect=False) -> bool`
98
+ Retrying login loop. If `ToEffect` is `False`, returns immediately on failure.
99
+
100
+ ---
101
+
102
+ ### Market Entry
103
+
104
+ #### `OpenPosition(self, symbol, side, volume, *, sl=None, tp=None, price=None, comment=None, ticket=None, sl_type="absolute", tp_type="absolute")`
105
+ Open a market position.
106
+
107
+ - **symbol**: e.g., `"EURUSD"`
108
+ - **side**: `"buy" | "sell" | "long" | "short"`
109
+ - **volume**: lot size (float)
110
+ - **sl**/**tp**: number (see `sl_type`/`tp_type`)
111
+ - **sl_type**/**tp_type**: `"absolute"` (prices) or `"offset"` (**POINTS**)
112
+ - **price**: optional direct price; if `None`, uses current tick (ask/bid) and retries on transient errors
113
+ - **comment**: optional MT5 order comment
114
+ - **ticket**: existing position id if needed (rarely used for market entry)
115
+
116
+ **Returns**: result of `order_send` (MT5 `TradeResult`)
117
+
118
+ **Examples**:
119
+ ```python
120
+ # Absolute prices
121
+ broker.OpenPosition("XAUUSD", "sell", 0.10, sl=2400.0, tp=2380.0, sl_type="absolute", tp_type="absolute")
122
+
123
+ # Offsets in POINTS
124
+ broker.OpenPosition("EURUSD", "buy", 0.10, sl=1000, tp=1500, sl_type="offset", tp_type="offset")
125
+ ```
126
+
127
+ ---
128
+
129
+ ### Backward‑Compat Wrappers
130
+
131
+ #### `Buy(self, symbol, volume, price=None, *, comment=None, ticket=None)`
132
+ Market BUY via `OpenPosition`.
133
+
134
+ #### `Sell(self, symbol, volume, price=None, *, comment=None, ticket=None)`
135
+ Market SELL via `OpenPosition`.
136
+
137
+ #### `BuySL(self, symbol, volume, sl, price=None, *, comment=None, ticket=None, sl_type="absolute")`
138
+ BUY with SL specified (absolute or offset in points).
139
+
140
+ #### `SellSL(self, symbol, volume, sl, price=None, *, comment=None, ticket=None, sl_type="absolute")`
141
+ SELL with SL specified (absolute or offset in points).
142
+
143
+ ---
144
+
145
+ ### Close & Pending Orders
146
+
147
+ #### `Close(self, symbol, *, comment=None, ticket=None) -> bool`
148
+ Iteratively closes all positions for a **ticket** or for a **symbol** (same filtering semantics as `positions_get`). Returns `False` if nothing to close.
149
+
150
+ #### `SellLimit(self, symbol, volume, stoplimit, price=None, comment=None, ticket=None)`
151
+ Create a SELL LIMIT order at `stoplimit`. If current `bid >= stoplimit`, executes a market SELL immediately for consistency.
152
+
153
+ #### `BuyLimit(self, symbol, volume, stoplimit, price=None, comment=None, ticket=None)`
154
+ Create a BUY LIMIT order at `stoplimit`. If current `ask <= stoplimit`, executes a market BUY immediately.
155
+
156
+ #### `CancelOrders(self, symbol)`
157
+ Cancel all BUY/SELL LIMIT pending orders on the given symbol.
158
+
159
+ #### `Disconnect(self)`
160
+ Shutdown MT5 connection.
161
+
162
+ ---
163
+
164
+ ### Positions Helpers
165
+
166
+ #### `GetPositionsBySymbol(self, symbol: str, as_dict: bool = False) -> list`
167
+ Return all open positions for a symbol. If `as_dict=True`, returns a list of plain dictionaries (ready for JSON/GUI).
168
+
169
+ #### `GetPositions(self, symbol=None, *, ticket=None, as_dict: bool = False) -> list`
170
+ Return positions with the same filter style as `Close()`:
171
+ - `ticket` provided → that single position
172
+ - else `symbol` provided → all for that symbol
173
+ - else → all positions
174
+
175
+ #### `GetPosition(self, symbol=None, *, ticket=None, as_dict: bool = False)`
176
+ Return the first matching position (or `None`). Useful when at most one position is expected.
177
+
178
+ **Example**:
179
+ ```python
180
+ p = broker.GetPosition(symbol="XAUUSD", as_dict=True)
181
+ if p:
182
+ print("Ticket:", p["ticket"], "Type:", "BUY" if p["type"] == 0 else "SELL", "Profit:", p["profit"])
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Error Handling & Retcodes
188
+
189
+ - Known retcodes are mapped in `RetCodes`:
190
+ - `10027`: Enable Algo Trading in MetaTrader5 app
191
+ - `10018`: Market closed
192
+ - `10016`: Wrong SL
193
+
194
+ - For `10027`, a `Ctrl+E` hotkey is issued via `pyautogui` to toggle Algo Trading.
195
+ - For `10016`, retries are **not** attempted (invalid SL/TP).
196
+
197
+ ---
198
+
199
+ ## Advanced Examples
200
+
201
+ ```python
202
+ # 1) BUY with SL absolute price, TP as offset in points
203
+ broker.OpenPosition(
204
+ "US500", "buy", 1.0,
205
+ sl=5780.0, sl_type="absolute",
206
+ tp=200, tp_type="offset"
207
+ )
208
+
209
+ # 2) SELL with both offsets in points
210
+ broker.OpenPosition(
211
+ "EURUSD", "sell", 0.2,
212
+ sl=800, tp=1200,
213
+ sl_type="offset", tp_type="offset"
214
+ )
215
+
216
+ # 3) Get all positions as dicts and filter by profit
217
+ pos = broker.GetPositions(as_dict=True)
218
+ winners = [p for p in pos if p["profit"] > 0]
219
+
220
+ # 4) Close by ticket
221
+ p = broker.GetPosition(symbol="XAUUSD")
222
+ if p:
223
+ broker.Close("XAUUSD", ticket=p.ticket)
224
+
225
+ # 5) Pending orders
226
+ broker.BuyLimit("EURUSD", 0.10, stoplimit=1.10000)
227
+ broker.SellLimit("EURUSD", 0.10, stoplimit=1.12000)
228
+ broker.CancelOrders("EURUSD")
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Notes
234
+
235
+ - Ensure the symbol is visible/active in MT5 Market Watch.
236
+ - Check `stops_level`/`freeze_level` on your broker if SL/TP are rejected:
237
+ ```python
238
+ info = symbol_info("EURUSD")
239
+ print(info.point, info.digits, info.stops_level, info.freeze_level, info.volume_min, info.volume_step)
240
+ ```
241
+ - `volume` must respect broker `volume_min`/`volume_step`.
242
+
243
+ ---
244
+
245
+ ## License
246
+
247
+ CC-BY-NC 4.0
248
+
249
+
250
+
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "PythonMetaTrader5"
7
- version = "2.02"
7
+ version = "2.3.2"
8
8
  description = "Connect MT5 with Python"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.6"
@@ -33,3 +33,7 @@ where = ["src"]
33
33
 
34
34
 
35
35
 
36
+
37
+
38
+
39
+
@@ -0,0 +1,267 @@
1
+ Metadata-Version: 2.4
2
+ Name: PythonMetaTrader5
3
+ Version: 2.3.2
4
+ Summary: Connect MT5 with Python
5
+ Author-email: Wiktor Jelen <wiktorjn@gmail.com>
6
+ License: CC BY-NC 4.0
7
+ Project-URL: Homepage, https://github.com/Akinzou/MetaTrader5-Python
8
+ Project-URL: Bug Tracker, https://github.com/Akinzou/MetaTrader5-Python/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: MetaTrader5
15
+ Requires-Dist: loguru
16
+ Requires-Dist: pyautogui
17
+
18
+ # PythonMetaTrader5 [![PyPI Publish](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml) ![PyPI](https://img.shields.io/pypi/v/pythonmetatrader5) ![Python](https://img.shields.io/badge/python-3.6%2B-blue?logo=python&logoColor=white) ![License](https://img.shields.io/badge/license-CC_BY--NC_4.0-lightgrey.svg) [![PyPI Downloads](https://static.pepy.tech/badge/pythonmetatrader5)](https://pepy.tech/projects/pythonmetatrader5)
19
+
20
+ [![Discord](https://img.shields.io/badge/Join_us_on-Discord-5865F2?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/BARYa55KS8)
21
+
22
+
23
+ # MetaTrader5 Python Broker Helper
24
+
25
+ Minimal, production‑ready helper around the official **MetaTrader5** Python package,
26
+ with a single market-entry function and clean handling of **SL/TP as absolute prices or offsets in POINTS**.
27
+ Includes utilities to read positions, close them, and manage pending orders.
28
+
29
+ > Works with: `MetaTrader5`, `loguru`, `pyautogui`
30
+
31
+ ---
32
+
33
+ ## Features
34
+
35
+ - ✅ One function to open market positions: `OpenPosition(...)`
36
+ - ✅ SL/TP can be passed **as absolute prices** or **offsets in POINTS**
37
+ - ✅ Automatic price normalization to instrument `digits`
38
+ - ✅ Consistent error handling (common MT5 retcodes mapped to messages)
39
+ - ✅ Backward‑compat wrappers: `Buy`, `Sell`, `BuySL`, `SellSL`
40
+ - ✅ Position helpers: `GetPositions`, `GetPosition`, `GetPositionsBySymbol`
41
+ - ✅ Closing and pending orders helpers: `Close`, `SellLimit`, `BuyLimit`, `CancelOrders`
42
+
43
+ ---
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install MetaTrader5
49
+ ```
50
+
51
+ > Ensure your MetaTrader 5 terminal is running, logged in, and **Algo Trading** is enabled.
52
+
53
+ ---
54
+
55
+ ## Quick Start
56
+
57
+ ```python
58
+ from PythonMetaTrader5 import Broker
59
+ import time
60
+
61
+ # Login to your account
62
+ broker = Broker(96540048, "PASSWORD", "MetaQuotes-Demo")
63
+ time.sleep(1) # small grace period after login
64
+
65
+ # Open BUY with SL/TP given as OFFSETS IN POINTS
66
+ r = broker.OpenPosition(
67
+ "EURUSD", "buy", 0.10,
68
+ sl=1000, sl_type="offset", # 1000 points (≈ 100 pips on 5-digit symbol)
69
+ tp=1500, tp_type="offset"
70
+ )
71
+
72
+ # Read positions for a symbol
73
+ xau_positions = broker.GetPositionsBySymbol("XAUUSD", as_dict=True)
74
+
75
+ # Close all positions on a symbol
76
+ broker.Close("EURUSD")
77
+
78
+ # Cancel pending limit orders on a symbol
79
+ broker.CancelOrders("EURUSD")
80
+
81
+ # Graceful shutdown
82
+ broker.Disconnect()
83
+ ```
84
+
85
+ ---
86
+
87
+ ## SL/TP Semantics (Important)
88
+
89
+ - `sl_type` / `tp_type`:
90
+ - `"absolute"` → you pass **absolute prices** (e.g., `1.23456`)
91
+ - `"offset"` → you pass **offsets in POINTS** (converted using `symbol_info(symbol).point`)
92
+
93
+ - Offsets are applied from the **current tick price** (`ask` for BUY, `bid` for SELL):
94
+ - BUY : `SL = ask - |sl|*point`, `TP = ask + |tp|*point`
95
+ - SELL: `SL = bid + |sl|*point`, `TP = bid - |tp|*point`
96
+
97
+ - All calculated prices (including absolute inputs) are normalized to the instrument `digits`.
98
+
99
+ > If you get `Wrong SL (10016)`, check `symbol_info(symbol).stops_level` and multiply by `point` to know the minimal allowed distance.
100
+
101
+ ---
102
+
103
+ ## API Reference
104
+
105
+ ### `class Broker`
106
+
107
+ #### `__init__(self, log, password, server)`
108
+ Initialize MT5, attempt login, and print account info on success.
109
+
110
+ - **log**: login number (int or str)
111
+ - **password**: account password (str)
112
+ - **server**: broker server name (str)
113
+
114
+ #### `login(self, ToEffect=False) -> bool`
115
+ Retrying login loop. If `ToEffect` is `False`, returns immediately on failure.
116
+
117
+ ---
118
+
119
+ ### Market Entry
120
+
121
+ #### `OpenPosition(self, symbol, side, volume, *, sl=None, tp=None, price=None, comment=None, ticket=None, sl_type="absolute", tp_type="absolute")`
122
+ Open a market position.
123
+
124
+ - **symbol**: e.g., `"EURUSD"`
125
+ - **side**: `"buy" | "sell" | "long" | "short"`
126
+ - **volume**: lot size (float)
127
+ - **sl**/**tp**: number (see `sl_type`/`tp_type`)
128
+ - **sl_type**/**tp_type**: `"absolute"` (prices) or `"offset"` (**POINTS**)
129
+ - **price**: optional direct price; if `None`, uses current tick (ask/bid) and retries on transient errors
130
+ - **comment**: optional MT5 order comment
131
+ - **ticket**: existing position id if needed (rarely used for market entry)
132
+
133
+ **Returns**: result of `order_send` (MT5 `TradeResult`)
134
+
135
+ **Examples**:
136
+ ```python
137
+ # Absolute prices
138
+ broker.OpenPosition("XAUUSD", "sell", 0.10, sl=2400.0, tp=2380.0, sl_type="absolute", tp_type="absolute")
139
+
140
+ # Offsets in POINTS
141
+ broker.OpenPosition("EURUSD", "buy", 0.10, sl=1000, tp=1500, sl_type="offset", tp_type="offset")
142
+ ```
143
+
144
+ ---
145
+
146
+ ### Backward‑Compat Wrappers
147
+
148
+ #### `Buy(self, symbol, volume, price=None, *, comment=None, ticket=None)`
149
+ Market BUY via `OpenPosition`.
150
+
151
+ #### `Sell(self, symbol, volume, price=None, *, comment=None, ticket=None)`
152
+ Market SELL via `OpenPosition`.
153
+
154
+ #### `BuySL(self, symbol, volume, sl, price=None, *, comment=None, ticket=None, sl_type="absolute")`
155
+ BUY with SL specified (absolute or offset in points).
156
+
157
+ #### `SellSL(self, symbol, volume, sl, price=None, *, comment=None, ticket=None, sl_type="absolute")`
158
+ SELL with SL specified (absolute or offset in points).
159
+
160
+ ---
161
+
162
+ ### Close & Pending Orders
163
+
164
+ #### `Close(self, symbol, *, comment=None, ticket=None) -> bool`
165
+ Iteratively closes all positions for a **ticket** or for a **symbol** (same filtering semantics as `positions_get`). Returns `False` if nothing to close.
166
+
167
+ #### `SellLimit(self, symbol, volume, stoplimit, price=None, comment=None, ticket=None)`
168
+ Create a SELL LIMIT order at `stoplimit`. If current `bid >= stoplimit`, executes a market SELL immediately for consistency.
169
+
170
+ #### `BuyLimit(self, symbol, volume, stoplimit, price=None, comment=None, ticket=None)`
171
+ Create a BUY LIMIT order at `stoplimit`. If current `ask <= stoplimit`, executes a market BUY immediately.
172
+
173
+ #### `CancelOrders(self, symbol)`
174
+ Cancel all BUY/SELL LIMIT pending orders on the given symbol.
175
+
176
+ #### `Disconnect(self)`
177
+ Shutdown MT5 connection.
178
+
179
+ ---
180
+
181
+ ### Positions Helpers
182
+
183
+ #### `GetPositionsBySymbol(self, symbol: str, as_dict: bool = False) -> list`
184
+ Return all open positions for a symbol. If `as_dict=True`, returns a list of plain dictionaries (ready for JSON/GUI).
185
+
186
+ #### `GetPositions(self, symbol=None, *, ticket=None, as_dict: bool = False) -> list`
187
+ Return positions with the same filter style as `Close()`:
188
+ - `ticket` provided → that single position
189
+ - else `symbol` provided → all for that symbol
190
+ - else → all positions
191
+
192
+ #### `GetPosition(self, symbol=None, *, ticket=None, as_dict: bool = False)`
193
+ Return the first matching position (or `None`). Useful when at most one position is expected.
194
+
195
+ **Example**:
196
+ ```python
197
+ p = broker.GetPosition(symbol="XAUUSD", as_dict=True)
198
+ if p:
199
+ print("Ticket:", p["ticket"], "Type:", "BUY" if p["type"] == 0 else "SELL", "Profit:", p["profit"])
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Error Handling & Retcodes
205
+
206
+ - Known retcodes are mapped in `RetCodes`:
207
+ - `10027`: Enable Algo Trading in MetaTrader5 app
208
+ - `10018`: Market closed
209
+ - `10016`: Wrong SL
210
+
211
+ - For `10027`, a `Ctrl+E` hotkey is issued via `pyautogui` to toggle Algo Trading.
212
+ - For `10016`, retries are **not** attempted (invalid SL/TP).
213
+
214
+ ---
215
+
216
+ ## Advanced Examples
217
+
218
+ ```python
219
+ # 1) BUY with SL absolute price, TP as offset in points
220
+ broker.OpenPosition(
221
+ "US500", "buy", 1.0,
222
+ sl=5780.0, sl_type="absolute",
223
+ tp=200, tp_type="offset"
224
+ )
225
+
226
+ # 2) SELL with both offsets in points
227
+ broker.OpenPosition(
228
+ "EURUSD", "sell", 0.2,
229
+ sl=800, tp=1200,
230
+ sl_type="offset", tp_type="offset"
231
+ )
232
+
233
+ # 3) Get all positions as dicts and filter by profit
234
+ pos = broker.GetPositions(as_dict=True)
235
+ winners = [p for p in pos if p["profit"] > 0]
236
+
237
+ # 4) Close by ticket
238
+ p = broker.GetPosition(symbol="XAUUSD")
239
+ if p:
240
+ broker.Close("XAUUSD", ticket=p.ticket)
241
+
242
+ # 5) Pending orders
243
+ broker.BuyLimit("EURUSD", 0.10, stoplimit=1.10000)
244
+ broker.SellLimit("EURUSD", 0.10, stoplimit=1.12000)
245
+ broker.CancelOrders("EURUSD")
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Notes
251
+
252
+ - Ensure the symbol is visible/active in MT5 Market Watch.
253
+ - Check `stops_level`/`freeze_level` on your broker if SL/TP are rejected:
254
+ ```python
255
+ info = symbol_info("EURUSD")
256
+ print(info.point, info.digits, info.stops_level, info.freeze_level, info.volume_min, info.volume_step)
257
+ ```
258
+ - `volume` must respect broker `volume_min`/`volume_step`.
259
+
260
+ ---
261
+
262
+ ## License
263
+
264
+ CC-BY-NC 4.0
265
+
266
+
267
+
@@ -1,29 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: PythonMetaTrader5
3
- Version: 2.2
4
- Summary: Connect MT5 with Python
5
- Author-email: Wiktor Jelen <wiktorjn@gmail.com>
6
- License: CC BY-NC 4.0
7
- Project-URL: Homepage, https://github.com/Akinzou/MetaTrader5-Python
8
- Project-URL: Bug Tracker, https://github.com/Akinzou/MetaTrader5-Python/issues
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
- Requires-Python: >=3.6
13
- Description-Content-Type: text/markdown
14
- Requires-Dist: MetaTrader5
15
- Requires-Dist: loguru
16
- Requires-Dist: pyautogui
17
-
18
- # PythonMetaTrader5 [![PyPI Publish](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml) ![PyPI](https://img.shields.io/pypi/v/pythonmetatrader5) ![Python](https://img.shields.io/badge/python-3.6%2B-blue?logo=python&logoColor=white) ![License](https://img.shields.io/badge/license-CC_BY--NC_4.0-lightgrey.svg) [![PyPI Downloads](https://static.pepy.tech/badge/pythonmetatrader5)](https://pepy.tech/projects/pythonmetatrader5)
19
-
20
- [![Discord](https://img.shields.io/badge/Join_us_on-Discord-5865F2?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/BARYa55KS8)
21
-
22
-
23
- MetaTrader 5
24
- This Python library enables you to connect with the MetaTrader 5 trading platform and interact with its features using Python. It allows executing trading operations, fetching market data, receiving notifications, and more.
25
-
26
- Soon -> huge update
27
-
28
-
29
-
@@ -1,12 +0,0 @@
1
- # PythonMetaTrader5 [![PyPI Publish](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml) ![PyPI](https://img.shields.io/pypi/v/pythonmetatrader5) ![Python](https://img.shields.io/badge/python-3.6%2B-blue?logo=python&logoColor=white) ![License](https://img.shields.io/badge/license-CC_BY--NC_4.0-lightgrey.svg) [![PyPI Downloads](https://static.pepy.tech/badge/pythonmetatrader5)](https://pepy.tech/projects/pythonmetatrader5)
2
-
3
- [![Discord](https://img.shields.io/badge/Join_us_on-Discord-5865F2?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/BARYa55KS8)
4
-
5
-
6
- MetaTrader 5
7
- This Python library enables you to connect with the MetaTrader 5 trading platform and interact with its features using Python. It allows executing trading operations, fetching market data, receiving notifications, and more.
8
-
9
- Soon -> huge update
10
-
11
-
12
-
@@ -1,29 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: PythonMetaTrader5
3
- Version: 2.2
4
- Summary: Connect MT5 with Python
5
- Author-email: Wiktor Jelen <wiktorjn@gmail.com>
6
- License: CC BY-NC 4.0
7
- Project-URL: Homepage, https://github.com/Akinzou/MetaTrader5-Python
8
- Project-URL: Bug Tracker, https://github.com/Akinzou/MetaTrader5-Python/issues
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
- Requires-Python: >=3.6
13
- Description-Content-Type: text/markdown
14
- Requires-Dist: MetaTrader5
15
- Requires-Dist: loguru
16
- Requires-Dist: pyautogui
17
-
18
- # PythonMetaTrader5 [![PyPI Publish](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Akinzou/MetaTrader5-Python/actions/workflows/python-publish.yml) ![PyPI](https://img.shields.io/pypi/v/pythonmetatrader5) ![Python](https://img.shields.io/badge/python-3.6%2B-blue?logo=python&logoColor=white) ![License](https://img.shields.io/badge/license-CC_BY--NC_4.0-lightgrey.svg) [![PyPI Downloads](https://static.pepy.tech/badge/pythonmetatrader5)](https://pepy.tech/projects/pythonmetatrader5)
19
-
20
- [![Discord](https://img.shields.io/badge/Join_us_on-Discord-5865F2?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/BARYa55KS8)
21
-
22
-
23
- MetaTrader 5
24
- This Python library enables you to connect with the MetaTrader 5 trading platform and interact with its features using Python. It allows executing trading operations, fetching market data, receiving notifications, and more.
25
-
26
- Soon -> huge update
27
-
28
-
29
-