(mp) market profile.mq5
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «(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? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.