mt5cli 1.5.0__tar.gz → 1.6.0__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 (84) hide show
  1. {mt5cli-1.5.0 → mt5cli-1.6.0}/PKG-INFO +1 -1
  2. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/public-contract.md +48 -19
  3. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/history.py +754 -189
  4. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/observability.py +138 -36
  5. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/rates.py +60 -0
  6. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/sdk.py +10 -1
  7. {mt5cli-1.5.0 → mt5cli-1.6.0}/pyproject.toml +1 -1
  8. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_history.py +5 -3
  9. mt5cli-1.6.0/tests/unit/test_history_capture_persist.py +211 -0
  10. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_history_contract.py +166 -29
  11. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_observability.py +24 -2
  12. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_rates.py +29 -1
  13. {mt5cli-1.5.0 → mt5cli-1.6.0}/uv.lock +2 -2
  14. {mt5cli-1.5.0 → mt5cli-1.6.0}/.agents/skills/local-qa/SKILL.md +0 -0
  15. {mt5cli-1.5.0 → mt5cli-1.6.0}/.agents/skills/local-qa/scripts/qa.sh +0 -0
  16. {mt5cli-1.5.0 → mt5cli-1.6.0}/.agents/skills/mt5cli/SKILL.md +0 -0
  17. {mt5cli-1.5.0 → mt5cli-1.6.0}/.claude/agents/codex.md +0 -0
  18. {mt5cli-1.5.0 → mt5cli-1.6.0}/.claude/settings.json +0 -0
  19. {mt5cli-1.5.0 → mt5cli-1.6.0}/.github/CODEOWNERS +0 -0
  20. {mt5cli-1.5.0 → mt5cli-1.6.0}/.github/FUNDING.yml +0 -0
  21. {mt5cli-1.5.0 → mt5cli-1.6.0}/.github/dependabot.yml +0 -0
  22. {mt5cli-1.5.0 → mt5cli-1.6.0}/.github/renovate.json +0 -0
  23. {mt5cli-1.5.0 → mt5cli-1.6.0}/.github/workflows/ci.yml +0 -0
  24. {mt5cli-1.5.0 → mt5cli-1.6.0}/.github/workflows/claude.yml +0 -0
  25. {mt5cli-1.5.0 → mt5cli-1.6.0}/.github/workflows/release.yml +0 -0
  26. {mt5cli-1.5.0 → mt5cli-1.6.0}/.gitignore +0 -0
  27. {mt5cli-1.5.0 → mt5cli-1.6.0}/LICENSE +0 -0
  28. {mt5cli-1.5.0 → mt5cli-1.6.0}/README.md +0 -0
  29. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/cli.md +0 -0
  30. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/client.md +0 -0
  31. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/converters.md +0 -0
  32. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/exceptions.md +0 -0
  33. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/grafana.md +0 -0
  34. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/history.md +0 -0
  35. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/index.md +0 -0
  36. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/marketdata.md +0 -0
  37. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/observability.md +0 -0
  38. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/schemas.md +0 -0
  39. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/telemetry.md +0 -0
  40. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/trading.md +0 -0
  41. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/api/utils.md +0 -0
  42. {mt5cli-1.5.0 → mt5cli-1.6.0}/docs/index.md +0 -0
  43. {mt5cli-1.5.0 → mt5cli-1.6.0}/examples/grafana/README.md +0 -0
  44. {mt5cli-1.5.0 → mt5cli-1.6.0}/examples/grafana/compose.yml +0 -0
  45. {mt5cli-1.5.0 → mt5cli-1.6.0}/examples/grafana/dashboards/mt5cli-market.json +0 -0
  46. {mt5cli-1.5.0 → mt5cli-1.6.0}/examples/grafana/dashboards/mt5cli-overview.json +0 -0
  47. {mt5cli-1.5.0 → mt5cli-1.6.0}/examples/grafana/dashboards/mt5cli-trades.json +0 -0
  48. {mt5cli-1.5.0 → mt5cli-1.6.0}/examples/grafana/provisioning/dashboards/mt5cli.yml +0 -0
  49. {mt5cli-1.5.0 → mt5cli-1.6.0}/examples/grafana/provisioning/datasources/mt5cli-sqlite.yml +0 -0
  50. {mt5cli-1.5.0 → mt5cli-1.6.0}/mkdocs.yml +0 -0
  51. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/__init__.py +0 -0
  52. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/__main__.py +0 -0
  53. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/cli.py +0 -0
  54. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/client.py +0 -0
  55. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/contract.py +0 -0
  56. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/converters.py +0 -0
  57. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/exceptions.py +0 -0
  58. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/grafana.py +0 -0
  59. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/lifecycle.py +0 -0
  60. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/marketdata.py +0 -0
  61. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/retry.py +0 -0
  62. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/schemas.py +0 -0
  63. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/telemetry.py +0 -0
  64. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/trading.py +0 -0
  65. {mt5cli-1.5.0 → mt5cli-1.6.0}/mt5cli/utils.py +0 -0
  66. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/cli/test_cli.bats +0 -0
  67. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/__init__.py +0 -0
  68. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/conftest.py +0 -0
  69. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_cli.py +0 -0
  70. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_client.py +0 -0
  71. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_contracts.py +0 -0
  72. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_docs_contract.py +0 -0
  73. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_examples.py +0 -0
  74. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_grafana.py +0 -0
  75. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_history_edge_contract.py +0 -0
  76. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_lifecycle.py +0 -0
  77. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_marketdata.py +0 -0
  78. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_packaging.py +0 -0
  79. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_rate_timestamp_contract.py +0 -0
  80. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_rates_contract.py +0 -0
  81. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_stable_sdk_cleanup.py +0 -0
  82. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_telemetry.py +0 -0
  83. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_trading.py +0 -0
  84. {mt5cli-1.5.0 → mt5cli-1.6.0}/tests/unit/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: mt5cli
