Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 320

 

Buenas noches.

Construido un indicador - tabla de resumen de la volatilidad para los instrumentos seleccionados. Los datos deben ser calculados igualmente, independientemente del gráfico en el que se haya instalado el indicador. Sin embargo, lo calcula de forma diferente. Dependiendo de si el gráfico tiene JPY en el denominador.

Si lo hay, la tabla tiene este aspecto:


si no, se ve así:


Aquí está el código:

#property copyright "Vasya Pupkin"
#property link      ""
#property indicator_separate_window

//------- Внешние параметры индикатора ----------------------------------------+

extern int   BARS = 100;                // Кол-во баров для рассчета
extern int   eiOffsetY = 15;           // Смещение текста по вертикали
extern int   eiStepY   = 12;           // Шаг смещения текста по вертикали
extern int   eiX1Row   = 3;            // Координата X первой колонки
extern int   eiX2Row   = 50;          // Координата X второй колонки
extern int   eiX3Row   = 100;          // Координата X третей колонки
extern int   eiX4Row   = 150;          // Координата X четвёртой колонки
extern int   eiX5Row   = 200;          // Координата X пятой колонки
extern int   eiX6Row   = 250;          // Координата X шестой колонки
extern int   eiX7Row   = 300;          // Координата X седьмой колонки
extern int   eiX8Row   = 350;          // Координата X восьмой колонки
extern int   eiX9Row   = 400;          // Координата X восьмой колонки
extern color ecText    = Gray;         // Цвет текста
extern string Symbols  = "audcad,audchf,audjpy,audnzd,audusd,cadchf,cadjpy,chfjpy,euraud,eurcad";

//------- Глобальные переменные индикатора ------------------------------------+
int nWindow_ToDay;       // Номер окна

//------- Буферы индикатора ---------------------------------------------------+

//------- Поключение внешних модулей ------------------------------------------+

//+----------------------------------------------------------------------------+
//|  Custom indicator initialization function                                  |
//+----------------------------------------------------------------------------+
void init() {
  nWindow_ToDay=WindowFind("VolatilityTab");
  if (nWindow_ToDay<0) nWindow_ToDay=WindowsTotal();
  DeleteObjects();
  Comment("");
}

//+----------------------------------------------------------------------------+
//|  Custom indicator deinitialization function                                |
//+----------------------------------------------------------------------------+
void deinit() {
  DeleteObjects();
  Comment("");
}

