olyakish_fractals_03

Download script
Author: olyakish
olyakish_fractals_03

This script is a specialized technical analysis tool designed to identify and categorize market "fractals" (turning points in price action) by comparing their relative strength, volume, and momentum. Instead of simply marking every peak or valley, it uses a logical filtering system to distinguish between different types of price movements.

Core Logic and Classification

The script scans the historical price data for fractal points. When it identifies a new high or low point, it looks back through history to find the previous opposite turning point. It then compares these two points based on two primary metrics: Volume and Money Flow Index (MFI).

Based on this comparison, the script categorizes every fractal into one of four distinct types, each represented by a specific color on your chart:

  • Green Fractals: Occur when the current price movement shows both higher volume and higher momentum (MFI) than the previous move.
  • Red Fractals: Occur when the current price movement shows significantly higher volume but lower momentum (MFI) compared to the previous move.
  • Blue Fractals: Occur when the current price movement shows lower volume but higher momentum (MFI) compared to the previous move.
  • Saddle Brown Fractals: Occur when both the volume and the momentum (MFI) are lower than those of the previous move.

Dynamic Visual Elements

Beyond just marking these points with arrows, the script includes a dynamic drawing system to help visualize trends:

  • Trend Lines: The tool automatically generates and updates trend lines based on these categorized fractals. These lines help provide a visual representation of the current price structure.
  • Historical Tracking: There is an option to display "Previous" trend lines (shown as dashed lines). This allows traders to see where the previous structural boundaries were located before they were updated by newer data.
  • Visual Updates: As new price data arrives, the script continuously recalculates these positions, moving the trend lines in real-time to reflect the most recent market behavior while maintaining a history of the last few significant levels.

Summary for the User

Essentially, this script filters out "noise" by only highlighting fractals that meet specific volume and momentum criteria. It tells you not just where the price turned, but how it turned—whether with aggressive strength, exhausted volume, or fading momentum—allowing for a more nuanced view of market dynamics than standard fractal indicators provide.

