Market_Statistics_v2

Download script
Author: Copyright � 2009, Akif TOKUZ
Market_Statistics_v2

This script is designed to provide a comprehensive visual breakdown of market activity by analyzing price movement and trading volume over a specific period. Instead of just looking at price trends, it reconstructs how "heavy" the trading activity has been at various price levels, offering a more nuanced view of market dynamics.

Core Functional Logic

The script processes data based on a user-defined date range and performs several complex calculations simultaneously to provide the following visual components:

1. Volume Profile (Histogram) This is one of the primary features of the tool. Rather than showing volume as a vertical bar over time, it maps volume horizontally against price. It calculates how much trading activity occurred at every specific price point between the highest and lowest prices of your selected period.

  • Visual Result: It creates a histogram (teal-colored blocks) on the side of your chart. The longer the block, the higher the concentration of trading volume at that specific price level. This helps identify "high-interest" zones where the market may face significant support or resistance.

2. VWAP (Volume Weighted Average Price) The script calculates the VWAP, which is a benchmark tool used to determine the average price paid for a security during a specific timeframe, weighted by volume.

  • Logic: It treats a high-volume price movement as more "significant" than a low-volume move. This helps traders see where the "true" average price lies, rather than just a simple arithmetic average of the highs and lows.

3. PVP (Point of Value Price) While similar to VWAP, the PVP is derived specifically from the data gathered by the volume profile. It identifies the price point that represents the most significant concentration of trading activity within the period.

4. Standard Deviation Bands (SD1, SD2, SD3) The script calculates the volatility of the market relative to the VWAP using Standard Deviation. It creates three distinct sets of "envelopes" or bands:

  • SD1: Represents the first layer of standard deviation (the immediate price range).
  • SD2 & SD3: Represent wider layers of deviation, showing extreme volatility boundaries.
  • Logic: By calculating these based on volume-weighted data, these bands expand and contract based on how much actual trading energy is behind a price move. They act as dynamic zones to help identify overextended prices or areas where the market is returning to "mean" equilibrium.

User Customization Options

The script includes several toggle switches that allow you to customize your view:

  • Visibility Toggles: You can independently turn on or off the Histogram, PVP, VWAP, and each of the three Standard Deviation layers to declutter your chart.
  • Time Frame Control: You can define the exact start and end dates for the analysis, allowing you to isolate specific market sessions or historical events.
  • Amplitude Adjustment: You can control how many "items" (price points) are calculated in the volume profile to balance detail with performance.

Summary of Workflow

When the script runs, it scans back from your current chart to your chosen start date. It then:

  1. Collects every price and volume data point.
  2. Distributes that volume across a price grid to build the Histogram.
  3. Calculates the weighted averages to draw the VWAP and PVP.
  4. Measures the mathematical "spread" of the price from those averages to plot the SD bands.
  5. Draws a vertical line at your starting date to clearly mark the beginning of the analyzed data set.
Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
Market_Statistics_v2
//+------------------------------------------------------------------+
//|                                         Market_Statistics_v2.mq4 |
//|                                     Copyright © 2009, Akif TOKUZ |
//|                                             akifusenet@gmail.com |
//| Volume histogram implementation is based on Vadim Shumilov       |
//| (DrShumiloff)'s VolumesHist2.3 indicator. Other concepts are     |
//| inspired from Jperl's `Trading With Market Statistics` thread on |
//| Traders Laboratory.                                              |
//|                                                                  |
//| History:                                                         |
//| 10.08.2009: v2=>End date added.SD2Show defaulted to true         |
//|               =>Show/disable options added for every line        |
//| 06.08.2009: v1=>Initial release                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Akif TOKUZ"
#property link      "akifusenet@gmail.com"

#property indicator_chart_window

#property indicator_buffers 8

#property indicator_color1 Red         //PVP
#property indicator_width1 2

#property indicator_color2 Aqua        //VWAP
#property indicator_width2 2

#property indicator_color3 Green       //SD1Pos
#property indicator_width3 1
#property indicator_style3 2

#property indicator_color4 Red         //SD1Neg
#property indicator_width4 1
#property indicator_style4 2

#property indicator_color5 DarkOliveGreen//SD2Pos
#property indicator_width5 1
#property indicator_style5 2

#property indicator_color6 Crimson     //SD2Neg
#property indicator_width6 1
#property indicator_style6 2

#property indicator_color7 DarkGreen   //SD2Pos
#property indicator_width7 1
#property indicator_style7 2

