Untitled

 avatar
unknown
plain_text
8 days ago
9.5 kB
4
Indexable
//+------------------------------------------------------------------+
//|                                                Moment Key.mq5 |
//|                                  Copyright 2025 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

//--- input parameters
input color    InpColor=clrRed;   // Line color

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Set timer to check for lines drawing
   EventSetTimer(1); // Check every second
   
   // Draw lines for all available history
   DrawAllLines();
   
   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[])
{
   // Nothing to do here as we're using timer events
   return(rates_total);
}

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
   // Check if we need to draw lines for the current day
   CheckAndDrawTodayLine();
}

//+------------------------------------------------------------------+
//| Deinitialization function                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Remove timer
   EventKillTimer();
   
   // Delete all vertical lines created by this indicator
   ObjectsDeleteAll(0, "MomentKey_");
}

//+------------------------------------------------------------------+
//| Draw lines for all historical data                               |
//+------------------------------------------------------------------+
void DrawAllLines()
{
   // Get the first visible date on the chart
   int first_bars = Bars(_Symbol, _Period) - 1;
   datetime first_date = iTime(_Symbol, _Period, first_bars > 0 ? first_bars : 0);
   datetime last_date = TimeCurrent();
   
   // Create a midnight datetime for the first day
   MqlDateTime first_time;
   TimeToStruct(first_date, first_time);
   
   first_time.hour = 0;
   first_time.min = 0;
   first_time.sec = 0;
   
   datetime current_day = StructToTime(first_time);
   datetime end_day = TimeCurrent() + 86400; // Add one day to make sure we include today
   
   // For each day between start and end, draw a line at 12:00 NY time
   while(current_day <= end_day)
   {
      DrawLineAt12PM(current_day);
      
      // Move to next day
      current_day += 86400; // Add 24 hours
   }
}

//+------------------------------------------------------------------+
//| Check and draw line for today                                    |
//+------------------------------------------------------------------+
void CheckAndDrawTodayLine()
{
   datetime current_time = TimeCurrent();
   MqlDateTime time_struct;
   TimeToStruct(current_time, time_struct);
   
   // Create a datetime for today at 00:00
   time_struct.hour = 0;
   time_struct.min = 0;
   time_struct.sec = 0;
   
   datetime today_midnight = StructToTime(time_struct);
   
   // Draw line at 12:00 PM NY time for today
   DrawLineAt12PM(today_midnight);
   
   // If it's past 20:00, also prepare tomorrow's line
   if(time_struct.hour >= 20)
   {
      MqlDateTime tomorrow;
      tomorrow.year = time_struct.year;
      tomorrow.mon = time_struct.mon;
      tomorrow.day = time_struct.day + 1;
      tomorrow.hour = 0;
      tomorrow.min = 0;
      tomorrow.sec = 0;
      
      datetime tomorrow_midnight = StructToTime(tomorrow);
      DrawLineAt12PM(tomorrow_midnight);
   }
}

//+------------------------------------------------------------------+
//| Draw a line at 12:00 PM New York time for a specific day         |
//+------------------------------------------------------------------+
void DrawLineAt12PM(datetime day_start)
{
   // Convert to New York timezone
   datetime ny_day = ConvertToNewYorkTime(day_start);
   MqlDateTime ny_day_struct;
   TimeToStruct(ny_day, ny_day_struct);
   
   // Set to exactly midnight in NY timezone
   ny_day_struct.hour = 0;
   ny_day_struct.min = 0;
   ny_day_struct.sec = 0;
   ny_day = StructToTime(ny_day_struct);
   
   // Add 12 hours for noon (12:00 PM)
   datetime line_time = ny_day + 12 * 3600;
   
   // Create a unique name for the line
   string line_name = "MomentKey_12PM_" + TimeToString(ny_day, TIME_DATE);
   
   // Draw only if the line doesn't exist yet
   if(ObjectFind(0, line_name) < 0)
   {
      ObjectCreate(0, line_name, OBJ_VLINE, 0, line_time, 0);
      ObjectSetInteger(0, line_name, OBJPROP_COLOR, InpColor);
      ObjectSetInteger(0, line_name, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, line_name, OBJPROP_WIDTH, 1);
      ObjectSetInteger(0, line_name, OBJPROP_BACK, false);
      ObjectSetInteger(0, line_name, OBJPROP_SELECTABLE, false);
      ObjectSetString(0, line_name, OBJPROP_TEXT, "Moment Key 12:00 PM");
   }
}

