forked from LengKundee/MQL5-Google-Onedrive
- Optimized `scripts/test_automation.py` by removing ProcessPoolExecutor and executing tests sequentially, reducing overhead for short-running tests. - Implemented 1-second caching for environment API calls and daily limit checks in `ExpertMAPSARSizeOptimized_Improved.mq5`. - Added log throttling and reordered `OnTick` in `ExpertMAPSARSizeOptimized_Improved.mq5` to prioritize cheap checks. - Implemented `IsTradingAllowed` with 1-second caching and integrated it into `SMC_TrendBreakout_MTF_EA.mq5`. - Updated `.jules/bolt.md` with new performance learnings.
32 lines
3.8 KiB
Markdown
32 lines
3.8 KiB
Markdown
# Bolt's Journal ⚡
|
|
|
|
This journal is for CRITICAL, non-routine performance learnings ONLY.
|
|
|
|
- Codebase-specific bottlenecks
|
|
- Failed optimizations (and why)
|
|
- Surprising performance patterns
|
|
- Rejected changes with valuable lessons
|
|
|
|
## 2024-07-25 - MQL5 Native Functions vs. Scripted Loops
|
|
**Learning:** My assumption that a manual MQL5 loop over a pre-cached array would be faster than built-in functions like `iHighest()` and `iLowest()` was incorrect. The code review pointed out that MQL5's native, built-in functions are implemented in highly optimized C++ and are significantly faster than loops executed in the MQL5 scripting layer. The original comment stating this was correct.
|
|
**Action:** Always prefer using MQL5's built-in, native functions for calculations like finding highs/lows over manual loops, even if the data is already in a local array. The performance gain from the native implementation outweighs the overhead of the function call.
|
|
|
|
## 2026-01-23 - Python File System Checks
|
|
**Learning:** Checking for file existence (`os.path.exists`) before getting metadata (`os.path.getmtime`) introduces a redundant syscall. `os.stat()` provides both pieces of information in a single syscall and uses the EAFP (Easier to Ask for Forgiveness than Permission) pattern, which is more Pythonic and slightly faster, especially in high-frequency loops or handlers.
|
|
**Action:** Use `os.stat()` when both existence and metadata are needed, wrapping it in a `try...except OSError` block.
|
|
|
|
## 2026-01-26 - yfinance Bulk Download
|
|
**Learning:** `yfinance` Ticker.history in a loop is significantly slower than `yf.download` with a list of tickers due to sequential HTTP requests. `yf.download` with `group_by='ticker'` provides a consistent MultiIndex structure even for single tickers, simplifying bulk processing.
|
|
**Action:** Always prefer `yf.download(tickers)` over iterating `yf.Ticker(t)` when fetching data for multiple symbols.
|
|
|
|
## 2026-02-09 - Git Command Performance
|
|
**Learning:** `git for-each-ref` is a powerful tool for batch data retrieval, but without filtering, it processes *all* refs, including thousands of stale merged branches in older repositories. Calculating `ahead-behind` counts for these stale branches is O(N) where N is total branches, which can be significantly slower than O(M) where M is active branches.
|
|
**Action:** Always filter `git for-each-ref` with `--no-merged` (or `--merged` depending on use case) when only interested in a subset of branches, especially when expensive formatting options like `ahead-behind` are used.
|
|
|
|
## 2026-02-12 - Python Test Parallelization Overhead
|
|
**Learning:** Using `concurrent.futures.ProcessPoolExecutor` for a small suite of short-running tests (like those executing quick subprocess calls) can be slower than sequential execution. The overhead of spawning processes and managing inter-process communication for output capturing exceeds the performance gain from parallelism when the individual tasks are extremely short.
|
|
**Action:** Prefer sequential execution for lightweight test suites. Parallelism should only be introduced when individual tests have significant execution time that outweighs the process/thread management overhead.
|
|
|
|
## 2026-02-12 - MQL5 Tick Path Caching
|
|
**Learning:** Environment API calls in MQL5 (e.g., `TerminalInfoInteger`, `MQLInfoInteger`) and logic that uses `TimeToStruct`/`StructToTime` are relatively expensive when called on every single price tick. Implementing a simple 1-second cache using a `static datetime` flag significantly reduces this overhead with no impact on trading logic accuracy, as terminal states rarely change more than once per second.
|
|
**Action:** Implement 1-second caching for environment and limit checks in `OnTick` hot paths. Prioritize cheaper internal logic checks before expensive API-based environment checks.
|