marketprofile

Download script
Author: Viatcheslav Suvorov
marketprofile

This script is designed to analyze and visualize the "Market Profile," a tool used by traders to identify price activity, volume distribution, and significant levels of interest within a specific trading period. Instead of simply showing you where the price went, it illustrates where the price spent the most time and at what levels the highest concentration of activity occurred.

Core Functional Logic

The script operates by scanning historical price data to build a visual map of market behavior. Here is the step-by-step breakdown of how it processes this information:

1. Timeframe and Period Identification The tool looks back at the trading history starting from a specific date. It identifies distinct trading sessions—specifically categorizing activity into three major global regions: Asia, Europe, and America. By doing this, the script can differentiate between "overnight" movements, early morning trends, and active afternoon sessions.

2. Identifying Highs and Lows The logic automatically detects the highest and lowest price points reached during a trading cycle. It uses these boundaries to create a "profile" area. By knowing the limits of where the price traveled, it can then begin to analyze everything that happened inside those boundaries.

3. Density Mapping (The "Profile") This is the heart of the script. Rather than just marking a single point, the logic scans every price level between the high and the low. For every specific price point:

  • It counts how many times the price interacted with that level.
  • It determines which session (Asia, Europe, or America) contributed most to that interaction based on the time of day.
  • It identifies the "Median"—the price level where the highest concentration of trading activity occurred.

4. Visual Representation Once the data is collected, the script draws this information directly onto your chart:

  • Volume Clusters: It creates colored rectangles to represent different sessions. Each region is assigned a unique color (e.g., Maroon for Asia, Yellow for Europe, and Blue for America). This allows you to see at a glance which global market was most active at specific price levels.
  • The Median Line: The script draws a prominent white horizontal line at the "Median" level. This highlights the "Fair Value" or the area of highest liquidity where the most trading occurred, providing a clear visual anchor for support and resistance.

Summary for the User

Essentially, this tool converts raw price candles into a heat map of market behavior. It tells you not just where the price moved, but where it liked to stay. By distinguishing between global sessions, it helps you see how different parts of the world influenced the price, while the white Median line identifies the most significant "battleground" for buyers and sellers during that period.

11 Views
0 Downloads
0 Favorites
marketprofile
//+------------------------------------------------------------------+
//|                                                MarketProfile.mq4 |
//|                             Copyright © 2006, Viatcheslav Suvorov| 
//+------------------------------------------------------------------+
#property copyright "Viatcheslav Suvorov"

#property indicator_chart_window


extern datetime StartDate = D'';
extern bool lastdayStart = true;
extern int CountProfile = 2;



int fontsize=10;
int i,j;
double LastHigh,LastLow,CurPos;
bool signal; 
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
ObjectsDeleteAll(0,OBJ_RECTANGLE);
ObjectsDeleteAll(0,OBJ_TREND);
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;