Price Data Components
Series array that contains open time of each bar
Indicators Used
Fractals
Miscellaneous
Implements a curve of type %1
16 Views
0 Downloads
0 Favorites
olyakish_fractals_03
//+------------------------------------------------------------------+
//|                                        olyakish_fractals_03.mq4  |
//|                                      Copyright © -2007, olyakish |
//|                                           plutonia-dmb#yandex.ru |
//| v02                                                              |
//| Äîáàâëåí ïðîöåíò äëÿ îòñåèâàíèÿ ôðàêòàëîâ                        |
//| v03                                                              |
//| Ðèñóåò ëèíèè                                                     |
//+------------------------------------------------------------------+
#property copyright "olyakish"
#property link ""
//----
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Green       // Çåëåíûé ôðàêòàë
#property indicator_color2 Red         // Ïðèñåäàþùèé
#property indicator_color3 SaddleBrown // Óâÿäàþùèé
#property indicator_color4 Blue        // Ôàëüøèâûé
//----
extern int			Pips		= 15;
extern int			ShiftBars	= 150;
extern string rem1 = "Ïðîöåíò äëÿ îòñåèâàíèÿ ïî îáúåìó";
extern int Percent = 110;
extern string rem2 = "Ðèñîâàòü ïðåäûäóùèå ëèíèè?";
extern bool UseOldLine = true;
double ExtLimeBuffer[];
double ExtRedBuffer[];
double ExtSaddleBrownBuffer[];
double ExtBlueBuffer[];
int i, j;
double a_Fractal[2]; // 0- ïîñëåäíèé 1-ïðåäûäóùèé
double a_MFI[2];     // 0- ïîñëåäíèé 1-ïðåäûäóùèé
double a_Volume[2];  // 0- ïîñëåäíèé 1-ïðåäûäóùèé
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {   
//----
   SetIndexBuffer(0, ExtLimeBuffer);
   SetIndexBuffer(1, ExtRedBuffer);
   SetIndexBuffer(2, ExtSaddleBrownBuffer);
   SetIndexBuffer(3, ExtBlueBuffer);
//----
   SetIndexStyle(0, DRAW_ARROW, 0, 2);
   SetIndexStyle(1, DRAW_ARROW, 0, 2);
   SetIndexStyle(2, DRAW_ARROW, 0, 2);
   SetIndexStyle(3, DRAW_ARROW, 0, 2);
   
   SetIndexArrow(0, 177);
   SetIndexArrow(1, 177);
   SetIndexArrow(2, 177);
   SetIndexArrow(3, 177);               
//----
   SetIndexLabel(0, "Çåëåíûé ôðàêòàë");
   SetIndexLabel(1, "Ïðèñåäàþùèé ôðàêòàë");
   SetIndexLabel(2, "Óâÿäàþùèé ôðàêòàë");
   SetIndexLabel(3, "Ôàëüøèâûé ôðàêòàë");  
//----
   ObjectCreate("Up", OBJ_TREND, 0, iTime(NULL,  0,  2), High[2], 
                iTime(NULL, 0, 1), High[1], 0, 0);
   ObjectSet("Up", OBJPROP_COLOR, Blue);
   ObjectSet("Up", OBJPROP_RAY, true);
   ObjectSet("Up", OBJPROP_BACK, 1);
   
   ObjectCreate("Down", OBJ_TREND, 0, iTime(NULL, 0, 2), Low[2], 
                iTime(NULL, 0, 1), Low[1], 0, 0);
   ObjectSet("Down", OBJPROP_COLOR, Tomato);
   ObjectSet("Down", OBJPROP_RAY, true);
   ObjectSet("Down", OBJPROP_BACK, 1);
   if(UseOldLine)
     {
       ObjectCreate("Up_Prev", OBJ_TREND, 0, iTime(NULL, 0, 2), 
                    High[2], iTime(NULL, 0, 1), High[1],0,0);
       ObjectSet("Up_Prev", OBJPROP_COLOR, Blue);
       ObjectSet("Up_Prev", OBJPROP_RAY, true);
       ObjectSet("Up_Prev", OBJPROP_STYLE, STYLE_DASH);
       ObjectSet("Up_Prev", OBJPROP_BACK, 1);
   
       ObjectCreate("Down_Prev", OBJ_TREND, 0, iTime(NULL, 0, 2), 
                    Low[2], iTime(NULL, 0, 1), Low[1], 0, 0);
       ObjectSet("Down_Prev", OBJPROP_COLOR, Tomato);
       ObjectSet("Down_Prev", OBJPROP_RAY, true);         
       ObjectSet("Down_Prev", OBJPROP_STYLE, STYLE_DASH);
       ObjectSet("Down_Prev", OBJPROP_BACK, 1);
    }
//----
   Comment("olyakish_fractals_03");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+  
int deinit()
  {
   ObjectDelete("Up");
   ObjectDelete("Down");
   if(UseOldLine)
     {
       ObjectDelete("Up_Prev");
       ObjectDelete("Down_Prev");
     }
//----
   Comment("");
//----
   return(0);
  }   
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {  
   int n = 3;
   while(ExtLimeBuffer[n] != NULL || ExtRedBuffer[n] != NULL || 
         ExtSaddleBrownBuffer[n] != NULL || ExtBlueBuffer[n] != NULL)
     {
       if(n > ShiftBars) 
         {
           n = ShiftBars;
           break;
         }
       n++;
     }
   for(int i = n + 20; i >= 3; i--)
     {
       //-- âåðõíèå ôðàêòàëû
       ArrayInitialize(a_Fractal, 0);
       ArrayInitialize(a_MFI, 0);
       ArrayInitialize(a_Volume, 0);
       // íà i áàðå åñòü ôðàêòàë ââåðõ
       if(iFractals(NULL, 0, MODE_UPPER, i) != 0) 
         {               
           // öåíà íà ôðàêòàëå 
           a_Fractal[0] = iFractals(NULL, 0, MODE_UPPER, i);              
           // îáúåì
           a_Volume[0] = Volume[i] + Volume[i+1] + Volume[i+2] + 
                         Volume[i-1] + Volume[i-2];
           // MFI
           a_MFI[0] = (High[i] - Low[i] + High[i-1] - Low[i-1] + 
                      High[i-2] - Low[i-2] + High[i+1] - Low[i+1] + 
                      High[i+2] - Low[i+2]) / a_Volume[0];
           // ïîøëè èñêàòü ôðàêòàë íà âíèç ïî èñòîðèè
           j = i + 1;
           while(a_Fractal[1] == 0)
             {
               if(iFractals(NULL,0,MODE_UPPER,j)!=0) 
                   break;
               //-- Íàøëè ôðàêòàë  âíèç
               if(iFractals(NULL, 0, MODE_LOWER, j) != 0)
                 {
                   a_Fractal[1] = iFractals(NULL, 0, MODE_LOWER, j);
                   a_Volume[1] = Volume[j+2] + Volume[j+1] + 
                                 Volume[j] + Volume[j-1] + Volume[j-2];
                   a_MFI[1] = (High[j+1] - Low[j+1] + High[j+2] - 
                              Low[j+2] + High[j] - Low[j] + High[j-1] - 
                              Low[j-1] + High[j-2] - Low[j-2]) / a_Volume[1];                                             
                   // èìååì ïðèñåäàþùèé ôðàêòàë (MFI - îáúåì +)
                   if(a_Volume[0] > a_Volume[1]*Percent / 100 && 
                      a_MFI[0] < a_MFI[1])
                     {
                       ExtRedBuffer[i] = High[i]; // + Pips*Point;
                       break;
                     }
                   // èìååì çåëåíûé ôðàêòàë (MFI + îáúåì +)
                   if(a_Volume[0] > a_Volume[1]*Percent / 100 && 
                      a_MFI[0] > a_MFI[1])
                     {
                       ExtLimeBuffer[i] = High[i]; // + Pips*Point;
                       break;
                     } 
                   // èìååì ôàëüøèâûé ôðàêòàë (MFI + îáúåì -)
                   if(a_Volume[0]*Percent / 100 < a_Volume[1] && 
                      a_MFI[0] > a_MFI[1])
                     {
                       ExtBlueBuffer[i] = High[i]; // + Pips*Point;
                       break;
                     }
                   // èìååì óâÿäàþùèé ôðàêòàë (MFI - îáúåì -)
                   if(a_Volume[0]*Percent / 100 < a_Volume[1] && 
                      a_MFI[0] < a_MFI[1])
                     {
                       ExtSaddleBrownBuffer[i]=High[i]; // + Pips*Point;
                       break;
                     }
                 }                          
               j++;                                         
             }
         }
       //--- íèæíèå ôðàêòàëû
       ArrayInitialize(a_Fractal, 0);
       ArrayInitialize(a_MFI, 0);
       ArrayInitialize(a_Volume, 0);
       // íà i áàðå åñòü ôðàêòàë âíèç
       if(iFractals(NULL, 0, MODE_LOWER, i) != 0)
         {
           // öåíà íà ôðàêòàëå    
           a_Fractal[0] = iFractals(NULL, 0, MODE_LOWER, i);           
           // îáúåì
           a_Volume[0] = Volume[i] + Volume[i+1] + Volume[i+2] + 
                         Volume[i-1] + Volume[i-2];
           // MFI
           a_MFI[0] = (High[i] - Low[i] + High[i-1] - Low[i-1] + 
                       High[i-2] - Low[i-2] + High[i+1] - Low[i+1] + 
                       High[i+2] - Low[i+2]) / a_Volume[0];
           // ïîøëè èñêàòü ôðàêòàë íà ââåðõ ïî èñòîðèè
           j = i + 1;
           while(a_Fractal[1] == 0)
             {
               if(iFractals(NULL, 0, MODE_LOWER, j) != 0) 
                   break;
               //-- Íàøëè ôðàêòàë  ââåðõ
               if(iFractals(NULL, 0, MODE_UPPER, j) != 0)
                 {
                   a_Fractal[1] = iFractals(NULL, 0, MODE_UPPER, j);
                   a_Volume[1] = Volume[j+2] + Volume[j+1] + Volume[j] + 
                                 Volume[j-1] + Volume[j-2];
                   a_MFI[1] = (High[j+1] - Low[j+1] + High[j+2] - Low[j+2] + 
                              High[j]-Low[j] + High[j-1] - Low[j-1] + 
                              High[j-2] - Low[j-2]) / a_Volume[1];                                             
                   // èìååì ïðèñåäàþùèé ôðàêòàë (MFI - îáúåì +)
                   if(a_Volume[0] > a_Volume[1]*Percent / 100 && 
                      a_MFI[0] < a_MFI[1])
                     {
                       ExtRedBuffer[i] = Low[i]; // - Pips*Point;
                       break;
                     }
                   // èìååì çåëåíûé ôðàêòàë (MFI + îáúåì +)
                   if(a_Volume[0] > a_Volume[1]*Percent / 100 && 
                      a_MFI[0] > a_MFI[1])
                     {
                       ExtLimeBuffer[i] = Low[i]; // - Pips*Point;
                       break;
                     }
                   // èìååì ôàëüøèâûé ôðàêòàë (MFI + îáúåì -)
                   if(a_Volume[0]*Percent / 100 < a_Volume[1] && 
                      a_MFI[0] > a_MFI[1])
                     {
                       ExtBlueBuffer[i] = Low[i]; // - Pips*Point;
                       break;
                     }
                   // èìååì óâÿäàþùèé ôðàêòàë (MFI - îáúåì -)
                   if(a_Volume[0]*Percent / 100 < a_Volume[1] && 
                      a_MFI[0] < a_MFI[1])
                     {
                       ExtSaddleBrownBuffer[i] = Low[i]; // - Pips*Point;
                       break;
                     }  
                 }
               j++;                                         
             }
         }
     }
   
// îòðèñîâêà ëèíèé
   double _Price[3,2];
   int  _Time[3,2];
   ArrayInitialize(_Price, -1);
   ArrayInitialize(_Time, -1);
   int up = 0, down = 0;
   for(i = 3; i <= 300; i++)
     {
       //up
       if(ExtRedBuffer[i] != 2147483647 && 
          iFractals(NULL, 0, MODE_UPPER, i) != NULL && 
          up <= 2 && 
          iFractals(NULL, 0, MODE_UPPER, i) <= ExtRedBuffer[i])
         {
           _Price[up,0] = ExtRedBuffer[i];
           _Time[up,0] = iTime(NULL, 0, i);
           up++;
         }
       if(ExtRedBuffer[i] != 2147483647 && 
          iFractals(NULL, 0, MODE_LOWER, i) != 0 && 
          down <= 2 && 
          iFractals(NULL, 0, MODE_LOWER, i) >= ExtRedBuffer[i])
         {
           _Price[down,1] = ExtRedBuffer[i];
           _Time[down,1] = iTime(NULL, 0, i);
           down++;         
         } 
     }
   ObjectMove("Up", 1, _Time[0,0], _Price[0,0]);
   ObjectMove("Up", 0, _Time[1,0], _Price[1,0]);
//----    
   ObjectMove("Down", 1, _Time[0,1], _Price[0,1]);
   ObjectMove("Down", 0, _Time[1,1], _Price[1,1]);
   if(UseOldLine)
     {
       ObjectMove("Up_Prev", 1, _Time[1,0], _Price[1,0]);
       ObjectMove("Up_Prev", 0, _Time[2,0], _Price[2,0]);
       //----
       ObjectMove("Down_Prev", 1, _Time[1,1], _Price[1,1]);
       ObjectMove("Down_Prev", 0, _Time[2,1], _Price[2,1]);         
     }
   return(0);
  }
//+------------------------------------------------------------------+



Comments