//+----------------------------------------------------------------------------+
//|  Custom indicator iteration function                                       |
//+----------------------------------------------------------------------------+
void start() {
  DeleteObjects();
  

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 
   SetLabel("Volatility_00", "TF", Red, eiX1Row, eiOffsetY+eiStepY);
   SetLabel("Volatility_10", "M5", ecText, eiX1Row, eiOffsetY+2*eiStepY);
   SetLabel("Volatility_20", "M15", ecText, eiX1Row, eiOffsetY+3*eiStepY);
   SetLabel("Volatility_30", "M30", ecText, eiX1Row, eiOffsetY+4*eiStepY);
   SetLabel("Volatility_40", "H1", ecText, eiX1Row, eiOffsetY+5*eiStepY);
   SetLabel("Volatility_50", "H4", ecText, eiX1Row, eiOffsetY+6*eiStepY);  
   SetLabel("Volatility_60", "D1", ecText, eiX1Row, eiOffsetY+7*eiStepY);
   SetLabel("Volatility_70", "Week", ecText, eiX1Row, eiOffsetY+8*eiStepY);
   SetLabel("Volatility_80", "Month", ecText, eiX1Row, eiOffsetY+9*eiStepY);

  string syb[];
  int   k, r, countX,countY=1;

  StrSplit(Symbols, syb, ",");
  if (ArraySize(syb)==0) StrSplit(Symbols, syb, ";");
  r=ArraySize(syb);
  for (k=0; k<r; k++) {
    syb[k]=StringUpper(syb[k]);     
    countX++;
    SetLabel("Volatility_"+"0"+countX, syb[k], Red, countX*eiX2Row, eiOffsetY+eiStepY);
  
      int i,s1=0,s2=0,s3=0,s4=0,s5=0,s6=0,s7=0,s8=0,b;
  
      for (i=BARS; i>0; i--)
        {
          s1+=(iHigh(syb[k],5,i)-iLow(syb[k],5,i))/Point;
          //Comment(MarketInfo(syb[k],MODE_DIGITS));
          s2+=(iHigh(syb[k],15,i)-iLow(syb[k],15,i))/Point;
          s3+=(iHigh(syb[k],30,i)-iLow(syb[k],30,i))/Point;
          s4+=(iHigh(syb[k],60,i)-iLow(syb[k],60,i))/Point;
          s5+=(iHigh(syb[k],240,i)-iLow(syb[k],240,i))/Point;
          s6+=(iHigh(syb[k],1440,i)-iLow(syb[k],1440,i))/Point;
          s7+=(iHigh(syb[k],10080,i)-iLow(syb[k],10080,i))/Point;
          s8+=(iHigh(syb[k],43200,i)-iLow(syb[k],43200,i))/Point;
          b++;
        }
      SetLabel("Volatility_"+countY+countX,s1/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+2*eiStepY);
      countY++;
      SetLabel("Volatility_"+countY+countX,s2/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+3*eiStepY);
      countY++;
      SetLabel("Volatility_"+countY+countX,s3/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+4*eiStepY);
      countY++;
      SetLabel("Volatility_"+countY+countX,s4/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+5*eiStepY);
      countY++;
      SetLabel("Volatility_"+countY+countX,s5/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+6*eiStepY);
      countY++;
      SetLabel("Volatility_"+countY+countX,s6/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+7*eiStepY);
      countY++;
      SetLabel("Volatility_"+countY+countX,s7/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+8*eiStepY);
      countY++;
      SetLabel("Volatility_"+countY+countX,s8/b+ " п.", ecText, countX*eiX2Row, eiOffsetY+9*eiStepY);
      s1=0;
      s2=0;
      s3=0;
      s4=0;
      s5=0;
      s6=0;
      s7=0;
      s8=0;
      b=0;
      countY=1;
}
  
}

//+----------------------------------------------------------------------------+
//|  Удаление объектов.                                                        |
//+----------------------------------------------------------------------------+
void DeleteObjects() {
  string st="Volatility_";
  int    i, j;

  for (i=0; i<9; i++) {
    for (j=0; j<15; j++) ObjectDelete(st+i+j);
  }
}



//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 12.10.2007                                                     |
//|  Описание : Установка текстовой метки                                      |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    nm - наименование объекта                                               |
//|    tx - текст                                                              |
//|    cl - цвет метки                                                         |
//|    xd - координата X в пикселах                                            |
//|    yd - координата Y в пикселах                                            |
//|    cr - номер угла привязки        (0 - левый верхний)                     |
//|    fs - размер шрифта              (8 - по умолчанию)                      |
//+----------------------------------------------------------------------------+
void SetLabel(string nm, string tx, color cl, int xd, int yd, int cr=0, int fs=8) {
  if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_LABEL, nWindow_ToDay, 0,0);
  ObjectSetText(nm, tx, fs);
  ObjectSet(nm, OBJPROP_COLOR    , cl);
  ObjectSet(nm, OBJPROP_XDISTANCE, xd);
  ObjectSet(nm, OBJPROP_YDISTANCE, yd);
  ObjectSet(nm, OBJPROP_CORNER   , cr);
  ObjectSet(nm, OBJPROP_FONTSIZE , fs);
}
//+----------------------------------------------------------------------------+

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 01.09.2005                                                     |
//|  Описание : Разбиение строки на массив элементов                           |
//+----------------------------------------------------------------------------+
//|  Возврат:                                                                  |
//|    Количество элементов в массиве                                          |
//|  Параметры:                                                                |
//|    source    - текстовая строка                                            |
//|    dest      - выходной массив                                             |
//|    delimeter - разделитель                                                 |
//+----------------------------------------------------------------------------+
int StrSplit(string source, string& dest[], string delimeter=";") { 
  int cnt=0;
  int last_pos=0;
  int pos=StringFind(source, delimeter, last_pos);

  while (pos!=-1) {
    ArrayResize(dest, cnt+1);
    dest[cnt]=StringSubstr(source, last_pos, pos-last_pos);
    cnt++;
    last_pos=pos+1;
    pos=StringFind(source, delimeter, last_pos);
  }
  if (last_pos!=0 && last_pos<StringLen(source)) {
    ArrayResize(dest, cnt+1);
    dest[cnt]=StringSubstr(source, last_pos, StringLen(source)-last_pos);
    cnt++;
  }
  return (cnt);
}
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 01.09.2005                                                     |
//|  Описание : Возвращает строку в ВЕРХНЕМ регистре                           |
//+----------------------------------------------------------------------------+
string StringUpper(string s) {
  int c, i, k=StringLen(s), n;
  for (i=0; i<k; i++) {
    n=0;
    c=StringGetChar(s, i);
    if (c>96 && c<123) n=c-32;    // a-z -> A-Z
    if (c>223 && c<256) n=c-32;   // а-я -> А-Я
    if (c==184) n=168;            //  ё  ->  Ё
    if (n>0) s=StringSetChar(s, i, n);
  }
  return(s);
}
Автоматизация торговли на финансовых рынках - Главная
Автоматизация торговли на финансовых рынках - Главная
  • www.kimiv.ru