#property indicator_color8 FireBrick   //SD2Neg
#property indicator_width8 1
#property indicator_style8 2


//---- input parameters
extern datetime  StartDate=D'2009.08.06 00:00';
extern datetime  EndDate=D'2009.08.07 00:00';
extern int    HistogramAmplitude = 100;
extern bool    Show_SD1 = true;
extern bool    Show_SD2 = true;
extern bool    Show_SD3 = false;
extern bool    Show_Histogram = true;
extern bool    Show_PVP = true;
extern bool    Show_VWAP = true;

//---- buffers
double PVP[];
double VWAP[];
double SD1Pos[];
double SD1Neg[];
double SD2Pos[];
double SD2Neg[];
double SD3Pos[];
double SD3Neg[];

double Hist[]; // drawn specifically

datetime OpenTime = 0;  // To check if we have a new bar
string   OBJECT_PREFIX = "VolumeHistogram_";
int      items;         // numbers of items inside volume histogram
int      Bars_Back = 0; // Shows the starting bar for given date
double   SD;            // standart deviation



// Finds the bar number for the given date
int FindStartIndex(datetime startDate)
{
   for (int i=Bars-1; i>=0; i--)
   {      
      if (Time[i]>=StartDate) return (i);
   }
   return( 0);
} 


int init()
{
   OBJECT_PREFIX = OBJECT_PREFIX + DoubleToStr(StartDate,0)+"_" ;
   
//---- indicators
   IndicatorBuffers(8);
   
   if (Show_PVP==true) SetIndexStyle(0,DRAW_LINE);
   else  SetIndexStyle(0,DRAW_NONE);
   SetIndexLabel(0,"PVP");      
   SetIndexBuffer(0,PVP);
   
   if (Show_VWAP==true) SetIndexStyle(1,DRAW_LINE);
   else  SetIndexStyle(1,DRAW_NONE);
   SetIndexLabel(1,"VWAP");      
   SetIndexBuffer(1,VWAP);
   
   if (Show_SD1==true) SetIndexStyle(2,DRAW_LINE);
   else  SetIndexStyle(2,DRAW_NONE);
   SetIndexLabel(2,"SD1Pos");      
   SetIndexBuffer(2,SD1Pos);
   
   if (Show_SD1==true) SetIndexStyle(3,DRAW_LINE);
   else  SetIndexStyle(3,DRAW_NONE);
   SetIndexLabel(3,"SD1Neg");      
   SetIndexBuffer(3,SD1Neg);
   
   if (Show_SD2==true) SetIndexStyle(4,DRAW_LINE);
   else  SetIndexStyle(4,DRAW_NONE);
   SetIndexLabel(4,"SD2Pos");      
   SetIndexBuffer(4,SD2Pos);
   
   if (Show_SD2==true) SetIndexStyle(5,DRAW_LINE);
   else  SetIndexStyle(5,DRAW_NONE);
   SetIndexLabel(5,"SD2Neg");      
   SetIndexBuffer(5,SD2Neg);
   
   if (Show_SD3==true) SetIndexStyle(6,DRAW_LINE);
   else  SetIndexStyle(6,DRAW_NONE);
   SetIndexLabel(6,"SD3Pos");      
   SetIndexBuffer(6,SD3Pos);
   
   if (Show_SD3==true) SetIndexStyle(7,DRAW_LINE);
   else  SetIndexStyle(7,DRAW_NONE);
   SetIndexLabel(7,"SD3Neg");      
   SetIndexBuffer(7,SD3Neg);
   
   string short_name="Market_Statistics";
   IndicatorShortName(short_name);
   
   
   return(0);
}