//---- name for DataWindow and indicator subwindow label
   short_name="MarketProfile";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);

   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()

  {  
  deinit();
double onetick;  
double Mediana=0;
int MaxSize=0;
int MySize=0;
int MySizeEuropa=0;
int MySizeAzia=0;
int MySizeAmerica=0;
int BACK=0;
if (lastdayStart) StartDate=Time[0];

//int x=Period();
//if (x>60) return(-1);
//if (x<5) return(-1);


  BACK=0;
  while (TimeDayOfYear(Time[BACK])>TimeDayOfYear(StartDate) || TimeYear(Time[BACK])!=TimeYear(StartDate) && (BACK<Bars)) {  
    BACK++;   
    if (BACK>=Bars) return(0);
  }//while


onetick = 1/(MathPow(10,Digits));
i=BACK;
////
int cycles;

for (cycles=CountProfile;cycles>0;cycles--) {

signal=false;
LastHigh=High[i];
LastLow=Low[i];
while (!signal)
{ 
//if (i+1==Bars) signal=true;
if (High[i+1]>LastHigh) LastHigh=High[i+1];
if (Low[i+1]<LastLow) LastLow=Low[i+1];
MaxSize=0;
MySize=0;

if (TimeDay(Time[i])!=TimeDay(Time[i+1]))
   { 
   
   signal=true;
   CurPos=LastLow;
   while (CurPos<=LastHigh){
     MySizeAzia=0;
     MySizeEuropa=0;
     MySizeAmerica=0;
     for (j=i;j>=BACK;j--) {
       if ((High[j]>=CurPos) && (Low[j]<=CurPos)) {
         MySize++;       
         if (TimeHour(Time[j])>=13)  MySizeAmerica++; else 
         if ((TimeHour(Time[j])>=8) && (TimeHour(Time[j])<13)) MySizeEuropa++; else 
           MySizeAzia++;
         
       }//if  
     }//for
     if (MySizeAzia+MySizeEuropa+MySizeAmerica>MaxSize){
       MaxSize=MySizeAzia+MySizeEuropa+MySizeAmerica;
       Mediana=CurPos;
     }
     if (i-MySizeAzia>=0)
     if(ObjectFind("rec"+"Azia"+TimeToStr(Time[i],TIME_DATE)+CurPos) == -1 && MySizeAzia!=0) {
           ObjectCreate("rec"+"Azia"+TimeToStr(Time[i],TIME_DATE)+CurPos, OBJ_RECTANGLE, 0, Time[i], CurPos,Time[i-MySizeAzia],CurPos+onetick);           
           ObjectSet("rec"+"Azia"+TimeToStr(Time[i],TIME_DATE)+CurPos, OBJPROP_COLOR, Maroon);
     }//if      
     if(ObjectFind("rec"+"Europa"+TimeToStr(Time[i],TIME_DATE)+CurPos) == -1 && MySizeEuropa!=0) {
           ObjectCreate("rec"+"Europa"+TimeToStr(Time[i],TIME_DATE)+CurPos, OBJ_RECTANGLE, 0, Time[i-MySizeAzia], CurPos,Time[i-MySizeAzia-MySizeEuropa],CurPos+onetick);
           ObjectSet("rec"+"Europa"+TimeToStr(Time[i],TIME_DATE)+CurPos, OBJPROP_COLOR, Yellow);           
     }//if      
     if(ObjectFind("rec"+"America"+TimeToStr(Time[i],TIME_DATE)+CurPos) == -1 && MySizeAmerica!=0) {
           ObjectCreate("rec"+"America"+TimeToStr(Time[i],TIME_DATE)+CurPos, OBJ_RECTANGLE, 0, Time[i-MySizeAzia-MySizeEuropa], CurPos,Time[i-MySizeAzia-MySizeEuropa-MySizeAmerica],CurPos+onetick);
           ObjectSet("rec"+"America"+TimeToStr(Time[i],TIME_DATE)+CurPos, OBJPROP_COLOR, Blue);                      
     }//if      
           
     
                     
       
     CurPos=CurPos+onetick;
   }//while
      ObjectCreate("mediana"+TimeToStr(Time[i],TIME_DATE), OBJ_TREND, 0, Time[i], Mediana,Time[i]+20000,Mediana);
      ObjectSet("mediana"+TimeToStr(Time[i],TIME_DATE), OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet("mediana"+TimeToStr(Time[i],TIME_DATE), OBJPROP_COLOR,White);  
      ObjectSet("mediana"+TimeToStr(Time[i],TIME_DATE), OBJPROP_WIDTH,2);   
      ObjectSet("mediana"+TimeToStr(Time[i],TIME_DATE), OBJPROP_RAY,false);
      ObjectSet("mediana"+TimeToStr(Time[i],TIME_DATE), OBJPROP_TIME2,Time[i]+20000);  
   BACK=i+1;   
   }//if
   i++;   
   if (i>=Bars) return(0);
}//while
}//for
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments