
Mql5 Indicator Patterns
- 436 installs
- 62 repo stars
- Updated August 3, 2026
- terrylica/cc-skills
mql5-indicator-patterns is a Claude Code skill that supplies battle-tested MetaTrader 5 indicator patterns for developers who need correct OnCalculate buffers, warmup, and display scaling.
About
mql5-indicator-patterns is an MQL5 development skill in terrylica/cc-skills with production patterns for custom MetaTrader 5 indicators. It covers explicit IndicatorSetDouble scaling for small values under 1.0, visible plus hidden SetIndexBuffer layouts, static new-bar detection to prevent rolling-window drift, and PLOT_DRAW_BEGIN warmup alignment. A troubleshooting table maps eight common failures—blank windows, drifting values, misaligned plots, reversed arrays, buffer type mistakes, compile mismatches, stale updates, and performance issues—to concrete fixes. Four reference docs expand display-scale, buffer-patterns, recalculation, complete-template, and debugging guidance. The skill is self-evolving: agents update SKILL.md when reproducible MT5 edge cases appear. Reach for mql5-indicator-patterns when authoring or debugging custom indicators where official docs leave buffer lifecycle and display scaling ambiguous.
- mql5-indicator-patterns
Mql5 Indicator Patterns by the numbers
- 436 all-time installs (skills.sh)
- +4 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #963 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/terrylica/cc-skills --skill mql5-indicator-patternsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 436 |
|---|---|
| repo stars | ★ 62 |
| Last updated | August 3, 2026 |
| Repository | terrylica/cc-skills ↗ |
How do you fix blank MQL5 indicator windows?
Use mql5-indicator-patterns for development tasks
Who is it for?
Developers building or debugging custom MetaTrader 5 indicators who hit blank charts, drift, or misaligned plot starts in production.
Skip if: Teams only needing Python parquet ingestion or log parsing in the same cc-skills MQL5 plugin without writing indicator code.
When should I use this skill?
User mentions MQL5 indicator, OnCalculate, indicator buffers, blank indicator window, or MetaTrader 5 plot misalignment.
What you get
Production-ready OnCalculate templates, buffer setup snippets, warmup-aligned plots, and a troubleshooting checklist for MT5 indicators.
- OnCalculate pattern snippets
- buffer architecture templates
- indicator troubleshooting checklist
By the numbers
- Includes an 8-row troubleshooting table for common MT5 indicator failures
- Documents 4 reference guides for display, buffers, recalculation, and templates
- Lists 6 essential production patterns from scaling through forward-indexed arrays
Files
MQL5 Visual Indicator Patterns
Battle-tested patterns for creating custom MQL5 indicators with proper display, buffer management, and real-time updates.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
When to Use This Skill
Use this skill when:
- Creating custom MQL5 indicators for MetaTrader 5
- Debugging indicator display or buffer issues
- Setting up OnCalculate with proper warmup handling
- Implementing new bar detection patterns
Quick Reference
Essential Patterns
Display Scale (for small values < 1.0):
IndicatorSetDouble(INDICATOR_MINIMUM, 0.0);
IndicatorSetDouble(INDICATOR_MAXIMUM, 0.1);Buffer Setup (visible + hidden):
SetIndexBuffer(0, BufVisible, INDICATOR_DATA); // Visible
SetIndexBuffer(1, BufHidden, INDICATOR_CALCULATIONS); // HiddenNew Bar Detection (prevents drift):
static int last_processed_bar = -1;
bool is_new_bar = (i > last_processed_bar);Warmup Calculation:
int StartCalcPosition = underlying_warmup + own_warmup;
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, StartCalcPosition);---
Common Pitfalls
Blank Display: Set explicit scale (see Display Scale reference)
Rolling Window Drift: Use new bar detection with hidden buffer (see Recalculation reference)
Misaligned Plots: Calculate correct PLOT_DRAW_BEGIN (see Complete Template reference)
Forward-Indexed Arrays: Always set ArraySetAsSeries(buffer, false)
---
Key Patterns
For production MQL5 indicators:
1. Explicit scale for small values (< 1.0 range) 2. Hidden buffers for recalculation tracking 3. New bar detection prevents rolling window drift 4. Static variables maintain state efficiently 5. Proper warmup calculation prevents misalignment 6. Forward indexing for code clarity
These patterns solve the most common indicator development issues encountered in real-world MT5 development.
---
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Blank indicator window | Scale not set for small values | Set INDICATOR_MINIMUM/MAXIMUM explicitly |
| Values drifting over time | Rolling window not reset | Use new bar detection with hidden buffer |
| Misaligned plot start | Wrong PLOT_DRAW_BEGIN | Calculate: underlying_warmup + own_warmup |
| Reversed array indexing | Series mode enabled | Call ArraySetAsSeries(buffer, false) |
| Buffer values incorrect | Wrong INDICATOR_DATA type | Use INDICATOR_CALCULATIONS for hidden buffers |
| Compile error on buffer | Buffer count mismatch | Match #property indicator_buffers with SetIndexBuffer |
| Indicator not updating | OnCalculate return wrong | Return rates_total to signal successful calculation |
| Performance issues | Recalculating all bars | Only recalculate from prev_calculated onwards |
---
Reference Documentation
For detailed information, see:
- Display Scale - Fix blank indicator windows for small values
- Buffer Patterns - Visible and hidden buffer architecture
- Recalculation - Bar detection and rolling window state management
- Complete Template - Full working example with all patterns
- Debugging - Checklist for troubleshooting display issues
Post-Execution Reflection
After this skill completes, check before closing:
1. Did the command succeed? — If not, fix the instruction or error table that caused the failure. 2. Did parameters or output change? — If the underlying tool's interface drifted, update Usage examples and Parameters table to match. 3. Was a workaround needed? — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.
Only update if the issue is real and reproducible — not speculative.
Skill: MQL5 Visual Indicator Patterns
Part 2: Buffer Architecture Patterns
Two-Buffer Pattern (Visible + Hidden)
Use when tracking previous values for recalculation:
#property indicator_buffers 2 // Total buffers
#property indicator_plots 1 // Visible plots
double BufVisible[]; // Plot buffer
double BufHidden[]; // Tracking buffer
int OnInit()
{
SetIndexBuffer(0, BufVisible, INDICATOR_DATA); // Visible
SetIndexBuffer(1, BufHidden, INDICATOR_CALCULATIONS); // Hidden
return INIT_SUCCEEDED;
}Buffer Types:
INDICATOR_DATA: Visible plot (appears on chart)INDICATOR_CALCULATIONS: Hidden buffer (for internal calculations)
Why use hidden buffers:
- Store previous bar values for recalculation
- Track intermediate calculation steps
- Maintain rolling window state
Skill: MQL5 Visual Indicator Patterns
Part 7: Complete Example Template
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
#property indicator_label1 "My Indicator"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrOrange
#property indicator_width1 2
input int InpPeriod = 20;
input int InpWindow = 30;
double BufVisible[];
double BufHidden[];
int hBase = INVALID_HANDLE;
int OnInit()
{
// Buffers
SetIndexBuffer(0, BufVisible, INDICATOR_DATA);
SetIndexBuffer(1, BufHidden, INDICATOR_CALCULATIONS);
// Warmup
int StartCalcPosition = InpPeriod + InpWindow - 1;
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, StartCalcPosition);
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
// Explicit scale for small values
IndicatorSetDouble(INDICATOR_MINIMUM, 0.0);
IndicatorSetDouble(INDICATOR_MAXIMUM, 1.0);
// Base indicator
hBase = iSomeIndicator(_Symbol, _Period, InpPeriod);
if(hBase == INVALID_HANDLE) return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(hBase != INVALID_HANDLE) IndicatorRelease(hBase);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
...)
{
int StartCalcPosition = InpPeriod + InpWindow - 1;
if(rates_total <= StartCalcPosition) return 0;
// Get base data
static double base[];
ArrayResize(base, rates_total);
ArraySetAsSeries(base, false);
if(CopyBuffer(hBase, 0, 0, rates_total, base) < rates_total)
return prev_calculated;
// Set forward indexing
ArraySetAsSeries(BufVisible, false);
ArraySetAsSeries(BufHidden, false);
// Start position
int start = (prev_calculated == 0) ? StartCalcPosition : prev_calculated - 1;
if(start < StartCalcPosition) start = StartCalcPosition;
// Initialize early bars
if(prev_calculated == 0)
{
for(int i = 0; i < start; i++)
{
BufVisible[i] = EMPTY_VALUE;
BufHidden[i] = EMPTY_VALUE;
}
}
// Rolling window state
static double sum = 0.0;
static int last_processed_bar = -1;
// Prime window on first run
if(prev_calculated == 0 || start == StartCalcPosition)
{
sum = 0.0;
last_processed_bar = StartCalcPosition - 1;
for(int j = start - InpWindow + 1; j <= start; j++)
sum += base[j];
}
// Main loop
for(int i = start; i < rates_total && !IsStopped(); i++)
{
bool is_new_bar = (i > last_processed_bar);
// Slide window on new bar
if(is_new_bar && i >= InpWindow)
{
int idx_out = i - InpWindow;
sum -= base[idx_out];
}
double current = base[i];
// Update sum
if(is_new_bar)
{
sum += current;
}
else
{
if(i == last_processed_bar && BufHidden[i] != EMPTY_VALUE)
sum -= BufHidden[i];
sum += current;
}
last_processed_bar = i;
// Calculate & store
BufHidden[i] = current;
BufVisible[i] = sum / InpWindow;
}
return rates_total;
}Skill: MQL5 Visual Indicator Patterns
Part 8: Debugging Checklist
When indicator not displaying correctly:
1. Check scale:
- [ ] Added
IndicatorSetDouble(INDICATOR_MINIMUM/MAXIMUM)? - [ ] Range appropriate for data values?
1. Check buffers:
- [ ]
indicator_buffers>=indicator_plots? - [ ] Hidden buffers for tracking old values?
- [ ]
ArraySetAsSeries(buffer, false)for all buffers?
1. Check warmup:
- [ ]
PLOT_DRAW_BEGINcalculated correctly? - [ ] Early bars initialized to
EMPTY_VALUE?
1. Check recalculation:
- [ ] Bar detection logic (
is_new_bar)? - [ ] Old value subtraction before adding new?
- [ ]
last_processed_bartracking working?
1. Check data flow:
- [ ] Base indicator handle valid?
- [ ]
CopyBufferreturning expected count? - [ ] No
EMPTY_VALUEin calculated range?
Skill: MQL5 Visual Indicator Patterns
Part 1: Display Scale Management
Problem: Blank Indicator Window
Symptom: Indicator compiles successfully but shows blank/empty window on chart
Root Cause: MT5 auto-scaling fails for very small values (e.g., 0.00-0.05 range)
Solution: Explicit Scale Setting
int OnInit()
{
// ... other initialization ...
// FIX: Explicitly set scale range for small values
IndicatorSetDouble(INDICATOR_MINIMUM, 0.0);
IndicatorSetDouble(INDICATOR_MAXIMUM, 0.1);
return INIT_SUCCEEDED;
}When to use:
- Score/probability indicators (0.0-1.0 range)
- Normalized metrics with small variations
- Any values where range < 1.0
Reference: MQL5 forum threads 135340, 137233, 154523 document this limitation
Evolution Log
Convention: Reverse chronological order (newest on top, oldest at bottom). Prepend new entries.
---
2026-02-26: Initial Evolution Log
Status: Skill is in use and maintained. Track improvements here.
Purpose
This evolution log tracks updates to the skill. Each entry should note:
- What changed (content, structure, tooling)
- Why it changed (bug fix, feature request, best practice)
- Files affected
How to Use
1. When updating SKILL.md or references, add an entry here with the date 2. Keep entries reverse-chronological (newest first) 3. Link to ADRs or GitHub issues when relevant 4. Reference specific line changes when helpful
---
Skill: MQL5 Visual Indicator Patterns
Part 3: Bar Recalculation Pattern
Problem: Rolling Window Drift
Current bar updates with each tick. Naive implementations double-count values, causing drift in rolling statistics.
Solution: New Bar Detection + Value Replacement
// Static variables preserve state between OnCalculate calls
static double sum = 0.0;
static int last_processed_bar = -1;
int OnCalculate(const int rates_total, const int prev_calculated, ...)
{
for(int i = start; i < rates_total; i++)
{
// Detect if this is a NEW bar (not recalculation)
bool is_new_bar = (i > last_processed_bar);
double current_value = GetValue(i);
if(is_new_bar)
{
// NEW BAR: Add to window, slide if needed
if(i >= window_size)
{
int idx_out = i - window_size;
sum -= BufHidden[idx_out]; // Remove oldest
}
sum += current_value; // Add newest
}
else
{
// RECALCULATION: Replace old value with new value
if(i == last_processed_bar && BufHidden[i] != EMPTY_VALUE)
{
sum -= BufHidden[i]; // Remove old contribution
}
sum += current_value; // Add new value
}
// Store for next recalculation
BufHidden[i] = current_value;
last_processed_bar = i;
// Calculate indicator using sum
BufVisible[i] = sum / window_size;
}
return rates_total;
}Key points:
is_new_bardifferentiates new bars from recalculation- Hidden buffer stores old values for subtraction
- Static
last_processed_bartracks position - Only slide window on NEW bars
---
Part 4: Rolling Window State Management
Pattern: Static Sum Variables
static double sum = 0.0;
static double sum_squared = 0.0;
static int last_processed_bar = -1;
// Initialize sums on first run
if(prev_calculated == 0 || start == StartCalcPosition)
{
sum = 0.0;
sum_squared = 0.0;
last_processed_bar = StartCalcPosition - 1;
// Prime the window with initial values
for(int j = start - window_size + 1; j <= start; j++)
{
double x = GetValue(j);
sum += x;
sum_squared += x * x;
}
}Why static variables:
- Preserve state between
OnCalculate()calls - Avoid recalculating entire window each tick
- Enable O(1) sliding window updates
Initialization pattern:
- Reset on first run (
prev_calculated == 0) - Prime window with initial N values
- Update incrementally thereafter
Related skills
How it compares
Use mql5-indicator-patterns for MT5 indicator buffer and display issues; pick generic MQL5 EA skills when strategy logic—not indicator rendering—is the blocker.
FAQ
Why do MQL5 indicators show blank windows for small values?
mql5-indicator-patterns explains that MetaTrader 5 auto-scales poorly for values under 1.0. Set IndicatorSetDouble on INDICATOR_MINIMUM and INDICATOR_MAXIMUM explicitly, as documented in the display-scale reference, to render small-range plots.
How does mql5-indicator-patterns prevent indicator drift?
mql5-indicator-patterns recommends static last_processed_bar tracking with hidden INDICATOR_CALCULATIONS buffers so OnCalculate only advances on new bars. This stops rolling-window state from accumulating errors across ticks.
What references ship with mql5-indicator-patterns?
mql5-indicator-patterns links four references—display-scale, buffer-patterns, recalculation, and complete-template—plus a debugging checklist. Together they cover warmup math, forward-indexed arrays, and full working indicator templates.