Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 320

 

Bonsoir.

Construit un indicateur - tableau récapitulatif de la volatilité pour les instruments sélectionnés. Les données doivent être calculées de manière égale, quel que soit le graphique sur lequel l'indicateur a été installé. Cependant, il le calcule différemment. Selon que le graphique comporte ou non du JPY au dénominateur.

Si c'est le cas, le tableau ressemble à ceci :


si non, ça ressemble à ça :


Voici le code :

#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:

Bonsoir.

Construit un indicateur - tableau récapitulatif de la volatilité pour les instruments sélectionnés. Les données doivent être calculées de manière égale, quel que soit le graphique sur lequel l'indicateur a été installé. Cependant, il le calcule différemment. Selon que le graphique comporte ou non du JPY au dénominateur.

J'ai déjà rencontré ce problème - le JPY a moins de chiffres fractionnaires. Le point sera donc différent. Ou quelque chose d'autre ?

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;
D'ailleurs, il est recommandé d 'utiliser Point() ou _Point
 
STARIJ:

J'ai déjà rencontré ce problème - le yen a moins de chiffres fractionnaires. Le point sera donc différent


J'ai essayé d'ajouter une condition

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

et ici divisé par 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++;
        }

mais au final, sur la paire sans le yen, tout est clair :

mais avec les yens, c'est le bordel :


 
Sergey:

J'ai essayé d'ajouter une condition

et ici divisé par Z^

mais au final, sur la paire sans le yen, tout est clair :

Mais avec les yens, c'est le bordel :


RemplacerPoint par "SymbolInfoDouble(syb[k],SYMBOL_POINT)".

 
Vitaly Muzichenko:

RemplacerPoint par "SymbolInfoDouble(syb[k],SYMBOL_POINT)".


Merci, maintenant c'est clair partout, et il n'y a pas d'erreur.

 
Sergey:

Merci, maintenant c'est clair partout, et pas d'erreur.

Optimisez un peu le code, appelez le calcul une seule fois sur un caractère :

      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:

Optimisez un peu le code, appelez le calcul une seule fois sur un caractère :

#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;
  }

Et dans cet esprit, réduisez tout le code à une opération de tableau concise. Toute répétition de la même logique doit être conçue comme une boucle.

 
Bonjour, pourriez-vous me dire comment faire ? Comment puis-je prescrire, que le trailing stop n'était pas proche de l'indicateur, mais 10 points plus bas ou plus haut respectivement ?
 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);
 

Bonne journée !

Comment résoudre ce problème ? J'ai écrit un EA où un ordre en attente avec un lot augmenté (par exemple de 2 fois) est placé sur une transaction infructueuse,

Mais lorsque l'ordre en attente est exécuté (rarement, dans 1 cas sur 10), le lot n'est pas multiplié par le coefficient, alors qu'il a été initialement placé selon l'algorithme.

Voici un exemple :

une transaction a été conclue avec 0,4 lot, un ordre en attente est immédiatement placé avec 0,8 lot et lorsqu'il est exécuté, le volume s'avère être de 0,4 lot.


Qu'est-ce que ça peut être ?


Merci.

 
yaaarik777:

Bonne journée !

Comment résoudre ce problème ? J'ai écrit un EA où un ordre en attente avec un lot augmenté (par exemple de 2 fois) est placé sur une transaction infructueuse,

Mais lorsque l'ordre en attente est exécuté (rarement, dans 1 cas sur 10), le lot n'est pas multiplié par le coefficient, alors qu'il a été initialement placé selon l'algorithme.

Voici un exemple :

une transaction a été conclue avec 0,4 lot, un ordre en attente est immédiatement placé avec 0,8 lot et lorsqu'il est exécuté, le volume s'avère être de 0,4 lot.


Qu'est-ce que ça peut être ?


Merci.

Pourrait-il s'agir d'une occurrence partielle ? Qu'y a-t-il dans les journaux ?