3
- Version: 1.5.0
3
+ Version: 1.6.0
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>
@@ -89,17 +89,34 @@ timestamp normalization in downstream apps.
89
89
 
90
90
  ### SQLite history collection and rate loading
91
91
 
92
- | Symbol | Role |
93
- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
94
- | `collect_history` | One-shot date-range export into SQLite |
95
- | `report_rate_gaps` | SQLite-only one-row-per-gap report for the canonical rates table or an explicit custom table |
96
- | `update_history`, `update_history_with_config` | Incremental append from `MAX(time)` cursors; explicit naive trade-server `date_to` required |
97
- | `ThrottledHistoryUpdater` | Minimum interval between successful incremental updates; explicit `date_to`; optional `update_backend` injection |
98
- | `RateTarget`, `build_rate_targets` | Neutral `(symbol, timeframe)` series descriptors |
99
- | `load_rate_series_from_sqlite`, `load_rate_series_by_granularity` | Load normalized `rates` series or explicit custom tables; reject invalid targets clearly |
92
+ | Symbol | Role |
93
+ | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
94
+ | `collect_history` | One-shot date-range export into SQLite |
95
+ | `report_rate_gaps` | SQLite-only one-row-per-gap report for the canonical rates table or an explicit custom table |
96
+ | `update_history`, `update_history_with_config` | Incremental append from `MAX(time)` cursors; explicit naive trade-server `date_to` required |
97
+ | `ThrottledHistoryUpdater` | Minimum interval between successful incremental updates; explicit `date_to`; optional `update_backend` injection |
98
+ | `capture_history_datasets` | MT5-bound half of `update_history`: resolves cursors and fetches MT5 data, returns a `HistoryCapture`, writes nothing |
99
+ | `persist_history_datasets` | MT5-free half of `update_history`: writes a `HistoryCapture` to SQLite (append/dedup/index/views); owns its own connection |
100
+ | `HistoryCapture` | Frozen, MT5-independent bundle returned by `capture_history_datasets` and consumed by `persist_history_datasets` |
101
+ | `RateTarget`, `build_rate_targets` | Neutral `(symbol, timeframe)` series descriptors |
102
+ | `load_rate_series_from_sqlite`, `load_rate_series_by_granularity` | Load normalized `rates` series or explicit custom tables; reject invalid targets clearly |
100
103
 
101
104
  See [History Collection (SQLite)](history.md) for the canonical schema, loading contract, and ER diagrams.
102
105
 
