← К каталогу
Исходный код · ID 4690

(mp) market profile.mq5

Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Индикатор «(mp) market profile» реализует визуализацию Market Profile и TPO-профилей (Time Price Opportunity) на графике в платформе MetaTrader 5. Он рассчитывает распределение цены по временным интервалам (день, неделя, месяц) и отображает результат в виде гистограммы, а также рисует линии POC (Point of Control), границы Value Area и стрелки открытия/закрытия.

Индикатор поддерживает два режима отображения профиля: на основе объёмов (Volume Profile) и на основе количества TPO (TPO Profile), переключаемые настройкой. Профиль может строиться на дневном, недельном или месячном таймфрейме с возможностью задать час начала торгового дня. Вспомогательные данные для каждого профиля берутся с указанных таймфреймов.

Все элементы рисуются прямо на ценовом графике в виде прямоугольников, горизонтальных трендовых линий, текстовых меток и стрелок. Цвета, высота гистограммы, отображение Value Area и дополнительных линий настраиваются пользователем индивидуально. Индикатор обновляет профиль при переходе на новый бар профильного периода и задерживает обработку на несколько секунд для корректного перерисовывания объектов.

Настройки программы

НастройкаОписание
LookBack Количество баров профильного периода, учитываемых при расчёте (ограничивается автоматически по доступным данным).
UseVolumeProfile Переключатель режима профиля: true — профиль на основе объёмов, false — профиль на основе количества TPO.
ProfileTimeframeInfo Информационный текст-подсказка о допустимых значениях таймфрейма профиля (не влияет на расчёт).
ProfileTimeframe Выбранный таймфрейм построения профиля: D — дневной, W — недельный, M — месячный.
DayStartHour Час начала торгового дня, с которого отсчитывается дневной профиль (0–23).
VATPOPercent Процент от общего объёма (или количества TPO), который определяет границы Value Area.
TickSize Размер тика, используемый для определения минимального ценового шага при построении профиля.
ExtendedPocLines Количество последних линий POC, которые продолжают отрисовываться до текущего момента времени на графике.
spr0 Текстовый разделитель-группировщик для настроек включения/отключения отображения элементов.
ShowPriceHistogram Переключатель отображения ценовой гистограммы профиля на графике.
ShowValueArea Переключатель отображения заштрихованной области Value Area на графике.
ShowVAHVALLines Переключатель отображения горизонтальных линий VAH (Value Area High) и VAL (Value Area Low).
ShowOpenCloseArrow Переключатель отображения стрелок открытия и закрытия на профильных барах.
spr1 Текстовый разделитель-группировщик для настроек дизайна и цветов.
VolAmplitudePercent Процент от полной амплитуды гистограммы, до которой отрисовывается объёмная гистограмма (влияет на длину прямоугольников).
HistoHeight Высота одного шага гистограммы в тиках, определяющая детализацию ценовых уровней.
HistoColor1 Первый цвет прямоугольников гистограммы (используется для чередования полос).
HistoColor2 Второй цвет прямоугольников гистограммы (используется для чередования полос).
OpenColor Цвет стрелки, обозначающей цену открытия бара профильного периода.
CloseColor Цвет стрелки, обозначающей цену закрытия бара профильного периода.
POCColor Цвет линии POC (Point of Control) — уровня с наибольшим количеством TPO или объёма.
VirginPOCColor Цвет линии VPOC (Virgin Point of Control) — POC предыдущего профильного периода, не достигнутый в текущем.
VAColor Цвет заливки области Value Area на графике.
VALinesColor Цвет горизонтальных линий VAH и VAL.
InfoColor Цвет текста информационной метки, отображаемой в углу графика.
spr2 Текстовый разделитель-группировщик для настроек данных профиля.
DailyProfileDataTf Таймфрейм источника данных для построения дневного профиля (числовое значение в минутах, например 60 — H1).
WeeklyProfileDataTf Таймфрейм источника данных для построения недельного профиля (числовое значение в минутах, например 240 — H4).
MonthlyProfileDataTf Таймфрейм источника данных для построения месячного профиля (числовое значение в минутах, например 1440 — D1).
Получить полный код

Поиск по коду файла

#property indicator_chart_window

#define PRICEIDX        0
#define TPOIDX          1
#define VOLIDX          2

extern int        LookBack                = 3;
extern bool       UseVolumeProfile        = false;
extern string     ProfileTimeframeInfo    = "use D, W, or M";
extern string     ProfileTimeframe        = "W";
extern int        DayStartHour            = 0;
extern double     VATPOPercent            = 70.0;
extern int        TickSize                = 1;
extern int        ExtendedPocLines        = 3;

extern string     spr0                    = "on/off settings..";
extern bool       ShowPriceHistogram      = true;
extern bool       ShowValueArea           = false;
extern bool       ShowVAHVALLines         = false;
extern bool       ShowOpenCloseArrow      = false;

