[in live chart and every thing is ok

In tester mode but touched low pivot didnt deleted from back or left

Deragon Trading Floor
β―οΈπ₯ποΈβΎοΈπ
[in live chart and every thing is ok

In tester mode but touched low pivot didnt deleted from back or left

i created this mq5 code but i have a little problem
#property copyright "FDFX Copyright 2025"
#property version "1.00"
#property description "Full Market History 10 Candle H1 Pivot Lines"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
#property indicator_type1 DRAW_NONE
#property indicator_type2 DRAW_NONE
#property indicator_label1 "High Pivots"
#property indicator_label2 "Low Pivots"
// Template Settings
input group "===== Template Settings ====="
input bool UseTemplate = true; // Use Chart Template
input bool UseWhiteTheme = true; // Use White Theme (false for Black)
// History Settings
input group "===== History Settings ====="
input bool UseFullHistory = true; // Use Full Market History
input int CustomBars = 1000000; // Custom History Bars (if not full)
input bool ProcessLive = true; // Process Live Market
// Pivot Settings
input group "===== Pivot Settings ====="
input int PivotPeriod = 10; // Pivot Period (Bars)
input bool ShowTouched = false; // Show Touched Pivots
input bool DeleteTouched = true; // Delete Touched Pivots
// Visual Settings
input group "===== Visual Settings ====="
input color HighColor = clrBlue; // High Pivot Color
input color LowColor = clrRed; // Low Pivot Color
input int LineWidth = 1; // Line Width
input ENUM_LINE_STYLE LineStyle = STYLE_SOLID; // Line Style
input bool ShowLabels = true; // Show Pivot Labels
// Global Variables
double HighPivotBuffer[];
double LowPivotBuffer[];
bool isFirstRun = true;
bool templateApplied = false;
bool isHistoricalPivot = false;
struct PIVOT_LINE {
string name;
double level;
datetime time;
bool isHigh;
bool isHistorical;
datetime creationTime;
bool isInitialRun; // New field
};
struct LOW_PIVOT {
datetime time;
double price;
int index;
};
struct PIVOT_STATE {
datetime lastUpdate;
double lastHigh;
double lastLow;
bool touched;
};
PIVOT_LINE currentPivots[];
LOW_PIVOT tempLowPivots[];
PIVOT_STATE pivotState;
datetime lastLineCheck = 0;
datetime currentBarTime = 0;
datetime lastBarTime = 0;
int highPivotCounter = 2;
bool firstHighFound = false;
bool isInTestMode = false;
bool isOptimization = false;
bool isVisualMode = false;
//+------------------------------------------------------------------+
void ApplyTemplate() {
if(!UseTemplate || templateApplied) return;
if(UseWhiteTheme) {
ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite);
ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack);
ChartSetInteger(0, CHART_COLOR_GRID, clrSilver);
ChartSetInteger(0, CHART_COLOR_CHART_UP, clrLimeGreen);
ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrRed);
ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrLimeGreen);
ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrRed);
ChartSetInteger(0, CHART_COLOR_CHART_LINE, clrBlack);
} else {
ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrBlack);
ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrWhite);
ChartSetInteger(0, CHART_COLOR_GRID, clrDimGray);
ChartSetInteger(0, CHART_COLOR_CHART_UP, clrLime);
ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrRed);
ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrLime);
ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrRed);
ChartSetInteger(0, CHART_COLOR_CHART_LINE, clrWhite);
}
templateApplied = true;
ChartRedraw();
}
//+------------------------------------------------------------------+
int OnInit() {
SetIndexBuffer(0, HighPivotBuffer, INDICATOR_DATA);
SetIndexBuffer(1, LowPivotBuffer, INDICATOR_DATA);
ArrayInitialize(HighPivotBuffer, 0.0);
ArrayInitialize(LowPivotBuffer, 0.0);
ArrayResize(currentPivots, 0);
ArrayResize(tempLowPivots, 0);
currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
lastBarTime = currentBarTime;
isInTestMode = MQLInfoInteger(MQL_TESTER);
isOptimization = (bool)MQLInfoInteger(MQL_OPTIMIZATION);
isVisualMode = (bool)MQLInfoInteger(MQL_VISUAL_MODE);
isFirstRun = true;
templateApplied = false;
isHistoricalPivot = false;
pivotState.lastUpdate = 0;
pivotState.lastHigh = 0;
pivotState.lastLow = 0;
pivotState.touched = false;
ResetPivotCounters();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void ResetPivotCounters() {
highPivotCounter = 2;
firstHighFound = false;
ArrayResize(tempLowPivots, 0);
}
//+------------------------------------------------------------------+
bool IsValidPivot(const int index, const int rates_total,
const double &high[], const double &low[],
const bool isHigh)
{
for(int j = 1; j <= PivotPeriod; j++) {
if(index+j >= rates_total-1 || index-j < 0) return false;
if(isHigh) {
if(high[index-j] >= high[index] || high[index+j] >= high[index]) return false;
} else {
if(low[index-j] <= low[index] || low[index+j] <= low[index]) return false;
}
}
return true;
}
//+------------------------------------------------------------------+
bool IsPivotTouched(double level, datetime pivotTime, bool isHigh) {
if(!DeleteTouched || ShowTouched || (isFirstRun && isInTestMode)) return false;
MqlRates currentBar[];
ArrayResize(currentBar, 1);
ArraySetAsSeries(currentBar, true);
if(CopyRates(_Symbol, PERIOD_CURRENT, 0, 1, currentBar) > 0) {
if(isInTestMode) {
if(currentBar[0].time > pivotTime) {
if(isHigh) return (currentBar[0].high > level);
return (currentBar[0].low < level);
}
return false;
}
MqlRates rates[];
ArraySetAsSeries(rates, true);
int bars = iBarShift(_Symbol, PERIOD_CURRENT, pivotTime);
int copied = CopyRates(_Symbol, PERIOD_CURRENT, 0, bars, rates);
if(copied > 0) {
for(int i = 0; i < copied; i++) {
if(isHigh && rates[i].high >= level) return true;
if(!isHigh && rates[i].low <= level) return true;
}
}
}
return false;
}
//+------------------------------------------------------------------+
void CreatePivotLine(string name, datetime time, double price, bool isHigh) {
if(ObjectFind(0, name) >= 0) return;
ObjectCreate(0, name, OBJ_TREND, 0, time, price,
time + PeriodSeconds(PERIOD_CURRENT)*1000, price);
ObjectSetInteger(0, name, OBJPROP_COLOR, isHigh ? HighColor : LowColor);
ObjectSetInteger(0, name, OBJPROP_WIDTH, LineWidth);
ObjectSetInteger(0, name, OBJPROP_STYLE, LineStyle);
ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true);
ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, false);
ObjectSetInteger(0, name, OBJPROP_BACK, false);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, true);
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
ObjectSetInteger(0, name, OBJPROP_HIDDEN, false);
int size = ArraySize(currentPivots);
ArrayResize(currentPivots, size + 1);
currentPivots[size].name = name;
currentPivots[size].level = price;
currentPivots[size].time = time;
currentPivots[size].isHigh = isHigh;
currentPivots[size].isHistorical = isInTestMode && isHistoricalPivot;
currentPivots[size].creationTime = TimeCurrent();
currentPivots[size].isInitialRun = isFirstRun && isInTestMode;
if(ShowLabels) {
string labelName = name + "_label";
ObjectCreate(0, labelName, OBJ_TEXT, 0, time, price);
ObjectSetString(0, labelName, OBJPROP_TEXT, name + " " + DoubleToString(price, _Digits));
ObjectSetInteger(0, labelName, OBJPROP_COLOR, isHigh ? HighColor : LowColor);
ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 8);
}
}
//+------------------------------------------------------------------+
void CheckTouchedLines() {
if(!DeleteTouched) return;
MqlRates currentBar[];
ArrayResize(currentBar, 1);
ArraySetAsSeries(currentBar, true);
if(CopyRates(_Symbol, PERIOD_CURRENT, 0, 1, currentBar) <= 0) return;
datetime currentTime = currentBar[0].time;
for(int i = ArraySize(currentPivots) - 1; i >= 0; i--) {
if(isInTestMode && (currentTime <= currentPivots[i].time || currentPivots[i].isInitialRun)) continue;
bool touched = false;
if(currentPivots[i].isHigh) {
touched = (currentBar[0].high >= currentPivots[i].level);
} else {
touched = (currentBar[0].low <= currentPivots[i].level);
}
if(touched) {
ObjectDelete(0, currentPivots[i].name);
if(ShowLabels) ObjectDelete(0, currentPivots[i].name + "_label");
DeletePivot(i);
}
}
}
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total < PivotPeriod*2 + 1) return(0);
if(isFirstRun) {
if(isInTestMode) {
ApplyTemplate();
isHistoricalPivot = true;
}
isFirstRun = false;
}
ArraySetAsSeries(time, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
currentBarTime = time[0];
if(isInTestMode) {
if(pivotState.lastUpdate != time[0]) {
pivotState.lastHigh = high[0];
pivotState.lastLow = low[0];
pivotState.lastUpdate = time[0];
pivotState.touched = true;
}
}
if(lastBarTime != currentBarTime || prev_calculated == 0) {
if(!isInTestMode || (!isFirstRun && !isHistoricalPivot)) {
ResetPivotCounters();
ObjectsDeleteAll(0, "H");
ObjectsDeleteAll(0, "L");
}
lastBarTime = currentBarTime;
}
int startPos;
if(prev_calculated == 0) {
startPos = UseFullHistory ? rates_total-PivotPeriod-1 : MathMin(CustomBars, rates_total-PivotPeriod-1);
} else {
startPos = MathMin(rates_total-prev_calculated+PivotPeriod, rates_total-2);
}
ArrayResize(tempLowPivots, 0);
for(int i = 2; i <= startPos; i++) {
if(time[i] >= currentBarTime) continue;
bool isLow = IsValidPivot(i, rates_total, high, low, false);
if(isLow && !IsPivotTouched(low[i], time[i], false)) {
int size = ArraySize(tempLowPivots);
ArrayResize(tempLowPivots, size + 1);
tempLowPivots[size].time = time[i];
tempLowPivots[size].price = low[i];
tempLowPivots[size].index = i;
}
bool isHigh = IsValidPivot(i, rates_total, high, low, true);
if(isHigh && !IsPivotTouched(high[i], time[i], true)) {
string objName;
if(!firstHighFound) {
objName = "H1";
firstHighFound = true;
} else {
objName = "H" + IntegerToString(highPivotCounter++);
}
CreatePivotLine(objName, time[i], high[i], true);
HighPivotBuffer[i] = high[i];
}
}
if(ArraySize(tempLowPivots) > 0) {
for(int i = 0; i < ArraySize(tempLowPivots); i++) {
string objName = "L" + IntegerToString(i + 1);
CreatePivotLine(objName, tempLowPivots[i].time, tempLowPivots[i].price, false);
LowPivotBuffer[tempLowPivots[i].index] = tempLowPivots[i].price;
}
}
if(DeleteTouched) {
CheckTouchedLines();
}
if(isInTestMode && !isOptimization && isVisualMode) {
ChartRedraw();
Sleep(50);
}
return(rates_total);
}
//+------------------------------------------------------------------+
void DeletePivot(int index) {
for(int i = index; i < ArraySize(currentPivots)-1; i++) {
currentPivots[i] = currentPivots[i+1];
}
ArrayResize(currentPivots, ArraySize(currentPivots)-1);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
ObjectsDeleteAll(0, "H");
ObjectsDeleteAll(0, "L");
ArrayFree(currentPivots);
ArrayFree(tempLowPivots);
}
everything is good
its draw all 10 candle pivot from entire history and delete touched pivot
in live vreate new pivot and when price touched the drew one it will be deleted
but my real problem is this indicator doase not act in tester mode like live mode
in tester mode it doase not delet used Low pivot from the back of market
i like to get easiest way but i really into build smaerter way to get my code light and clean and fast .... even by the hard way
i appriciate your helping and god bless you and it is
