mt5cli 1.1.1__tar.gz → 1.1.3__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-1.1.1 → mt5cli-1.1.3}/.agents/skills/mt5cli/SKILL.md +6 -5
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.agents/skills/pr-feedback-triage/SKILL.md +25 -15
- mt5cli-1.1.3/.github/workflows/opencode.yml +72 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/PKG-INFO +57 -36
- {mt5cli-1.1.1 → mt5cli-1.1.3}/README.md +53 -34
- mt5cli-1.1.3/docs/api/grafana.md +25 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/index.md +2 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/public-contract.md +15 -3
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/sdk.md +5 -4
- mt5cli-1.1.3/docs/api/telemetry.md +50 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/index.md +10 -7
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mkdocs.yml +2 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/__init__.py +4 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/cli.py +166 -13
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/contract.py +2 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/exceptions.py +4 -14
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/history.py +352 -60
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/retry.py +2 -3
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/sdk.py +14 -14
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/trading.py +119 -3
- {mt5cli-1.1.1 → mt5cli-1.1.3}/pyproject.toml +4 -2
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/test_cli.py +761 -791
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/test_contracts.py +29 -23
- mt5cli-1.1.3/tests/test_examples.py +92 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/test_grafana.py +376 -424
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/test_history.py +1366 -349
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/test_sdk.py +605 -555
- mt5cli-1.1.3/tests/test_telemetry.py +312 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/test_trading.py +799 -705
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/test_utils.py +167 -144
- {mt5cli-1.1.1 → mt5cli-1.1.3}/uv.lock +114 -107
- mt5cli-1.1.1/tests/test_examples.py +0 -75
- mt5cli-1.1.1/tests/test_telemetry.py +0 -249
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.agents/skills/local-qa/SKILL.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.agents/skills/local-qa/scripts/qa.sh +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.claude/agents/codex.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.claude/settings.json +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.github/FUNDING.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.github/dependabot.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.github/renovate.json +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.github/workflows/ci.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.github/workflows/claude.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.github/workflows/release.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/.gitignore +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/AGENTS.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/CLAUDE.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/LICENSE +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/cli.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/client.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/converters.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/exceptions.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/history.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/schemas.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/trading.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/docs/api/utils.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/examples/grafana/README.md +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/examples/grafana/compose.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/examples/grafana/dashboards/mt5cli-market.json +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/examples/grafana/dashboards/mt5cli-overview.json +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/examples/grafana/dashboards/mt5cli-trades.json +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/examples/grafana/provisioning/dashboards/mt5cli.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/examples/grafana/provisioning/datasources/mt5cli-sqlite.yml +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/__main__.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/client.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/converters.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/grafana.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/schemas.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/telemetry.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/mt5cli/utils.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/__init__.py +0 -0
- {mt5cli-1.1.1 → mt5cli-1.1.3}/tests/conftest.py +0 -0
|
@@ -32,10 +32,10 @@ Global options MUST precede the subcommand.
|
|
|
32
32
|
| `-o, --output PATH` | Output file path (required). |
|
|
33
33
|
| `-f, --format FORMAT` | `csv`, `json`, `parquet`, or `sqlite3` (auto from extension). |
|
|
34
34
|
| `--table NAME` | Table name for SQLite3 output (default: `data`). |
|
|
35
|
-
| `--login INT` | MT5 trading account login.
|
|
36
|
-
| `--password TEXT` | MT5 trading account password.
|
|
37
|
-
| `--server TEXT` | MT5 trading server name.
|
|
38
|
-
| `--path TEXT` | Path to MetaTrader 5 terminal EXE.
|
|
35
|
+
| `--login INT` | MT5 trading account login (`MT5_LOGIN`). |
|
|
36
|
+
| `--password TEXT` | MT5 trading account password (`MT5_PASSWORD`). |
|
|
37
|
+
| `--server TEXT` | MT5 trading server name (`MT5_SERVER`). |
|
|
38
|
+
| `--path TEXT` | Path to MetaTrader 5 terminal EXE (`MT5_PATH`). |
|
|
39
39
|
| `--timeout INT` | Connection timeout in milliseconds. |
|
|
40
40
|
| `--log-level LEVEL` | `DEBUG`, `INFO`, `WARNING` (default), `ERROR`. |
|
|
41
41
|
|
|
@@ -106,7 +106,8 @@ mt5cli -o history.db collect-history \
|
|
|
106
106
|
local MT5 terminal is already logged in.
|
|
107
107
|
- Avoid passing `--password` on the command line in shared or logged
|
|
108
108
|
environments — it is visible in `ps`, shell history, and CI logs. Prefer
|
|
109
|
-
|
|
109
|
+
`MT5_PASSWORD`/`MT5_LOGIN`/`MT5_SERVER`/`MT5_PATH` environment variables or a
|
|
110
|
+
pre-authenticated local terminal session.
|
|
110
111
|
- Reach for `--log-level DEBUG` when a command fails silently — MT5
|
|
111
112
|
connection errors surface there.
|
|
112
113
|
- If the user asks to run from source in this repo, prefix with `uv run`
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pr-feedback-triage
|
|
3
3
|
description: Triage pull request review comments into fixes, replies, clarification requests, or open follow-ups while respecting safe execution modes.
|
|
4
|
+
allowed-tools: Bash(git:*), Bash(gh:*), mcp__github__*, Read, Grep, Glob, Edit, MultiEdit, Write
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# PR Feedback Triage
|
|
@@ -43,9 +44,10 @@ When a mode disables an action, skip that destructive or externally visible acti
|
|
|
43
44
|
|
|
44
45
|
Gather the complete feedback set before editing:
|
|
45
46
|
|
|
46
|
-
- Fetch unresolved review threads, requested-change reviews,
|
|
47
|
-
- Use
|
|
48
|
-
- For bot reviewers that post both summary comments and inline comments,
|
|
47
|
+
- Fetch unresolved review threads, requested-change reviews, inline comments, copied comments, and PR-level summary comments.
|
|
48
|
+
- Use whichever authenticated GitHub-capable interface is available and reliable. This skill explicitly permits both `gh` and GitHub MCP tools; paginate results and do not inspect only the first page of threads or comments.
|
|
49
|
+
- For bot reviewers that post both summary comments and inline comments, prefer inline comments for actionable triage. Incorporate summary findings only when they contain distinct severity, rationale, or fix instructions not already captured from inline comments.
|
|
50
|
+
- Summary comments may be excluded from triage when they do not add distinct actionable context.
|
|
49
51
|
- Preserve every thread/comment identifier needed to reply or resolve later.
|
|
50
52
|
- Compare each comment with the current diff and file contents because review lines can become outdated.
|
|
51
53
|
|
|
@@ -56,7 +58,7 @@ Build one triage record per distinct finding:
|
|
|
56
58
|
- Prefer exact review-thread identity when available.
|
|
57
59
|
- For duplicate bot findings appearing in both summary and inline comments, merge by exact issue title first, then by file path plus line range as a fallback.
|
|
58
60
|
- Prefer inline comments for location and current code context.
|
|
59
|
-
-
|
|
61
|
+
- Use summary comments only for distinct severity, category, rationale, or detailed agent prompts that are not already available from inline comments.
|
|
60
62
|
- Preserve the reviewer’s exact issue title and original wording where practical. Do not rename findings in a way that would make replies hard to map back to comments.
|
|
61
63
|
- Preserve the reviewer’s original ordering unless the user asks for priority reordering. Many review bots already order findings by severity.
|
|
62
64
|
|
|
@@ -70,13 +72,20 @@ Keep a thread open only when it still needs reviewer, maintainer, or product inp
|
|
|
70
72
|
|
|
71
73
|
When resolving a thread, add a concise reply first only if it provides useful context, such as what changed, why no code change was needed, why a finding was intentionally deferred, or why the original comment is now outdated. Do not add noisy replies for self-evident fixes unless project norms require them.
|
|
72
74
|
|
|
75
|
+
## Platform Comment Style
|
|
76
|
+
|
|
77
|
+
- Keep every posted reply or comment brief: one sentence by default, two short sentences only when necessary.
|
|
78
|
+
- Do not post PR-level summary or status comments by default. Omit them when they only restate completed fixes, resolved threads, or verification already visible in commits/checks.
|
|
79
|
+
- Avoid templates, long bullet lists, exhaustive status logs, and duplicated explanations in platform comments.
|
|
80
|
+
- For simple fixes, already-addressed findings, or outdated findings, prefer `resolve_only` over adding a reply.
|
|
81
|
+
|
|
73
82
|
## Platform Action Contract
|
|
74
83
|
|
|
75
|
-
Do not treat triage as complete until every
|
|
84
|
+
Do not treat triage as complete until every incorporated source ID reaches an explicit terminal state:
|
|
76
85
|
|
|
77
86
|
- `resolved`: a platform resolve action succeeded, or a re-check shows the thread is already resolved.
|
|
78
87
|
- `replied_left_open`: a reply or question was posted and the thread is intentionally left unresolved.
|
|
79
|
-
- `not_resolvable`: the source is a PR-level summary comment or copied comment that has no platform-level resolve action;
|
|
88
|
+
- `not_resolvable`: the source is a PR-level summary comment or copied comment that has no platform-level resolve action; post a brief reply only when useful.
|
|
80
89
|
- `skipped_by_mode`: `dry_run`, `no_push`, or `no_reply` prevented the external action.
|
|
81
90
|
- `failed_action`: a reply or resolve action was attempted and failed; include the attempted action and failure in the final summary.
|
|
82
91
|
|
|
@@ -85,13 +94,13 @@ In normal mode, build and execute a platform action queue after fixes are verifi
|
|
|
85
94
|
- `reply_then_resolve`: use for handled threads where the reviewer needs context before resolution.
|
|
86
95
|
- `resolve_only`: use for self-evident fixes and already-addressed or outdated threads where an extra reply would add noise.
|
|
87
96
|
- `reply_leave_open`: use only for clarification requests, blocked work, or intentionally open follow-ups.
|
|
88
|
-
- `reply_only`: use for PR-level comments or summaries that cannot be resolved
|
|
97
|
+
- `reply_only`: use for PR-level comments or summaries that cannot be resolved, only when a short reply adds value.
|
|
89
98
|
|
|
90
99
|
For duplicate findings, execute the terminal action for every source thread ID, not only the primary triage record. If one finding is represented by three unresolved inline threads, all three must be resolved or explicitly left open.
|
|
91
100
|
|
|
92
101
|
## GitHub Action Guidance
|
|
93
102
|
|
|
94
|
-
|
|
103
|
+
Use whichever authenticated GitHub-capable interface is available and reliable, preferably `gh` or GitHub MCP. Prefer interfaces that expose review-thread resolution state. For GitHub inline review threads, use the thread node ID and the GraphQL `resolveReviewThread` mutation, or an equivalent GitHub MCP resolve-thread tool, rather than assuming that a reply resolves the conversation.
|
|
95
104
|
|
|
96
105
|
A reliable pattern is:
|
|
97
106
|
|
|
@@ -150,9 +159,9 @@ flowchart TD
|
|
|
150
159
|
## Compact Workflow
|
|
151
160
|
|
|
152
161
|
1. **Collect all relevant feedback**
|
|
153
|
-
- Identify the PR and gather unresolved review threads, requested-change reviews,
|
|
162
|
+
- Identify the PR and gather unresolved review threads, requested-change reviews, inline comments, copied comments, and PR-level summaries.
|
|
154
163
|
- Paginate all platform calls and keep comment/thread IDs for later replies and resolution.
|
|
155
|
-
- For bot reviews,
|
|
164
|
+
- For bot reviews, prioritize inline comments and incorporate summary findings only when they add distinct actionable context.
|
|
156
165
|
|
|
157
166
|
2. **Classify each triage record**
|
|
158
167
|
- **Fix**: Valid requested change; make the smallest focused edit when not in `dry_run`.
|
|
@@ -168,7 +177,7 @@ flowchart TD
|
|
|
168
177
|
- In `dry_run`, stop at triage, proposed fixes, suggested replies, and verification plan.
|
|
169
178
|
- In `no_push`, local edits are allowed, but do not push or resolve threads whose fix is only local. Reply or resolve non-code, already-addressed, or outdated threads only when the action does not depend on unpushed work and `no_reply` is not set.
|
|
170
179
|
- In `no_reply`, do not post replies or resolve threads; report suggested replies/actions instead.
|
|
171
|
-
- In normal mode, commit and push changed code when appropriate, then execute the platform action queue for every
|
|
180
|
+
- In normal mode, commit and push changed code when appropriate, then execute the platform action queue for every incorporated source ID.
|
|
172
181
|
|
|
173
182
|
4. **Verify before claiming completion**
|
|
174
183
|
- For fixes, run appropriate checks or explain why they could not run.
|
|
@@ -178,15 +187,16 @@ flowchart TD
|
|
|
178
187
|
- If a resolve or reply operation fails, retry once when safe; then report `failed_action` with the affected source ID and reason.
|
|
179
188
|
|
|
180
189
|
5. **Finish**
|
|
181
|
-
- Normal mode: commit/push changes when appropriate, post useful replies
|
|
190
|
+
- Normal mode: commit/push changes when appropriate, post only useful short replies/comments, omit PR-level summaries when they add no value, resolve all handled threads by default, and reconcile the final unresolved set.
|
|
182
191
|
- Safe modes: report the local state and the exact replies/resolution actions a human could take.
|
|
183
192
|
|
|
184
193
|
## Reply Guidance
|
|
185
194
|
|
|
186
|
-
- Keep inline replies short
|
|
187
|
-
- For fixed findings, mention the concrete change or commit if
|
|
188
|
-
- For already-addressed or outdated findings, cite the current code path or behavior
|
|
195
|
+
- Keep inline replies short: one sentence by default, two short sentences only when needed.
|
|
196
|
+
- For fixed findings, mention the concrete change or commit only if it helps the reviewer.
|
|
197
|
+
- For already-addressed or outdated findings, cite the current code path or behavior only as briefly as needed.
|
|
189
198
|
- For deferred or won't-fix findings, provide the reason and any follow-up issue or owner if known.
|
|
199
|
+
- Avoid posting PR-level summary comments unless they communicate a decision, blocker, or requested reviewer action.
|
|
190
200
|
- If a reply or resolve operation fails, continue with the remaining threads and report the failure in the final summary.
|
|
191
201
|
|
|
192
202
|
## Final Summary Checklist
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Pull request review and mention bot using OpenCode
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types:
|
|
6
|
+
- opened
|
|
7
|
+
- ready_for_review
|
|
8
|
+
issue_comment:
|
|
9
|
+
types:
|
|
10
|
+
- created
|
|
11
|
+
pull_request_review_comment:
|
|
12
|
+
types:
|
|
13
|
+
- created
|
|
14
|
+
pull_request_review:
|
|
15
|
+
types:
|
|
16
|
+
- submitted
|
|
17
|
+
issues:
|
|
18
|
+
types:
|
|
19
|
+
- opened
|
|
20
|
+
- assigned
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
jobs:
|
|
24
|
+
opencode-review:
|
|
25
|
+
if: >
|
|
26
|
+
github.event_name == 'pull_request'
|
|
27
|
+
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)
|
|
28
|
+
&& (! github.event.pull_request.draft)
|
|
29
|
+
&& (! startsWith(github.head_ref, 'dependabot/'))
|
|
30
|
+
&& (! startsWith(github.head_ref, 'renovate/'))
|
|
31
|
+
permissions:
|
|
32
|
+
contents: read
|
|
33
|
+
pull-requests: write
|
|
34
|
+
issues: write
|
|
35
|
+
id-token: write
|
|
36
|
+
actions: read
|
|
37
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/opencode-review.yml@main # zizmor: ignore[unpinned-uses]
|
|
38
|
+
with:
|
|
39
|
+
model: opencode-go/kimi-k2.7-code
|
|
40
|
+
secrets:
|
|
41
|
+
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
42
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }}
|
|
43
|
+
opencode-bot:
|
|
44
|
+
if: >
|
|
45
|
+
(
|
|
46
|
+
(github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
|
|
47
|
+
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
|
|
48
|
+
&& (contains(github.event.comment.body, '/oc') || contains(github.event.comment.body, '/opencode'))
|
|
49
|
+
) || (
|
|
50
|
+
github.event_name == 'pull_request_review'
|
|
51
|
+
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)
|
|
52
|
+
&& (contains(github.event.review.body, '/oc') || contains(github.event.review.body, '/opencode'))
|
|
53
|
+
) || (
|
|
54
|
+
github.event_name == 'issues'
|
|
55
|
+
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)
|
|
56
|
+
&& (
|
|
57
|
+
(contains(github.event.issue.body, '/oc') || contains(github.event.issue.title, '/oc'))
|
|
58
|
+
|| (contains(github.event.issue.body, '/opencode') || contains(github.event.issue.title, '/opencode'))
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
permissions:
|
|
62
|
+
contents: read
|
|
63
|
+
pull-requests: write
|
|
64
|
+
issues: write
|
|
65
|
+
id-token: write
|
|
66
|
+
actions: read
|
|
67
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/opencode-bot.yml@main # zizmor: ignore[unpinned-uses]
|
|
68
|
+
with:
|
|
69
|
+
model: opencode-go/glm-5.2
|
|
70
|
+
secrets:
|
|
71
|
+
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
72
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mt5cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.3
|
|
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>
|
|
@@ -17,7 +17,9 @@ Classifier: Programming Language :: Python :: 3
|
|
|
17
17
|
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
18
18
|
Requires-Python: <3.14,>=3.11
|
|
19
19
|
Requires-Dist: click>=8.1.0
|
|
20
|
-
Requires-Dist:
|
|
20
|
+
Requires-Dist: pandas>=2.2.2
|
|
21
|
+
Requires-Dist: pdmt5>=1.1.0
|
|
22
|
+
Requires-Dist: pydantic>=2.13.4
|
|
21
23
|
Requires-Dist: typer>=0.15.0
|
|
22
24
|
Provides-Extra: otel
|
|
23
25
|
Requires-Dist: opentelemetry-api; extra == 'otel'
|
|
@@ -173,9 +175,10 @@ mt5cli -o ticks.json ticks-from --symbol EURUSD \
|
|
|
173
175
|
# Export symbols to SQLite3 with custom table name
|
|
174
176
|
mt5cli -o data.db --table symbols symbols --group "*USD*"
|
|
175
177
|
|
|
176
|
-
# Export with connection credentials
|
|
177
|
-
|
|
178
|
-
-o positions.csv positions
|
|
178
|
+
# Export with connection credentials from env or placeholders
|
|
179
|
+
MT5_LOGIN=12345 MT5_PASSWORD=secret MT5_SERVER=MyBroker-Demo \
|
|
180
|
+
mt5cli -o positions.csv positions
|
|
181
|
+
MT5_PATH="/path/to/terminal64.exe" mt5cli -o positions.csv positions
|
|
179
182
|
```
|
|
180
183
|
|
|
181
184
|
Run as a Python module:
|
|
@@ -186,40 +189,54 @@ python -m mt5cli -o account.csv account-info
|
|
|
186
189
|
|
|
187
190
|
## Commands
|
|
188
191
|
|
|
189
|
-
| Command | Description
|
|
190
|
-
| ---------------------- |
|
|
191
|
-
| `rates-from` | Export rates from a start date
|
|
192
|
-
| `rates-from-pos` | Export rates from a start position
|
|
193
|
-
| `latest-rates` | Export latest rates from a start position
|
|
194
|
-
| `rates-range` | Export rates for a date range
|
|
195
|
-
| `ticks-from` | Export ticks from a start date
|
|
196
|
-
| `ticks-range` | Export ticks for a date range
|
|
197
|
-
| `ticks-recent` | Export ticks from a recent trailing window
|
|
198
|
-
| `account-info` | Export account information
|
|
199
|
-
| `terminal-info` | Export terminal information
|
|
200
|
-
| `version` | Export MetaTrader 5 version information
|
|
201
|
-
| `last-error` | Export the last error information
|
|
202
|
-
| `symbols` | Export symbol list
|
|
203
|
-
| `symbol-info` | Export symbol details
|
|
204
|
-
| `symbol-info-tick` | Export the last tick for a symbol
|
|
205
|
-
| `minimum-margins` | Export minimum-volume buy and sell margin requirements
|
|
206
|
-
| `market-book` | Export market depth (order book)
|
|
207
|
-
| `orders` | Export active orders
|
|
208
|
-
| `positions` | Export open positions
|
|
209
|
-
| `history-orders` | Export historical orders
|
|
210
|
-
| `history-deals` | Export historical deals
|
|
211
|
-
| `recent-history-deals` | Export historical deals from a recent trailing window
|
|
212
|
-
| `mt5-summary` | Export terminal/account status summary
|
|
213
|
-
| `order-check` | Check funds sufficiency for a trade request
|
|
214
|
-
| `order-send` | Send a raw trade request to the trade server (`--yes` required; expert path)
|
|
215
|
-
| `close-positions` | Close open positions by `--symbol` or `--ticket` (`--yes` required for live; `--dry-run` available)
|
|
216
|
-
| `collect-history` | Collect rates, history-orders, and history-deals for one or more symbols into a single SQLite database (ticks opt-in via `--dataset ticks`)
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
192
|
+
| Command | Description |
|
|
193
|
+
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
194
|
+
| `rates-from` | Export rates from a start date |
|
|
195
|
+
| `rates-from-pos` | Export rates from a start position |
|
|
196
|
+
| `latest-rates` | Export latest rates from a start position |
|
|
197
|
+
| `rates-range` | Export rates for a date range |
|
|
198
|
+
| `ticks-from` | Export ticks from a start date |
|
|
199
|
+
| `ticks-range` | Export ticks for a date range |
|
|
200
|
+
| `ticks-recent` | Export ticks from a recent trailing window |
|
|
201
|
+
| `account-info` | Export account information |
|
|
202
|
+
| `terminal-info` | Export terminal information |
|
|
203
|
+
| `version` | Export MetaTrader 5 version information |
|
|
204
|
+
| `last-error` | Export the last error information |
|
|
205
|
+
| `symbols` | Export symbol list |
|
|
206
|
+
| `symbol-info` | Export symbol details |
|
|
207
|
+
| `symbol-info-tick` | Export the last tick for a symbol |
|
|
208
|
+
| `minimum-margins` | Export minimum-volume buy and sell margin requirements |
|
|
209
|
+
| `market-book` | Export market depth (order book) |
|
|
210
|
+
| `orders` | Export active orders |
|
|
211
|
+
| `positions` | Export open positions |
|
|
212
|
+
| `history-orders` | Export historical orders |
|
|
213
|
+
| `history-deals` | Export historical deals |
|
|
214
|
+
| `recent-history-deals` | Export historical deals from a recent trailing window |
|
|
215
|
+
| `mt5-summary` | Export terminal/account status summary |
|
|
216
|
+
| `order-check` | Check funds sufficiency for a trade request |
|
|
217
|
+
| `order-send` | Send a raw trade request to the trade server (`--yes` required; expert path) |
|
|
218
|
+
| `close-positions` | Close open positions by `--symbol` or `--ticket` (`--yes` required for live; `--dry-run` available; optional `--deviation` / `--comment` / `--magic`) |
|
|
219
|
+
| `collect-history` | Collect rates, history-orders, and history-deals for one or more symbols into a single SQLite database (ticks opt-in via `--dataset ticks`) |
|
|
220
|
+
| `history-gaps` | Export a SQLite-only one-row-per-gap report from managed rate compatibility views without connecting to MT5 |
|
|
221
|
+
| `grafana-schema` | Create or refresh Grafana-ready views and indexes in an existing SQLite database (idempotent, no MT5 connection) |
|
|
222
|
+
| `snapshot` | Snapshot current account, position, order, and terminal state into SQLite for live Grafana dashboards |
|
|
219
223
|
|
|
220
224
|
Use `order-check` to validate a request payload before running `order-send --yes`.
|
|
221
225
|
`close-positions` is the safer high-level alternative that builds correct close
|
|
222
226
|
requests automatically. At least one `--symbol` or `--ticket` must be provided.
|
|
227
|
+
CLI connection flags fall back to `MT5_LOGIN`, `MT5_PASSWORD`, `MT5_SERVER`,
|
|
228
|
+
and `MT5_PATH` when unset, and explicit CLI values still win.
|
|
229
|
+
|
|
230
|
+
### `history-gaps`
|
|
231
|
+
|
|
232
|
+
Inspect collected SQLite rate views offline and export one row per detected gap.
|
|
233
|
+
For managed compatibility views, the command infers bar spacing from the view
|
|
234
|
+
name. Use `--granularity-seconds` for custom tables or views.
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
mt5cli -o gaps.json history-gaps --sqlite3 history.db
|
|
238
|
+
mt5cli -o eurusd.csv history-gaps --sqlite3 history.db --table rate_EURUSD__M1_1
|
|
239
|
+
```
|
|
223
240
|
|
|
224
241
|
### `collect-history`
|
|
225
242
|
|
|
@@ -331,7 +348,11 @@ WHERE run_id = (SELECT MAX(run_id) FROM snapshot_runs WHERE status = 'ok');
|
|
|
331
348
|
SELECT symbol, total_profit FROM grafana_trade_stats ORDER BY total_profit DESC;
|
|
332
349
|
```
|
|
333
350
|
|
|
334
|
-
|
|
351
|
+
#### Grafana and telemetry API docs
|
|
352
|
+
|
|
353
|
+
The shipped Grafana helpers are documented in [`docs/api/grafana.md`](docs/api/grafana.md), including `publish_grafana_copy()` for creating a WAL-safe published SQLite copy for Grafana.
|
|
354
|
+
|
|
355
|
+
OpenTelemetry metrics are documented in [`docs/api/telemetry.md`](docs/api/telemetry.md), including `enable_otel_metrics()`, `configure_metrics()`, the `mt5cli[otel]` extra, and `OTEL_EXPORTER_OTLP_ENDPOINT`.
|
|
335
356
|
|
|
336
357
|
### Incremental history SDK
|
|
337
358
|
|
|
@@ -144,9 +144,10 @@ mt5cli -o ticks.json ticks-from --symbol EURUSD \
|
|
|
144
144
|
# Export symbols to SQLite3 with custom table name
|
|
145
145
|
mt5cli -o data.db --table symbols symbols --group "*USD*"
|
|
146
146
|
|
|
147
|
-
# Export with connection credentials
|
|
148
|
-
|
|
149
|
-
-o positions.csv positions
|
|
147
|
+
# Export with connection credentials from env or placeholders
|
|
148
|
+
MT5_LOGIN=12345 MT5_PASSWORD=secret MT5_SERVER=MyBroker-Demo \
|
|
149
|
+
mt5cli -o positions.csv positions
|
|
150
|
+
MT5_PATH="/path/to/terminal64.exe" mt5cli -o positions.csv positions
|
|
150
151
|
```
|
|
151
152
|
|
|
152
153
|
Run as a Python module:
|
|
@@ -157,40 +158,54 @@ python -m mt5cli -o account.csv account-info
|
|
|
157
158
|
|
|
158
159
|
## Commands
|
|
159
160
|
|
|
160
|
-
| Command | Description
|
|
161
|
-
| ---------------------- |
|
|
162
|
-
| `rates-from` | Export rates from a start date
|
|
163
|
-
| `rates-from-pos` | Export rates from a start position
|
|
164
|
-
| `latest-rates` | Export latest rates from a start position
|
|
165
|
-
| `rates-range` | Export rates for a date range
|
|
166
|
-
| `ticks-from` | Export ticks from a start date
|
|
167
|
-
| `ticks-range` | Export ticks for a date range
|
|
168
|
-
| `ticks-recent` | Export ticks from a recent trailing window
|
|
169
|
-
| `account-info` | Export account information
|
|
170
|
-
| `terminal-info` | Export terminal information
|
|
171
|
-
| `version` | Export MetaTrader 5 version information
|
|
172
|
-
| `last-error` | Export the last error information
|
|
173
|
-
| `symbols` | Export symbol list
|
|
174
|
-
| `symbol-info` | Export symbol details
|
|
175
|
-
| `symbol-info-tick` | Export the last tick for a symbol
|
|
176
|
-
| `minimum-margins` | Export minimum-volume buy and sell margin requirements
|
|
177
|
-
| `market-book` | Export market depth (order book)
|
|
178
|
-
| `orders` | Export active orders
|
|
179
|
-
| `positions` | Export open positions
|
|
180
|
-
| `history-orders` | Export historical orders
|
|
181
|
-
| `history-deals` | Export historical deals
|
|
182
|
-
| `recent-history-deals` | Export historical deals from a recent trailing window
|
|
183
|
-
| `mt5-summary` | Export terminal/account status summary
|
|
184
|
-
| `order-check` | Check funds sufficiency for a trade request
|
|
185
|
-
| `order-send` | Send a raw trade request to the trade server (`--yes` required; expert path)
|
|
186
|
-
| `close-positions` | Close open positions by `--symbol` or `--ticket` (`--yes` required for live; `--dry-run` available)
|
|
187
|
-
| `collect-history` | Collect rates, history-orders, and history-deals for one or more symbols into a single SQLite database (ticks opt-in via `--dataset ticks`)
|
|
188
|
-
| `
|
|
189
|
-
| `
|
|
161
|
+
| Command | Description |
|
|
162
|
+
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
163
|
+
| `rates-from` | Export rates from a start date |
|
|
164
|
+
| `rates-from-pos` | Export rates from a start position |
|
|
165
|
+
| `latest-rates` | Export latest rates from a start position |
|
|
166
|
+
| `rates-range` | Export rates for a date range |
|
|
167
|
+
| `ticks-from` | Export ticks from a start date |
|
|
168
|
+
| `ticks-range` | Export ticks for a date range |
|
|
169
|
+
| `ticks-recent` | Export ticks from a recent trailing window |
|
|
170
|
+
| `account-info` | Export account information |
|
|
171
|
+
| `terminal-info` | Export terminal information |
|
|
172
|
+
| `version` | Export MetaTrader 5 version information |
|
|
173
|
+
| `last-error` | Export the last error information |
|
|
174
|
+
| `symbols` | Export symbol list |
|
|
175
|
+
| `symbol-info` | Export symbol details |
|
|
176
|
+
| `symbol-info-tick` | Export the last tick for a symbol |
|
|
177
|
+
| `minimum-margins` | Export minimum-volume buy and sell margin requirements |
|
|
178
|
+
| `market-book` | Export market depth (order book) |
|
|
179
|
+
| `orders` | Export active orders |
|
|
180
|
+
| `positions` | Export open positions |
|
|
181
|
+
| `history-orders` | Export historical orders |
|
|
182
|
+
| `history-deals` | Export historical deals |
|
|
183
|
+
| `recent-history-deals` | Export historical deals from a recent trailing window |
|
|
184
|
+
| `mt5-summary` | Export terminal/account status summary |
|
|
185
|
+
| `order-check` | Check funds sufficiency for a trade request |
|
|
186
|
+
| `order-send` | Send a raw trade request to the trade server (`--yes` required; expert path) |
|
|
187
|
+
| `close-positions` | Close open positions by `--symbol` or `--ticket` (`--yes` required for live; `--dry-run` available; optional `--deviation` / `--comment` / `--magic`) |
|
|
188
|
+
| `collect-history` | Collect rates, history-orders, and history-deals for one or more symbols into a single SQLite database (ticks opt-in via `--dataset ticks`) |
|
|
189
|
+
| `history-gaps` | Export a SQLite-only one-row-per-gap report from managed rate compatibility views without connecting to MT5 |
|
|
190
|
+
| `grafana-schema` | Create or refresh Grafana-ready views and indexes in an existing SQLite database (idempotent, no MT5 connection) |
|
|
191
|
+
| `snapshot` | Snapshot current account, position, order, and terminal state into SQLite for live Grafana dashboards |
|
|
190
192
|
|
|
191
193
|
Use `order-check` to validate a request payload before running `order-send --yes`.
|
|
192
194
|
`close-positions` is the safer high-level alternative that builds correct close
|
|
193
195
|
requests automatically. At least one `--symbol` or `--ticket` must be provided.
|
|
196
|
+
CLI connection flags fall back to `MT5_LOGIN`, `MT5_PASSWORD`, `MT5_SERVER`,
|
|
197
|
+
and `MT5_PATH` when unset, and explicit CLI values still win.
|
|
198
|
+
|
|
199
|
+
### `history-gaps`
|
|
200
|
+
|
|
201
|
+
Inspect collected SQLite rate views offline and export one row per detected gap.
|
|
202
|
+
For managed compatibility views, the command infers bar spacing from the view
|
|
203
|
+
name. Use `--granularity-seconds` for custom tables or views.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
mt5cli -o gaps.json history-gaps --sqlite3 history.db
|
|
207
|
+
mt5cli -o eurusd.csv history-gaps --sqlite3 history.db --table rate_EURUSD__M1_1
|
|
208
|
+
```
|
|
194
209
|
|
|
195
210
|
### `collect-history`
|
|
196
211
|
|
|
@@ -302,7 +317,11 @@ WHERE run_id = (SELECT MAX(run_id) FROM snapshot_runs WHERE status = 'ok');
|
|
|
302
317
|
SELECT symbol, total_profit FROM grafana_trade_stats ORDER BY total_profit DESC;
|
|
303
318
|
```
|
|
304
319
|
|
|
305
|
-
|
|
320
|
+
#### Grafana and telemetry API docs
|
|
321
|
+
|
|
322
|
+
The shipped Grafana helpers are documented in [`docs/api/grafana.md`](docs/api/grafana.md), including `publish_grafana_copy()` for creating a WAL-safe published SQLite copy for Grafana.
|
|
323
|
+
|
|
324
|
+
OpenTelemetry metrics are documented in [`docs/api/telemetry.md`](docs/api/telemetry.md), including `enable_otel_metrics()`, `configure_metrics()`, the `mt5cli[otel]` extra, and `OTEL_EXPORTER_OTLP_ENDPOINT`.
|
|
306
325
|
|
|
307
326
|
### Incremental history SDK
|
|
308
327
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Grafana
|
|
2
|
+
|
|
3
|
+
::: mt5cli.grafana
|
|
4
|
+
|
|
5
|
+
## Grafana-ready SQLite workflow
|
|
6
|
+
|
|
7
|
+
Use `ensure_grafana_schema(conn)` or the `grafana-schema` CLI command to create
|
|
8
|
+
the snapshot tables, `grafana_*` views, and supporting indexes in one step.
|
|
9
|
+
|
|
10
|
+
`publish_grafana_copy(source, target)` creates a consistent SQLite copy via the
|
|
11
|
+
SQLite backup API, which is useful when the primary database is running in WAL
|
|
12
|
+
mode and Grafana should read from a separate published file.
|
|
13
|
+
|
|
14
|
+
## Main APIs
|
|
15
|
+
|
|
16
|
+
- `ensure_grafana_schema()`: idempotently creates snapshot tables, Grafana
|
|
17
|
+
views, and indexes.
|
|
18
|
+
- `create_grafana_views()`: rebuilds the shipped `grafana_*` views.
|
|
19
|
+
- `create_grafana_indexes()`: creates read-oriented indexes for Grafana
|
|
20
|
+
queries.
|
|
21
|
+
- `publish_grafana_copy()`: writes an atomic, WAL-safe published copy for a
|
|
22
|
+
Grafana datasource.
|
|
23
|
+
|
|
24
|
+
For end-to-end snapshot collection examples, see the Grafana and observability
|
|
25
|
+
section in the project `README.md`.
|
|
@@ -18,6 +18,8 @@ responsibilities.
|
|
|
18
18
|
| [SDK](sdk.md) | Module-level fetch helpers, multi-account collectors, incremental history |
|
|
19
19
|
| [Trading](trading.md) | Trading-capable sessions and operational helpers |
|
|
20
20
|
| [History Collection (SQLite)](history.md) | SQLite schema, incremental writes, dedup, and rate views |
|
|
21
|
+
| [Telemetry](telemetry.md) | OpenTelemetry metrics setup, meters, and emitted metric names |
|
|
22
|
+
| [Grafana](grafana.md) | Grafana-ready SQLite schema, views, snapshots, and published copies |
|
|
21
23
|
| [CLI](cli.md) | Typer commands that delegate to the Python API |
|
|
22
24
|
| [Utils](utils.md) | Parsing helpers and Click parameter types |
|
|
23
25
|
|
|
@@ -20,8 +20,8 @@ Downstream code should import raw pdmt5 types and constants (such as
|
|
|
20
20
|
from `pdmt5` when needed. mt5cli does not serve as a pass-through compatibility
|
|
21
21
|
namespace for pdmt5. mt5cli's trading helpers type their client parameter against
|
|
22
22
|
an internal protocol backed by `pdmt5.Mt5DataClient`; `Mt5TradingClient` is no
|
|
23
|
-
longer required. `Mt5TradingError`
|
|
24
|
-
|
|
23
|
+
longer required. `pdmt5.Mt5TradingError` was removed upstream in pdmt5 1.0.4;
|
|
24
|
+
mt5cli raises `Mt5OperationError` for all trading-related failures.
|
|
25
25
|
|
|
26
26
|
Note: the former `mt5cli` re-export `TICK_FLAG_MAP` corresponds to `COPY_TICKS_MAP`
|
|
27
27
|
in pdmt5 — the name changed, it was not simply moved.
|
|
@@ -70,6 +70,7 @@ timestamp normalization in downstream apps.
|
|
|
70
70
|
| Symbol | Role |
|
|
71
71
|
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
72
72
|
| `collect_history` | One-shot date-range export into SQLite |
|
|
73
|
+
| `report_rate_gaps` | SQLite-only one-row-per-gap report for a rate table or compatibility view |
|
|
73
74
|
| `update_history`, `update_history_with_config` | Incremental append from `MAX(time)` cursors |
|
|
74
75
|
| `ThrottledHistoryUpdater` | Minimum interval between successful incremental updates; optional `update_backend` injection |
|
|
75
76
|
| `RateTarget`, `build_rate_targets` | Neutral `(symbol, timeframe)` series descriptors |
|
|
@@ -98,6 +99,7 @@ strategy entries, exits, Kelly sizing, or signal logic.
|
|
|
98
99
|
| `calculate_symbol_group_margin_ratio` | Estimated symbol-group margin/equity with optional exposure |
|
|
99
100
|
| `determine_order_limits` | SL/TP price levels from ratios |
|
|
100
101
|
| `calculate_trailing_stop_updates` | Per-ticket generic trailing stop-loss update plan |
|
|
102
|
+
| `resolve_broker_filling_mode` | Broker-supported filling-mode selection helper |
|
|
101
103
|
| `ensure_symbol_selected` | Select/verify Market Watch visibility |
|
|
102
104
|
| `fetch_recent_history_deals_for_trading_client` | Recent deal history from a connected trading client |
|
|
103
105
|
| `place_market_order`, `close_open_positions`, `update_sltp_for_open_positions`, `update_trailing_stop_loss_for_open_positions` | Order execution helpers (`dry_run` supported) |
|
|
@@ -211,6 +213,9 @@ The Typer application in `mt5cli.cli` exposes file-export commands documented in
|
|
|
211
213
|
- Require `-o/--output` and write CSV, JSON, Parquet, or SQLite.
|
|
212
214
|
- Accept global MT5 connection options (`--login`, `--password`, `--server`,
|
|
213
215
|
`--path`, `--timeout`).
|
|
216
|
+
- Resolve unset CLI connection options from `MT5_LOGIN`, `MT5_PASSWORD`,
|
|
217
|
+
`MT5_SERVER`, and `MT5_PATH`, and expand `${ENV_VAR}` placeholders in CLI
|
|
218
|
+
string fields before building the MT5 config.
|
|
214
219
|
- Delegate to the same Python APIs described here; they are not duplicated
|
|
215
220
|
business logic.
|
|
216
221
|
|
|
@@ -228,7 +233,14 @@ constructed request payload. `close-positions` is the safer high-level helper
|
|
|
228
233
|
that closes open positions by `--symbol` or `--ticket` using
|
|
229
234
|
`close_open_positions()`. Both `order-send --yes` and `close-positions --yes`
|
|
230
235
|
are live execution paths. `close-positions --dry-run` previews close orders
|
|
231
|
-
without placing them and does not require `--yes`.
|
|
236
|
+
without placing them and does not require `--yes`. `close-positions` also
|
|
237
|
+
accepts optional `--deviation`, `--comment`, and `--magic`; `--magic` scopes
|
|
238
|
+
the selected open positions fail-closed when position magic metadata is absent.
|
|
239
|
+
|
|
240
|
+
`history-gaps` reads an existing SQLite history database and exports one row
|
|
241
|
+
per detected gap from managed rate compatibility views. It never initializes
|
|
242
|
+
MT5. Pass `--granularity-seconds` for custom tables or views whose bar spacing
|
|
243
|
+
cannot be inferred from the name.
|
|
232
244
|
|
|
233
245
|
## Internal helpers (not stable)
|
|
234
246
|
|
|
@@ -12,8 +12,8 @@ application.
|
|
|
12
12
|
|
|
13
13
|
`collect_latest_rates_for_accounts_with_retries()` wraps
|
|
14
14
|
`collect_latest_rates_for_accounts()` with bounded exponential backoff. Only
|
|
15
|
-
`pdmt5.
|
|
16
|
-
|
|
15
|
+
`pdmt5.Mt5RuntimeError` is retried; the final failure is re-raised once
|
|
16
|
+
`retry_count` is exhausted.
|
|
17
17
|
|
|
18
18
|
```python
|
|
19
19
|
from mt5cli import AccountSpec, collect_latest_rates_for_accounts_with_retries
|
|
@@ -32,8 +32,9 @@ rates = collect_latest_rates_for_accounts_with_retries(
|
|
|
32
32
|
|
|
33
33
|
MetaTrader 5 `start_pos=0` includes the still-forming current bar as the last
|
|
34
34
|
row. `fetch_latest_closed_rates()` handles one connected `MT5Client`; use
|
|
35
|
-
`fetch_latest_closed_rates_for_trading_client()` from an active
|
|
36
|
-
`
|
|
35
|
+
`fetch_latest_closed_rates_for_trading_client()` from an active trading
|
|
36
|
+
session created by `create_trading_client()`. Multi-account helpers fetch
|
|
37
|
+
`count + 1` bars, drop
|
|
37
38
|
that row with `drop_forming_rate_bar()`, and validate each series is non-empty. Returned frames are ordered
|
|
38
39
|
oldest-to-newest and may contain fewer than `count` rows only when MT5 returns
|
|
39
40
|
fewer closed bars.
|