extern string     spr1                    = "design & colors..";
extern double     VolAmplitudePercent     = 40.0;
extern int        HistoHeight             = 2;
extern color      HistoColor1             = Black;
extern color      HistoColor2             = Black;
extern color      OpenColor               = Black;
extern color      CloseColor              = Black;
extern color      POCColor                = White;
extern color      VirginPOCColor          = White;
extern color      VAColor                 = Black;
extern color      VALinesColor            = Black;
extern color      InfoColor               = Black;

extern string     spr2                    = "Profile Data.............";
extern int        DailyProfileDataTf      = 60;
extern int        WeeklyProfileDataTf     = 240;
extern int        MonthlyProfileDataTf    = 1440;

string            gsPref                  = "ay.mp.";
double            fpoint
                , gdOneTick
                , gdHistoRange;
int               fdigits
                , giStep
                , giProfileTf             = PERIOD_D1
                , giDataTf                = 0;

int init()
{
      // код доступен только после оплаты
   }

int deinit()
{
   delObjs();
   return(0);
}

int start()
{
      // код доступен только после оплаты
   }

bool isOK()
{   
   switch (Period())
   {
      case PERIOD_M1:         
      case PERIOD_M5:         
      case PERIOD_M15:
         if (giProfileTf == PERIOD_D1) return(true);
         break;      
      case PERIOD_M30: 
         if (giProfileTf <= PERIOD_W1) return(true);
         break;          
      case PERIOD_H1:   
         return(true);
         break;            
      case PERIOD_H4:
      case PERIOD_D1:
         if (giProfileTf >= PERIOD_W1) return(true);
         break;
      default:
         return(false);               
         break;
   }          

   return(false);
}

void getStartAndEndBar(int ibar_proftf, int &startbar, int &endbar)
{      

   int i, j;
   datetime dt_proftf;     
   datetime dt_proftf_next; 

   switch (giProfileTf)
   {
      case PERIOD_D1:
         int oneday = PERIOD_D1*60;
         int iday = -1;
         datetime dt;
         startbar = 0; endbar = 0;         

         if (DayStartHour == 0)
         {
           dt_proftf       = iTime( NULL, giProfileTf, ibar_proftf );
           dt_proftf_next  = iTime( NULL, giProfileTf, ibar_proftf - 1 );         
           startbar        = iBarShift ( NULL, giDataTf, dt_proftf);
           endbar          = iBarShift ( NULL, giDataTf, dt_proftf_next - (giDataTf * 60) );   

           if (dt_proftf_next < dt_proftf) endbar = 0;         

           if ( iTime(NULL, giDataTf, startbar) < dt_proftf ) startbar--; 

           if (TimeDayOfWeek(iTime( NULL, giDataTf, startbar )) == 0) startbar = -1;

           break;
         }         

         for (i=0; i<iBars(NULL, giDataTf); i++)
         {
            dt = iTime(NULL, giDataTf, i);
            if (TimeHour(dt) == DayStartHour && TimeMinute(dt) == 0 )
            {
               iday++;
               if (iday == ibar_proftf) 
               {
                  startbar = i;         
                  if (ibar_proftf !=0) 
                  {
                     endbar  = iBarShift( NULL, giDataTf, dt + oneday - (giDataTf * 60) );                
                     if ( iTime(NULL, giDataTf, endbar) < dt + oneday - (giDataTf * 60) ) 
                     {
                        endbar++;
                        for (j=endbar; j>=0; j--)
                        {
                           dt = iTime(NULL, giDataTf, j);
                           if (TimeHour(dt) == DayStartHour && TimeMinute(dt) == 0 )
                           {
                              endbar = j+1;
                              break;
                           }                            
                        }// end for j
                     }
                  }
                  else endbar = 0;

                  break;
               }
            }
         }// end for i

         if (iday == -1) {startbar = -1; endbar = -1;}

         break;

      default:
         dt_proftf      = iTime( NULL, giProfileTf, ibar_proftf );
         dt_proftf_next = iTime( NULL, giProfileTf, ibar_proftf - 1 );

         startbar  = iBarShift ( NULL, giDataTf, dt_proftf);
         endbar    = iBarShift ( NULL, giDataTf, dt_proftf_next - (giDataTf * 60) );

         if (dt_proftf_next < dt_proftf) endbar = 0;         

         if ( iTime(NULL, giDataTf, startbar) < dt_proftf ) startbar--;    

         break;
   }         
}

void getHHLL(int startbar, int endbar, double &hh, double &ll)
{
   hh = iHigh ( NULL, giDataTf, iHighest(NULL, giDataTf, MODE_HIGH, (startbar - endbar)+1, endbar) );
   ll = iLow  ( NULL, giDataTf, iLowest (NULL, giDataTf, MODE_LOW,  (startbar - endbar)+1, endbar) );
   hh = NormalizeDouble(hh, fdigits);
   ll = NormalizeDouble(ll, fdigits);
}

