Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2690

 

Есть вот такой индикатор, нужно расставить имена по значениям в порядке уменьшения, сейчас порядок фиксирован 

Не могу придумать алгоритм, как это сделать.

Помогите воплотить, индикатор с кодобазы

 

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_plots   8
#property indicator_level1  1
#property strict

extern int  per=7; // Период средней
extern int  calc=200; // Глубина расчетов
extern int  cross=100; //Выбор бара, на котором индексы нормализованы

input color AUD = clrRed;
input color CAD = clrOrange;
input color CHF = clrYellow;
input color EUR = clrLimeGreen;
input color GBP = clrDodgerBlue;
input color JPY = clrMagenta;
input color NZD = clrFireBrick;
input color USD = clrLightBlue;
input int   lWidth = 2;
double aud[];
double cad[];
double chf[];
double eur[];
double gbp[];
double jpy[];
double nzd[];
double usd[];
static string sy[28]= {
  "AUDCAD","AUDCHF","EURAUD","GBPAUD","AUDJPY","AUDNZD","AUDUSD",
  "CADCHF","EURCAD","GBPCAD","CADJPY","NZDCAD","USDCAD","EURCHF",
  "GBPCHF","CHFJPY","NZDCHF","USDCHF","EURGBP","EURJPY","EURNZD",
  "EURUSD","GBPJPY","GBPNZD","GBPUSD","NZDJPY","USDJPY","NZDUSD"
};
double Ma[][28];
double Cross[][8];
bool warning=false;
string ShortName;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
{
  IndicatorSetInteger(INDICATOR_DIGITS,5);
  SetIndexBuffer(0,aud);
  SetIndexLabel(0,"AUD");
  SetIndexStyle(0,AUD==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,AUD);
  SetIndexBuffer(1,cad);
  SetIndexLabel(1,"CAD");
  SetIndexStyle(1,CAD==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,CAD);
  SetIndexBuffer(2,chf);
  SetIndexLabel(2,"CHF");
  SetIndexStyle(2,CHF==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,CHF);
  SetIndexBuffer(3,eur);
  SetIndexLabel(3,"EUR");
  SetIndexStyle(3,EUR==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,EUR);
  SetIndexBuffer(4,gbp);
  SetIndexLabel(4,"GBP");
  SetIndexStyle(4,GBP==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,GBP);
  SetIndexBuffer(5,jpy);
  SetIndexLabel(5,"JPY");
  SetIndexStyle(5,JPY==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,JPY);
  SetIndexBuffer(6,nzd);
  SetIndexLabel(6,"NZD");
  SetIndexStyle(6,NZD==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,NZD);
  SetIndexBuffer(7,usd);
  SetIndexLabel(7,"USD");
  SetIndexStyle(7,USD==clrNONE?DRAW_NONE:DRAW_LINE,0,lWidth,USD);
//
  ArrayResize(Ma, MathMax(calc+1,cross+1));
  ArrayResize(Cross, MathMax(calc+1,cross+1));
//-
  ShortName="Index ("+(string)per+","+(string)calc+","+(string)cross+")";
  IndicatorSetString(INDICATOR_SHORTNAME,ShortName);
//
  long h=0;
  ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,ChartWindowFind(),h);
  int t=int(h/8);
  int n=0;
  CreateLabel("aud",5,t*n,AUD,"AUD");
  n++;
  CreateLabel("cad",5,t*n,CAD,"CAD");
  n++;
  CreateLabel("chf",5,t*n,CHF,"CHF");
  n++;
  CreateLabel("eur",5,t*n,EUR,"EUR");
  n++;
  CreateLabel("gbp",5,t*n,GBP,"GBP");
  n++;
  CreateLabel("jpy",5,t*n,JPY,"JPY");
  n++;
  CreateLabel("nzd",5,t*n,NZD,"NZD");
  n++;
  CreateLabel("usd",5,t*n,USD,"USD");
  return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  ObjectsDeleteAll(0,ShortName);
  ChartRedraw();
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
  for(int i=0; i<MathMax(calc+1,cross+1); i++)
    for(int j=0; j<28; j++) {
      Ma[i][j]=iMA(sy[j],0,per,0,MODE_EMA,PRICE_CLOSE,i);
      if(Ma[i][j]==0) {
        Print("Zero value for MA(",sy[j],"). Check in Market Watch");
        if(!warning) {
          Alert("Zero value for MA(",sy[j],"). Check in Market Watch");
          warning=true;
        }
        return(0);
      }
    }
  for(int i=0; i<MathMax(calc+1,cross+1); i++) {
    Cross[i][0]=Ma[i][0]*Ma[i][1]*(Ma[i][4]/100)*Ma[i][5]*Ma[i][6]/(Ma[i][2]*Ma[i][3]);
    Cross[i][1]=Ma[i][7]*(Ma[i][10]/100)/(Ma[i][0]*Ma[i][8]*Ma[i][9]*Ma[i][11]*Ma[i][12]);
    Cross[i][2]=(Ma[i][15]/100)/(Ma[i][1]*Ma[i][7]*Ma[i][13]*Ma[i][14]*Ma[i][16]*Ma[i][17]);
    Cross[i][3]=Ma[i][2]*Ma[i][8]*Ma[i][13]*Ma[i][18]*(Ma[i][19]/100)*Ma[i][20]*Ma[i][21];
    Cross[i][4]=Ma[i][3]*Ma[i][9]*Ma[i][14]*(Ma[i][22]/100)*Ma[i][23]*Ma[i][24]/Ma[i][18];
    Cross[i][5]=(100/Ma[i][4])*(100/Ma[i][10])*(100/Ma[i][15])*(100/Ma[i][19])*(100/Ma[i][22])*(100/Ma[i][25])*(100/Ma[i][26]);
    Cross[i][6]=Ma[i][11]*Ma[i][16]*(Ma[i][25]/100)*Ma[i][27]/(Ma[i][5]*Ma[i][20]*Ma[i][23]);
    Cross[i][7]=Ma[i][12]*Ma[i][17]*(Ma[i][26]/100)/(Ma[i][6]*Ma[i][21]*Ma[i][24]*Ma[i][27]);
  }
  for(int i=0; i<calc; i++) {
    aud[i]=Cross[i][0]/Cross[cross][0];
    cad[i]=Cross[i][1]/Cross[cross][1];
    chf[i]=Cross[i][2]/Cross[cross][2];
    eur[i]=Cross[i][3]/Cross[cross][3];
    gbp[i]=Cross[i][4]/Cross[cross][4];
    jpy[i]=Cross[i][5]/Cross[cross][5];
    nzd[i]=Cross[i][6]/Cross[cross][6];
    usd[i]=Cross[i][7]/Cross[cross][7];
  }
  return(rates_total);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CreateLabel(string nm,int xd,int yd,color clr,string text)
{
  nm=ShortName+nm;
  if(ObjectFind(0,nm)<0) {
    ObjectCreate(0,nm,OBJ_LABEL,ChartWindowFind(),0,0);
    ObjectSetInteger(0,nm,OBJPROP_CORNER,CORNER_RIGHT_UPPER);
    ObjectSetInteger(0,nm,OBJPROP_ANCHOR,ANCHOR_RIGHT_UPPER);
    ObjectSetString(0,nm,OBJPROP_FONT,"Arial");
    ObjectSetInteger(0,nm,OBJPROP_BACK,false);
    ObjectSetInteger(0,nm,OBJPROP_SELECTABLE,false);
    ObjectSetInteger(0,nm,OBJPROP_SELECTED,false);
    ObjectSetInteger(0,nm,OBJPROP_FONTSIZE,11);
    ObjectSetString(0,nm,OBJPROP_TOOLTIP,"\n");
    ObjectSetInteger(0,nm,OBJPROP_HIDDEN,false);
    ObjectSetInteger(0,nm,OBJPROP_XDISTANCE,xd);
    ObjectSetInteger(0,nm,OBJPROP_YDISTANCE,yd);
    ObjectSetInteger(0,nm,OBJPROP_COLOR,clr);
    ObjectSetString(0,nm,OBJPROP_TEXT,text);
  }
}
//+------------------------------------------------------------------+
 
