2026-03-11 22:57:36 +00:00
<p align="center">
<img src="./Images/MQLCIByLeo.png" alt="MQLCIByLeo Logo" width="1150" height="175"/>
</p>
2026-03-08 23:13:28 +00:00
2026-03-11 22:57:36 +00:00
<p align="center">
CI framework for MQL5. Automatically compiles and validates EAs and libraries.
</p>
<p align="center">
<img src="https://img.shields.io/badge/Language-MQL5-1B6CA8?style=flat-square"/>
<img src="https://img.shields.io/badge/Platform-MetaTrader%205-0D1B2A?style=flat-square"/>
<img src="https://img.shields.io/badge/Author-nique__372%20and%20Leo-C9D6DF?style=flat-square"/>
<a href="./LICENSE.md">
<img src="https://img.shields.io/badge/License-Source%20Available-blue.svg?style=flat-square"/>
</a>
<a href="./LICENSE.md">
<img src="https://img.shields.io/badge/Non--Commercial-Free-brightgreen.svg?style=flat-square"/>
</a>
<a href="./LICENSE.md">
<img src="https://img.shields.io/badge/AI%20LLm%20Training-Prohibited-critical.svg?style=flat-square"/>
</a>
</p>
---
## How it works
2026-03-12 16:54:31 +00:00
1. `repo_update.py` Recursively updates all repository dependencies
2. `launcher.py` opens MT5 with the orchestrator EA
3. The orchestrator compiles and runs each test EA sequentially
4. Each test EA uses `CiTestUtil` to validate and report results via `EventChartCustom`
5. `reviser.py` reads the result and returns exit code `0` or `1` to Actions
2026-03-11 22:57:36 +00:00
---
## Features
### Orchestrator — run multiple test EAs automatically
```cpp
CMqlCIClassCi g_ci_ea;
#define FOLDER_CI "TbpCi\\"
// Initial config
MqlCiConfigCompiler config;
config.max_timeout_ms_compile = (60 * 1000); // 1 minute
config.max_timeout_esecution_per_test = (60 * 1); // 1 minute per test
config.file_name_out_json = FOLDER_CI + "result_logs.json";
config.file_name_read_py = FOLDER_CI + "read_py.bin";
config.file_name_res = FOLDER_CI + "result.bin";
config.filename_compiled_log = FOLDER_CI + "last_compile_log.log";
// Define test EAs
TestExpertCi experts[1];
experts[0].expert_ex5_name = "Experts\\Shared Projects\\TbpWrraper\\Workflows\\Test\\GetAllClients.ex5";
experts[0].expert_mq5_path = "Shared Projects\\TbpWrraper\\Workflows\\Test\\GetAllClients.mq5";
experts[0].symbol = "EURUSD";
experts[0].timeframe = PERIOD_M1;
experts[0].params[2].type = TYPE_STRING;
experts[0].params[2].string_value = InpApiKey;
// Init and run
g_ci_ea.AddLogFlags(LOG_ALL);
if(!g_ci_ea.Init(config, experts))
return INIT_FAILED;
if(!g_ci_ea.First())
return INIT_FAILED;
```
> **Note:** `params[0]` and `params[1]` are always reserved by the framework (EA name and chart ID). User params start at index `2`.
---
### Unit test class — validate a single class or module
```cpp
CiTestUtil test_util;
test_util.TestSize(2);
test_util.SetTestPtr(0, new CTestCustomer());
test_util.SetTestPtr(1, new CTestJobs());
// (chart_id, min_importance_for_early_exit, label, min_percentage_to_pass)
test_util.Init(InpCharId, 70, "Test api #1 ", 80.0);
test_util.RunAllTestAndSend();
```
Each test implements `ICiTest` and declares its own importance (1–100):
```cpp
class CTestCustomer : public ICiTest
{
inline string Name() const override { return "GetCustomers"; }
inline int Importance() const override { return 90; } // High — early exit if fails
bool Run(string &msg) override
{
if(!m_api.GetCustomersSoftware()) { msg = "HTTP call failed"; return false; }
return true;
}
};
```
| Importance range | Level | Behavior on failure |
|------------------|--------|-----------------------------------|
| 70 – 100 | High | Early exit, test suite aborted |
| 30 – 69 | Medium | Continues, lowers overall score |
| 0 – 29 | Low | Informational, minimal impact |
The final score is calculated as:
```
score = (sum of passed importances / total importances) * 100
```
If `score < min_percentage_to_pass` → test suite fails.
### Complete example
- The repository [TbpWrraper ](https://forge.mql5.io/nique_372/TbpWrraper ) integrates this repository for testing
---
### Python scripts
| Script | Purpose |
|----------------|------------------------------------------------------------------|
2026-03-12 16:54:31 +00:00
| `repo_update.py` | Recursively updates all repository dependencies |
2026-03-11 22:57:36 +00:00
| `compiler.py` | Compiles the orchestrator EA |
| `launcher.py` | Launches MT5 with the orchestrator EA |
| `reviser.py` | Polls for results and returns exit code `0` (pass) or `1` (fail) |
---
### Actions integration
```yaml
jobs:
test:
runs-on: self-hosted # Windows or linux (preference: windows)
steps:
- uses: actions/checkout@v3
- name: Run CI
run: |
python Src/Py/reviser.py \
--terminal_path "C:\Users\...\Terminal\XXX" \
--file_name_res "TbpCi/result.bin" \
--file_name_out_json "TbpCi/result_logs.json" \
--filename_compiled_log "TbpCi/last_compile_log.log" \
--file_name_read_py "TbpCi/read_py.bin"
```
> **Note:** The YAML is not included in this repository — each project integrates its own workflow.
> `reviser.py` works on both Windows and Linux out of the box. `launcher.py` and `compiler.py`
> may require adjustments depending on your OS and MT5 installation path.
> The `--terminal_path` argument varies by OS:
> - **Windows example:** `C:\Users\USER\AppData\Roaming\MetaQuotes\Terminal\XXX`
> - **Linux (Wine) example:** `/home/user/.mt5/drive_c/Program Files/MetaTrader 5`
---
## Repository structure
```
MqlCIByLeo/
├── Src/
│ ├── Tester/ # MQL5 orchestrator (CMqlCIClassCi)
│ ├── UnitTest/ # ICiTest + CiTestUtil
│ └── Py/ # Python scripts (compiler, launcher, reviser)
└── Images/ # Repository banner
```
---
## Requirements
2026-03-12 01:14:29 +00:00
See [dependencies.json ](./dependencies.json ).
2026-03-11 22:57:36 +00:00
---
## Installation
- Clone the repository into your MT5 `Shared Projects` folder via cmd.
- Contact me privately on MQL5 (user: `nique_372` ) to be added as a collaborator — the repository will then appear automatically in your Shared Projects.
- Or fork the repository.
---
## Disclaimer
**Trading involves substantial risk of loss.**
- This software is a technical tool, not financial advice
- Past performance does not guarantee future results
- You are solely responsible for your trading decisions
- Always test thoroughly before deploying with real capital
- Apply appropriate risk management at all times
The authors assume no liability for trading losses, system failures, or any damages arising from the use of this software.
---
## License
**[Read Full License ](./LICENSE.md )**
---
## Contact
- **Platform:** [MQL5 Community ](https://www.mql5.com/es/users/nique_372 )
- **Profile:** https://www.mql5.com/es/users/nique_372/news
---
<p align="center">Copyright © 2026 Nique-Leo.</p>