This commit refactors `scripts/review_pull_requests.py` to use bulk Git metadata
retrieval, significantly reducing the number of subprocess calls to the `git` CLI.
Key improvements:
- Replaced O(N) `git log` and `git branch` calls with a single `git for-each-ref`
command utilizing the `%(ahead-behind)` atom (Git 2.41+).
- Implemented `BRANCH_METADATA_CACHE` to store ahead/behind counts, last commit
dates, and commit subjects.
- Added robust Git version detection and a safe fallback for older Git versions.
- Used a multi-character delimiter (|||) to safely handle commit subjects containing
pipes or other special characters.
- Maintained data parity by ensuring unmerged branches still fetch up to 5 recent
commits while merged branches correctly report 0 commits in the range.
Performance impact:
- Reduced execution time from ~0.74s to ~0.37s in a repository with 320+ remote
branches (approx. 50% improvement).
- Subprocess calls reduced from hundreds (proportional to branch count) to ~10.
⚡ Bolt: Speed is a feature. Measure first, optimize second.
Optimized `scripts/ci_validate_repo.py` for performance and memory efficiency:
- Refactored `check_no_nul_bytes` and `check_reasonable_size` into a single-pass `validate_files` function.
- Implemented early size check using `p.stat().st_size` to avoid reading files larger than 5MB.
- Replaced `p.read_bytes()` with chunked binary reading (64KB chunks) to detect NUL bytes, significantly reducing memory overhead.
- Added performance comments and maintained the efficient `rglob('*')` traversal pattern.
Measurements:
- Reduced I/O passes from 2 to 1.
- Reduced peak memory usage for large files from O(N) to O(1) buffer size.
- Faster rejection for oversized files (rejection before reading).
This commit introduces several performance optimizations to the Flask web dashboard:
1. Consolidated file metadata checks in `MarkdownCache` using `os.stat()`. This reduces the number of system calls per request by retrieving both file existence and modification time in a single operation.
2. Extracted the large HTML template into a module-level constant `DASHBOARD_TEMPLATE`. This eliminates redundant memory allocations and string concatenations within the request lifecycle.
3. Pre-defined markdown file paths as constants to avoid repeated `os.path.join()` calls.
4. Simplified `render_template_string` calls by hardcoding static values (like the footer year).
These changes reduce CPU overhead and latency for both the main dashboard and the health check endpoint. Verified via integration tests and Playwright screenshots.
This commit implements a caching mechanism for the web dashboard's Markdown content.
Previously, README.md and VERIFICATION.md were read and rendered on every request.
Now, they are cached and only re-rendered if the file modification time (mtime) changes.
This significantly reduces CPU and I/O overhead for dashboard requests.
Key changes:
- Added MarkdownCache class to scripts/web_dashboard.py
- Moved file path definitions to module level
- Updated health_check route to use cached HTML
- Verified logic with standalone test script (mocked)
- Updated .jules/bolt.md journal with this learning
This commit improves the performance and efficiency of the `ExpertMAPSARSizeOptimized_Improved.mq5` Expert Advisor by:
1. **Optimizing `CheckDailyLimits`**: Added a `static datetime lastLimitLogDay` flag to throttle logs and alerts. Once a daily limit is reached, subsequent calls for the rest of the day exit immediately, avoiding redundant string formatting, logging, and expensive `Alert()` API calls on every tick.
2. **Optimizing `OnTick` Flow**: Reordered the execution path to call `CheckDailyLimits()` before `IsTradingAllowed()`. This prioritizes cheap, internal math checks over more expensive terminal environment API calls (`TerminalInfoInteger`, `MQLInfoInteger`), allowing the EA to exit significantly faster when trading is halted by daily limits.
These changes reduce CPU overhead in the "hot path" and eliminate log/alert flooding during high volatility.
- Pre-calculate daily risk factors (g_lossFactor, g_profitFactor) in OnInit to replace divisions with multiplications in statistics updates.
- Reorder IsTradingAllowed to perform time filter checks before expensive terminal API calls (TerminalInfoInteger, MQLInfoInteger).
- Implement log throttling for trading status messages to prevent flooding during high-frequency ticks.
- Guard new bar debug check in OnTick with log level check to avoid redundant iTime calls.
- Fix invalid LogInfo/LogDebug calls by switching from multiple arguments to string concatenation.
- Optimize Day-Rollover check in OnTick by using casted long for day calculation.
- Add explicit long cast for day calculation to ensure cross-platform consistency.
CI was previously throttled by GitHub API (429), this push triggers a retry.
- Pre-calculate daily risk factors (g_lossFactor, g_profitFactor) in OnInit to replace divisions with multiplications in statistics updates.
- Reorder IsTradingAllowed to perform time filter checks before expensive terminal API calls (TerminalInfoInteger, MQLInfoInteger).
- Implement log throttling for trading status messages to prevent flooding during high-frequency ticks.
- Guard new bar debug check in OnTick with log level check to avoid redundant iTime calls.
- Fix invalid LogInfo/LogDebug calls by switching from multiple arguments to string concatenation.
- Optimize Day-Rollover check in OnTick by using casted long for day calculation.
# Vercel Web Analytics Implementation
## Summary
Successfully implemented Vercel Web Analytics for the MQL5 Trading Automation dashboard project. The implementation follows Vercel's recommended HTML/plain JavaScript approach, which is ideal for this Flask-based application.
## Changes Made
### Modified Files:
1. **dashboard/index.html**
- Added Vercel Web Analytics script tags before the closing `</body>` tag
- Implemented the standard HTML analytics tracking code that initializes the `window.va` function
- Added deferred loading of the Vercel insights script from `/_vercel/insights/script.js`
2. **scripts/web_dashboard.py**
- Updated the Flask application's HTML template to include Vercel Web Analytics
- Added the same analytics script tags to the dynamically generated HTML
- Ensures analytics tracking works on both the static and Flask-rendered pages
### Created Files:
3. **vercel.json**
- Created Vercel deployment configuration file
- Configured builds for both the Python Flask app and static dashboard files
- Set up routing to properly serve the Flask app and static assets
- Added production environment variables for Flask
## Implementation Details
The implementation uses Vercel's HTML/JavaScript approach for web analytics, which:
- Requires no package installation (no @vercel/analytics npm package needed)
- Works seamlessly with Flask and static HTML pages
- Automatically tracks page views and visitor metrics
- Uses deferred script loading for optimal performance
- Will be activated once the project is deployed to Vercel with Web Analytics enabled
## Next Steps for Deployment
To complete the Vercel Web Analytics setup:
1. **Enable Web Analytics in Vercel Dashboard:**
- Go to your Vercel project dashboard
- Click the "Analytics" tab
- Click "Enable" to activate Web Analytics
- This will make the `/_vercel/insights/*` routes available
2. **Deploy to Vercel:**
- Run `vercel deploy` or push to your connected Git repository
- The analytics will automatically start tracking after deployment
3. **Verify Installation:**
- After deployment, visit your site
- Open browser DevTools > Network tab
- Look for a request to `/_vercel/insights/view` to confirm tracking is active
## Technical Notes
- No changes to requirements.txt were needed (Python-only dependencies)
- No package manager operations required (npm/yarn/pnpm)
- The implementation is framework-agnostic and works with plain HTML/JavaScript
- Analytics tracking is non-blocking and won't affect page load performance
- The solution supports both the static HTML dashboard and Flask-rendered pages
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
- Pre-calculate inverse of initial margin in OnInit to avoid division in hot path.
- Refactor CalculateLots to apply margin clamping before normalization.
- Consolidate rounding and clamping logic into a single execution path.
- Remove redundant NormalizeDouble and duplicate calculations.
- Replace GITHUB_TOKEN with PAGES_SYNC_TOKEN for external repo access
- Add graceful degradation when token is not configured
- Add setup documentation in GITHUB_PAGES_SYNC_SETUP.md
- Update GITHUB_CI_CD_SETUP.md with token configuration steps
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
This commit implements significant performance optimizations in the OnTick execution path of the Expert Advisor:
- Caches daily loss and profit limits in currency units (g_maxDailyLossCurrency, g_maxDailyProfitCurrency) to avoid redundant AccountInfoDouble(ACCOUNT_BALANCE) calls and divisions on every tick.
- Refactors IsTradingAllowed and UpdateDailyStatistics to accept an optional datetime parameter, allowing OnTick to pass a pre-fetched TimeCurrent() value and reducing redundant system calls.
- Preserves standard risk management behavior by updating cached limits whenever statistics are refreshed (init, rollover, trades, and timer).
Verified with scripts/ci_validate_repo.py and scripts/test_automation.py.
This optimization improves the execution efficiency of the `SMC_TrendBreakout_MTF` indicator by:
- Replacing the manual buffer clearing loop in `OnCalculate()` with the native `ArrayFill()` function.
- Replacing the `CopyTime()` call in `GetMTFDir()` with the lighter `iTime()` function for MTF bar timestamp checks.
- Refactoring input-based logic (Donchian lookback and signal bar index) into global cached variables initialized in `OnInit()`, avoiding redundant calculations on every new bar.
These changes reduce CPU overhead and improve the indicator's responsiveness, especially when attached to multiple charts or using lower timeframe confirmations.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
- Pre-calculated constants in OnInit() to replace recurring divisions and point-conversions in the trade execution path.
- Optimized CalculateLots(), CalculateSL(), and CalculateTP() by using pre-calculated factors and inverses.
- Consolidated lot limit checks into a single range check.
- Reduced mathematical operations in OnTick() and trade functions.
- Verified with repository CI and automation test scripts.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Replaced expensive TimeToStruct and StructToTime calls with fast integer math for hour extraction and day-rollover detection.
- Consolidated history scanning into UpdateDailyStatistics to handle both profit calculation and trade counting in a single pass.
- Optimized history property retrieval by using ticket-less variants (e.g., HistoryDealGetInteger(DEAL_MAGIC)) after deal selection.
- Refined trade counting to specifically target DEAL_ENTRY_IN deals for robustness against terminal restarts and cleaner logic.
- Removed redundant history scans in OnTrade handler.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
This PR implements several high-impact performance optimizations in `ExpertMAPSARSizeOptimized_Improved.mq5`:
1. **Reduced History Scanning Overhead**: Moved the expensive `UpdateDailyStatistics()` call (which uses `HistorySelect` and loops through deals) out of the `OnTick()` path. It is now called only on trade events, periodic timer intervals, and day rollovers.
2. **Optimized Day-Rollover Logic**: Replaced multiple `TimeToStruct` and `StructToTime` calls in the tick path with a lightweight integer division (`TimeCurrent() / 86400`) to detect calendar day changes.
3. **Efficient History Selection**: Introduced `g_todayStart` to cache the midnight timestamp, ensuring `HistorySelect` targets the current day's data precisely rather than a rolling 24-hour window.
4. **Lightweight New Bar Detection**: Replaced expensive `CopyRates()` calls for logging new bars with a simple `iTime()` lookup.
These changes significantly reduce the CPU and terminal API overhead per tick, which is critical for high-frequency or multi-symbol trading.
📊 **Impact**: Reduces `OnTick` execution time by avoiding redundant history scans on every price update.
🔬 **Measurement**: Verified with `scripts/ci_validate_repo.py` and manual code review against MQL5 performance best practices.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
This commit implements several performance optimizations in the SMC_TrendBreakout_MTF_EA.mq5 Expert Advisor:
1. **Early Exit for Open Positions**: Moved the PositionSelect check to the top of the OnTick handler, immediately after the new bar check. This skips expensive indicator data fetching (CopyRates, CopyBuffer) when a position is already open.
2. **Minimized Data Payload**: Reduced the number of bars fetched from 3 to 2 for CopyRates and all CopyBuffer calls. The current strategy logic only requires the current and previous bars.
3. **Lazy Evaluation of Prices and Indicators**: Deferred SymbolInfoTick and ATR fetching until a trade signal is confirmed.
4. **Atomic Price Retrieval**: Replaced non-standard Ask/Bid variables with SymbolInfoTick for more efficient and robust price retrieval in MQL5.
These changes significantly reduce terminal overhead and data transfer per tick, particularly improving performance during optimization and backtesting.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
Optimized the OnTick hot path in SMC_TrendBreakout_MTF_EA.mq5 by moving TerminalInfoInteger and MQLInfoInteger calls below the iTime() new bar check. This prevents redundant API calls on every price tick, saving CPU resources during high volatility.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
- Optimized lot size calculation by pre-calculating constants in OnInit.
- Converted local arrays in OnTick to static to reuse memory.
- Implemented one-time ArraySetAsSeries calls using a static flag.
- Removed redundant close array and accessed rates directly.
- Deferred ATR CopyBuffer until signal confirmation.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
This commit implements several performance optimizations in the SMC MTF indicator:
1. Robust Early Exit: Added a 'new bar' check using iTime() to skip redundant calculations on every price tick. Handled prev_calculated=0 to ensure full history recalculations when requested.
2. Lazy Loading: Wrapped expensive fractal and Donchian calculations in conditional blocks so they only execute if the respective features are enabled.
3. Efficient Buffer Clearing: Replaced manual O(N) loops with ArrayInitialize() for bulk clearing of indicator buffers on first run.
4. Robustness: Added 'history not ready' checks (iTime == 0) to both the indicator and EA.
5. Cleanup: Removed redundant ArraySetAsSeries calls on static arrays in GetMTFDir and updated comments.
Impact: Reduces CPU usage on every tick by skipping unnecessary logic and improves initialization speed during history loading.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
What:
- Introduced a cached object counter `g_objCount` in `SMC_TrendBreakout_MTF.mq5`.
- Updated `OnInit`, `DrawHLine`, and `DrawText` to maintain this counter.
- Refactored `SafeDeleteOldObjects` to use the cached counter and native `ObjectsDeleteAll()` for efficient bulk removal.
- Fixed a bug in fractal detection logic where `EMPTY_VALUE` was incorrectly identified as a valid swing point.
Why:
- The original `SafeDeleteOldObjects` performed two $O(N)$ passes over every object on the chart using relatively slow scripted functions (`ObjectName`, `StringFind`) on every new bar. This created a performance bottleneck on charts with many objects.
- The fractal bug caused incorrect swing point identification, leading to false signals and unnecessary processing of invalid data.
Impact:
- Significantly reduces CPU usage on new bars by avoiding redundant iterations over chart objects.
- Improves indicator accuracy and reliability by ensuring only valid fractal points are used for signal calculation.
Measurement:
- Verified via code review and manual inspection of the logic.
- Repository integrity confirmed by `ci_validate_repo.py` and `test_automation.py`.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
💡 What: Replaced manual `for` loops in `HighestHigh` and `LowestLow` with native `ArrayMaximum` and `ArrayMinimum` functions in `mt5/MQL5/Indicators/SMC_TrendBreakout_MTF.mq5`.
🎯 Why: Native MQL5 functions are implemented in optimized C++ and are significantly faster than loops executed in the MQL5 scripting layer.
📊 Impact: Improves the performance of Donchian channel calculation, reducing indicator overhead per bar.
🔬 Measurement: Verified with existing CI validation and code inspection.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
Replaced manual loops in HighestHigh and LowestLow functions with native MQL5 ArrayMaximum and ArrayMinimum functions in mt5/MQL5/Indicators/SMC_TrendBreakout_MTF.mq5.
What: Replaced MQL5 script-level iterative loops with native C++ implemented functions for finding extreme values in price arrays.
Why: Native MQL5 functions are significantly faster than manual loops as they are executed in compiled C++.
Impact: Reduces execution time for indicator calculations on every new bar, improving overall EA performance during backtesting and live trading.
Measurement: MQL5 documentation confirms native functions are optimized for performance. The code now includes safety checks for the -1 return value.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
Refactored the CalculateSL function in the SMC Trend Breakout EA to merge the logic for SL_ATR and SL_SWING modes.
The original implementation had redundant code blocks for these two modes. This change consolidates the logic into a single, more efficient path, improving code readability and maintainability. While the performance impact is negligible, this change aligns with best practices for writing clean and efficient code.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
Corrects the CI workflow to prevent 'manifest unknown' errors.
The `docker/metadata-action` generates a Docker tag with a shortened git SHA, but subsequent `docker run` and `docker pull` commands were attempting to use the full-length SHA, causing the image to not be found.
This fix modifies the `build-and-test` job to expose the generated tags as an output. The test and deployment steps are updated to consume this output, ensuring that the correct, shortened SHA tag is used throughout the workflow.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>