// Delete all objects with given prefix
void ObDeleteObjectsByPrefix(string Prefix)
{
   int L = StringLen(Prefix);
   int i = 0; 
   while(i < ObjectsTotal())
   {
       string ObjName = ObjectName(i);
       if(StringSubstr(ObjName, 0, L) != Prefix) 
       { 
           i++; 
           continue;
       }
       ObjectDelete(ObjName);
   }
}
  




  
int start()
{
   double TotalVolume=0;
   double TotalPV=0;
   int n;

   
   if (OpenTime != Open[0])
   {
      Bars_Back=FindStartIndex(StartDate);
      if (Bars_Back!=0)
      {
      ObjectSet( "Starting_Time", OBJPROP_TIME1, Time[Bars_Back]);
      ObjectSet("Starting_Time", OBJPROP_COLOR, Red);
      ObjectCreate("Starting_Time", OBJ_VLINE, 0, Time[Bars_Back], 0);
      }
      
      OpenTime = Open[0];
                             
      double max = High[iHighest( NULL , 0, MODE_HIGH, Bars_Back, 0)];
      double min =  Low[ iLowest( NULL , 0, MODE_LOW,  Bars_Back, 0)];
      items = MathRound((max - min) / Point);

      ArrayResize(Hist, items);
      ArrayInitialize(Hist, 0);

      TotalVolume=0;
      TotalPV=0;
      for (int i = Bars_Back; i >= 1; i--)
      {         
      
         if (Time[i]<EndDate) // Only calculate if we didnt reach the end date
         {
         double t1 = Low[i], t2 = Open[i], t3 = Close[i], t4 = High[i];
         if (t2 > t3) {t3 = Open[i]; t2 = Close[i];}
         double totalRange = 2*(t4 - t1) - t3 + t2;         

         if (totalRange != 0.0)
         {
            for (double Price_i = t1; Price_i <= t4; Price_i += Point)
            {
               n = MathRound((Price_i - min) / Point);

               if (t1 <= Price_i && Price_i <  t2)
               {
                  Hist[n] += MathRound(Volume[i]*2*(t2-t1)/totalRange);
               }
               if (t2 <= Price_i && Price_i <= t3)
               {
                  Hist[n] += MathRound(Volume[i]*(t3-t2)/totalRange);
               }
               if (t3 <  Price_i && Price_i <= t4)
               {
                  Hist[n] += MathRound(Volume[i]*2*(t4-t3)/totalRange);
               }
            }//for
         }else
         {
            // Check if all values are equal to each other
            n = MathRound((t3 - min) / Point);
            Hist[n] += Volume[i];                     
         }//if


         // use H+L+C/3 as average price
         TotalPV+=Volume[i]*((Low[i]+High[i]+Close[i])/3);
         TotalVolume+=Volume[i];                          
      
         if (i==Bars_Back) PVP[i]=Close[i];        
         else PVP[i]=min+ArrayMaximum(Hist)*Point;

         if (i==Bars_Back) VWAP[i]=Close[i];        
         else VWAP[i]=TotalPV/TotalVolume;
 

         SD=0;         
         for (int k = Bars_Back; k >= i; k--)
         {
            double avg=(High[k]+Close[k]+Low[k])/3;
            double diff=avg-VWAP[i];
            SD+=(Volume[k]/TotalVolume)*(diff*diff);         
          }
          SD=MathSqrt(SD);
          SD1Pos[i]=VWAP[i]+SD;
          SD1Neg[i]=VWAP[i]-SD;
          SD2Pos[i]=SD1Pos[i]+SD;
          SD2Neg[i]=SD1Neg[i]-SD;
          SD3Pos[i]=SD2Pos[i]+SD;
          SD3Neg[i]=SD2Neg[i]-SD;
          
        }//if for checking end date  
      }//for BARS BACK
      
      ObDeleteObjectsByPrefix(OBJECT_PREFIX);
      if (Show_Histogram)
      {
      int MaxVolume = Hist[ArrayMaximum(Hist)];      
      int multiplier;        
      for (i = 0; i <= items; i++)
      {
         // Protection if we have less bar than amplitude yet      
         if (Bars_Back<HistogramAmplitude) multiplier=Bars_Back;
         else multiplier=HistogramAmplitude;                  
         
         if (MaxVolume != 0) Hist[i] = MathRound(multiplier * Hist[i] / MaxVolume );
         
         if (Hist[i] > 0)
         {
            int time_i = Bars_Back-Hist[i];
            if (time_i>=0)
            {
               ObjectCreate(OBJECT_PREFIX+i, OBJ_RECTANGLE, 0, Time[Bars_Back], min + i*Point, Time[time_i], min + (i+1)*Point);
               ObjectSet(OBJECT_PREFIX+i, OBJPROP_STYLE, DRAW_HISTOGRAM);
               ObjectSet(OBJECT_PREFIX+i, OBJPROP_COLOR, Teal);
               ObjectSet(OBJECT_PREFIX+i, OBJPROP_BACK, true);               
            }//if
         } //if        
      }//for
      
      }//if show histogram
   }//MAIN IF BAR START
   
   return(0);
}

int deinit()
{
   ObDeleteObjectsByPrefix(OBJECT_PREFIX);
   ObjectDelete("Starting_Time");
   return(0);
}

Comments