Development Guide
This guide covers a source checkout, offline validation, bilingual documentation, and the automated delivery pipeline. Runtime behavior and public interfaces are documented in API Reference and Protocol Reference; record user-visible changes in Changelog.
Set up an editable checkout
Python 3.11 or newer is required. CI tests Python 3.11, 3.12, and 3.13 on Linux, macOS, and Windows. Create and activate a virtual environment using your platform’s normal workflow, then install the development and documentation extras from the repository root:
git clone https://github.com/cloudQuant/pymt5.git
cd pymt5
python -m pip install --upgrade pip
python -m pip install -e ".[dev,docs]"
The editable install keeps the pymt5 import pointed at the checkout. The
dev extra supplies pytest, pytest-asyncio, coverage, Hypothesis, mypy, Ruff,
build, and twine; docs supplies Sphinx, the Read the Docs theme, and autodoc
type-hint support. The distribution name remains mt5-web-client.
Run the complete local check
From the repository root:
make check
The target runs, in order:
lint— Ruff lint checks forpymt5/andtests/;typecheck— mypy checks forpymt5/;test— the offline pytest suite with the asyncio plugin explicitly loaded;docs— the Sphinx documentation check; andpackage-check— a clean, isolated wheel/sdist build followed by strict twine metadata validation.
Install both extras before using this target. make package-check removes
stale build metadata and artifacts before building fresh output under dist/
and related build directories; inspect rather than commit generated output. If
one stage fails, fix that stage and rerun it individually before repeating the
complete check.
Individual quality commands
Use the same commands as the Makefile and workflows:
ruff check pymt5/ tests/
python -m mypy pymt5/ --ignore-missing-imports
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest -p pytest_asyncio.plugin tests/ -v --tb=short
On shells that do not support inline environment assignments, set
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 in the process environment and run the same
python -m pytest command. To select a test or file:
python -m pytest tests/test_protocol_smoke.py -v --tb=short
python -m pytest tests/ -k test_name -v --tb=short
For the CI coverage variant, explicitly load both plugins:
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest -p pytest_asyncio.plugin -p pytest_cov.plugin tests/ -v --tb=short --cov=pymt5 --cov-report=term-missing
make format runs ruff format pymt5/ tests/ and rewrites files. Use it
only when formatting changes are intended; it is not a read-only check. Ruff’s
configured target is Python 3.11 with a 120-character line limit. Do not broaden
a formatting or cleanup change beyond the task at hand.
Tests are offline by default
The default suite uses local fakes and binary fixtures; it needs no MT5 server
or credentials. Tests marked integration are skipped unless
PYMT5_INTEGRATION is set. Default CI installs no live credentials and does
not run a live-server acceptance job.
A manual integration run requires a separately authorized demo environment and
PYMT5_SERVER, PYMT5_LOGIN, and PYMT5_PASSWORD.
PYMT5_TEST_SYMBOL can select an exact server symbol for the tick test. No
ticks within 30 seconds causes a skip because the market may be closed, not a
pass that validates tick parsing. Cleanup errors, including rejected
unsubscribes, still matter.
Do not enable live tests in default CI, add real credentials to test files, or use live trading as a substitute for offline tests. Review Security and Operational Safety before any manual live run, keep it read-only unless a mutation is explicitly authorized, and sanitize all output. Passing offline tests establishes local regression coverage, not compatibility with every broker or server build.
Build English and Chinese documentation
Install the docs extra, then run the bilingual build from the repository
root:
python docs/build_docs.py
The documentation build uses docs/ as the English source root and
docs/zh_CN/ as the Simplified Chinese source root. Generated HTML is placed
at:
docs/_build/html/en/for English; anddocs/_build/html/zh-CN/for Simplified Chinese.
These are generated directories and should not be edited or committed. Open the
respective index.html files to inspect navigation, tables, code blocks,
cross-references, and API rendering. Run make docs from the repository root
to build both languages and validate the generated links and language switches,
or run the two scripts separately:
python docs/build_docs.py
python docs/check_docs.py
Sphinx warnings should be fixed at their source rather than hidden. When a page references Python objects, verify signatures against API Reference and current code; when it describes bytes or command behavior, align it with Protocol Reference and identify observations that are build-specific.
Translation parity rule
English and Simplified Chinese pages are complete counterparts. Every new page, section, warning, table row, command, and behavioral qualification must be updated in both languages in the same change. Do not leave one language as a stub, an outdated summary, or a machine-translated fragment.
Keep API names, class and method names, environment variables, command IDs, literal configuration values, file paths, and shell commands identical unless a language-specific convention requires otherwise. Translate prose, headings, and explanatory labels while preserving warnings and uncertainty. In particular, never soften statements about unknown trade outcomes, unofficial protocol support, read-only scope, or unverified server compatibility.
Use each language tree’s local :doc: references. The source directory name
zh_CN intentionally differs from the published zh-CN path. Check both
outputs after documentation changes and review Changelog when describing
release behavior.
CI and GitHub Pages
The CI workflow has separate jobs for tests, lint/type checking, package build, and documentation:
Tests run on Ubuntu, macOS, and Windows with Python 3.11, 3.12, and 3.13.
Ruff and mypy run on Ubuntu with Python 3.12.
Package artifacts are built and checked with twine.
Sphinx documentation is built with warnings treated as errors and
--keep-goingenabled.
No live integration credentials are part of the default matrix. A green CI run therefore means the offline tests and static/package/documentation checks pass; it is not live broker certification.
The GitHub Pages workflow runs on pushes to main or master and by manual
dispatch. It builds the documentation, configures Pages, uploads
docs/_build/html as the Pages artifact, and deploys it through the
github-pages environment. The bilingual site layout exposes English under
/en/ and Simplified Chinese under /zh-CN/. Deployment permissions are
scoped to repository read, Pages write, and the OIDC identity token. A failed
build or upload should be fixed before examining deployment permissions.
Read the Docs
Read the Docs uses its native translation model: pymt5 is the English parent
project and a separate Simplified Chinese project is linked as its translation.
Both projects use the same repository and .readthedocs.yaml. The build
selects docs/ or docs/zh_CN/ from READTHEDOCS_LANGUAGE and writes one
language directly into $READTHEDOCS_OUTPUT/html:
python docs/build_docs.py --readthedocs
Canonical URLs come from READTHEDOCS_CANONICAL_URL rather than a hard-coded
host. Language switches use Read the Docs language/version paths, while GitHub
Pages keeps the combined /en/ and /zh-CN/ artifact. A project maintainer
must create and link the Chinese translation in the Read the Docs dashboard;
this cannot be done by the repository configuration alone.
Release pipeline
Pushing a v*.*.* tag first checks that the tag matches project.version,
both changelog languages, and the source version fallbacks. Tests, lint/type
checks, bilingual documentation, and package verification must all pass before
publication. The package job builds a wheel and sdist, runs strict twine checks,
installs the wheel in a clean virtual environment outside the source tree, and
uploads the exact artifacts for later jobs.
The PyPI job downloads those artifacts and uses Trusted Publishing through the
protected pypi environment. Only that job receives OIDC permission. The
GitHub Release job downloads the same artifacts and attaches them to the release.
Do not upload distributions from a dirty local checkout. PyPI filenames are
immutable, so every release requires a new version and tag.
Contribution checklist
Keep changes focused and preserve public behavior unless the change explicitly requires otherwise.
Add offline regression coverage for fixes, especially timeout, cancellation, protocol parsing, and connection-generation cases.
Run the relevant test first, then
make checkbefore submitting.Update English and Chinese documentation together and verify both builds.
Reference exact APIs and observed protocol evidence; do not invent numeric response-code meanings or claim cross-build validation that was not performed.
Keep credentials, live account data, private terminal bundles, and generated analysis excerpts out of commits and reports, following Security and Operational Safety.
Update Changelog for user-visible changes and use Troubleshooting for operational diagnostics rather than hiding them in development notes.