//+---------------------------------------------------------------------+
//| #_i_3D_ADX.mq4 |
//| Copyright � 2009, TigraVK |
//| |
//|��������� ������� ����� �� ������ ADX � |
//|���������� ��������� � �������� ���� ������� ��������� |
//|�����������. ��������� ����������� ����������� ������ � �������� |
//|���������������� ���������. |
//|� ���������� ���������� ���������� �������� ����� ADX |
//|� ������ ������ ���������� �������� ������ ����������� |
//| - ����������� ������ �� ������� +DI � -DI; |
//| - ����������� �������� ������ MAIN; |
//| - �������� ����� ��� �������� +DI ������������ -DI. |
//| |
//|���������� � �� ��������� - ����� � ������� ������� ��������� |
//|����������� |
//|���������� Y �� ��������� - ������ ���� ���������������� ����������� |
//|ADX � ���������� ����������� |
//|���������� Z �������� ���������� ������� � ����������� �� �������� |
//|� ��������� ������ ADX � ������ ��������� ����� |
//+---------------------------------------------------------------------+
#property copyright "Copyright � 2009, TigraVK"
#property link "tigravk@yandex.ru"
#property indicator_chart_window
#include <stdlib.mqh>
#define ELEMENTS 80 //���������� ������������ ����� � ���������
extern int IndMode = 0; //���� �� ���� ������� ��������� ��������: 0-�����������;1-���������� ��������;2-������� �������� ���������
extern int Columns = 600; //���������� ������������ �������� ���������
extern int Width = 1; //������ �������, � �����
extern int DrawShift = 0; //�������� �������� ������� (� �����) ������������ ������ ������� ���� �������
//����������� � ������ ������ ���� ����� ���������� � ������� ����������� � ���� ����
//��� ���������� ���������� ����������� ��������
//��������, ��� ������ ������ ��������� ��������� ����� ���������� DrawShift=Columns+4
//-- ��������� ��������� iADX � ���������� ������� -----------
extern int ADXperiod = 3;
extern int ADXperiod_step = 5;
extern int Method = MODE_SMA;
extern int ADXappliedPrice = 0; //PRICE_CLOSE 0 ���� ��������
//PRICE_OPEN 1 ���� ��������
//PRICE_HIGH 2 ������������ ����
//PRICE_LOW 3 ����������� ����
//PRICE_MEDIAN 4 ������� ����, (high+low)/2
//PRICE_TYPICAL 5 �������� ����, (high+low+close)/3
//PRICE_WEIGHTED 6 ���������� ���� ��������, (high+low+close+close)/4
//-------------------------------
#define COLUMNS_DOP 3 //���-�� �������������� ������� � ������� ADX[][] (����, �������������� �����)
#define HEADER 6 //����� ��� ��������� (���������� ������� ������� ���������)
#define GAP 0 //������ (� �����) ����� ���������� ��������� � �����������
#define GAP_PERCENT 20 //������ (� ��������� �� ������ �������� ���������) ����� ���������� ��������� � ���������
double ADXMAIN[][ELEMENTS];//������ ����� ������ MAIN
double ADXPLUS[][ELEMENTS];//������ ����� ������ +DI
double ADXMINUS[][ELEMENTS];//������ ����� ������ -DI
double Top;
double Bottom;
int FreeBars;
string el_name;
string indname = "#_i_3D_ADX";
datetime tm;
int shift;
//+------------------------------------------------------------------+
int init()
{
tm=Time[0];
shift=DrawShift*(Width+GAP);
Top =WindowPriceMax(0);
Bottom =WindowPriceMin(0);
FreeBars=WindowBarsPerChart()-WindowFirstVisibleBar()-shift;
if(IndMode==0)
{
el_name = "ADXDIR";
CreateHeader("ADX direction", Top, Width, Columns, FreeBars, Yellow);
}
else if(IndMode==1)
{
el_name = "ADXABS";
CreateHeader("ADX absolute", Top, Width, Columns, FreeBars, Yellow);
}
else if(IndMode==2)
{
el_name = "ADXACC";
CreateHeader("ADX acceleration", Top, Width, Columns, FreeBars, Yellow);
}
else
{
el_name = "ADX";
CreateHeader("NONE", Top, Width, Columns, FreeBars, Yellow);
}
IndicatorShortName(indname);
ArrayResize(ADXMAIN,Columns+COLUMNS_DOP);
ArrayInitialize(ADXMAIN, 0.0);
ArrayResize(ADXPLUS,Columns+COLUMNS_DOP);
ArrayInitialize(ADXPLUS, 0.0);
ArrayResize(ADXMINUS,Columns+COLUMNS_DOP);
ArrayInitialize(ADXMINUS, 0.0);
//������� ����������
for(int i=0; i<Columns; i++)
CreateShield(el_name+i+"_", Top, Bottom, Width, FreeBars-(Width+GAP)*i, Gray);
return(0);
}
//+------------------------------------------------------------------+
int deinit()
{
DeleteIndicatorObject(el_name);
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int i;
int limit;
double top =WindowPriceMax(0);
double bottom =WindowPriceMin(0);
int free_bars =WindowBarsPerChart()-WindowFirstVisibleBar()-shift;
int counted_bars=IndicatorCounted();
limit=Bars-counted_bars;
if(limit>Columns+COLUMNS_DOP) limit=Columns+COLUMNS_DOP;
//��������� ����������� ��������� ��� ����� �������� ���� ��� �������� �������� ������� �������
if(Top!=top || Bottom!=bottom || FreeBars!=free_bars || tm!=Time[0])
{
Top=top; Bottom=bottom; FreeBars=free_bars; tm=Time[0];
for(i=0; i<Columns; i++)
{
if(MoveShield(el_name+i+"_", Top, Bottom, Width, FreeBars-(Width+GAP)*i)<0)
{
DeleteIndicatorObject(el_name+i+"_");
CreateShield(el_name+i+"_", Top, Bottom, Width, FreeBars-(Width+GAP)*i, Gray);
}
}
MoveHeader(Top, Width, Columns, FreeBars, Yellow);
}
if(limit>=Columns+COLUMNS_DOP) //������ ��������� ��� ������� ����������
{
AdxDATA_fill(ADXMAIN, ADXPLUS, ADXMINUS, limit, 0, 0);
if(IndMode==0) AdxWeerDirection(ADXPLUS, ADXMINUS, Columns);
else if(IndMode==1) AdxWeerAbsolute(ADXMAIN, Columns);
else if(IndMode==2) AdxWeerAcceleration(ADXPLUS, ADXMINUS, Columns);
}
else if(limit>1 && limit<Columns+COLUMNS_DOP) //����������� ��� ����� ����
{
AdxDATA_leftShift(ADXMAIN, ADXPLUS, ADXMINUS, Columns+COLUMNS_DOP, limit-1);
AdxDATA_fill(ADXMAIN, ADXPLUS, ADXMINUS, limit-1, 0, 0);
if(IndMode==0) AdxWeerDirection(ADXPLUS, ADXMINUS, Columns);
else if(IndMode==1) AdxWeerAbsolute(ADXMAIN, Columns);
else if(IndMode==2) AdxWeerAcceleration(ADXPLUS, ADXMINUS, Columns);
}
else //����������� ������ �������� ����
{
AdxDATA_fill(ADXMAIN, ADXPLUS, ADXMINUS, limit, 0, 0);
if(IndMode==0) AdxWeerDirection(ADXPLUS, ADXMINUS, limit);
else if(IndMode==1) AdxWeerAbsolute(ADXMAIN, limit);
else if(IndMode==2) AdxWeerAcceleration(ADXPLUS, ADXMINUS, Columns);
}
err("Start: ");
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void AdxDATA_fill(double& MAIN[][], double& PDI[][], double& MDI[][], int recount_columns, int start_columns, int historyBarShift)
{
int i,j;
int adxp;
for(j=start_columns; j<recount_columns+start_columns; j++)
{
adxp=ADXperiod;
for(i=0; i<ELEMENTS; i++)
{
PDI[j][i] =iADX(NULL,0,adxp,ADXappliedPrice,MODE_PLUSDI,j+historyBarShift);
MDI[j][i] =iADX(NULL,0,adxp,ADXappliedPrice,MODE_MINUSDI,j+historyBarShift);
MAIN[j][i]=iADX(NULL,0,adxp,ADXappliedPrice,MODE_MAIN,j+historyBarShift);
adxp=adxp+ADXperiod_step;
}
}
return;
}
//+------------------------------------------------------------------+
void AdxDATA_leftShift(double& MAIN[][], double& PDI[][], double& MDI[][], int columns, int shift_columns_count)
{
int i,j,k;
for(k=1; k<=shift_columns_count; k++)
{
for(j=columns-1; j>0; j--)
{
for(i=0; i<ELEMENTS; i++)
{
MAIN[j][i] = MAIN[j-1][i];
PDI[j][i] = PDI[j-1][i];
MDI[j][i] = MDI[j-1][i];
}
}
for(i=0; i<ELEMENTS; i++)
{
MAIN[j][i] = 0.0;
PDI[j][i] = 0.0;
MDI[j][i] = 0.0;
}
}
}
//+------------------------------------------------------------------+
// ������� ����, ���� +DI ���� -DI
// ������� ����, ���� -DI ���� +DI
void AdxWeerDirection(double& PDI[][], double& MDI[][], int recount_columns)
{
int i,j;
for(j=recount_columns-1; j>=0; j--)
{
for(i=0; i<ELEMENTS; i++)
{
if(PDI[j][i]-MDI[j][i]>=0.0) ObjectSet(el_name+DoubleToStr(j,0)+"_"+i, OBJPROP_COLOR, LightGreen);
else ObjectSet(el_name+DoubleToStr(j,0)+"_"+i, OBJPROP_COLOR, Red);
}
}
}
//+------------------------------------------------------------------+
// ���������� �������� ��������� � �������� �� ������ (�������) �� ��������(��������)
// �������� ����������� � ������������� �������� ������ �� ����������� ������ �������
void AdxWeerAbsolute(double& DATA[][], int columns)
{
int i,j;
color clr;
double min, max;
for(i=0; i<ELEMENTS; i++)
{
min=10000;
max=-10000;
for(j=0; j<columns; j++)
{
min=MathMin(min, MathAbs(DATA[j][i]));
max=MathMax(max, MathAbs(DATA[j][i]));
}
for(j=0; j<columns; j++)
{
clr = ColorGradient(DATA[j][i], min, max, 1); //�������
ObjectSet(el_name+j+"_"+i, OBJPROP_COLOR, clr);
}
}
}
//+------------------------------------------------------------------+
void AdxWeerAcceleration(double& PDI[][], double& MDI[][], int columns)
{
int i,j;
color clr;
double max_vel;
double VEL[][ELEMENTS];
ArrayResize(VEL, columns);
//�������� ������� ������� ��������� +DI � -DI
for(j=columns-1; j>=0; j--)
for(i=0; i<ELEMENTS; i++)
VEL[j][i]=PDI[j][i]-MDI[j][i];
//�� ������ Columns ����� ������� ���������� ������� ��������
for(i=0; i<ELEMENTS; i++)
{
max_vel=-10000;
for(j=0; j<columns; j++)
max_vel=MathMax(max_vel, MathAbs(VEL[j][i]));
//�������� ���� - ������� ��������; �������� ����� - �������
for(j=0; j<columns; j++)
{
if(VEL[j][i]>=0)
{
clr = ColorGradient(VEL[j][i], 0, max_vel, 1); //�������
ObjectSet(el_name+j+"_"+i, OBJPROP_COLOR, clr);
}
else
{
clr = ColorGradient(-VEL[j][i], 0, max_vel, 0); //�������
ObjectSet(el_name+j+"_"+i, OBJPROP_COLOR, clr);
}
}
}
}
//+------------------------------------------------------------------+
color ColorGradient(double current_vol, double min_vol, double max_vol, int maincolor)
{
int R,G,B;
int cur;
if(current_vol<min_vol) current_vol=min_vol;
if(current_vol>max_vol) current_vol=max_vol;
cur = 255-255*(current_vol-min_vol)/(max_vol-min_vol);
if(maincolor==0) //RED
{ R=255; G=cur; B=cur; }
else if(maincolor==1) //GREEN
{ R=cur; G=255; B=cur; }
else if(maincolor==2) //BLUE
{ R=cur; G=cur; B=255; }
else {R=0;G=0;B=0;}
G<<=8;
B<<=16;
return(R+G+B);
}
//+------------------------------------------------------------------+
void CreateShield(string name_mask, double top, double bottom, int width, int freebars, color clr)
{
double high, gap, y1, y2;
datetime fut0, fut1;
high = (top-bottom)/(ELEMENTS*1.0);
gap= high*GAP_PERCENT/100.0;
bottom=bottom+gap;
top=top-HEADER*high;
high = (top-bottom)/(ELEMENTS*1.0);
gap= high*GAP_PERCENT/100.0;
high=high-gap;
if(freebars>0)
{
fut0=Time[0]+Period()*freebars*60;
fut1=Time[width]+Period()*freebars*60;
}
else
{
fut0=iTime(NULL,0,-freebars);
fut1=iTime(NULL,0,-freebars+width);
}
y2=top;
for(int i=0; i<ELEMENTS; i++)
{
y1=y2-gap;
y2=y1-high;
ObjectCreate(name_mask+i, OBJ_RECTANGLE, 0, fut0, y1, fut1, y2);
ObjectSet(name_mask+i, OBJPROP_COLOR, clr);
}
return;
}
//+------------------------------------------------------------------+
int MoveShield(string name_mask, double top, double bottom, int width, int freebars)
{
double high, gap, y1, y2;
datetime fut0, fut1;
high = (top-bottom)/(ELEMENTS*1.0);
gap= high*GAP_PERCENT/100.0;
bottom=bottom+gap;
top=top-HEADER*high;
high = (top-bottom)/(ELEMENTS*1.0);
gap= high*GAP_PERCENT/100.0;
high=high-gap;
if(freebars>0)
{
fut0=Time[0]+Period()*freebars*60;
fut1=Time[width]+Period()*freebars*60;
}
else
{
fut0=iTime(NULL,0,-freebars);
fut1=iTime(NULL,0,-freebars+width);
}
y2=top;
for(int i=0; i<ELEMENTS; i++)
{
y1=y2-gap;
y2=y1-high;
if(ObjectMove(name_mask+i, 0, fut0, y1)==false) return(-1);
ObjectMove(name_mask+i, 1, fut1, y2);
}
return(0);
}
//+------------------------------------------------------------------+
void CreateHeader(string text, double top, int width, int columns, int freebars, color clr)
{
datetime time_center;
int allbars;
if(freebars<0) {Print("ERROR CreateHeader: freebars<0"); return;}
allbars = columns*(width+GAP); //������� ����� ����� ��� ���������
if(allbars/2<freebars) //����� ��������� ��������� � ���� �� �������� ������
time_center=Time[0] + 60*Period()*(freebars - columns*(width+GAP)/2);
else //��������� �������� ����������� ������������ ����
time_center = iTime(NULL, 0, allbars/2-freebars);
ObjectCreate(el_name+"_HEAD", OBJ_TEXT, 0, time_center, top);
ObjectSetText(el_name+"_HEAD", text, 12, "Areal", clr);
return;
}
//+------------------------------------------------------------------+
void MoveHeader(double top, int width, int columns, int freebars, color clr)
{
datetime time_center;
int allbars;
if(freebars<0) {Print("ERROR CreateHeader: freebars<0"); return;}
allbars = columns*(width+GAP); //������� ����� ����� ��� ���������
if(allbars/2<freebars) //����� ��������� ��������� � ���� �� �������� ������
time_center=Time[0] + 60*Period()*(freebars - columns*(width+GAP)/2);
else //��������� �������� ����������� ������������ ����
time_center = iTime(NULL, 0, allbars/2-freebars);
ObjectMove(el_name+"_HEAD", 0, time_center, top);
}
//+------------------------------------------------------------------+
void DeleteIndicatorObject(string mask)
{
int obj_total, i, out;
string name;
out=1;
while(out>0)
{
obj_total=ObjectsTotal();
out=0;
for(i=0;i<obj_total;i++)
{
name = ObjectName(i);
if(StringFind(name,mask)>=0) { ObjectDelete(name); out++; }
}
}
}
//+------------------------------------------------------------------+
void err(string name)
{
int err=GetLastError();
if(err!=0) Print(name," ERROR(",err,"): ",ErrorDescription(err));
}