Madeleine_v2.0
Download scriptThis script is a visual analytical tool designed for the MetaTrader 4 platform. Its primary purpose is to automatically plot trend lines on your trading chart based on specific price points and angles, helping traders visualize potential market structures.
Core Functionality
The script scans a specified number of recent historical bars (customizable by the user) and identifies key price levels—specifically Highs, Lows, Opens, and Closes. Depending on your settings, it automatically draws geometric trend lines originating from these points.
Key Logic Components
1. Dynamic Visual Mapping The tool calculates specific angles for every line it draws. It primarily uses two distinct angles: 45 degrees and 315 degrees. By projecting these angles forward from historical price data, the script helps identify where price might travel in the future if current trends persist.
2. Customizable Visualization Modes The logic allows you to toggle between different "styles" of trend identification through several settings:
- High/Low Tracking: You can choose to have the script focus on the highest and lowest points of previous candles.
- Open/Close Tracking: Alternatively, the script can be set to ignore extremes and instead focus on the price at which a candle opened versus where it closed.
- Directional Filtering: The script includes internal logic to check the relationship between prices. For example, it can distinguish between "Bullish" movements (where the close is higher than the open) and "Bearish" movements (where the close is lower than the open), assigning different colors (like Red, Lime, Blue, or White) to reflect these directions accurately.
3. Ray Projection The script includes an option to extend these trend lines into "Rays." When enabled, the lines do not stop at a specific point in time but continue infinitely to the right of the chart, making it easier to see potential targets or areas of support and resistance.
4. Automatic Cleanup To keep your trading workspace clean, the script contains built-in management logic. When you remove the indicator from your chart, it is programmed to automatically identify and delete all the lines it created, preventing "chart clutter" from previous sessions.
Summary for the User
Essentially, this tool acts as an automated technical analyst. You define which price points matter most to you (Highs, Lows, Opens, or Closes), and the script handles the manual labor of drawing perfectly angled trend lines across your history, allowing you to see potential market trajectories at a glance.
//+------------------------------------------------------------------+
//| Madeleine_v2.0.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property indicator_chart_window
//----
string str="Madeleine_v2.0";
extern string _Bars="Êîëè÷åñòâî áàðîâ äëÿ îòðèñîâêè";
extern int cfg_Bars=18; //êîëè÷åñòâî áàðîâ äëÿ îòðèñîâêè
extern string Ray="Îòðèñîâêà ëó÷åé";
extern bool cfg_Ray=false; //îòðèñîâêà ëó÷åé
extern string HL1="High (315), Low (45)";
extern bool cfg_HL1=true; //îòðèñîâêà òîëüêî ïî High (315), Low (45)
extern string OC1="Open (315), Close (45)";
extern bool cfg_OC1=false; //îòðèñîâêà òîëüêî ïî Open (315), Close (45)
extern string HL2="High (45), Low (315)";
extern bool cfg_HL2=false; //îòðèñîâêà òîëüêî ïî High (45), Low (315)
extern string OC2="Open (45), Close (315)";
extern bool cfg_OC2=false; //îòðèñîâêà òîëüêî ïî Open (45), Close (315)
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
DrawLine45();
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//àâòî-óäàëåíèå âñåõ ëèíèé
for(int i=1;i<Bars;i++){
string ss=TimeToStr(Time[i]);
for(int j=0;j<StringLen(ss);j++){
if(StringGetChar(ss,j)=='.' || StringGetChar(ss,j)==':' || StringGetChar(ss,j)==' ')
ss=StringSetChar(ss,j,'_');
}
string n45L="trend45L_"+ss;
string n45H="trend45H_"+ss;
string n315L="trend315L_"+ss;
string n315H="trend315H_"+ss;
string n45O="trend45O_"+ss;
string n45C="trend45C_"+ss;
string n315O="trend315O_"+ss;
string n315C="trend315C_"+ss;
if(ObjectFind(n45L)==0) ObjectDelete(n45L);
if(ObjectFind(n315L)==0) ObjectDelete(n315L);
if(ObjectFind(n45H)==0) ObjectDelete(n45H);
if(ObjectFind(n315H)==0) ObjectDelete(n315H);
if(ObjectFind(n45O)==0) ObjectDelete(n45O);
if(ObjectFind(n315O)==0) ObjectDelete(n315O);
if(ObjectFind(n45C)==0) ObjectDelete(n45C);
if(ObjectFind(n315C)==0) ObjectDelete(n315C);
}
// Print("Deinit");
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
DrawLine45();
//----
return(0);
}
//+------------------------------------------------------------------+
void DrawLine45()
{
for(int i=1;i<=cfg_Bars;i++)
{
string ss=TimeToStr(Time[i]);
for(int j=0;j<StringLen(ss);j++)
{
if(StringGetChar(ss,j)=='.' || StringGetChar(ss,j)==':' || StringGetChar(ss,j)==' ')
ss=StringSetChar(ss,j,'_');
}
string n45L="trend45L_"+ss;
string n45H="trend45H_"+ss;
string n315L="trend315L_"+ss;
string n315H="trend315H_"+ss;
//----
string n45O="trend45O_"+ss;
string n45C="trend45C_"+ss;
string n315O="trend315O_"+ss;
string n315C="trend315C_"+ss;
// Print(n45);
// Print(n315);
//High 45 - Low 315
if(ObjectFind(n315L)==-1)
{
if (cfg_HL2)
ObjectCreate(n315L,OBJ_TRENDBYANGLE,0,Time[i],Low[i]);
ObjectSet (n315L,OBJPROP_RAY,cfg_Ray);
ObjectSet (n315L,OBJPROP_ANGLE,315);
ObjectSet (n315L,OBJPROP_TIME2,Time[0]);
ObjectSet (n315L,OBJPROP_COLOR,Blue);
}
if(ObjectFind(n45H)==-1)
{
if (cfg_HL2)
ObjectCreate(n45H,OBJ_TRENDBYANGLE,0,Time[i],High[i]);
ObjectSet (n45H,OBJPROP_RAY,cfg_Ray);
ObjectSet (n45H,OBJPROP_ANGLE,45);
ObjectSet (n45H,OBJPROP_TIME2,Time[0]);
ObjectSet (n45H,OBJPROP_COLOR,Lime);
}
//Open-Close
if(ObjectFind(n45O)==-1)
{
if (cfg_OC2)
if (iOpen(NULL,0,i)>iClose(NULL,0,i))
ObjectCreate(n45O,OBJ_TRENDBYANGLE,0,Time[i],Open[i]);
ObjectSet (n45O,OBJPROP_RAY,cfg_Ray);
ObjectSet (n45O,OBJPROP_ANGLE,45);
ObjectSet (n45O,OBJPROP_TIME2,Time[0]);
ObjectSet (n45O,OBJPROP_COLOR,White);
}
if(ObjectFind(n315O)==-1)
{
if (cfg_OC2)
if (iOpen(NULL,0,i)<iClose(NULL,0,i))
ObjectCreate(n315O,OBJ_TRENDBYANGLE,0,Time[i],Open[i]);
ObjectSet (n315O,OBJPROP_RAY,cfg_Ray);
ObjectSet (n315O,OBJPROP_ANGLE,315);
ObjectSet (n315O,OBJPROP_TIME2,Time[0]);
ObjectSet (n315O,OBJPROP_COLOR,White);
}
if(ObjectFind(n45C)==-1)
{
if (cfg_OC2)
if (iClose(NULL,0,i)>iOpen(NULL,0,i))
ObjectCreate(n45C,OBJ_TRENDBYANGLE,0,Time[i],Close[i]);
ObjectSet (n45C,OBJPROP_RAY,cfg_Ray);
ObjectSet (n45C,OBJPROP_ANGLE,45);
ObjectSet (n45C,OBJPROP_TIME2,Time[0]);
ObjectSet (n45C,OBJPROP_COLOR,Red);
}
if(ObjectFind(n315C)==-1)
{
if (cfg_OC2)
if (iClose(NULL,0,i)<iOpen(NULL,0,i))
ObjectCreate(n315C,OBJ_TRENDBYANGLE,0,Time[i],Close[i]);
ObjectSet (n315C,OBJPROP_RAY,cfg_Ray);
ObjectSet (n315C,OBJPROP_ANGLE,315);
ObjectSet (n315C,OBJPROP_TIME2,Time[0]);
ObjectSet (n315C,OBJPROP_COLOR,Red);
}
//High 315 - Low 45
if(ObjectFind(n45L)==-1)
{
if (cfg_HL1)
ObjectCreate(n45L,OBJ_TRENDBYANGLE,0,Time[i],Low[i]);
ObjectSet (n45L,OBJPROP_RAY,cfg_Ray);
ObjectSet (n45L,OBJPROP_ANGLE,45);
ObjectSet (n45L,OBJPROP_TIME2,Time[0]);
ObjectSet (n45L,OBJPROP_COLOR,Blue);
}
if(ObjectFind(n315H)==-1)
{
if (cfg_HL1)
ObjectCreate(n315H,OBJ_TRENDBYANGLE,0,Time[i],High[i]);
ObjectSet (n315H,OBJPROP_RAY,cfg_Ray);
ObjectSet (n315H,OBJPROP_ANGLE,315);
ObjectSet (n315H,OBJPROP_TIME2,Time[0]);
ObjectSet (n315H,OBJPROP_COLOR,Lime);
}
//Open 315 or 45 - Close 315 or 45 (if Close>Open or Close<Open)
if(ObjectFind(n45O)==-1)
{
if (cfg_OC1)
if (iOpen(NULL,0,i)<iClose(NULL,0,i))
ObjectCreate(n45O,OBJ_TRENDBYANGLE,0,Time[i],Open[i]);
ObjectSet (n45O,OBJPROP_RAY,cfg_Ray);
ObjectSet (n45O,OBJPROP_ANGLE,45);
ObjectSet (n45O,OBJPROP_TIME2,Time[0]);
ObjectSet (n45O,OBJPROP_COLOR,White);
}
if(ObjectFind(n315O)==-1)
{
if (cfg_OC1)
if (iOpen(NULL,0,i)>iClose(NULL,0,i))
ObjectCreate(n315O,OBJ_TRENDBYANGLE,0,Time[i],Open[i]);
ObjectSet (n315O,OBJPROP_RAY,cfg_Ray);
ObjectSet (n315O,OBJPROP_ANGLE,315);
ObjectSet (n315O,OBJPROP_TIME2,Time[0]);
ObjectSet (n315O,OBJPROP_COLOR,White);
}
if(ObjectFind(n45C)==-1)
{
if (cfg_OC1)
if (iClose(NULL,0,i)<iOpen(NULL,0,i))
ObjectCreate(n45C,OBJ_TRENDBYANGLE,0,Time[i],Close[i]);
ObjectSet (n45C,OBJPROP_RAY,cfg_Ray);
ObjectSet (n45C,OBJPROP_ANGLE,45);
ObjectSet (n45C,OBJPROP_TIME2,Time[0]);
ObjectSet (n45C,OBJPROP_COLOR,Red);
}
if(ObjectFind(n315C)==-1)
{
if (cfg_OC1)
if (iClose(NULL,0,i)>iOpen(NULL,0,i))
ObjectCreate(n315C,OBJ_TRENDBYANGLE,0,Time[i],Close[i]);
ObjectSet (n315C,OBJPROP_RAY,cfg_Ray);
ObjectSet (n315C,OBJPROP_ANGLE,315);
ObjectSet (n315C,OBJPROP_TIME2,Time[0]);
ObjectSet (n315C,OBJPROP_COLOR,Red);
}
}
}
//+------------------------------------------------------------------+
Comments