106
+ `update_history(client=...)` is exactly `capture_history_datasets(client=...)`
107
+ followed by `persist_history_datasets(...)` on the returned capture (skipped
108
+ when it is `None`, i.e. no datasets selected). Downstream applications that
109
+ must keep SQLite writes off an MT5-bound thread — for example a live trading
110
+ loop that cannot block on database I/O — call `capture_history_datasets` on
111
+ the thread holding the connected client, hand the returned `HistoryCapture` to
112
+ a separate persistence worker, and call `persist_history_datasets` there;
113
+ `persist_history_datasets` never accesses MT5 or any connection-scoped MT5
114
+ state. Capturing again for the same `output` before a prior capture has been
115
+ persisted re-reads the same not-yet-advanced incremental cursor and may
116
+ re-fetch an overlapping range (safe under `deduplicate=True`, but wasteful);
117
+ callers that queue persistence work should avoid capturing a new batch for a
118
+ target while one is still pending.
119
+
103
120
  Shared package-root helpers used by downstream adapters include `Dataset`,
104
121
  `parse_timeframe`, and `resolve_history_timeframes`. These are stable exports;
105
122
  downstream applications should not import them from `mt5cli.utils` or
@@ -186,16 +203,28 @@ idempotent (`CREATE TABLE IF NOT EXISTS`, `DROP VIEW IF EXISTS` + `CREATE
186
203
  VIEW`, `CREATE INDEX IF NOT EXISTS`). Missing source tables are skipped with a
187
204
  warning rather than raising an error.
188
205
 
189
- | Symbol | Role |
190
- | ---------------------------------- | ------------------------------------------------------------------------------------------- |
191
- | `update_observability` | Append one timestamped snapshot row per data type from a connected client implementation |
192
- | `update_observability_with_config` | Standalone wrapper: opens/closes MT5 connection automatically around `update_observability` |
193
-
194
- Both functions write to the SQLite path given by `output=`. The optional
195
- `symbols` parameter filters `positions_get` / `orders_get` by symbol.
196
- `with_grafana_schema=False` (default) skips Grafana view/index setup; run
197
- `grafana-schema` once to set up the schema, then call `snapshot` repeatedly
198
- without this flag.
206
+ | Symbol | Role |
207
+ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
208
+ | `update_observability` | Append one timestamped snapshot row per data type from a connected client implementation |
209
+ | `update_observability_with_config` | Standalone wrapper: opens/closes MT5 connection automatically around `update_observability` |
210
+ | `capture_observability_snapshot` | MT5-bound half of `update_observability`: reads account/position/order/terminal state, returns an `ObservabilitySnapshot`, writes nothing |
211
+ | `persist_observability_snapshot` | MT5-free half of `update_observability`: writes an `ObservabilitySnapshot` to SQLite; owns its own connection |
212
+ | `ObservabilitySnapshot` | Frozen, MT5-independent bundle returned by `capture_observability_snapshot` and consumed by `persist_observability_snapshot` |
213
+
214
+ `update_observability` and `persist_observability_snapshot` write to the
215
+ SQLite path given by `output=`. The optional `symbols` parameter filters
216
+ `positions_get` / `orders_get` by symbol. `with_grafana_schema=False`
217
+ (default) skips Grafana view/index setup; run `grafana-schema` once to set up
218
+ the schema, then call `snapshot` repeatedly without this flag.
219
+
220
+ `update_observability(client=...)` is exactly
221
+ `capture_observability_snapshot(client=...)` followed by
222
+ `persist_observability_snapshot(...)`. As with history, a downstream
223
+ application that must keep SQLite writes off an MT5-bound thread calls
224
+ `capture_observability_snapshot` on the thread holding the connected client
225
+ and hands the returned `ObservabilitySnapshot` to a separate persistence
226
+ worker; `persist_observability_snapshot` never accesses MT5 or any
227
+ connection-scoped MT5 state.
199
228
 
200
229
  Pass the `MT5Client` yielded by `mt5_session()` directly to both
201
230
  `update_history(client=...)` and `update_observability(client=...)`. These
@@ -376,4 +405,4 @@ their own adapter layer.
376
405
  `tests/unit/test_contracts.py` asserts that every name in `STABLE_SDK_EXPORTS` is
377
406
  importable from `mt5cli`, that all package-root exports are covered by the
378
407
  stable set, and documents key closed-bar, SQLite loading, account-resolution,
379
- and trading-session behaviors.
408
+ and trading-session behaviors.