..
#property copyright "Copyright © 2025" #property version "1.00" #property strict #property indicator_chart_window
//--- Input parameters extern string Separator1 = "=== Opening Range Settings ===" extern int OR_StartHour = 9 // Hour when OR starts (0-23) extern int OR_StartMinute = 30 // Minute when OR starts (0-59) extern int OR_DurationMinutes = 30 // Length of OR in minutes (e.g. 15, 30, 60, 120) extern color OR_HighColor = clrLime extern color OR_LowColor = clrYellow extern int OR_LineStyle = STYLE_DOT extern int OR_LineWidth = 1 extern bool ShowComment = true
//--- Global variables string prefix = "FlexOR_" datetime last_day_checked = 0 double or_high = 0 double or_low = 0 bool or_complete = false
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { ObjectDelete(0, prefix+"High") ObjectDelete(0, prefix+"Low") last_day_checked = 0 return(INIT_SUCCEEDED) }
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { datetime current_day = TimeCurrent() - (TimeCurrent() % 86400) // Midnight of today
// New day? Reset and recalculate if(current_day != last_day_checked) { last_day_checked = current_day CalculateOpeningRange() }
// Draw or update lines if(or_complete) { DrawLine(prefix+"High", or_high, OR_HighColor) DrawLine(prefix+"Low", or_low, OR_LowColor) }
// Optional comment if(ShowComment) { string status = or_complete ? "Complete" : "In Progress" Comment("Opening Range ", OR_StartHour, ":", StringFormat("%02d", OR_StartMinute), " +", OR_DurationMinutes, "min\n", "Status: ", status, "\n", "High: ", DoubleToStr(or_high, _Digits), " Low: ", DoubleToStr(or_low, _Digits)) } else Comment("")
return(rates_total) }
//+------------------------------------------------------------------+ //| Calculate the Opening Range High/Low | //+------------------------------------------------------------------+ void CalculateOpeningRange() { datetime or_start_time = TimeCurrent() - (TimeCurrent() % 86400) // Today 00:00 or_start_time += OR_StartHour * 3600 + OR_StartMinute * 60
// If OR starts tomorrow (e.g. 23:30), adjust if(or_start_time > TimeCurrent()) or_start_time -= 86400
datetime or_end_time = or_start_time + OR_DurationMinutes * 60
// If OR hasn't started yet if(TimeCurrent() < or_start_time) { or_complete = false or_high = 0 or_low = 0 return }
// Find the highest high and lowest low in the range or_high = 0 or_low = 999999
int start_bar = iBarShift(NULL, 0, or_start_time, false) int end_bar = iBarShift(NULL, 0, or_end_time, false)
// If end_bar is before start (happens when OR is in progress), use current bar if(end_bar < 0) end_bar = 0
for(int i = start_bar i >= end_bar i--) { if(i < 0) break double h = iHigh(NULL, 0, i) double l = iLow(NULL, 0, i)
if(h > or_high) or_high = h if(l < or_low) or_low = l }
or_complete = (TimeCurrent() >= or_end_time) // Safety: if no bars found (weekend?), use previous day if(or_high <= or_low && TimeCurrent() >= or_end_time) { // Fallback: use previous completed day datetime yesterday = TimeCurrent() - 86400 - (TimeCurrent() % 86400) yesterday += OR_StartHour*3600 + OR_StartMinute*60 datetime yesterday_end = yesterday + OR_DurationMinutes*60 start_bar = iBarShift(NULL, 0, yesterday, false) end_bar = iBarShift(NULL, 0, yesterday_end, false) for(int i = start_bar i >= MathMax(end_bar, 0) i--) { double h = iHigh(NULL, 0, i) double l = iLow(NULL, 0, i) if(h > or_high) or_high = h if(l < or_low) or_low = l } } }
//+------------------------------------------------------------------+ //| Draw or update horizontal line | //+------------------------------------------------------------------+ void DrawLine(string name, double price, color clr) { if(ObjectFind(0, name) == -1) { ObjectCreate(0, name, OBJ_HLINE, 0, Time[0], price) ObjectSetInteger(0, name, OBJPROP_STYLE, OR_LineStyle) ObjectSetInteger(0, name, OBJPROP_WIDTH, OR_LineWidth) ObjectSetInteger(0, name, OBJPROP_COLOR, clr) ObjectSetInteger(0, name, OBJPROP_BACK, false) } else { ObjectMove(0, name, 0, Time[0], price) } }
//+------------------------------------------------------------------+
|