void drawInfo()
{

   string info = "Volume Profile";
   if (!UseVolumeProfile) info = "TPO Profile";

   if (ObjectFind(gsPref+"lblinfo1") == -1)
    ObjectCreate (gsPref+"lblinfo1", OBJ_LABEL,0,0,0);

   ObjectSet    (gsPref+"lblinfo1", OBJPROP_CORNER, 3);
   ObjectSetText(gsPref+"lblinfo1", info, 3, "Impact", InfoColor);
   ObjectSet    (gsPref+"lblinfo1", OBJPROP_XDISTANCE, 10);
   ObjectSet    (gsPref+"lblinfo1", OBJPROP_YDISTANCE, 20);

   if (giProfileTf == PERIOD_D1)
   {
      if (ObjectFind(gsPref+"lblinfo2") == -1)      
        ObjectCreate (gsPref+"lblinfo2", OBJ_LABEL,0,0,0);

      ObjectSet    (gsPref+"lblinfo2", OBJPROP_CORNER, 3);
      ObjectSetText(gsPref+"lblinfo2", "DayStartHour: " + DayStartHour, 3, "Impact", InfoColor);
      ObjectSet    (gsPref+"lblinfo2", OBJPROP_XDISTANCE, 10);
      ObjectSet    (gsPref+"lblinfo2", OBJPROP_YDISTANCE, 5);            
   }

}

void getPriceTPO
(
     int       startbar
   , int       endbar
   , double    hh
   , double    ll
   , double    &aprice_step[][3]
   , int       &countps
   , int       &maxtpo
   , int       &maxtpoidx
   , double    &totaltpo
   , double    &maxvol
   , int       &maxvolidx   
   , double    &totalvol
)
{

   maxtpo        = 0;
   maxtpoidx     = 0;
   totaltpo      = 0.0;
   maxvol        = 0.000001;
   maxvolidx     = 0; 
   totalvol      = 0.0;

   double     shh = hh; //start hh
   double     profile_range       = MathMax(hh - ll, gdOneTick)
            , mid_profile_price   = hh - (0.5 * profile_range);   

   countps  = 0;          
   while (shh >= ll)
   {   
      ArrayResize(aprice_step, countps+1);   
      aprice_step [countps][PRICEIDX] = shh;
      aprice_step [countps][TPOIDX]   = 0.0;
      aprice_step [countps][VOLIDX]   = 0.0;

      shh -= gdOneTick;
      countps  ++;

   } // while (shh >= ll)   

   int      i, j;
   double   price_step;

   for (i=0; i<countps; i++)
   {
      price_step = aprice_step[i][PRICEIDX];
      j = startbar;
      while ( j >= endbar)
      {            
         double hp        = iHigh  (NULL, giDataTf, j);
         double lp        = iLow   (NULL, giDataTf, j);         
         double bar_vol   = iVolume(NULL, giDataTf, j);
         double bar_range = MathMax( (hp - lp) / fpoint, gdOneTick );
         double pip_vol   = bar_vol / bar_range;         

         if (  price_step >= lp && price_step <= hp )   
         {
            aprice_step[i][TPOIDX] += 1;  
            aprice_step[i][VOLIDX] += pip_vol;
            totaltpo += 1; 
            totalvol += pip_vol;

            if (aprice_step[i][TPOIDX] > maxtpo) 
            {
               maxtpo    = aprice_step[i][TPOIDX];
               maxtpoidx = i;               
            }

            if (aprice_step[i][TPOIDX] == maxtpo) 
            {

               if (   MathAbs(mid_profile_price - aprice_step[i][PRICEIDX]) 
                    < MathAbs(mid_profile_price - aprice_step[maxtpoidx][PRICEIDX]) 
                   )
               {
                  maxtpo    = aprice_step[i][TPOIDX];
                  maxtpoidx = i;
               }
            }

            if (aprice_step[i][VOLIDX] > maxvol) 
            {
               maxvol    = aprice_step[i][VOLIDX];
               maxvolidx = i;               
            }

            if (aprice_step[i][VOLIDX] == maxvol) 
            {

               if (   MathAbs(mid_profile_price - aprice_step[i][PRICEIDX]) 
                    < MathAbs(mid_profile_price - aprice_step[maxvolidx][PRICEIDX]) 
                   )
               {
                  maxvol    = aprice_step[i][VOLIDX];
                  maxvolidx = i;
               }
            }

         } // end if (price-gdHistoRange <= High[j] && price >= Low[j])   

         j--;
      } // end while ( iBarShift(NULL, giProfileTf, Time[j]) == itfsource )

   }// end for (i=0; i<countps; i++)   

}

void drawPriceHistoAndPOCLines
(
     int    startbar
   , int    endbar  
   , int    ibar_proftf  
   , int    countps
   , double aprice_step[][]
   , int    maxtpo
   , int    maxtpoidx
   , double maxvol
   , int    maxvolidx
)
{
   double   price1, price2, dstep;
   int      numtpo; 
   double   numvol;
   int      step, i;
   int      chart_startbar = iBarShift( NULL, 0, iTime(NULL, giDataTf, startbar) );
   int      chart_endbar   = iBarShift( NULL, 0, iTime(NULL, giDataTf, endbar) );
   int      numbar         = chart_startbar - chart_endbar;
   color    clr; 
   d

Показано первые 50% кода (символов: 17061)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
1 706,10₽ ≈ $20.87