197 lines
7.0 KiB
Plaintext
197 lines
7.0 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| Forex Sessions and Day Range Indicator |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Your Name"
|
|
#property link "https://www.example.com"
|
|
#property version "1.00"
|
|
#property indicator_chart_window
|
|
|
|
#include <Arrays\ArrayObj.mqh>
|
|
|
|
struct SessionInfo {
|
|
string name;
|
|
int startHour; // Standard start hour (GMT)
|
|
int startMinute;
|
|
int endHour; // Standard end hour (GMT)
|
|
int endMinute;
|
|
bool *isDST(datetime); // DST check function
|
|
int dstAdjustment; // Hours to add during DST
|
|
};
|
|
|
|
SessionInfo sessions[] = {
|
|
{"Sydney", 21, 0, 5, 0, IsSydneyDST, 1},
|
|
{"Tokyo", 23, 0, 8, 0, IsTokyoDST, 0},
|
|
{"London", 7, 0, 15, 0, IsLondonDST, 1},
|
|
{"New York", 12, 0, 17, 0, IsNewYorkDST, 1}
|
|
};
|
|
|
|
bool sessionActive[];
|
|
double sessionHigh[];
|
|
double sessionLow[];
|
|
datetime sessionStartTime[];
|
|
datetime sessionEndTime[];
|
|
|
|
double dayHigh = 0;
|
|
double dayLow = 0;
|
|
datetime dayStartTime;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 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;
|
|
|
|
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 currentTime = TimeCurrent();
|
|
|
|
// Check each session
|
|
for(int i=0; i<ArraySize(sessions); i++) {
|
|
SessionInfo session = sessions[i];
|
|
bool dstActive = session.isDST(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] = Bid;
|
|
sessionLow[i] = Ask;
|
|
} else {
|
|
if(Bid > sessionHigh[i]) sessionHigh[i] = Bid;
|
|
if(Ask < sessionLow[i]) sessionLow[i] = Ask;
|
|
}
|
|
} else {
|
|
sessionActive[i] = false;
|
|
}
|
|
}
|
|
|
|
// Check day range
|
|
bool dstActiveNY = IsNewYorkDST(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 = Bid;
|
|
dayLow = Ask;
|
|
} else {
|
|
if(Bid > dayHigh) dayHigh = Bid;
|
|
if(Ask < dayLow) dayLow = Ask;
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| DST Check Functions |
|
|
//+------------------------------------------------------------------+
|
|
bool IsLondonDST(datetime time) {
|
|
int year = TimeYear(time);
|
|
datetime march31 = StringToTime(year + ".03.31 00:00");
|
|
int lastSundayMarch = TimeDay(march31) - (TimeDayOfWeek(march31) % 7);
|
|
datetime dstStart = StringToTime(year + ".03." + IntegerToString(lastSundayMarch) + " 01:00");
|
|
|
|
datetime oct31 = StringToTime(year + ".10.31 00:00");
|
|
int lastSundayOct = TimeDay(oct31) - (TimeDayOfWeek(oct31) % 7);
|
|
datetime dstEnd = StringToTime(year + ".10." + IntegerToString(lastSundayOct) + " 01:00");
|
|
|
|
return time >= dstStart && time < dstEnd;
|
|
}
|
|
|
|
bool IsNewYorkDST(datetime time) {
|
|
int year = TimeYear(time);
|
|
datetime march1 = StringToTime(year + ".03.01 00:00");
|
|
int dayOfWeekMarch1 = TimeDayOfWeek(march1);
|
|
int secondSundayMarch = 1 + (7 - dayOfWeekMarch1) % 7 + 7;
|
|
datetime dstStart = StringToTime(year + ".03." + IntegerToString(secondSundayMarch) + " 07:00");
|
|
|
|
datetime nov1 = StringToTime(year + ".11.01 00:00");
|
|
int dayOfWeekNov1 = TimeDayOfWeek(nov1);
|
|
int firstSundayNov = 1 + (7 - dayOfWeekNov1) % 7;
|
|
datetime dstEnd = StringToTime(year + ".11." + IntegerToString(firstSundayNov) + " 06:00");
|
|
|
|
return time >= dstStart && time < dstEnd;
|
|
}
|
|
|
|
bool IsSydneyDST(datetime time) {
|
|
int year = TimeYear(time);
|
|
datetime oct1 = StringToTime(year + ".10.01 00:00");
|
|
int dayOfWeekOct1 = TimeDayOfWeek(oct1);
|
|
int firstSundayOct = 1 + (7 - dayOfWeekOct1) % 7;
|
|
datetime dstStart = StringToTime(year + ".10." + IntegerToString(firstSundayOct) + " 13:00");
|
|
|
|
datetime apr1 = StringToTime(year + ".04.01 00:00");
|
|
int dayOfWeekApr1 = TimeDayOfWeek(apr1);
|
|
int firstSundayApr = 1 + (7 - dayOfWeekApr1) % 7;
|
|
datetime dstEnd = StringToTime(year + ".04." + IntegerToString(firstSundayApr) + " 15:00");
|
|
|
|
return time >= dstStart && time < dstEnd;
|
|
}
|
|
|
|
bool IsTokyoDST(datetime time) {
|
|
return false;
|
|
} |