Vitaly Muzichenko #:
Есть вот такой индикатор, нужно расставить имена по значениям в порядке уменьшения, сейчас порядок фиксирован 

В двумерном int массиве заполняем кросс цены валют и индекс string массива с их названиями, сортируем по цене, и по индексу находим название 

int total=8;
int prices[total,2];
string symbols[total];    

prices[0,0]=int(cross_AUD*100000); //умножить на число, которого будет достаточно для различия валют в целых числах
prices[0,1]=0;
symbols[0]="AUD";
prices[1,0]=int(cross_CAD*100000);
prices[1,1]=1;
symbols[1]="CAD";

.....

ArraySort(prices,WHOLE_ARRAY,0,MODE_DESCEND);
for(int n=0; n<total; n++) {
int i=prices[n,1];
CreateLabel(symbols[i],5,t*n,symbols[i],symbols[i]);//Виталий, здесь не разбирался, почему три раза символы в разных вариантах повторяются, но думаю, идею поняли 
}
 
Aleksei Stepanenko #:

В двумерном int массиве заполняем кросс цены валют и индекс string массива с их названиями, сортируем по цене, и по индексу находим название 

Спасибо, всё получилось


 
grezky #:

Если стрелка добавлена на график вручную, можно ли программным путем получить координаты (по шкале цены) этих top и bottom?

