This commit implements several performance optimizations in the `SMC_TrendBreakout_MTF_EA.mq5` Expert Advisor:
1. **Lazy Account Info Retrieval**: Refactored `OnTick` to fetch `ACCOUNT_BALANCE`, `ACCOUNT_EQUITY`, and `ACCOUNT_MARGIN_FREE` only when a signal is confirmed and based on current risk settings. This significantly reduces terminal API calls.
2. **Local Fixed-Size Arrays**: Replaced `static` dynamic arrays with local fixed-size arrays for `emaFast`, `emaSlow`, and `atr` data. This avoids the overhead of dynamic memory management and `ArraySetAsSeries`.
3. **Redundant Calculation Removal**: Optimized `OpenBuyTrade` and `OpenSellTrade` by pre-calculating `slDistance` once and passing it to `CalculateTP` and `CalculateLots`.
4. **Optimized Function Signatures**: Updated `CalculateTP` and `CalculateLots` to accept only the necessary metrics and pre-calculated values.
These changes result in a leaner "hot path" and reduced overhead during trade execution.
- 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>
Lazily loads the EMA confirmation indicator data in the `OnTick` function.
This change refactors the `OnTick` function to first check for a primary trade signal (Donchian Channel breakout) before fetching the data for the secondary confirmation indicators (EMAs).
This avoids two expensive `CopyBuffer()` calls on every new bar, reducing unnecessary processing and improving the overall efficiency of the EA, especially in non-trending markets where trade signals are infrequent. The functional logic remains identical.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
After multiple unsuccessful attempts to dynamically correct the Docker image name, this commit resolves the persistent CI failures by hardcoding the `IMAGE_NAME` environment variable to a valid, lowercase string.
The root cause of the failures was the use of ` ${{ github.repository }}`, which contains uppercase letters, as the Docker image name. This is not allowed by Docker's naming conventions. Previous attempts to fix this with dynamic conversions proved unreliable.
This change ensures that the image name is always valid, which will allow the CI build to pass without any "invalid reference format" or "manifest unknown" errors.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
The CI build was failing with a "manifest unknown" error because the `docker/metadata-action` was generating a Docker tag with a short Git SHA, while the testing step was trying to pull the image using the full-length SHA.
This commit fixes the issue by configuring the `docker/metadata-action` to use the full-length Git SHA for its tags. This is achieved by adding `sha-len=0` to the `sha` tag type in the workflow file. This ensures that the tag used to build and push the image is the same one used to run the tests, resolving the mismatch.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
The CI build was failing because the Docker image name, derived from the GitHub repository name, contained uppercase letters, which is not allowed by Docker.
This commit fixes the issue by adding a step to the GitHub Actions workflow to convert the repository name to lowercase before using it as the image name. The corrected lowercase name is then used in all subsequent Docker commands within the `build-and-test` and `deploy-dev` jobs.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
This optimization caches account information (balance, equity, free margin) by fetching it once at the start of the `OnTick` function. This data is then passed down as arguments to the trade execution and lot calculation functions.
This change reduces the number of `AccountInfoDouble()` calls from three to one per tick when a trade signal is evaluated, lowering the execution time of the `OnTick` function and making the EA more efficient.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>
Refactored the `OnTick()` function to use the lightweight `iTime()` function for the new bar check *before* the expensive `CopyRates()` call.
The original implementation called `CopyRates()` on every single price tick, which is highly inefficient. The `OnTick` function is a performance-critical hot path, and this caused unnecessary resource consumption.
This change reduces CPU usage by preventing the `CopyRates()` data-copying operation on the vast majority of ticks. The EA now only performs expensive calculations once per bar, as intended.
Co-authored-by: Mouy-leng <199350297+Mouy-leng@users.noreply.github.com>