Что нового по сравнению с версией 1.4? stSender. Изменена процедура записи файлов под требования билда 610 и выше. stReceiver. Функции проверки существования файла и копирования файлов заменены на аналогичные, поддерживающие UNICODE (для работоспособности в билде 610 и выше). Разработан и доступен для покупки новый советник e-Reverser...
 
Sergey:

Buenas noches.

Construido un indicador - tabla de resumen de la volatilidad para los instrumentos seleccionados. Los datos deben ser calculados igualmente, independientemente del gráfico en el que se haya instalado el indicador. Sin embargo, lo calcula de forma diferente. Dependiendo de si el gráfico tiene JPY en el denominador.

Ya me he encontrado con esto: el JPY tiene menos dígitos fraccionarios. Por lo tanto, el Punto será diferente. ¿O algo más?

s1+=(iHigh(syb[k],5,i)-iLow(syb[k],5,i))/Point;
//Comment(MarketInfo(syb[k],MODE_DIGITS));
s2+=(iHigh(syb[k],15,i)-iLow(syb[k],15,i))/Point;
s3+=(iHigh(syb[k],30,i)-iLow(syb[k],30,i))/Point;
s4+=(iHigh(syb[k],60,i)-iLow(syb[k],60,i))/Point;
s5+=(iHigh(syb[k],240,i)-iLow(syb[k],240,i))/Point;
s6+=(iHigh(syb[k],1440,i)-iLow(syb[k],1440,i))/Point;
s7+=(iHigh(syb[k],10080,i)-iLow(syb[k],10080,i))/Point;
s8+=(iHigh(syb[k],43200,i)-iLow(syb[k],43200,i))/Point;
Por cierto, se recomienda utilizar Point() o _Point
 
STARIJ:

Ya me he encontrado con esto: el JPY tiene menos dígitos fraccionarios. Por lo tanto, el punto será diferente


intentó añadir una condición

 if (MarketInfo(syb[k],MODE_DIGITS)==3) {z=100;}
    else z=1;

y aquí dividido por Z^

  
      for (i=BARS; i>0; i--)
        {
          s1+=(iHigh(syb[k],5,i)-iLow(syb[k],5,i))/(z*Point);
          //Comment(MarketInfo(syb[k],MODE_DIGITS));
          s2+=(iHigh(syb[k],15,i)-iLow(syb[k],15,i))/(z*Point);
          s3+=(iHigh(syb[k],30,i)-iLow(syb[k],30,i))/(z*Point);
          s4+=(iHigh(syb[k],60,i)-iLow(syb[k],60,i))/(z*Point);
          s5+=(iHigh(syb[k],240,i)-iLow(syb[k],240,i))/(z*Point);
          s6+=(iHigh(syb[k],1440,i)-iLow(syb[k],1440,i))/(z*Point);
          s7+=(iHigh(syb[k],10080,i)-iLow(syb[k],10080,i))/(z*Point);
          s8+=(iHigh(syb[k],43200,i)-iLow(syb[k],43200,i))/(z*Point);
          b++;
        }

pero al final, en el par sin el yen, todo está claro:

pero con el yen es un lío:


 
Sergey:

intentó añadir una condición

y aquí dividido por Z^

pero al final, en el par sin el yen, todo está claro:

Pero con el yen es un lío:


