Untitled
unknown
plain_text
9 months ago
9.5 kB
7
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