Да, конечно. При создании объекта задать уникальное Имя.

По имени, используя  ObjectFind(), найти объект.

Координаты/свойства прочитать функциями:

ObjectGetDouble(),

ObjectGetInteger()

ObjectGetString()

В справке есть примеры.

 
Putnik #:

Да, конечно. При создании объекта задать уникальное Имя.

По имени, используя  ObjectFind(), найти объект.

Координаты/свойства прочитать функциями:

ObjectGetDouble(),

ObjectGetInteger()

ObjectGetString()

В справке есть примеры.


Насколько я понял,
- выбирая за точку привязки top метатрейдер располагает стрелку ниже значения ее цены, а 
- выбирая за точку привязки bottom метатрейдер располагает стрелку выше значения ее цены. 

Т.о. иконка стрелки на графике пляшет вокруг значения цены, но само значение будет возвращаться то же самое.
Т.е. проблему не решает.

Я отказался от идеи использовать стрелки, жаль что то что работало в МТ4 загублено в МТ5. Но есть другие решения.
В любом случае спасибо!
 
grezky #:

Насколько я понял,
- выбирая за точку привязки top метатрейдер располагает стрелку ниже значения ее цены, а 
- выбирая за точку привязки bottom метатрейдер располагает стрелку выше значения ее цены. 

Т.о. иконка стрелки на графике пляшет вокруг значения цены, но само значение будет возвращаться то же самое.
Т.е. проблему не решает.

Я отказался от идеи использовать стрелки, жаль что то что работало в МТ4 загублено в МТ5. Но есть другие решения.
В любом случае спасибо!
Что мешает Вам вместо стрелки использовать коротюсенький отрезок линии тренда, у которой выключено свойство "Луч"? Там и цену можно ОЧЕНЬ точно поставить. И даж чётко горизонтально/вертикально (если надо) расположить. И имя уникальное присвоить...
 

Привет. Подскажите, пожалста: можно ли в IDE без использования мыши выделить строку в окне инструменты?


 

Это мт5 в тестере.

Подскажите по перекрашиванию стрелок, пж.

В одном тике открываются две сделки, покупка и продажа. Есть задача изменить цвет стрелок. Пытался сделать так: после торговой операции по тикету, в списке объектов нахожу стрелку и задаю ей цвет. Но проблема в том что в списке объектов на этом тике появляется только одна из двух стрелок, вторая появляется только на следующем тике, ChartRedraw не помогает. Пока сделал такой костыль: после сделки записываю тикет и когда нужный объект появляется - перекрашиваю его 

   if(ticket_to_color_sell != 0)
   {
                for(int i = 0; i < ObjectsTotal(0) - 1; i ++)
                {
                        if(StringFind(ObjectName(0, i), "#" + (string)ticket_to_color_sell + " sell") > -1 )
                        {
                                ObjectSetInteger(0, ObjectName(0, i), OBJPROP_COLOR, (long)Color_sell_helper);
                                ticket_to_color_sell = 0;
                        }
                }
   }

Но получается что перекрашивание происходит только на следующим тике. 

Есть ли решение чтоб перекрашивать сразу и вообще может быть более феншуйное решение?

 
Andrei Sokolov #:

Это мт5 в тестере.

Подскажите по перекрашиванию стрелок, пж.

В одном тике открываются две сделки, покупка и продажа. Есть задача изменить цвет стрелок. Пытался сделать так: после торговой операции по тикету, в списке объектов нахожу стрелку и задаю ей цвет. Но проблема в том что в списке объектов на этом тике появляется только одна из двух стрелок, вторая появляется только на следующем тике, ChartRedraw не помогает. Пока сделал такой костыль: после сделки записываю тикет и когда нужный объект появляется - перекрашиваю его 


Но получается что перекрашивание происходит только на следующим тике. 

Есть ли решение чтоб перекрашивать сразу и вообще может быть более феншуйное решение?

Я бы делал здесь без перебора всех объектов

void  OnTradeTransaction( 
   const MqlTradeTransaction&    trans,        // структура торговой транзакции 
   const MqlTradeRequest&        request,      // структура запроса 
   const MqlTradeResult&         result        // структура ответа 
   );


 
Vitaly Muzichenko #:
Я бы делал здесь без перебора всех объектов
Благодарю за ответ, но не понял, прошу подробнее.