mt5cli 0.9.6__tar.gz → 0.9.7__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.
- {mt5cli-0.9.6 → mt5cli-0.9.7}/PKG-INFO +9 -2
- {mt5cli-0.9.6 → mt5cli-0.9.7}/README.md +6 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/index.md +6 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/utils.py +9 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/pyproject.toml +5 -2
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_contracts.py +22 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_utils.py +12 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/uv.lock +10 -3
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/local-qa/SKILL.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/local-qa/scripts/qa.sh +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/mt5cli/SKILL.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.agents/skills/pr-feedback-triage/SKILL.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.claude/agents/codex.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.claude/settings.json +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/FUNDING.yml +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/dependabot.yml +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/renovate.json +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/workflows/ci.yml +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/workflows/claude.yml +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.github/workflows/release.yml +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/.gitignore +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/AGENTS.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/CLAUDE.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/LICENSE +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/cli.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/client.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/converters.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/exceptions.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/history.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/index.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/public-contract.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/schemas.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/sdk.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/storage.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/trading.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/docs/api/utils.md +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mkdocs.yml +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/__init__.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/__main__.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/cli.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/client.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/contract.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/converters.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/exceptions.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/history.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/retry.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/schemas.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/sdk.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/storage.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/mt5cli/trading.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/__init__.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/conftest.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_cli.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_history.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_sdk.py +0 -0
- {mt5cli-0.9.6 → mt5cli-0.9.7}/tests/test_trading.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mt5cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.7
|
|
4
4
|
Summary: Generic MT5 data and execution infrastructure for Python applications
|
|
5
5
|
Project-URL: Repository, https://github.com/dceoy/mt5cli.git
|
|
6
6
|
Author-email: dceoy <dceoy@users.noreply.github.com>
|
|
@@ -18,8 +18,9 @@ Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
|
18
18
|
Requires-Python: <3.14,>=3.11
|
|
19
19
|
Requires-Dist: click>=8.1.0
|
|
20
20
|
Requires-Dist: pdmt5>=0.3.0
|
|
21
|
-
Requires-Dist: pyarrow>=19.0.0
|
|
22
21
|
Requires-Dist: typer>=0.15.0
|
|
22
|
+
Provides-Extra: parquet
|
|
23
|
+
Requires-Dist: pyarrow>=19.0.0; extra == 'parquet'
|
|
23
24
|
Description-Content-Type: text/markdown
|
|
24
25
|
|
|
25
26
|
# mt5cli
|
|
@@ -53,6 +54,12 @@ Built on top of [pdmt5](https://github.com/dceoy/pdmt5), a pandas-based data han
|
|
|
53
54
|
pip install -U mt5cli MetaTrader5
|
|
54
55
|
```
|
|
55
56
|
|
|
57
|
+
Parquet export is not included by default. To enable it, install the `parquet` extra:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install -U "mt5cli[parquet]" MetaTrader5
|
|
61
|
+
```
|
|
62
|
+
|
|
56
63
|
## Python API (downstream packages)
|
|
57
64
|
|
|
58
65
|
Import `MT5Client` for generic MT5 data access, schema normalization, and optional order primitives.
|
|
@@ -29,6 +29,12 @@ Built on top of [pdmt5](https://github.com/dceoy/pdmt5), a pandas-based data han
|
|
|
29
29
|
pip install -U mt5cli MetaTrader5
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
Parquet export is not included by default. To enable it, install the `parquet` extra:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install -U "mt5cli[parquet]" MetaTrader5
|
|
36
|
+
```
|
|
37
|
+
|
|
32
38
|
## Python API (downstream packages)
|
|
33
39
|
|
|
34
40
|
Import `MT5Client` for generic MT5 data access, schema normalization, and optional order primitives.
|
|
@@ -27,6 +27,12 @@ mt5cli provides a stable `MT5Client` Python API, standardized dataset schemas, s
|
|
|
27
27
|
pip install mt5cli
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Parquet export is not included by default. To enable it, install the `parquet` extra:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install "mt5cli[parquet]"
|
|
34
|
+
```
|
|
35
|
+
|
|
30
36
|
## Python API for downstream packages
|
|
31
37
|
|
|
32
38
|
Import `MT5Client` for generic MT5 data access, schema normalization, and optional order primitives.
|
|
@@ -314,6 +314,7 @@ def export_dataframe(
|
|
|
314
314
|
table_name: Table name for SQLite3 output.
|
|
315
315
|
|
|
316
316
|
Raises:
|
|
317
|
+
ImportError: If the parquet format is requested but pyarrow is not installed.
|
|
317
318
|
ValueError: If the output format is not supported.
|
|
318
319
|
"""
|
|
319
320
|
if output_format == "csv":
|
|
@@ -326,6 +327,14 @@ def export_dataframe(
|
|
|
326
327
|
indent=2,
|
|
327
328
|
)
|
|
328
329
|
elif output_format == "parquet":
|
|
330
|
+
try:
|
|
331
|
+
__import__("pyarrow")
|
|
332
|
+
except ImportError as exc:
|
|
333
|
+
msg = (
|
|
334
|
+
"Parquet export requires the optional dependency pyarrow. "
|
|
335
|
+
'Install it with: pip install "mt5cli[parquet]"'
|
|
336
|
+
)
|
|
337
|
+
raise ImportError(msg) from exc
|
|
329
338
|
df.to_parquet(output_path, index=False)
|
|
330
339
|
elif output_format == "sqlite3":
|
|
331
340
|
export_dataframe_to_sqlite(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mt5cli"
|
|
3
|
-
version = "0.9.
|
|
3
|
+
version = "0.9.7"
|
|
4
4
|
description = "Generic MT5 data and execution infrastructure for Python applications"
|
|
5
5
|
authors = [{name = "dceoy", email = "dceoy@users.noreply.github.com"}]
|
|
6
6
|
maintainers = [{name = "dceoy", email = "dceoy@users.noreply.github.com"}]
|
|
@@ -11,7 +11,6 @@ requires-python = ">= 3.11, < 3.14"
|
|
|
11
11
|
dependencies = [
|
|
12
12
|
"pdmt5>=0.3.0",
|
|
13
13
|
"click >= 8.1.0",
|
|
14
|
-
"pyarrow >= 19.0.0",
|
|
15
14
|
"typer >= 0.15.0",
|
|
16
15
|
]
|
|
17
16
|
classifiers = [
|
|
@@ -25,6 +24,9 @@ classifiers = [
|
|
|
25
24
|
"Topic :: Office/Business :: Financial :: Investment",
|
|
26
25
|
]
|
|
27
26
|
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
parquet = ["pyarrow >= 19.0.0"]
|
|
29
|
+
|
|
28
30
|
[project.scripts]
|
|
29
31
|
mt5cli = "mt5cli.cli:main"
|
|
30
32
|
|
|
@@ -42,6 +44,7 @@ dev = [
|
|
|
42
44
|
"pytest-mock >= 3.12.0",
|
|
43
45
|
"pytest-cov >= 5.0.0",
|
|
44
46
|
"pandas-stubs >= 2.2.3.250527",
|
|
47
|
+
"pyarrow >= 19.0.0",
|
|
45
48
|
"mkdocs >= 1.6.1",
|
|
46
49
|
"mkdocs-material >= 9.7.6",
|
|
47
50
|
"mkdocstrings[python] >= 1.0.4",
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import re
|
|
6
6
|
import sqlite3
|
|
7
7
|
from datetime import UTC, datetime
|
|
8
|
+
from importlib.metadata import requires
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import get_type_hints
|
|
10
11
|
from unittest.mock import MagicMock
|
|
@@ -832,3 +833,24 @@ class TestStableSdkContract:
|
|
|
832
833
|
assert result.index.tz is not None
|
|
833
834
|
assert "time" not in result.columns
|
|
834
835
|
assert "close" in result.columns
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
# ---------------------------------------------------------------------------
|
|
839
|
+
# Packaging metadata
|
|
840
|
+
# ---------------------------------------------------------------------------
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
def test_parquet_extra_declares_pyarrow() -> None:
|
|
844
|
+
"""Package metadata lists pyarrow under the parquet optional extra."""
|
|
845
|
+
reqs = requires("mt5cli") or []
|
|
846
|
+
parquet_reqs = [r for r in reqs if "pyarrow" in r and "parquet" in r]
|
|
847
|
+
assert parquet_reqs, "pyarrow not found in parquet optional extra"
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
def test_pyarrow_not_in_core_dependencies() -> None:
|
|
851
|
+
"""Pyarrow is not a core dependency; it belongs only in the parquet extra."""
|
|
852
|
+
reqs = requires("mt5cli") or []
|
|
853
|
+
core_reqs = [r for r in reqs if "extra ==" not in r]
|
|
854
|
+
assert not any("pyarrow" in r for r in core_reqs), (
|
|
855
|
+
"pyarrow should not appear in core dependencies"
|
|
856
|
+
)
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
6
|
import sqlite3
|
|
7
|
+
import sys
|
|
7
8
|
from datetime import UTC, datetime
|
|
8
9
|
from typing import TYPE_CHECKING
|
|
9
10
|
|
|
@@ -111,6 +112,17 @@ class TestExportDataframe:
|
|
|
111
112
|
result = pd.read_parquet(output)
|
|
112
113
|
pd.testing.assert_frame_equal(result, sample_df)
|
|
113
114
|
|
|
115
|
+
def test_export_parquet_without_pyarrow(
|
|
116
|
+
self,
|
|
117
|
+
tmp_path: Path,
|
|
118
|
+
sample_df: pd.DataFrame,
|
|
119
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
120
|
+
) -> None:
|
|
121
|
+
"""Test that a clear error is raised when pyarrow is not installed."""
|
|
122
|
+
monkeypatch.setitem(sys.modules, "pyarrow", None)
|
|
123
|
+
with pytest.raises(ImportError, match="mt5cli\\[parquet\\]"):
|
|
124
|
+
export_dataframe(sample_df, tmp_path / "out.parquet", "parquet")
|
|
125
|
+
|
|
114
126
|
def test_export_sqlite3(self, tmp_path: Path, sample_df: pd.DataFrame) -> None:
|
|
115
127
|
"""Test SQLite3 export."""
|
|
116
128
|
output = tmp_path / "out.db"
|
|
@@ -487,21 +487,26 @@ wheels = [
|
|
|
487
487
|
|
|
488
488
|
[[package]]
|
|
489
489
|
name = "mt5cli"
|
|
490
|
-
version = "0.9.
|
|
490
|
+
version = "0.9.7"
|
|
491
491
|
source = { editable = "." }
|
|
492
492
|
dependencies = [
|
|
493
493
|
{ name = "click" },
|
|
494
494
|
{ name = "pdmt5" },
|
|
495
|
-
{ name = "pyarrow" },
|
|
496
495
|
{ name = "typer" },
|
|
497
496
|
]
|
|
498
497
|
|
|
498
|
+
[package.optional-dependencies]
|
|
499
|
+
parquet = [
|
|
500
|
+
{ name = "pyarrow" },
|
|
501
|
+
]
|
|
502
|
+
|
|
499
503
|
[package.dev-dependencies]
|
|
500
504
|
dev = [
|
|
501
505
|
{ name = "mkdocs" },
|
|
502
506
|
{ name = "mkdocs-material" },
|
|
503
507
|
{ name = "mkdocstrings", extra = ["python"] },
|
|
504
508
|
{ name = "pandas-stubs" },
|
|
509
|
+
{ name = "pyarrow" },
|
|
505
510
|
{ name = "pymdown-extensions" },
|
|
506
511
|
{ name = "pyright" },
|
|
507
512
|
{ name = "pytest" },
|
|
@@ -514,9 +519,10 @@ dev = [
|
|
|
514
519
|
requires-dist = [
|
|
515
520
|
{ name = "click", specifier = ">=8.1.0" },
|
|
516
521
|
{ name = "pdmt5", specifier = ">=0.3.0" },
|
|
517
|
-
{ name = "pyarrow", specifier = ">=19.0.0" },
|
|
522
|
+
{ name = "pyarrow", marker = "extra == 'parquet'", specifier = ">=19.0.0" },
|
|
518
523
|
{ name = "typer", specifier = ">=0.15.0" },
|
|
519
524
|
]
|
|
525
|
+
provides-extras = ["parquet"]
|
|
520
526
|
|
|
521
527
|
[package.metadata.requires-dev]
|
|
522
528
|
dev = [
|
|
@@ -524,6 +530,7 @@ dev = [
|
|
|
524
530
|
{ name = "mkdocs-material", specifier = ">=9.7.6" },
|
|
525
531
|
{ name = "mkdocstrings", extras = ["python"], specifier = ">=1.0.4" },
|
|
526
532
|
{ name = "pandas-stubs", specifier = ">=2.2.3.250527" },
|
|
533
|
+
{ name = "pyarrow", specifier = ">=19.0.0" },
|
|
527
534
|
{ name = "pymdown-extensions", specifier = ">=10.21.2" },
|
|
528
535
|
{ name = "pyright", specifier = ">=1.1.407" },
|
|
529
536
|
{ name = "pytest", specifier = ">=9.0.3" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|