last ...
This commit is contained in:
@@ -0,0 +1,318 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Forex Sessions and Day Range Indicator |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Your Name"
|
||||
#property link "https://www.example.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 8 // 4 sessions * (High + Low)
|
||||
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include <Arrays/ArrayObj.mqh>
|
||||
|
||||
// Define an enumeration for DST rules
|
||||
enum DST_RULE
|
||||
{
|
||||
DST_SYDNEY,
|
||||
DST_TOKYO,
|
||||
DST_LONDON,
|
||||
DST_NEW_YORK
|
||||
};
|
||||
|
||||
struct SessionInfo
|
||||
{
|
||||
string name;
|
||||
int startHour; // Standard start hour (GMT)
|
||||
int startMinute;
|
||||
int endHour; // Standard end hour (GMT)
|
||||
int endMinute;
|
||||
DST_RULE dstRule; // DST rule for the session
|
||||
int dstAdjustment; // Hours to add during DST
|
||||
};
|
||||
|
||||
SessionInfo sessions[] = {
|
||||
{"Sydney", 21, 0, 5, 0, DST_SYDNEY, 1},
|
||||
{"Tokyo", 23, 0, 8, 0, DST_TOKYO, 0},
|
||||
{"London", 7, 0, 15, 0, DST_LONDON, 1},
|
||||
{"New York", 12, 0, 17, 0, DST_NEW_YORK, 1}};
|
||||
|
||||
double sessionHighBuffers[]; // Buffer for session highs
|
||||
double sessionLowBuffers[]; // Buffer for session lows
|
||||
|
||||
bool sessionActive[];
|
||||
double sessionHigh[];
|
||||
double sessionLow[];
|
||||
datetime sessionStartTime[];
|
||||
datetime sessionEndTime[];
|
||||
|
||||
double dayHigh = 0;
|
||||
double dayLow = 0;
|
||||
datetime dayStartTime;
|
||||
|
||||
// Function to extract the year from a datetime value
|
||||
int GetYear(datetime time)
|
||||
{
|
||||
return (int)StringSubstr(TimeToString(time, TIME_DATE), 0, 4);
|
||||
}
|
||||
|
||||
// Function to extract the day of the month from a datetime value
|
||||
int GetDay(datetime time)
|
||||
{
|
||||
MqlDateTime dt;
|
||||
TimeToStruct(time, dt);
|
||||
return dt.day;
|
||||
}
|
||||
|
||||
// Function to extract the day of the week from a datetime value (0=Sunday, 6=Saturday)
|
||||
int GetDayOfWeek(datetime time)
|
||||
{
|
||||
MqlDateTime dt;
|
||||
TimeToStruct(time, dt);
|
||||
return dt.day_of_week;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
ArrayResize(sessionActive, ArraySize(sessions));
|
||||
ArrayResize(sessionHigh, ArraySize(sessions));
|
||||
ArrayResize(sessionLow, ArraySize(sessions));
|
||||
ArrayResize(sessionStartTime, ArraySize(sessions));
|
||||
ArrayResize(sessionEndTime, ArraySize(sessions));
|
||||
|
||||
for (int i = 0; i < ArraySize(sessions); i++)
|
||||
{
|
||||
sessionActive[i] = false;
|
||||
sessionHigh[i] = 0;
|
||||
sessionLow[i] = 0;
|
||||
sessionStartTime[i] = 0;
|
||||
sessionEndTime[i] = 0;
|
||||
}
|
||||
|
||||
dayHigh = 0;
|
||||
dayLow = 0;
|
||||
dayStartTime = 0;
|
||||
|
||||
// Initialize buffers for session highs and lows
|
||||
int totalSessions = ArraySize(sessions);
|
||||
int totalBars = iBars(NULL, 0); // Get the number of bars on the chart
|
||||
|
||||
ArrayResize(sessionHighBuffers, totalBars); // Resize to match the number of bars
|
||||
ArrayResize(sessionLowBuffers, totalBars); // Resize to match the number of bars
|
||||
|
||||
for (int i = 0; i < totalSessions; i++)
|
||||
{
|
||||
SetIndexBuffer(i * 2, sessionHighBuffers, INDICATOR_DATA);
|
||||
SetIndexBuffer(i * 2 + 1, sessionLowBuffers, INDICATOR_DATA);
|
||||
|
||||
// Optional: Set colors for high and low buffers
|
||||
PlotIndexSetInteger(i * 2, PLOT_LINE_COLOR, clrGreen);
|
||||
PlotIndexSetInteger(i * 2 + 1, PLOT_LINE_COLOR, clrRed);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_LEVELS, 0); // No predefined levels
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Forex Sessions");
|
||||
}
|
||||
|
||||
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[])
|
||||
{
|
||||
// Ensure buffers are resized to match the number of bars
|
||||
if (ArraySize(sessionHighBuffers) < rates_total)
|
||||
{
|
||||
ArrayResize(sessionHighBuffers, rates_total);
|
||||
ArrayResize(sessionLowBuffers, rates_total);
|
||||
}
|
||||
|
||||
datetime currentTime = TimeCurrent();
|
||||
|
||||
// Retrieve Ask and Bid prices dynamically
|
||||
double askPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
|
||||
double bidPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
|
||||
|
||||
// Check each session
|
||||
for (int i = 0; i < ArraySize(sessions); i++)
|
||||
{
|
||||
SessionInfo session = sessions[i];
|
||||
|
||||
// Determine if DST is active using the session's DST rule
|
||||
bool dstActive = IsDSTActive(session.dstRule, currentTime);
|
||||
int adjStartHour = session.startHour + (dstActive ? session.dstAdjustment : 0);
|
||||
int adjEndHour = session.endHour + (dstActive ? session.dstAdjustment : 0);
|
||||
|
||||
datetime todayStart = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
|
||||
IntegerToString(adjStartHour) + ":" +
|
||||
IntegerToString(session.startMinute));
|
||||
datetime todayEnd = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
|
||||
IntegerToString(adjEndHour) + ":" +
|
||||
IntegerToString(session.endMinute));
|
||||
|
||||
// Handle sessions spanning midnight
|
||||
if (adjEndHour < adjStartHour)
|
||||
{
|
||||
todayEnd += 24 * 3600;
|
||||
}
|
||||
|
||||
if (currentTime >= todayStart && currentTime < todayEnd)
|
||||
{
|
||||
if (!sessionActive[i])
|
||||
{
|
||||
sessionActive[i] = true;
|
||||
sessionStartTime[i] = todayStart;
|
||||
sessionEndTime[i] = todayEnd;
|
||||
sessionHigh[i] = askPrice;
|
||||
sessionLow[i] = bidPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (askPrice > sessionHigh[i])
|
||||
sessionHigh[i] = askPrice;
|
||||
if (bidPrice < sessionLow[i])
|
||||
sessionLow[i] = bidPrice;
|
||||
}
|
||||
|
||||
// Update buffers for the current bar
|
||||
sessionHighBuffers[rates_total - 1] = sessionHigh[i];
|
||||
sessionLowBuffers[rates_total - 1] = sessionLow[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionActive[i] = false;
|
||||
sessionHighBuffers[rates_total - 1] = EMPTY_VALUE; // Clear buffer when session is inactive
|
||||
sessionLowBuffers[rates_total - 1] = EMPTY_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Check day range
|
||||
bool dstActiveNY = IsDSTActive(DST_NEW_YORK, currentTime);
|
||||
int dayStartHour = dstActiveNY ? 21 : 22;
|
||||
datetime todayDayStart = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
|
||||
IntegerToString(dayStartHour) + ":00");
|
||||
|
||||
if (currentTime < todayDayStart)
|
||||
{
|
||||
todayDayStart -= 24 * 3600;
|
||||
}
|
||||
|
||||
if (dayStartTime != todayDayStart)
|
||||
{
|
||||
dayStartTime = todayDayStart;
|
||||
dayHigh = askPrice;
|
||||
dayLow = bidPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (askPrice > dayHigh)
|
||||
dayHigh = askPrice;
|
||||
if (bidPrice < dayLow)
|
||||
dayLow = bidPrice;
|
||||
}
|
||||
|
||||
// Display information on chart
|
||||
string comment = "Active Forex Sessions:\n";
|
||||
for (int i = 0; i < ArraySize(sessions); i++)
|
||||
{
|
||||
if (sessionActive[i])
|
||||
{
|
||||
comment += sessions[i].name + " Session\n" +
|
||||
"High: " + DoubleToString(sessionHigh[i], _Digits) + "\n" +
|
||||
"Low: " + DoubleToString(sessionLow[i], _Digits) + "\n";
|
||||
}
|
||||
}
|
||||
comment += "\nDay Range:\n" +
|
||||
"High: " + DoubleToString(dayHigh, _Digits) + "\n" +
|
||||
"Low: " + DoubleToString(dayLow, _Digits);
|
||||
Comment(comment);
|
||||
|
||||
return (rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check if DST is active for a given session |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsDSTActive(DST_RULE dstRule, datetime time)
|
||||
{
|
||||
switch (dstRule)
|
||||
{
|
||||
case DST_SYDNEY:
|
||||
return IsSydneyDST(time);
|
||||
case DST_TOKYO:
|
||||
return IsTokyoDST(time);
|
||||
case DST_LONDON:
|
||||
return IsLondonDST(time);
|
||||
case DST_NEW_YORK:
|
||||
return IsNewYorkDST(time);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| DST Check Functions |
|
||||
//+------------------------------------------------------------------+
|
||||
bool IsLondonDST(datetime time)
|
||||
{
|
||||
int year = GetYear(time);
|
||||
datetime march31 = StringToTime(ToString(year) + ".03.31 00:00");
|
||||
int lastSundayMarch = GetDay(march31) - (GetDayOfWeek(march31) % 7);
|
||||
datetime dstStart = StringToTime(ToString(year) + ".03." + IntegerToString(lastSundayMarch) + " 01:00");
|
||||
|
||||
datetime oct31 = StringToTime(ToString(year) + ".10.31 00:00");
|
||||
int lastSundayOct = GetDay(oct31) - (GetDayOfWeek(oct31) % 7);
|
||||
datetime dstEnd = StringToTime(ToString(year) + ".10." + IntegerToString(lastSundayOct) + " 01:00");
|
||||
|
||||
return time >= dstStart && time < dstEnd;
|
||||
}
|
||||
|
||||
bool IsNewYorkDST(datetime time)
|
||||
{
|
||||
int year = GetYear(time);
|
||||
datetime march1 = StringToTime(ToString(year) + ".03.01 00:00");
|
||||
int dayOfWeekMarch1 = GetDayOfWeek(march1);
|
||||
int secondSundayMarch = 1 + (7 - dayOfWeekMarch1) % 7 + 7;
|
||||
datetime dstStart = StringToTime(ToString(year) + ".03." + IntegerToString(secondSundayMarch) + " 07:00");
|
||||
|
||||
datetime nov1 = StringToTime(ToString(year) + ".11.01 00:00");
|
||||
int dayOfWeekNov1 = GetDayOfWeek(nov1);
|
||||
int firstSundayNov = 1 + (7 - dayOfWeekNov1) % 7;
|
||||
datetime dstEnd = StringToTime(ToString(year) + ".11." + IntegerToString(firstSundayNov) + " 06:00");
|
||||
|
||||
return time >= dstStart && time < dstEnd;
|
||||
}
|
||||
|
||||
bool IsSydneyDST(datetime time)
|
||||
{
|
||||
int year = GetYear(time);
|
||||
datetime oct1 = StringToTime(ToString(year) + ".10.01 00:00");
|
||||
int dayOfWeekOct1 = GetDayOfWeek(oct1);
|
||||
int firstSundayOct = 1 + (7 - dayOfWeekOct1) % 7;
|
||||
datetime dstStart = StringToTime(ToString(year) + ".10." + IntegerToString(firstSundayOct) + " 13:00");
|
||||
|
||||
datetime apr1 = StringToTime(ToString(year) + ".04.01 00:00");
|
||||
int dayOfWeekApr1 = GetDayOfWeek(apr1);
|
||||
int firstSundayApr = 1 + (7 - dayOfWeekApr1) % 7;
|
||||
datetime dstEnd = StringToTime(ToString(year) + ".04." + IntegerToString(firstSundayApr) + " 15:00");
|
||||
|
||||
return time >= dstStart && time < dstEnd;
|
||||
}
|
||||
|
||||
bool IsTokyoDST(datetime time)
|
||||
{
|
||||
// Tokyo does not observe Daylight Saving Time (DST)
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user