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.
Files changed (37) hide show
  1. {mt5cli-0.4.0 → mt5cli-0.4.2}/PKG-INFO +41 -2
  2. {mt5cli-0.4.0 → mt5cli-0.4.2}/README.md +40 -1
  3. mt5cli-0.4.2/docs/api/history.md +131 -0
  4. {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/index.md +4 -0
  5. {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/index.md +2 -0
  6. {mt5cli-0.4.0 → mt5cli-0.4.2}/mkdocs.yml +2 -0
  7. {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/__init__.py +7 -1
  8. mt5cli-0.4.2/mt5cli/history.py +1176 -0
  9. {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/sdk.py +208 -314
  10. {mt5cli-0.4.0 → mt5cli-0.4.2}/pyproject.toml +2 -1
  11. {mt5cli-0.4.0 → mt5cli-0.4.2}/tests/test_cli.py +3 -3
  12. mt5cli-0.4.2/tests/test_history.py +1497 -0
  13. {mt5cli-0.4.0 → mt5cli-0.4.2}/tests/test_sdk.py +344 -0
  14. {mt5cli-0.4.0 → mt5cli-0.4.2}/uv.lock +1 -1
  15. {mt5cli-0.4.0 → mt5cli-0.4.2}/.agents/skills/local-qa/SKILL.md +0 -0
  16. {mt5cli-0.4.0 → mt5cli-0.4.2}/.agents/skills/local-qa/scripts/qa.sh +0 -0
  17. {mt5cli-0.4.0 → mt5cli-0.4.2}/.agents/skills/mt5cli/SKILL.md +0 -0
  18. {mt5cli-0.4.0 → mt5cli-0.4.2}/.claude/agents/codex.md +0 -0
  19. {mt5cli-0.4.0 → mt5cli-0.4.2}/.claude/settings.json +0 -0
  20. {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/FUNDING.yml +0 -0
  21. {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/dependabot.yml +0 -0
  22. {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/renovate.json +0 -0
  23. {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/workflows/ci.yml +0 -0
  24. {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/workflows/claude.yml +0 -0
  25. {mt5cli-0.4.0 → mt5cli-0.4.2}/.github/workflows/release.yml +0 -0
  26. {mt5cli-0.4.0 → mt5cli-0.4.2}/.gitignore +0 -0
  27. {mt5cli-0.4.0 → mt5cli-0.4.2}/AGENTS.md +0 -0
  28. {mt5cli-0.4.0 → mt5cli-0.4.2}/CLAUDE.md +0 -0
  29. {mt5cli-0.4.0 → mt5cli-0.4.2}/LICENSE +0 -0
  30. {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/cli.md +0 -0
  31. {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/sdk.md +0 -0
  32. {mt5cli-0.4.0 → mt5cli-0.4.2}/docs/api/utils.md +0 -0
  33. {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/__main__.py +0 -0
  34. {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/cli.py +0 -0
  35. {mt5cli-0.4.0 → mt5cli-0.4.2}/mt5cli/utils.py +0 -0
  36. {mt5cli-0.4.0 → mt5cli-0.4.2}/tests/__init__.py +0 -0
  37. {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.0
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 deals, and uses volume-weighted open/close prices; reversal deals (`DEAL_ENTRY_INOUT`) are reported via `volume_reversal` / `reversal_count` columns and do not contribute to the weighted prices.
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 deals, and uses volume-weighted open/close prices; reversal deals (`DEAL_ENTRY_INOUT`) are reported via `volume_reversal` / `reversal_count` columns and do not contribute to the weighted prices.
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
  ]