pdmt5 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl
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.
- pdmt5/trading.py +18 -7
- pdmt5/utils.py +2 -2
- {pdmt5-0.2.0.dist-info → pdmt5-0.2.2.dist-info}/METADATA +3 -3
- pdmt5-0.2.2.dist-info/RECORD +9 -0
- {pdmt5-0.2.0.dist-info → pdmt5-0.2.2.dist-info}/WHEEL +1 -1
- pdmt5-0.2.0.dist-info/RECORD +0 -9
- {pdmt5-0.2.0.dist-info → pdmt5-0.2.2.dist-info}/licenses/LICENSE +0 -0
pdmt5/trading.py
CHANGED
|
@@ -131,6 +131,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
131
131
|
self,
|
|
132
132
|
symbol: str | None = None,
|
|
133
133
|
order_filling_mode: Literal["IOC", "FOK", "RETURN"] = "IOC",
|
|
134
|
+
raise_on_error: bool = False,
|
|
134
135
|
dry_run: bool = False,
|
|
135
136
|
**kwargs: Any, # noqa: ANN401
|
|
136
137
|
) -> list[dict[str, Any]]:
|
|
@@ -139,6 +140,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
139
140
|
Args:
|
|
140
141
|
symbol: Optional symbol filter.
|
|
141
142
|
order_filling_mode: Order filling mode, either "IOC", "FOK", or "RETURN".
|
|
143
|
+
raise_on_error: If True, raise an exception on error.
|
|
142
144
|
dry_run: If True, only check the order without sending it.
|
|
143
145
|
**kwargs: Additional keyword arguments for request parameters.
|
|
144
146
|
|
|
@@ -170,6 +172,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
170
172
|
"position": p["ticket"],
|
|
171
173
|
**kwargs,
|
|
172
174
|
},
|
|
175
|
+
raise_on_error=raise_on_error,
|
|
173
176
|
dry_run=dry_run,
|
|
174
177
|
)
|
|
175
178
|
for p in positions_dict
|
|
@@ -225,6 +228,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
225
228
|
order_side: Literal["BUY", "SELL"],
|
|
226
229
|
order_filling_mode: Literal["IOC", "FOK", "RETURN"] = "IOC",
|
|
227
230
|
order_time_mode: Literal["GTC", "DAY", "SPECIFIED", "SPECIFIED_DAY"] = "GTC",
|
|
231
|
+
raise_on_error: bool = False,
|
|
228
232
|
dry_run: bool = False,
|
|
229
233
|
**kwargs: Any, # noqa: ANN401
|
|
230
234
|
) -> dict[str, Any]:
|
|
@@ -237,6 +241,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
237
241
|
order_filling_mode: Order filling mode, either "IOC", "FOK", or "RETURN".
|
|
238
242
|
order_time_mode: Order time mode, either "GTC", "DAY", "SPECIFIED",
|
|
239
243
|
or "SPECIFIED_DAY".
|
|
244
|
+
raise_on_error: If True, raise an error on operation failure.
|
|
240
245
|
dry_run: If True, only check the order without sending it.
|
|
241
246
|
**kwargs: Additional keyword arguments for request parameters.
|
|
242
247
|
|
|
@@ -256,6 +261,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
256
261
|
"type_time": getattr(self.mt5, f"ORDER_TIME_{order_time_mode.upper()}"),
|
|
257
262
|
**kwargs,
|
|
258
263
|
},
|
|
264
|
+
raise_on_error=raise_on_error,
|
|
259
265
|
dry_run=dry_run,
|
|
260
266
|
)
|
|
261
267
|
|
|
@@ -265,6 +271,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
265
271
|
stop_loss: float | None = None,
|
|
266
272
|
take_profit: float | None = None,
|
|
267
273
|
tickets: list[int] | None = None,
|
|
274
|
+
raise_on_error: bool = False,
|
|
268
275
|
dry_run: bool = False,
|
|
269
276
|
**kwargs: Any, # noqa: ANN401
|
|
270
277
|
) -> list[dict[str, Any]]:
|
|
@@ -276,6 +283,7 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
276
283
|
take_profit: New Take Profit price. If None, it will not be changed.
|
|
277
284
|
tickets: List of position tickets to filter positions. If None, all open
|
|
278
285
|
positions for the symbol will be considered.
|
|
286
|
+
raise_on_error: If True, raise an error on operation failure.
|
|
279
287
|
dry_run: If True, only check the order without sending it.
|
|
280
288
|
**kwargs: Additional keyword arguments for request parameters.
|
|
281
289
|
|
|
@@ -324,7 +332,9 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
324
332
|
tp,
|
|
325
333
|
)
|
|
326
334
|
return [
|
|
327
|
-
self._send_or_check_order(
|
|
335
|
+
self._send_or_check_order(
|
|
336
|
+
request=r, raise_on_error=raise_on_error, dry_run=dry_run
|
|
337
|
+
)
|
|
328
338
|
for r in order_requests
|
|
329
339
|
]
|
|
330
340
|
else:
|
|
@@ -579,30 +589,31 @@ class Mt5TradingClient(Mt5DataClient):
|
|
|
579
589
|
price=symbol_info_tick["bid"],
|
|
580
590
|
)
|
|
581
591
|
result = (
|
|
582
|
-
positions_df
|
|
592
|
+
positions_df
|
|
593
|
+
.assign(
|
|
583
594
|
elapsed_seconds=lambda d: (
|
|
584
595
|
symbol_info_tick["time"] - d["time"]
|
|
585
596
|
).dt.total_seconds(),
|
|
586
597
|
underlier_increase_ratio=lambda d: (
|
|
587
598
|
d["price_current"] / d["price_open"] - 1
|
|
588
599
|
),
|
|
589
|
-
buy=lambda d:
|
|
590
|
-
sell=lambda d:
|
|
600
|
+
buy=lambda d: d["type"] == self.mt5.POSITION_TYPE_BUY,
|
|
601
|
+
sell=lambda d: d["type"] == self.mt5.POSITION_TYPE_SELL,
|
|
591
602
|
)
|
|
592
603
|
.assign(
|
|
593
604
|
buy_i=lambda d: d["buy"].astype(int),
|
|
594
605
|
sell_i=lambda d: d["sell"].astype(int),
|
|
595
606
|
)
|
|
596
607
|
.assign(
|
|
597
|
-
sign=lambda d:
|
|
608
|
+
sign=lambda d: d["buy_i"] - d["sell_i"],
|
|
598
609
|
margin=lambda d: (
|
|
599
610
|
(d["buy_i"] * ask_margin + d["sell_i"] * bid_margin)
|
|
600
611
|
* d["volume"]
|
|
601
612
|
),
|
|
602
613
|
)
|
|
603
614
|
.assign(
|
|
604
|
-
signed_volume=lambda d:
|
|
605
|
-
signed_margin=lambda d:
|
|
615
|
+
signed_volume=lambda d: d["volume"] * d["sign"],
|
|
616
|
+
signed_margin=lambda d: d["margin"] * d["sign"],
|
|
606
617
|
underlier_profit_ratio=lambda d: (
|
|
607
618
|
d["underlier_increase_ratio"] * d["sign"]
|
|
608
619
|
),
|
pdmt5/utils.py
CHANGED
|
@@ -87,9 +87,9 @@ def _convert_time_columns_in_df(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
87
87
|
new_df = df.copy()
|
|
88
88
|
for c in new_df.columns:
|
|
89
89
|
if c.startswith("time_") and c.endswith("_msc"):
|
|
90
|
-
new_df[c] = pd.to_datetime(new_df[c], unit="ms")
|
|
90
|
+
new_df[c] = pd.to_datetime(new_df[c], unit="ms").astype("datetime64[ns]")
|
|
91
91
|
elif c == "time" or c.startswith("time_"):
|
|
92
|
-
new_df[c] = pd.to_datetime(new_df[c], unit="s")
|
|
92
|
+
new_df[c] = pd.to_datetime(new_df[c], unit="s").astype("datetime64[ns]")
|
|
93
93
|
return new_df
|
|
94
94
|
|
|
95
95
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pdmt5
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Pandas-based data handler for MetaTrader 5
|
|
5
5
|
Project-URL: Repository, https://github.com/dceoy/pdmt5.git
|
|
6
6
|
Author-email: dceoy <dceoy@users.noreply.github.com>
|
|
@@ -15,7 +15,7 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
17
|
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
18
|
-
Requires-Python:
|
|
18
|
+
Requires-Python: <3.14,>=3.11
|
|
19
19
|
Requires-Dist: metatrader5>=5.0.4424; sys_platform == 'win32'
|
|
20
20
|
Requires-Dist: pandas>=2.2.2
|
|
21
21
|
Requires-Dist: pydantic>=2.9.0
|
|
@@ -339,7 +339,7 @@ with Mt5TradingClient(config=config) as trader:
|
|
|
339
339
|
sell_margin = trader.calculate_minimum_order_margin("EURUSD", "SELL")
|
|
340
340
|
print(f"Minimum BUY margin: {buy_margin['margin']} (volume: {buy_margin['volume']})")
|
|
341
341
|
print(f"Minimum SELL margin: {sell_margin['margin']} (volume: {sell_margin['volume']})")
|
|
342
|
-
|
|
342
|
+
|
|
343
343
|
# Calculate volume by margin
|
|
344
344
|
available_margin = 1000.0
|
|
345
345
|
max_buy_volume = trader.calculate_volume_by_margin("EURUSD", available_margin, "BUY")
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
pdmt5/__init__.py,sha256=QbSFrsi7_bgFzb-ma4DmmUjR90UvrqKMnRZq1wPRmoI,446
|
|
2
|
+
pdmt5/dataframe.py,sha256=rUWtR23hrXBdBqzJhbOlIemNy73RrjSTZZJUhwoL6io,38084
|
|
3
|
+
pdmt5/mt5.py,sha256=KgxHapIrh5b4L0wIOAQIjfXNZafalihbFrh9fhYHmrI,32254
|
|
4
|
+
pdmt5/trading.py,sha256=OFBkONLTrut9aWPvi0-JJMVdoaZBFEsVIC8ZrErqfY8,25576
|
|
5
|
+
pdmt5/utils.py,sha256=1-NDVVLSkwgPWfGhwWMeYphnFwi8vCLo_UCL5KAO-uQ,3963
|
|
6
|
+
pdmt5-0.2.2.dist-info/METADATA,sha256=VO8I_fkEFjpzo_TL8sQVHqgGhm9le3cA9KHcDyPwHxM,16096
|
|
7
|
+
pdmt5-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
8
|
+
pdmt5-0.2.2.dist-info/licenses/LICENSE,sha256=iABrdaUGOBWLYotFupB_PGe8arV5o7rVhn-_vK6P704,1073
|
|
9
|
+
pdmt5-0.2.2.dist-info/RECORD,,
|
pdmt5-0.2.0.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
pdmt5/__init__.py,sha256=QbSFrsi7_bgFzb-ma4DmmUjR90UvrqKMnRZq1wPRmoI,446
|
|
2
|
-
pdmt5/dataframe.py,sha256=rUWtR23hrXBdBqzJhbOlIemNy73RrjSTZZJUhwoL6io,38084
|
|
3
|
-
pdmt5/mt5.py,sha256=KgxHapIrh5b4L0wIOAQIjfXNZafalihbFrh9fhYHmrI,32254
|
|
4
|
-
pdmt5/trading.py,sha256=TprWMtocw_eP5u4fVA6yflVk7Rd0-GL0kymM18YuiR4,25070
|
|
5
|
-
pdmt5/utils.py,sha256=Ll5Q3OE5h1A_sZ_qVEnOPGniFlT6_MmHfuu0zqeLdeU,3913
|
|
6
|
-
pdmt5-0.2.0.dist-info/METADATA,sha256=DmVhjOtTOivrig_YhvbVzqvunGHNx9lZAG1Y6XLzAGI,16094
|
|
7
|
-
pdmt5-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
8
|
-
pdmt5-0.2.0.dist-info/licenses/LICENSE,sha256=iABrdaUGOBWLYotFupB_PGe8arV5o7rVhn-_vK6P704,1073
|
|
9
|
-
pdmt5-0.2.0.dist-info/RECORD,,
|
|
File without changes
|