SustituirPunto por "SymbolInfoDouble(syb[k],SYMBOL_POINT)"

 
Vitaly Muzichenko:

SustituirPunto por "SymbolInfoDouble(syb[k],SYMBOL_POINT)"


Gracias, ahora está claro en todas partes, y no hay meteduras de pata

 
Sergey:

Gracias, ahora está claro en todas partes, y no hay meteduras de pata.

Optimiza un poco el código, llama al cálculo sólo una vez en un carácter:

      for (i=BARS; i>0; i--)
        {
          point=SymbolInfoDouble(syb[k],SYMBOL_POINT);
          s1+=(iHigh(syb[k],5,i)-iLow(syb[k],5,i))/point;
          s2+=(iHigh(syb[k],15,i)-iLow(syb[k],15,i))/point;
          s3+=(iHigh(syb[k],30,i)-iLow(syb[k],30,i))/point;
          s4+=(iHigh(syb[k],60,i)-iLow(syb[k],60,i))/point;
          s5+=(iHigh(syb[k],240,i)-iLow(syb[k],240,i))/point;
          s6+=(iHigh(syb[k],1440,i)-iLow(syb[k],1440,i))/point;
          s7+=(iHigh(syb[k],10080,i)-iLow(syb[k],10080,i))/point;
          s8+=(iHigh(syb[k],43200,i)-iLow(syb[k],43200,i))/point;
          b++;
        }
 
Vitaly Muzichenko:

Optimiza un poco el código, llama al cálculo sólo una vez en un carácter:

#define  AMOUNT_PERIODS (sizeof(Periods) / sizeof(ENUM_TIMEFRAMES)) // Лучше, чем ArraySize(Periods)

static const ENUM_TIMEFRAMES Periods[] = {PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1};

double s[AMOUNT_PERIODS];
ArrayInitialize(s, 0);

for (int i=BARS; i>0; i--)
  {
    const string Symb = syb[k];
    const double point=SymbolInfoDouble(syb[k],SYMBOL_POINT);

    for (int j = 0; j < AMOUNT_PERIODS; j++)
      s[j]+=(iHigh(Symb,Periods[j],i)-iLow(Symb,Periods[j],i))/point;
  }

Y con ese espíritu, reducir todo el código a una operación de matriz concisa. Las repeticiones de la misma lógica deben diseñarse como bucles.

 
Hola, ¿podría decirme cómo hacer esto? ¿Cómo puedo prescribir, que el trailing stop no estaba cerca del indicador, pero 10 puntos más bajo o más alto, respectivamente?
 if (OrderMagicNumber()==Magic&&OrderSymbol()==Symbol()&&OrderType()==OP_BUY&&
   NormalizeDouble(SAR,Digits)>NormalizeDouble(OrderStopLoss(),Digits)&&NormalizeDouble(SAR,Digits)<NormalizeDouble(Bid,Digits))
      OrderModify(OrderTicket(),0,SAR,0,0,Blue);
 

¡Buenos días!

¿Cómo resolver este problema? Escribí un EA en el que se coloca una orden pendiente con un lote aumentado (por ejemplo, por 2 veces) en una operación fallida,

Pero cuando se ejecuta la orden pendiente (raramente, en 1 de cada 10 casos), el lote no se multiplica por el coeficiente, aunque se haya colocado inicialmente según el algoritmo.

He aquí un ejemplo:

se cerró una operación con 0,4 lotes, inmediatamente se coloca una orden pendiente con 0,8 lotes y cuando se ejecuta, el volumen resulta ser de 0,4 lotes.


¿Qué puede ser?


Gracias.

 
yaaarik777:

¡Buenos días!

¿Cómo resolver este problema? Escribí un EA en el que se coloca una orden pendiente con un lote aumentado (por ejemplo, por 2 veces) en una operación fallida,

Pero cuando se ejecuta la orden pendiente (raramente, en 1 de cada 10 casos), el lote no se multiplica por el coeficiente, aunque se haya colocado inicialmente según el algoritmo.

He aquí un ejemplo:

se cerró una operación con 0,4 lotes, inmediatamente se coloca una orden pendiente con 0,8 lotes y cuando se ejecuta, el volumen resulta ser de 0,4 lotes.


¿Qué puede ser?


Gracias.

¿Podría ser una ocurrencia parcial? ¿Qué hay en los registros?

Razón de la queja: