mt5cli 0.4.0__tar.gz → 0.4.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.
- {mt5cli-0.4.0 → mt5cli-0.4.2}/PKG-INFO +41 -2
- {mt5cli-0.4.0 → mt5cli-0.4.2}/README.md +40 -1
- mt5cli-0.4.2/docs/api/history.md +131 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/index.md +4 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/index.md +2 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/mkdocs.yml +2 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/__init__.py +7 -1
- mt5cli-0.4.2/mt5cli/history.py +1176 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/sdk.py +208 -314
- {mt5cli-0.4.0 → mt5cli-0.4.2}/pyproject.toml +2 -1
- {mt5cli-0.4.0 → mt5cli-0.4.2}/tests/test_cli.py +3 -3
- mt5cli-0.4.2/tests/test_history.py +1497 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/tests/test_sdk.py +344 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/uv.lock +1 -1
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.agents/skills/local-qa/SKILL.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.agents/skills/local-qa/scripts/qa.sh +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.agents/skills/mt5cli/SKILL.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.claude/agents/codex.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.claude/settings.json +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/FUNDING.yml +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/dependabot.yml +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/renovate.json +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/workflows/ci.yml +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/workflows/claude.yml +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/workflows/release.yml +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/.gitignore +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/AGENTS.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/CLAUDE.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/LICENSE +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/cli.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/sdk.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/utils.md +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/__main__.py +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/cli.py +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/utils.py +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/tests/__init__.py +0 -0
- {mt5cli-0.4.0 → mt5cli-0.4.2}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mt5cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Command-line tool for MetaTrader 5
|
|
5
5
|
Project-URL: Repository, https://github.com/dceoy/mt5cli.git
|
|
6
6
|
Author-email: dceoy <dceoy@users.noreply.github.com>
|
|
@@ -111,7 +111,46 @@ mt5cli -o history.db collect-history \
|
|
|
111
111
|
--timeframe M1 --flags ALL --if-exists append --with-views
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
History orders and deals are fetched per symbol and concatenated, so the symbol filter is applied consistently across all datasets. The `cash_events` view is derived from symbol-filtered `history_deals`, so account-level cash events with empty or non-matching symbols may be excluded. The `rates` table records the requested `timeframe` so appended runs at different timeframes remain distinguishable. The `positions_reconstructed` view aggregates trade deals by `position_id`, excludes positions without closing
|
|
114
|
+
History orders and deals are fetched per symbol and concatenated, so the symbol filter is applied consistently across all datasets. The `cash_events` view is derived from symbol-filtered `history_deals`, so account-level cash events with empty or non-matching symbols may be excluded. The `rates` table records the requested `timeframe` so appended runs at different timeframes remain distinguishable. The `positions_reconstructed` view aggregates trade deals by `position_id`, excludes positions without closing-side entries, and uses volume-weighted open/close prices; reversal deals (`DEAL_ENTRY_INOUT`) are reported via `volume_reversal` / `reversal_count` columns.
|
|
115
|
+
|
|
116
|
+
### Incremental history SDK
|
|
117
|
+
|
|
118
|
+
For automated pipelines, use the importable incremental API instead of re-fetching fixed date ranges:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from pdmt5 import Mt5Config, Mt5DataClient
|
|
122
|
+
from mt5cli import Dataset, update_history, update_history_with_config
|
|
123
|
+
|
|
124
|
+
# Reuse an already-connected pdmt5 client (does not open/close MT5)
|
|
125
|
+
client = Mt5DataClient(config=Mt5Config(login=12345))
|
|
126
|
+
client.initialize_and_login_mt5()
|
|
127
|
+
try:
|
|
128
|
+
update_history(
|
|
129
|
+
client=client,
|
|
130
|
+
output="history.db",
|
|
131
|
+
symbols=["EURUSD", "GBPUSD"],
|
|
132
|
+
datasets={Dataset.rates, Dataset.history_deals},
|
|
133
|
+
timeframes=["M1", "H1"], # default: all fixed MT5 timeframes
|
|
134
|
+
lookback_hours=24,
|
|
135
|
+
create_rate_views=True,
|
|
136
|
+
with_views=True,
|
|
137
|
+
include_account_events=True,
|
|
138
|
+
)
|
|
139
|
+
finally:
|
|
140
|
+
client.shutdown()
|
|
141
|
+
|
|
142
|
+
# Standalone wrapper that opens and closes MT5 for you
|
|
143
|
+
update_history_with_config(
|
|
144
|
+
output="history.db",
|
|
145
|
+
symbols=["EURUSD"],
|
|
146
|
+
config=Mt5Config(login=12345),
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
- **`collect-history`**: explicit date-range export into SQLite.
|
|
151
|
+
- **`update_history`**: incremental append based on existing SQLite `MAX(time)` per symbol (and timeframe for rates); account-level deals use a separate cursor when `include_account_events=True`.
|
|
152
|
+
- **`rates` table**: normalized storage with `symbol` and `timeframe` columns.
|
|
153
|
+
- **Rate compatibility views**: mt5cli manages all `rate_*` views. Naming is `rate_<symbol>__<timeframe>` when a symbol has one timeframe, otherwise `rate_<symbol>__<granularity>_<timeframe>` (for example `rate_EURUSD__M1_1`). Stale `rate_*` views are dropped and recreated when rates change for offline tools such as mteor optimize.
|
|
115
154
|
|
|
116
155
|
## Requirements
|
|
117
156
|
|
|
@@ -87,7 +87,46 @@ mt5cli -o history.db collect-history \
|
|
|
87
87
|
--timeframe M1 --flags ALL --if-exists append --with-views
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
History orders and deals are fetched per symbol and concatenated, so the symbol filter is applied consistently across all datasets. The `cash_events` view is derived from symbol-filtered `history_deals`, so account-level cash events with empty or non-matching symbols may be excluded. The `rates` table records the requested `timeframe` so appended runs at different timeframes remain distinguishable. The `positions_reconstructed` view aggregates trade deals by `position_id`, excludes positions without closing
|
|
90
|
+
History orders and deals are fetched per symbol and concatenated, so the symbol filter is applied consistently across all datasets. The `cash_events` view is derived from symbol-filtered `history_deals`, so account-level cash events with empty or non-matching symbols may be excluded. The `rates` table records the requested `timeframe` so appended runs at different timeframes remain distinguishable. The `positions_reconstructed` view aggregates trade deals by `position_id`, excludes positions without closing-side entries, and uses volume-weighted open/close prices; reversal deals (`DEAL_ENTRY_INOUT`) are reported via `volume_reversal` / `reversal_count` columns.
|
|
91
|
+
|
|
92
|
+
### Incremental history SDK
|
|
93
|
+
|
|
94
|
+
For automated pipelines, use the importable incremental API instead of re-fetching fixed date ranges:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from pdmt5 import Mt5Config, Mt5DataClient
|
|
98
|
+
from mt5cli import Dataset, update_history, update_history_with_config
|
|
99
|
+
|
|
100
|
+
# Reuse an already-connected pdmt5 client (does not open/close MT5)
|
|
101
|
+
client = Mt5DataClient(config=Mt5Config(login=12345))
|
|
102
|
+
client.initialize_and_login_mt5()
|
|
103
|
+
try:
|
|
104
|
+
update_history(
|
|
105
|
+
client=client,
|
|
106
|
+
output="history.db",
|
|
107
|
+
symbols=["EURUSD", "GBPUSD"],
|
|
108
|
+
datasets={Dataset.rates, Dataset.history_deals},
|
|
109
|
+
timeframes=["M1", "H1"], # default: all fixed MT5 timeframes
|
|
110
|
+
lookback_hours=24,
|
|
111
|
+
create_rate_views=True,
|
|
112
|
+
with_views=True,
|
|
113
|
+
include_account_events=True,
|
|
114
|
+
)
|
|
115
|
+
finally:
|
|
116
|
+
client.shutdown()
|
|
117
|
+
|
|
118
|
+
# Standalone wrapper that opens and closes MT5 for you
|
|
119
|
+
update_history_with_config(
|
|
120
|
+
output="history.db",
|
|
121
|
+
symbols=["EURUSD"],
|
|
122
|
+
config=Mt5Config(login=12345),
|
|
123
|
+
)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
- **`collect-history`**: explicit date-range export into SQLite.
|
|
127
|
+
- **`update_history`**: incremental append based on existing SQLite `MAX(time)` per symbol (and timeframe for rates); account-level deals use a separate cursor when `include_account_events=True`.
|
|
128
|
+
- **`rates` table**: normalized storage with `symbol` and `timeframe` columns.
|
|
129
|
+
- **Rate compatibility views**: mt5cli manages all `rate_*` views. Naming is `rate_<symbol>__<timeframe>` when a symbol has one timeframe, otherwise `rate_<symbol>__<granularity>_<timeframe>` (for example `rate_EURUSD__M1_1`). Stale `rate_*` views are dropped and recreated when rates change for offline tools such as mteor optimize.
|
|
91
130
|
|
|
92
131
|
## Requirements
|
|
93
132
|
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# History Collection (SQLite)
|
|
2
|
+
|
|
3
|
+
::: mt5cli.history
|
|
4
|
+
|
|
5
|
+
## `collect-history` schema
|
|
6
|
+
|
|
7
|
+
The `collect-history` command (and the matching `collect_history` SDK function) writes
|
|
8
|
+
selected MT5 datasets into one SQLite database. Each dataset becomes a table; column
|
|
9
|
+
names and types mirror the pdmt5 DataFrame schema for that export, with two additions:
|
|
10
|
+
|
|
11
|
+
- `symbol` is prepended on every table.
|
|
12
|
+
- `timeframe` is prepended on `rates` so appended runs at different bar sizes stay
|
|
13
|
+
distinguishable.
|
|
14
|
+
|
|
15
|
+
SQLite does not declare foreign keys. Rows are linked logically by `symbol`, time
|
|
16
|
+
windows, and (for deals) `position_id` / `order`. Duplicate rows are removed on
|
|
17
|
+
append using dataset-specific keys (for example `ticket` on history tables, or
|
|
18
|
+
`(symbol, timeframe, time)` on rates).
|
|
19
|
+
|
|
20
|
+
Optional views are created when `--with-views` is set and the `history-deals` dataset
|
|
21
|
+
was written.
|
|
22
|
+
|
|
23
|
+
### Entity-relationship diagram
|
|
24
|
+
|
|
25
|
+
Sample layout for a full collection with `--with-views`:
|
|
26
|
+
|
|
27
|
+
```mermaid
|
|
28
|
+
erDiagram
|
|
29
|
+
rates {
|
|
30
|
+
TEXT symbol "dedup key"
|
|
31
|
+
INTEGER timeframe "dedup key"
|
|
32
|
+
TEXT time "dedup key"
|
|
33
|
+
REAL open
|
|
34
|
+
REAL high
|
|
35
|
+
REAL low
|
|
36
|
+
REAL close
|
|
37
|
+
INTEGER tick_volume
|
|
38
|
+
INTEGER spread
|
|
39
|
+
INTEGER real_volume
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
ticks {
|
|
43
|
+
TEXT symbol "dedup key"
|
|
44
|
+
TEXT time "dedup key"
|
|
45
|
+
INTEGER time_msc "dedup key (preferred)"
|
|
46
|
+
REAL bid
|
|
47
|
+
REAL ask
|
|
48
|
+
REAL last
|
|
49
|
+
INTEGER volume
|
|
50
|
+
INTEGER flags
|
|
51
|
+
REAL volume_real
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
history_orders {
|
|
55
|
+
INTEGER ticket "dedup key"
|
|
56
|
+
TEXT symbol
|
|
57
|
+
TEXT time
|
|
58
|
+
INTEGER type
|
|
59
|
+
INTEGER state
|
|
60
|
+
REAL volume_initial
|
|
61
|
+
REAL price_open
|
|
62
|
+
REAL price_current
|
|
63
|
+
INTEGER magic
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
history_deals {
|
|
67
|
+
INTEGER ticket "dedup key"
|
|
68
|
+
INTEGER order
|
|
69
|
+
INTEGER position_id "groups position view"
|
|
70
|
+
TEXT symbol
|
|
71
|
+
TEXT time
|
|
72
|
+
INTEGER type "0/1 trade, else cash event"
|
|
73
|
+
INTEGER entry "0 IN, 1 OUT, 2 INOUT, 3 OUT_BY"
|
|
74
|
+
REAL volume
|
|
75
|
+
REAL price
|
|
76
|
+
REAL profit
|
|
77
|
+
REAL commission
|
|
78
|
+
REAL swap
|
|
79
|
+
REAL fee
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
cash_events {
|
|
83
|
+
INTEGER ticket
|
|
84
|
+
TEXT symbol
|
|
85
|
+
TEXT time
|
|
86
|
+
INTEGER type
|
|
87
|
+
REAL profit
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
positions_reconstructed {
|
|
91
|
+
INTEGER position_id
|
|
92
|
+
TEXT symbol
|
|
93
|
+
TEXT open_time
|
|
94
|
+
TEXT close_time
|
|
95
|
+
INTEGER direction
|
|
96
|
+
REAL volume_open
|
|
97
|
+
REAL volume_close
|
|
98
|
+
REAL volume_reversal
|
|
99
|
+
REAL open_price
|
|
100
|
+
REAL close_price
|
|
101
|
+
REAL total_profit
|
|
102
|
+
INTEGER reversal_count
|
|
103
|
+
INTEGER deals_count
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
rates ||--o{ history_deals : "symbol (logical)"
|
|
107
|
+
ticks ||--o{ history_deals : "symbol (logical)"
|
|
108
|
+
history_orders ||--o{ history_deals : "order ~ ticket (logical)"
|
|
109
|
+
history_deals ||--|| cash_events : "VIEW: type NOT IN (0,1)"
|
|
110
|
+
history_deals ||--o{ positions_reconstructed : "VIEW: GROUP BY position_id"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Tables and views
|
|
114
|
+
|
|
115
|
+
| Object | Kind | Source | Notes |
|
|
116
|
+
| ------------------------- | ----- | -------------------- | ------------------------------------------------------------------------------------------- |
|
|
117
|
+
| `rates` | table | `copy_rates_range` | Indexed on `(symbol, timeframe, time)` when columns exist. |
|
|
118
|
+
| `ticks` | table | `copy_ticks_range` | Indexed on `(symbol, time)` when columns exist. |
|
|
119
|
+
| `history_orders` | table | `history_orders_get` | Fetched per `--symbol`, then concatenated. |
|
|
120
|
+
| `history_deals` | table | `history_deals_get` | Fetched per `--symbol`, then concatenated. Indexed on `(position_id, symbol)` when present. |
|
|
121
|
+
| `cash_events` | view | `history_deals` | Non-trade deal types (deposits, balance ops, etc.). Requires `type` column. |
|
|
122
|
+
| `positions_reconstructed` | view | `history_deals` | One row per closed `position_id`; volume-weighted prices and reversal stats. |
|
|
123
|
+
|
|
124
|
+
Column sets can vary with terminal and pdmt5 version. Views are skipped with a warning
|
|
125
|
+
when required columns are missing.
|
|
126
|
+
|
|
127
|
+
### Incremental collection
|
|
128
|
+
|
|
129
|
+
The `update_history` SDK path uses the same base tables and optional
|
|
130
|
+
`cash_events` / `positions_reconstructed` views. It additionally maintains
|
|
131
|
+
`rate_<symbol>__<timeframe>` compatibility views when `create_rate_views=True`.
|
|
@@ -18,6 +18,10 @@ Utility module providing constants, enums, Click parameter types, and helper fun
|
|
|
18
18
|
|
|
19
19
|
Programmatic SDK for read-only MetaTrader 5 data collection. Returns pandas DataFrames and provides `collect_history` for SQLite bulk collection.
|
|
20
20
|
|
|
21
|
+
### [History Collection (SQLite)](history.md)
|
|
22
|
+
|
|
23
|
+
SQLite storage helpers for the `collect-history` command schema, incremental updates, deduplication, indexes, and optional views.
|
|
24
|
+
|
|
21
25
|
## Architecture Overview
|
|
22
26
|
|
|
23
27
|
The package follows a simple architecture built on top of pdmt5:
|
|
@@ -152,6 +152,8 @@ mt5cli -o history.db collect-history \
|
|
|
152
152
|
|
|
153
153
|
History orders and deals are fetched per symbol and concatenated, so the symbol filter is applied consistently across all datasets. The `cash_events` view is derived from symbol-filtered `history_deals`, so account-level cash events with empty or non-matching symbols may be excluded. The `positions_reconstructed` view excludes positions with no closing deal, uses volume-weighted open/close prices, and reports reversal deals (`DEAL_ENTRY_INOUT`) via `volume_reversal` / `reversal_count`.
|
|
154
154
|
|
|
155
|
+
See the [History schema diagram](api/history.md#entity-relationship-diagram) for a sample ER layout of the resulting database.
|
|
156
|
+
|
|
155
157
|
## Global Options
|
|
156
158
|
|
|
157
159
|
| Option | Description |
|
|
@@ -24,6 +24,7 @@ theme:
|
|
|
24
24
|
features:
|
|
25
25
|
- content.code.annotate
|
|
26
26
|
- content.code.copy
|
|
27
|
+
- content.code.mermaid
|
|
27
28
|
- navigation.indexes
|
|
28
29
|
- navigation.sections
|
|
29
30
|
- navigation.tabs
|
|
@@ -57,6 +58,7 @@ nav:
|
|
|
57
58
|
- Overview: api/index.md
|
|
58
59
|
- CLI: api/cli.md
|
|
59
60
|
- SDK: api/sdk.md
|
|
61
|
+
- History Collection (SQLite): api/history.md
|
|
60
62
|
- Utils: api/utils.md
|
|
61
63
|
|
|
62
64
|
markdown_extensions:
|
|
@@ -22,15 +22,19 @@ from .sdk import (
|
|
|
22
22
|
symbol_info_tick,
|
|
23
23
|
symbols,
|
|
24
24
|
terminal_info,
|
|
25
|
+
update_history,
|
|
26
|
+
update_history_with_config,
|
|
25
27
|
)
|
|
26
28
|
from .sdk import (
|
|
27
29
|
version as mt5_version,
|
|
28
30
|
)
|
|
29
|
-
from .utils import detect_format, export_dataframe
|
|
31
|
+
from .utils import Dataset, IfExists, detect_format, export_dataframe
|
|
30
32
|
|
|
31
33
|
__version__ = version(__package__) if __package__ else None
|
|
32
34
|
|
|
33
35
|
__all__ = [
|
|
36
|
+
"Dataset",
|
|
37
|
+
"IfExists",
|
|
34
38
|
"Mt5CliClient",
|
|
35
39
|
"account_info",
|
|
36
40
|
"build_config",
|
|
@@ -53,4 +57,6 @@ __all__ = [
|
|
|
53
57
|
"symbol_info_tick",
|
|
54
58
|
"symbols",
|
|
55
59
|
"terminal_info",
|
|
60
|
+
"update_history",
|
|
61
|
+
"update_history_with_config",
|
|
56
62
|
]
|