mt5cli 0.1.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.
@@ -0,0 +1,25 @@
1
+ # local-qa
2
+
3
+ Run local QA checks (format, lint, test) on the repository.
4
+
5
+ ## When to use
6
+
7
+ After making changes to repository files, run `scripts/qa.sh` to validate formatting, linting, and tests.
8
+
9
+ ## Steps
10
+
11
+ 1. Execute `scripts/qa.sh` and capture the results.
12
+ 2. Report successes, failures, warnings, and any modified files.
13
+
14
+ ## If tools are missing
15
+
16
+ Install them following this priority order:
17
+
18
+ 1. Project package managers (`uv`, `poetry`, npm scripts)
19
+ 2. System package managers (`brew`, `apt`)
20
+ 3. Language-specific installers (`pipx`, `pip`, `npm`, `go install`)
21
+
22
+ ## Constraints
23
+
24
+ - Only execute QA and tool-installation commands.
25
+ - If installation fails or requires unavailable privileges, report the attempt and exact failure, then stop.
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euox pipefail
4
+ cd "$(git rev-parse --show-toplevel)"
5
+
6
+ # Python
7
+ uv run ruff format .
8
+ uv run ruff check --fix .
9
+ uv run pyright .
10
+ uv run pytest
11
+
12
+ # Markdown
13
+ npx -y prettier --write './**/*.md'
14
+
15
+ # GitHub Actions
16
+ zizmor --fix=safe .github/workflows
17
+ git ls-files -z -- '.github/workflows/*.yml' | xargs -0 -t actionlint
18
+ git ls-files -z -- '.github/workflows/*.yml' | xargs -0 -t yamllint -d '{"extends": "relaxed", "rules": {"line-length": "disable"}}'
19
+ checkov --framework=all --output=github_failed_only --directory=.
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: mt5cli
3
+ description: Use the `mt5cli` CLI to export MetaTrader 5 data (rates, ticks, account, symbols, orders, positions, history) to CSV, JSON, Parquet, or SQLite3. Invoke when the user asks to export, dump, download, or fetch MT5 market data or account data to a file.
4
+ ---
5
+
6
+ # mt5cli
7
+
8
+ Export MetaTrader 5 data to CSV, JSON, Parquet, or SQLite3 via the `mt5cli`
9
+ command. Output format is auto-detected from the file extension (`.csv`,
10
+ `.json`, `.parquet`/`.pq`, `.db`/`.sqlite`/`.sqlite3`) or overridden with
11
+ `--format/-f`.
12
+
13
+ ## Requirements
14
+
15
+ - Python 3.11+ on Windows with MetaTrader 5 installed (pdmt5 requires the
16
+ MT5 terminal).
17
+ - Install: `pip install -U mt5cli MetaTrader5`.
18
+ - In this repo, run via `uv run mt5cli ...` or `uv run python -m mt5cli ...`.
19
+
20
+ ## Invocation shape
21
+
22
+ ```
23
+ mt5cli [GLOBAL OPTIONS] -o OUTPUT COMMAND [COMMAND OPTIONS]
24
+ ```
25
+
26
+ Global options MUST precede the subcommand.
27
+
28
+ ### Global options (apply to every subcommand)
29
+
30
+ | Option | Purpose |
31
+ | --------------------- | ------------------------------------------------------------- |
32
+ | `-o, --output PATH` | Output file path (required). |
33
+ | `-f, --format FORMAT` | `csv`, `json`, `parquet`, or `sqlite3` (auto from extension). |
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. |
39
+ | `--timeout INT` | Connection timeout in milliseconds. |
40
+ | `--log-level LEVEL` | `DEBUG`, `INFO`, `WARNING` (default), `ERROR`. |
41
+
42
+ ### Parameter value formats
43
+
44
+ - **Datetimes** (`--date-from`, `--date-to`): ISO 8601 (`2024-01-01` or
45
+ `2024-01-01T12:00:00+00:00`). Naive values are treated as UTC.
46
+ - **Timeframe** (`--timeframe`): `M1`, `M2`, `M3`, `M4`, `M5`, `M6`, `M10`,
47
+ `M12`, `M15`, `M20`, `M30`, `H1`, `H2`, `H3`, `H4`, `H6`, `H8`, `H12`,
48
+ `D1`, `W1`, `MN1`, or the raw integer.
49
+ - **Tick flags** (`--flags`): `ALL`, `INFO`, `TRADE`, or the raw integer.
50
+
51
+ ## Commands
52
+
53
+ | Command | Required options | Optional options |
54
+ | ---------------- | ----------------------------------------------------- | --------------------------------------------------------------------------- |
55
+ | `rates-from` | `--symbol`, `--timeframe`, `--date-from`, `--count` | — |
56
+ | `rates-from-pos` | `--symbol`, `--timeframe`, `--start-pos`, `--count` | — |
57
+ | `rates-range` | `--symbol`, `--timeframe`, `--date-from`, `--date-to` | — |
58
+ | `ticks-from` | `--symbol`, `--date-from`, `--count`, `--flags` | — |
59
+ | `ticks-range` | `--symbol`, `--date-from`, `--date-to`, `--flags` | — |
60
+ | `account-info` | — | — |
61
+ | `terminal-info` | — | — |
62
+ | `symbols` | — | `--group` (e.g., `*USD*`) |
63
+ | `symbol-info` | `--symbol` | — |
64
+ | `orders` | — | `--symbol`, `--group`, `--ticket` |
65
+ | `positions` | — | `--symbol`, `--group`, `--ticket` |
66
+ | `history-orders` | — | `--date-from`, `--date-to`, `--group`, `--symbol`, `--ticket`, `--position` |
67
+ | `history-deals` | — | `--date-from`, `--date-to`, `--group`, `--symbol`, `--ticket`, `--position` |
68
+
69
+ ## Examples
70
+
71
+ ```bash
72
+ # Account snapshot as CSV.
73
+ mt5cli -o account.csv account-info
74
+
75
+ # EURUSD M1 bars (1000 rows) from a start date to Parquet.
76
+ mt5cli -o rates.parquet rates-from \
77
+ --symbol EURUSD --timeframe M1 --date-from 2024-01-01 --count 1000
78
+
79
+ # EURUSD tick stream for a date range to JSON.
80
+ mt5cli -o ticks.json ticks-range \
81
+ --symbol EURUSD --date-from 2024-01-01 --date-to 2024-01-02 --flags ALL
82
+
83
+ # USD symbols into a named table in SQLite3.
84
+ mt5cli -o data.db --table symbols symbols --group "*USD*"
85
+
86
+ # Historical deals filtered by symbol (using an already-logged-in MT5 terminal).
87
+ mt5cli -o deals.csv history-deals --symbol EURUSD --date-from 2024-01-01
88
+ ```
89
+
90
+ ## Guidelines
91
+
92
+ - Pick the output extension to avoid passing `--format`.
93
+ - Use `--table` only with SQLite3 outputs; it is otherwise ignored.
94
+ - `--count` is required for `rates-from`, `rates-from-pos`, and `ticks-from`.
95
+ Prefer `rates-range` / `ticks-range` when a fixed window is known.
96
+ - Credentials (`--login`, `--password`, `--server`) are optional when the
97
+ local MT5 terminal is already logged in.
98
+ - Avoid passing `--password` on the command line in shared or logged
99
+ environments — it is visible in `ps`, shell history, and CI logs. Prefer
100
+ logging in through the MT5 terminal first, then omit credentials here.
101
+ - Reach for `--log-level DEBUG` when a command fails silently — MT5
102
+ connection errors surface there.
103
+ - If the user asks to run from source in this repo, prefix with `uv run`
104
+ (e.g., `uv run mt5cli -o out.csv account-info`).
@@ -0,0 +1,46 @@
1
+ # Codex Agent
2
+
3
+ Specialized Claude agent for autonomous development work using OpenAI's Codex CLI.
4
+
5
+ ## Modes
6
+
7
+ ### Ask Mode
8
+
9
+ Read-only code analysis: answer questions about implementation, architecture, and debugging with specific file references and code examples.
10
+
11
+ ### Exec Mode
12
+
13
+ Generate and modify code: create new components, refactor existing code, fix bugs, and write tests while maintaining quality standards.
14
+
15
+ ### Review Mode
16
+
17
+ Comprehensive code review: identify security vulnerabilities, bugs, performance issues, and quality improvements without making changes.
18
+
19
+ ### Search Mode
20
+
21
+ Research current documentation, best practices, solutions, and technology comparisons using web resources.
22
+
23
+ ## Core Requirements
24
+
25
+ - Prioritize Codex CLI as the primary execution engine.
26
+ - Ask, Review, and Search modes are read-only; only Exec mode modifies code.
27
+ - All answers require verification:
28
+ - Ask mode must confirm file paths exist.
29
+ - Exec mode requires test passage and linting.
30
+ - Review mode needs severity prioritization.
31
+ - Search mode demands sourced citations.
32
+
33
+ ## Workflow
34
+
35
+ 1. Understand the task.
36
+ 2. Gather context from the codebase.
37
+ 3. Execute via Codex CLI with specific parameters.
38
+ 4. Verify results.
39
+ 5. Communicate findings with appropriate structure and detail.
40
+
41
+ ## Constraints
42
+
43
+ - No hardcoded secrets.
44
+ - Thorough testing.
45
+ - Specific file references.
46
+ - Honest communication about limitations.
@@ -0,0 +1,18 @@
1
+ {
2
+ "hooks": {
3
+ "Stop": [
4
+ {
5
+ "matcher": "",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": ".claude/skills/local-qa/scripts/qa.sh"
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ },
15
+ "enabledPlugins": {
16
+ "code-simplifier@claude-plugins-official": true
17
+ }
18
+ }
@@ -0,0 +1,3 @@
1
+ ---
2
+ github:
3
+ - dceoy
@@ -0,0 +1,17 @@
1
+ ---
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: github-actions
5
+ directory: /
6
+ schedule:
7
+ interval: daily
8
+ cooldown:
9
+ default-days: 7
10
+ open-pull-requests-limit: 10
11
+ - package-ecosystem: pip
12
+ directory: /
13
+ schedule:
14
+ interval: daily
15
+ cooldown:
16
+ default-days: 7
17
+ open-pull-requests-limit: 10
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": ["config:recommended"],
4
+ "minimumReleaseAge": "7 days",
5
+ "packageRules": [
6
+ {
7
+ "description": "Automatically merge minor and patch-level updates",
8
+ "matchUpdateTypes": ["minor", "patch", "digest"],
9
+ "automerge": true,
10
+ "automergeType": "branch"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: CI/CD
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ branches:
9
+ - main
10
+ types:
11
+ - opened
12
+ - synchronize
13
+ - reopened
14
+ workflow_dispatch: # checkov:skip=CKV_GHA_7:workflow_dispatch inputs are required for manual runs
15
+ inputs:
16
+ workflow:
17
+ required: true
18
+ type: choice
19
+ options:
20
+ - lint-and-test
21
+ - docs-deploy
22
+ description: Choose the workflow to run
23
+ default: lint-and-test
24
+ permissions:
25
+ contents: read
26
+ defaults:
27
+ run:
28
+ shell: bash -euo pipefail {0}
29
+ working-directory: .
30
+ jobs:
31
+ python-lint-and-scan:
32
+ if: >
33
+ github.event_name == 'push'
34
+ || github.event_name == 'pull_request'
35
+ || (github.event_name == 'workflow_dispatch' && inputs.workflow == 'lint-and-test')
36
+ permissions:
37
+ contents: read
38
+ uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-lint-and-scan.yml@main # zizmor: ignore[unpinned-uses]
39
+ with:
40
+ package-path: .
41
+ runs-on: windows-latest
42
+ python-test:
43
+ if: >
44
+ github.event_name == 'push'
45
+ || github.event_name == 'pull_request'
46
+ || (github.event_name == 'workflow_dispatch' && inputs.workflow == 'lint-and-test')
47
+ permissions:
48
+ contents: read
49
+ uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-test.yml@main # zizmor: ignore[unpinned-uses]
50
+ with:
51
+ package-path: .
52
+ runs-on: windows-latest
53
+ python-docs-deploy:
54
+ if: >
55
+ github.event_name == 'push'
56
+ || (github.event_name == 'workflow_dispatch' && inputs.workflow == 'docs-deploy')
57
+ permissions:
58
+ contents: write
59
+ uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-mkdocs-gh-deploy.yml@main # zizmor: ignore[unpinned-uses]
60
+ with:
61
+ package-path: .
62
+ mkdocs-theme: material
63
+ runs-on: ubuntu-slim
64
+ secrets:
65
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
66
+ python-package-release:
67
+ if: >
68
+ github.event_name == 'push'
69
+ || (github.event_name == 'workflow_dispatch' && inputs.workflow == 'lint-and-test')
70
+ permissions:
71
+ contents: write
72
+ id-token: write
73
+ uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-release-on-pypi-and-github.yml@main # zizmor: ignore[unpinned-uses]
74
+ with:
75
+ package-path: .
76
+ create-releases: false
77
+ secrets:
78
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
79
+ dependabot-auto-merge:
80
+ if: >
81
+ github.event_name == 'pull_request' && github.actor == 'dependabot[bot]'
82
+ needs:
83
+ - python-lint-and-scan
84
+ - python-test
85
+ uses: dceoy/gh-actions-for-devops/.github/workflows/dependabot-auto-merge.yml@main # zizmor: ignore[unpinned-uses]
86
+ permissions:
87
+ contents: write
88
+ pull-requests: write
89
+ actions: read
90
+ with:
91
+ unconditional: true
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: Claude Code review and mention bot
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ types:
8
+ - opened
9
+ - ready_for_review
10
+ issue_comment:
11
+ types:
12
+ - created
13
+ pull_request_review_comment:
14
+ types:
15
+ - created
16
+ issues:
17
+ types:
18
+ - opened
19
+ - assigned
20
+ pull_request_review:
21
+ types:
22
+ - submitted
23
+ permissions:
24
+ contents: read
25
+ jobs:
26
+ claude-code-review:
27
+ if: >
28
+ github.event_name == 'pull_request'
29
+ && (! github.event.pull_request.draft)
30
+ && (! startsWith(github.head_ref, 'dependabot/'))
31
+ && (! startsWith(github.head_ref, 'renovate/'))
32
+ permissions:
33
+ contents: read
34
+ pull-requests: write
35
+ issues: write
36
+ id-token: write
37
+ actions: read
38
+ uses: dceoy/gh-actions-for-devops/.github/workflows/claude-code-review.yml@main # zizmor: ignore[unpinned-uses]
39
+ secrets:
40
+ CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} # zizmor: ignore[secrets-outside-env]
41
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42
+ claude-code-bot:
43
+ if: >
44
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude'))
45
+ || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude'))
46
+ || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude'))
47
+ || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
48
+ permissions:
49
+ contents: read
50
+ pull-requests: write
51
+ issues: write
52
+ id-token: write
53
+ actions: read
54
+ uses: dceoy/gh-actions-for-devops/.github/workflows/claude-code-bot.yml@main # zizmor: ignore[unpinned-uses]
55
+ secrets:
56
+ CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} # zizmor: ignore[secrets-outside-env]
57
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: Release
3
+ on:
4
+ workflow_dispatch:
5
+ permissions:
6
+ contents: read
7
+ defaults:
8
+ run:
9
+ shell: bash -euo pipefail {0}
10
+ working-directory: .
11
+ jobs:
12
+ build:
13
+ permissions:
14
+ contents: write
15
+ id-token: write
16
+ uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-release-on-pypi-and-github.yml@main # zizmor: ignore[unpinned-uses]
17
+ with:
18
+ package-path: .
19
+ create-releases: false
20
+ secrets:
21
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22
+ github-release:
23
+ name: Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release
24
+ if: >
25
+ startsWith(github.ref, 'refs/tags/')
26
+ needs:
27
+ - build
28
+ runs-on: ubuntu-latest
29
+ permissions:
30
+ contents: write # IMPORTANT: mandatory for making GitHub Releases
31
+ id-token: write # IMPORTANT: mandatory for sigstore
32
+ steps:
33
+ - name: Download all the dists
34
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
35
+ with:
36
+ name: ${{ needs.build.outputs.distribution-artifact-name }}
37
+ path: dist/
38
+ - name: Validate the version-tag consistency
39
+ env:
40
+ TAG_NAME: ${{ github.ref_name }}
41
+ NEEDS_BUILD_OUTPUTS_PROJECT_NAME: ${{ needs.build.outputs.project-name }}
42
+ run: |
43
+ v="$( \
44
+ find dist -type f -name "${NEEDS_BUILD_OUTPUTS_PROJECT_NAME}-*" -exec basename {} \; \
45
+ | head -n 1 \
46
+ | cut -d '-' -f 2 \
47
+ )"
48
+ v="${v%.tar.gz}"
49
+ if [[ "${TAG_NAME}" != "${v}" ]] && [[ "${TAG_NAME}" != "v${v}" ]]; then
50
+ echo "The tag (${TAG_NAME}) is inconsistent with the version (${v})." && exit 1
51
+ fi
52
+ - name: Sign the dists with Sigstore
53
+ uses: sigstore/gh-action-sigstore-python@04cffa1d795717b140764e8b640de88853c92acc # v3.3.0
54
+ with:
55
+ inputs: >-
56
+ ./dist/*.whl
57
+ - name: Create GitHub Release
58
+ env:
59
+ REPOSITORY: ${{ github.repository }}
60
+ GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} # zizmor: ignore[secrets-outside-env] caller-provided secret
61
+ run: |
62
+ gh release create "${GITHUB_REF_NAME}" --repo "${REPOSITORY}" --generate-notes --verify-tag
63
+ - name: Upload artifact signatures to GitHub Release
64
+ env:
65
+ REPOSITORY: ${{ github.repository }}
66
+ GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} # zizmor: ignore[secrets-outside-env] caller-provided secret
67
+ # Upload to GitHub Release using the `gh` CLI.
68
+ # `dist/` contains the built packages, and the
69
+ # sigstore-produced signatures and certificates.
70
+ run: |
71
+ gh release upload "${GITHUB_REF_NAME}" dist/** --repo "${REPOSITORY}"
72
+ publish-to-pypi:
73
+ name: Publish the Python 🐍 distribution 📦 to PyPI
74
+ if: >
75
+ startsWith(github.ref, 'refs/tags/')
76
+ needs:
77
+ - build
78
+ - github-release
79
+ runs-on: ubuntu-latest
80
+ environment:
81
+ name: pypi
82
+ url: https://pypi.org/p/${{ needs.build.outputs.project-name }}
83
+ permissions:
84
+ id-token: write # IMPORTANT: mandatory for trusted publishing
85
+ steps:
86
+ - name: Download all the dists
87
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
88
+ with:
89
+ name: ${{ needs.build.outputs.distribution-artifact-name }}
90
+ path: dist/
91
+ - name: Publish distribution 📦 to PyPI
92
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
93
+ with:
94
+ verbose: true