forked from LengKundee/MQL5-Google-Onedrive
This commit implements several performance optimizations for the `ExpertMAPSARSizeOptimized_Improved.mq5` Expert Advisor: 1. **OnTick Gatekeeper Optimization**: Added an early-exit 'new bar' check using the lightweight `iTime()` function at the very beginning of `OnTick`. This prevents expensive terminal API calls and logic from executing on every price tick when not required (when `Expert_EveryTick` is false). 2. **Event-Driven Statistics**: Relocated the expensive `UpdateDailyStatistics()` call, which performs history scanning, from the high-frequency `OnTick` path to the event-driven `OnTrade()` handler and a periodic `OnTimer()` handler (60 seconds). 3. **Startup Initialization**: Added an initial call to `UpdateDailyStatistics()` in `OnInit()` to ensure accurate statistics upon EA startup. 4. **Timer Management**: Enabled `EventSetTimer(60)` in `OnInit()` and added proper cleanup with `EventKillTimer()` in `OnDeinit()`. 5. **Efficient History Selection**: Refactored `UpdateDailyStatistics()` to use a specifically calculated `todayStart` timestamp for `HistorySelect()`, reducing terminal data retrieval overhead compared to the previous rolling 24-hour window. 6. **Redundancy Removal**: Removed an expensive and redundant `CopyRates()` call used for bar time tracking at the end of `OnTick()`. These changes significantly reduce CPU usage and terminal overhead, especially during high-volatility market conditions with rapid tick streams. Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
32 lines
4.2 KiB
Markdown
32 lines
4.2 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-01-20 - MQL5 Event-Driven Statistics Optimization
|
|
**Learning:** Relocating heavy history scanning logic (like calculating daily profit/loss) from the high-frequency `OnTick` handler to event-driven handlers (`OnTrade`) and periodic timers (`OnTimer`) significantly reduces per-tick CPU overhead. However, it is critical to also call these functions in `OnInit` to ensure data is correctly initialized on startup. Additionally, optimizing `HistorySelect` to use a calendar-day `todayStart` instead of a rolling 24-hour window further reduces terminal data retrieval overhead.
|
|
**Action:** Move expensive statistics and history processing out of `OnTick`. Use `EventSetTimer` for periodic updates and call the processing function in `OnInit` and `OnTrade`. Use specific `HistorySelect` ranges to minimize data volume.
|