MQL5-Google-Onedrive/.jules/bolt.md
google-labs-jules[bot] afeaaa0c39 Bolt: optimize PR review with bulk git metadata
This commit optimizes `scripts/review_pull_requests.py` by implementing bulk
metadata retrieval for Git branches.

Key improvements:
- Reduced subprocess calls from O(N) to O(1) for branch metadata (ahead/behind,
  last commit date, subject) using `git for-each-ref`.
- Implemented `get_git_version()` for safe usage of the `%(ahead-behind)` atom
  (introduced in Git 2.41).
- Added a `BRANCH_METADATA_CACHE` to eliminate redundant `git log` calls.
- Maintained full compatibility with older Git versions via a robust fallback path.
- Preserved output parity with the original script.

Performance impact:
- Execution time reduced from ~2.3s to ~0.56s (~76% improvement) in an
  environment with 315 remote branches.
2026-02-25 18:15:14 +00:00

44 lines
6.5 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.
## 2024-07-26 - Native ArrayMaximum/ArrayMinimum Efficiency
**Learning:** Confirmed that native `ArrayMaximum()` and `ArrayMinimum()` are the preferred way to find extreme values in price arrays. Also, when using these functions, it's important to check if they return `-1` to avoid invalid array access, especially if the `count` or `start` parameters might be dynamic.
**Action:** When replacing manual loops with native array functions, always include a check for the `-1` return value to ensure robustness while gaining performance.
## 2026-01-19 - Native Object Cleanup in MQL5
**Learning:** While iterating through chart objects manually is flexible, it becomes a major bottleneck if the chart has thousands of objects. For simple prefix-based cleanup (often used in indicators), the native `ObjectsDeleteAll(0, prefix)` is significantly more efficient than a scripted loop calling `ObjectName()` and `StringFind()` for every object on the chart.
**Action:** Use `ObjectsDeleteAll()` for bulk object removal by prefix whenever the "keep N latest" logic is not strictly required or can be safely bypassed for performance.
## 2026-01-20 - Robust New Bar Check in MQL5 OnCalculate
**Learning:** An early exit in `OnCalculate` based on bar time MUST check `prev_calculated > 0`. If `prev_calculated == 0`, the terminal is requesting a full recalculation (e.g., after a history sync or data gap fill), and exiting early would result in stale data. Also, using `iTime()` is more robust than indexing into the `time[]` array if the array's series state is unknown.
**Action:** Always wrap "new bar" early exits in indicators with `if(prev_calculated > 0 && ...)` and prefer `iTime()` for the current bar's timestamp.
## 2026-01-20 - MQL5 OnTick Execution Flow Optimization
**Learning:** Significant performance gains in MQL5 EAs can be achieved by carefully ordering the logic in `OnTick`. Moving the `PositionSelect` check before `CopyRates` and `CopyBuffer` avoids expensive data operations when a trade is already active. Additionally, reducing the requested bar count in data fetching functions to the absolute minimum (e.g., 2 instead of 3) and using `SymbolInfoTick` for atomic, lazy price retrieval further reduces overhead.
**Action:** Always place 'gatekeeper' checks (new bar, position existence, terminal trading allowed) at the top of `OnTick` and minimize the data payload for indicator and price fetching to only what is strictly necessary for the current bar's logic.
## 2026-02-04 - Single-Path Lot Normalization and Margin Clamping
**Learning:** Redundant calculations in `CalculateLots()` can be eliminated by applying margin constraints to the raw lot size before any rounding or volume limit checks. This ensures that `MathFloor`, `MathMax`, `MathMin`, and `NormalizeDouble` are executed exactly once. Additionally, pre-calculating the inverse of `SYMBOL_MARGIN_INITIAL` in `OnInit` allows replacing an expensive division with a fast multiplication in the margin clamping path.
**Action:** Always refactor lot calculation functions to follow a "raw-calculate -> clamp-by-margin -> normalize-and-limit" flow, using cached inverse constants for any divisions by fixed symbol properties.
## 2026-02-05 - Optimization of EA Execution Flow and Log Throttling
**Learning:** Major performance gains in high-frequency trading EAs can be achieved by reordering gatekeeper logic in `OnTick`. Placing cheap local math (like time filters or daily limit checks) before expensive cross-process API calls (`TerminalInfoInteger`, `MQLInfoInteger`) saves significant overhead. Additionally, throttling repetitive error logs (like "AutoTrading disabled" or "Daily limit reached") using `static datetime` timers prevents log flooding, which is a common performance bottleneck during market volatility.
**Action:** Always prioritize internal state and arithmetic checks over environment API calls in `OnTick` and implement time-based throttling for any logs or alerts that could be triggered repeatedly on every price tick. In `CheckDailyLimits`, using a `static datetime` flag to remember a reached limit for the day allows for a near-instant exit on subsequent ticks.
## 2026-02-11 - Flask Dashboard Markdown Caching and Syscall Reduction
**Learning:** Rendering Markdown files on every request in a web dashboard is a significant CPU/IO bottleneck. Efficiency can be further improved by consolidating file metadata checks. Using `os.stat()` once is faster than calling `os.path.exists()` and `os.path.getmtime()` separately, as it retrieves all metadata in a single system call. Additionally, extracting large HTML templates to module-level constants avoids repeated memory allocations and string concatenations within the request lifecycle.
**Action:** In Python web scripts, consolidate file metadata retrieval into a single `os.stat()` call and move static template strings outside of request handler functions.
## 2026-02-25 - Bulk Git Metadata Retrieval Performance
**Learning:** In repositories with many branches, calling `git log` or `git branch` repeatedly in a loop is a major performance bottleneck (O(N) subprocess overhead). Using `git for-each-ref` with the `%(ahead-behind:<base>)` atom (Git 2.41+) allows retrieving branch states and metadata in a single call (O(1)). However, robust version checking and fallback logic are essential to prevent functional regressions in environments with older Git versions.
**Action:** When analyzing multiple git references, prioritize bulk retrieval via `for-each-ref` and use a global cache to eliminate redundant subprocess calls for the same reference. Always implement a `git --version` check and a fallback path for the `ahead-behind` atom.