Skip to content

Instantly share code, notes, and snippets.

@tayyebi
Created March 21, 2025 21:40
Show Gist options
  • Save tayyebi/f7dedec2d40541bae7543dff62dbbb97 to your computer and use it in GitHub Desktop.
Save tayyebi/f7dedec2d40541bae7543dff62dbbb97 to your computer and use it in GitHub Desktop.
//+------------------------------------------------------------------+
//| Tayyebi.mq5 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
#property version ""
#property strict
// Session Configuration
input group "Session Settings"
input int LondonOpenHour = 8; // Session start hour (server time)
input int LondonOpenMinute = 0; // Session start minute
input int LondonCloseHour = 16; // Session end hour
input int LondonCloseMinute = 0; // Session end minute
// Swing Detection
input group "Swing Settings"
input int ZigZagDepth = 12; // ZigZag depth (bars)
input int ZigZagDeviation = 5; // ZigZag deviation (points)
input int ZigZagBackstep = 3; // ZigZag backstep (bars)
input bool ShowPeakLines = true; // Display peak lines
input bool ShowValleyLines = true; // Display valley lines
// Visual Customization
input group "Visual Markers"
input color SessionOpenColor = clrDodgerBlue; // Open marker color
input color SessionCloseColor = clrOrangeRed; // Close marker color
input color PeakColor = clrRoyalBlue; // Peak line color
input color ValleyColor = clrDarkOrange; // Valley line color
input int LineWidth = 2; // Line width
input ENUM_LINE_STYLE LineStyle= STYLE_DOT; // Line style
input int TextSize = 8; // Text label size
input string FontName = "Arial"; // Text font
// Global Variables
int zigzagHandle;
datetime currentSessionClose;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
zigzagHandle = iCustom(_Symbol, _Period, "Examples\\ZigZag",
ZigZagDepth, ZigZagDeviation, ZigZagBackstep);
if(zigzagHandle == INVALID_HANDLE) return(INIT_FAILED);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
CleanupSessionObjects();
IndicatorRelease(zigzagHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
datetime now = TimeCurrent();
datetime sessionOpen = CalculateSessionTime(now, LondonOpenHour, LondonOpenMinute);
currentSessionClose = CalculateSessionTime(now, LondonCloseHour, LondonCloseMinute);
DrawSessionMarkers(sessionOpen, currentSessionClose);
if(now >= sessionOpen && !IsNewSessionProcessed(sessionOpen))
{
if(ShowPeakLines || ShowValleyLines) DrawPreSessionSwings(sessionOpen);
currentSessionClose = CalculateSessionTime(now, LondonCloseHour, LondonCloseMinute);
}
}
//+------------------------------------------------------------------+
//| Calculate session boundary time |
//+------------------------------------------------------------------+
datetime CalculateSessionTime(datetime refTime, int hour, int minute)
{
MqlDateTime mdt;
TimeToStruct(refTime, mdt);
mdt.hour = hour;
mdt.min = minute;
mdt.sec = 0;
return StructToTime(mdt);
}
//+------------------------------------------------------------------+
//| Create session boundary line |
//+------------------------------------------------------------------+
void CreateSessionLine(datetime time, color clr, string text)
{
string lineName = "SessionLine_" + TimeToString(time, TIME_DATE) + text;
if(ObjectFind(0, lineName) == -1)
{
ObjectCreate(0, lineName, OBJ_VLINE, 0, time, 0);
ObjectSetInteger(0, lineName, OBJPROP_COLOR, clr);
ObjectSetInteger(0, lineName, OBJPROP_WIDTH, 2);
ObjectCreate(0, lineName+"_Text", OBJ_TEXT, 0, time, ChartGetDouble(0, CHART_PRICE_MAX));
ObjectSetString(0, lineName+"_Text", OBJPROP_TEXT, text);
ObjectSetInteger(0, lineName+"_Text", OBJPROP_COLOR, clr);
ObjectSetInteger(0, lineName+"_Text", OBJPROP_FONTSIZE, TextSize);
ObjectSetString(0, lineName+"_Text", OBJPROP_FONT, FontName);
}
}
//+------------------------------------------------------------------+
//| Draw session markers |
//+------------------------------------------------------------------+
void DrawSessionMarkers(datetime openTime, datetime closeTime)
{
CreateSessionLine(openTime, SessionOpenColor, "LON Open");
CreateSessionLine(closeTime, SessionCloseColor, "LON Close");
}
//+------------------------------------------------------------------+
//| Draw pre-session swing levels |
//+------------------------------------------------------------------+
void DrawPreSessionSwings(datetime sessionOpen)
{
double zigzagHighs[], zigzagLows[];
CopyBuffer(zigzagHandle, 1, 0, 500, zigzagHighs);
CopyBuffer(zigzagHandle, 2, 0, 500, zigzagLows);
ArraySetAsSeries(zigzagHighs, true);
ArraySetAsSeries(zigzagLows, true);
datetime lastPeakTime = 0;
double lastPeakPrice = 0;
datetime lastValleyTime = 0;
double lastValleyPrice = 0;
// Find last peak before session
if(ShowPeakLines)
{
for(int i=0; i<500; i++)
{
datetime barTime = iTime(_Symbol, _Period, i);
if(barTime >= sessionOpen) continue;
if(zigzagHighs[i] != 0 && zigzagHighs[i] != EMPTY_VALUE)
{
lastPeakTime = barTime;
lastPeakPrice = zigzagHighs[i];
break;
}
}
}
// Find last valley before session
if(ShowValleyLines)
{
for(int i=0; i<500; i++)
{
datetime barTime = iTime(_Symbol, _Period, i);
if(barTime >= sessionOpen) continue;
if(zigzagLows[i] != 0 && zigzagLows[i] != EMPTY_VALUE)
{
lastValleyTime = barTime;
lastValleyPrice = zigzagLows[i];
break;
}
}
}
// Create limited duration lines
string sessionTag = TimeToString(sessionOpen, TIME_DATE);
if(lastPeakTime > 0) CreateSwingLine("Peak_"+sessionTag, lastPeakTime, lastPeakPrice, currentSessionClose, PeakColor);
if(lastValleyTime > 0) CreateSwingLine("Valley_"+sessionTag, lastValleyTime, lastValleyPrice, currentSessionClose, ValleyColor);
}
//+------------------------------------------------------------------+
//| Create limited duration swing line |
//+------------------------------------------------------------------+
void CreateSwingLine(string name, datetime startTime, double price, datetime endTime, color clr)
{
if(ObjectFind(0, name) == -1)
{
ObjectCreate(0, name, OBJ_TREND, 0, startTime, price, endTime, price);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_WIDTH, LineWidth);
ObjectSetInteger(0, name, OBJPROP_STYLE, LineStyle);
ObjectSetInteger(0, name, OBJPROP_RAY, false);
// Store session end time for cleanup
ObjectSetString(0, name, OBJPROP_TOOLTIP, TimeToString(endTime, TIME_DATE));
}
// Price label
ObjectCreate(0, name+"_Label", OBJ_TEXT, 0, startTime, price);
ObjectSetString(0, name+"_Label", OBJPROP_TEXT, DoubleToString(price, _Digits));
ObjectSetInteger(0, name+"_Label", OBJPROP_COLOR, clr);
ObjectSetInteger(0, name+"_Label", OBJPROP_FONTSIZE, TextSize);
ObjectSetString(0, name+"_Label", OBJPROP_FONT, FontName);
}
//+------------------------------------------------------------------+
//| Check if new session needs processing |
//+------------------------------------------------------------------+
bool IsNewSessionProcessed(datetime sessionOpen)
{
static datetime lastProcessed = 0;
if(sessionOpen != lastProcessed)
{
lastProcessed = sessionOpen;
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Cleanup session-specific objects |
//+------------------------------------------------------------------+
void CleanupSessionObjects()
{
datetime now = TimeCurrent();
for(int i=ObjectsTotal(0)-1; i>=0; i--)
{
string name = ObjectName(0,i);
// Skip session lines (open/close vertical lines)
if(StringFind(name, "SessionLine_") == 0) continue;
string tooltip = ObjectGetString(0, name, OBJPROP_TOOLTIP);
datetime endTime = StringToTime(tooltip);
if(endTime > 0 && now > endTime)
{
ObjectDelete(0, name); // Delete the line
ObjectDelete(0, name+"_Label"); // Delete the label
}
}
}
//+------------------------------------------------------------------+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment