//+------------------------------------------------------------------+ //| CustomWatermark.mq4 | //| Copyright 2024, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property indicator_chart_window enum DisplayOptions { CUSTOM_TEXT, SYMBOL_NAME, TIMEFRAME }; enum CornerOptions { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT }; input string FirstLineCustomText = "First Custom Text"; // Custom text for the first line input DisplayOptions FirstLineOption = CUSTOM_TEXT; // Option for the first line input string SecondLineCustomText = "Second Custom Text"; // Custom text for the second line input DisplayOptions SecondLineOption = CUSTOM_TEXT; // Option for the second line input string ThirdLineCustomText = "Third Custom Text"; // Custom text for the third line input DisplayOptions ThirdLineOption = CUSTOM_TEXT; // Option for the third line input int FirstLineFontSize = 24; // Font size for the first line input int SecondLineFontSize = 18; // Font size for the second line input int ThirdLineFontSize = 14; // Font size for the third line input color FirstLineColor = clrRed; // Text color for the first line input color SecondLineColor = clrBlue; // Text color for the second line input color ThirdLineColor = clrGreen; // Text color for the third line string ImagesFolder = "\\Images\\"; //Lines bellow to include extension input string TopLeftImageFileName = "top_left.bmp"; // Image file name for the top left corner input string TopRightImageFileName = "top_right.bmp"; // Image file name for the top right corner input string BottomLeftImageFileName = "bottom_left.bmp"; // Image file name for the bottom left corner input string BottomRightImageFileName = "bottom_right.bmp"; // Image file name for the bottom right corner input int ImageWidth = 200; // Width of the images input int ImageHeight = 200; // Height of the images //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { // Create the watermark text objects CreateWatermark("FirstLine", FirstLineCustomText, FirstLineOption, FirstLineFontSize, 0, FirstLineColor); CreateWatermark("SecondLine", SecondLineCustomText, SecondLineOption, SecondLineFontSize, FirstLineFontSize, SecondLineColor); CreateWatermark("ThirdLine", ThirdLineCustomText, ThirdLineOption, ThirdLineFontSize, FirstLineFontSize + SecondLineFontSize, ThirdLineColor); // Create the watermark image objects for each corner CreateWatermarkImage("TopLeftImage", TopLeftImageFileName, CORNER_LEFT_UPPER,ANCHOR_LEFT_UPPER); CreateWatermarkImage("TopRightImage", TopRightImageFileName, CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER); CreateWatermarkImage("BottomLeftImage", BottomLeftImageFileName, CORNER_LEFT_LOWER,ANCHOR_LEFT_LOWER); CreateWatermarkImage("BottomRightImage", BottomRightImageFileName, CORNER_RIGHT_LOWER,ANCHOR_RIGHT_LOWER); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Delete the text and image objects when the indicator is removed ObjectDelete("FirstLine"); ObjectDelete("SecondLine"); ObjectDelete("ThirdLine"); ObjectDelete("TopLeftImage"); ObjectDelete("TopRightImage"); ObjectDelete("BottomLeftImage"); ObjectDelete("BottomRightImage"); } //+------------------------------------------------------------------+ //| 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[]) { // Update the watermark position on every tick UpdateWatermarkPosition(); return(rates_total); } //+------------------------------------------------------------------+ //| CreateWatermark function | //+------------------------------------------------------------------+ void CreateWatermark(string name, string custom_text, DisplayOptions option, int font_size, int y_offset, color text_color) { string text; switch(option) { case CUSTOM_TEXT: text = custom_text; break; case SYMBOL_NAME: text = Symbol(); break; case TIMEFRAME: text = TimeFrameToString(Period()); break; } // Create the text object if (ObjectFind(0, name) != 0) { ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0); } // Set the text and style ObjectSetString(0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_COLOR, text_color); ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, font_size); ObjectSetString(0, name, OBJPROP_FONT, "Arial"); // Set the Y offset (distance from the top) ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y_offset); } //+------------------------------------------------------------------+ //| UpdateWatermarkPosition function | //+------------------------------------------------------------------+ void UpdateWatermarkPosition() { int window_width = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); int window_height = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); // Calculate the Y positions for the first, second, and third lines int total_font_height = FirstLineFontSize + SecondLineFontSize + ThirdLineFontSize; int first_line_y = (window_height / 2) - (total_font_height / 2); int second_line_y = first_line_y + FirstLineFontSize; int third_line_y = second_line_y + SecondLineFontSize; // Set the X and Y positions of the text objects int center_x = window_width / 2; ObjectSetInteger(0, "FirstLine", OBJPROP_XDISTANCE, center_x); ObjectSetInteger(0, "SecondLine", OBJPROP_XDISTANCE, center_x); ObjectSetInteger(0, "ThirdLine", OBJPROP_XDISTANCE, center_x); ObjectSetInteger(0, "FirstLine", OBJPROP_YDISTANCE, first_line_y); ObjectSetInteger(0, "SecondLine", OBJPROP_YDISTANCE, second_line_y); ObjectSetInteger(0, "ThirdLine", OBJPROP_YDISTANCE, third_line_y); // Align the text to center ObjectSetInteger(0, "FirstLine", OBJPROP_ANCHOR, ANCHOR_CENTER); ObjectSetInteger(0, "SecondLine", OBJPROP_ANCHOR, ANCHOR_CENTER); ObjectSetInteger(0, "ThirdLine", OBJPROP_ANCHOR, ANCHOR_CENTER); // Update the position of the watermark images based on their corners UpdateImagePosition("TopLeftImage", CORNER_LEFT_UPPER, 0, 0,ANCHOR_LEFT_UPPER); UpdateImagePosition("TopRightImage", CORNER_RIGHT_UPPER, 0, 0,ANCHOR_RIGHT_UPPER); UpdateImagePosition("BottomLeftImage", CORNER_LEFT_LOWER, 0, 0,ANCHOR_LEFT_LOWER); UpdateImagePosition("BottomRightImage", CORNER_RIGHT_LOWER, 0, 0,ANCHOR_RIGHT_LOWER); } //+------------------------------------------------------------------+ //| UpdateImagePosition function | //+------------------------------------------------------------------+ void UpdateImagePosition(string name, int corner, int x_dist, int y_dist, int anchor) { ObjectSetInteger(0, name, OBJPROP_CORNER, corner); ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x_dist); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y_dist); } //+------------------------------------------------------------------+ //| CreateWatermarkImage function | //+------------------------------------------------------------------+ void CreateWatermarkImage(string name, string filename, int corner, int anchor) { // Create the image object if (ObjectFind(0, name) != 0) { ObjectCreate(0, name, OBJ_BITMAP_LABEL, 0, 0, 0); } // Set the image properties ObjectSetString(0, name, OBJPROP_BMPFILE,0,ImagesFolder + filename); ObjectSetInteger(0, name, OBJPROP_CORNER, corner); ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor); } //+------------------------------------------------------------------+ //| TimeFrameToString function | //+------------------------------------------------------------------+ string TimeFrameToString(int period) { switch(period) { case PERIOD_M1: return "M1"; case PERIOD_M5: return "M5"; case PERIOD_M15: return "M15"; case PERIOD_M30: return "M30"; case PERIOD_H1: return "H1"; case PERIOD_H4: return "H4"; case PERIOD_D1: return "D1"; case PERIOD_W1: return "W1"; case PERIOD_MN1: return "MN1"; default: return "Unknown"; } } //+------------------------------------------------------------------+