//+------------------------------------------------------------------+
//| Convert local time to New York time                              |
//+------------------------------------------------------------------+
datetime ConvertToNewYorkTime(datetime local_time)
{
   // Get current times in different timezones
   datetime gmt_time = TimeGMT();
   datetime local_now = TimeLocal();
   
   // Calculate local to GMT offset in seconds
   int local_to_gmt_offset = (int)(gmt_time - local_now);
   
   // Determine New York timezone offset from GMT
   int ny_gmt_offset = -5 * 3600; // EST by default (UTC-5)
   
   // Check if New York is currently observing DST
   if(IsNewYorkInDST(gmt_time))
   {
      ny_gmt_offset = -4 * 3600; // EDT (UTC-4)
   }
   
   // Apply both offsets to convert local time to NY time
   return local_time + local_to_gmt_offset + ny_gmt_offset;
}

//+------------------------------------------------------------------+
//| Check if New York is in Daylight Saving Time                     |
//+------------------------------------------------------------------+
bool IsNewYorkInDST(datetime time)
{
   MqlDateTime time_struct;
   TimeToStruct(time, time_struct);
   
   int year = time_struct.year;
   int month = time_struct.mon;
   int day = time_struct.day;
   
   // Basic US DST rule (simplified):
   // From second Sunday in March to first Sunday in November
   
   // Months definitely not in DST
   if(month < 3 || month > 11)
      return false;
      
   // Months definitely in DST
   if(month > 3 && month < 11)
      return true;
      
   // Handle March (starts on 2nd Sunday)
   if(month == 3)
   {
      // Calculate the day of the second Sunday
      int first_day_dow = (1 + DayOfWeek(1, 3, year)) % 7; // Get day of week for March 1
      int second_sunday = 8 - first_day_dow; // First Sunday
      if(second_sunday == 1) second_sunday = 8; // If March 1 is Sunday, we want March 8
      second_sunday += 7; // Add 7 days to get to the second Sunday
      
      // After 2 AM on 2nd Sunday = DST
      if(day > second_sunday)
         return true;
      if(day == second_sunday && time_struct.hour >= 2)
         return true;
         
      return false;
   }
   
   // Handle November (ends on 1st Sunday)
   if(month == 11)
   {
      // Calculate the day of the first Sunday
      int first_day_dow = (1 + DayOfWeek(1, 11, year)) % 7; // Get day of week for November 1
      int first_sunday = 8 - first_day_dow; // First Sunday
      if(first_sunday == 8) first_sunday = 1; // If November 1 is Sunday, we want November 1
      
      // Before 2 AM on 1st Sunday = still DST
      if(day < first_sunday)
         return true;
      if(day == first_sunday && time_struct.hour < 2)
         return true;
         
      return false;
   }
   
   return false; // Should never get here
}

//+------------------------------------------------------------------+
//| Calculate day of week (0=Sunday, 1=Monday, etc)                  |
//+------------------------------------------------------------------+
int DayOfWeek(int day, int month, int year)
{
   // Based on Zeller's congruence algorithm
   if(month < 3)
   {
      month += 12;
      year--;
   }
   
   int k = year % 100;
   int j = year / 100;
   
   int dow = (day + (13 * (month + 1)) / 5 + k + (k / 4) + (j / 4) - (2 * j)) % 7;
   
   // Adjust to match MQL5 day of week (0 = Sunday, 1 = Monday, etc.)
   dow = (dow + 6) % 7;
   
   return dow;
}
//+------------------------------------------------------------------+
Editor is loading...
Leave a Comment