新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 320

 

晚上好。

为选定的工具建立了一个指标--波动率汇总表。无论指标安装在哪个图表上,数据的计算结果应该是一样的。然而,它的计算方式不同。取决于图表的分母中是否有日元。

如果有,表格看起来像这样。


如果没有,它看起来像这样。


以下是代码。

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

晚上好。

为选定的工具建立了一个指标--波动率汇总表。无论指标安装在哪个图表上,数据的计算结果应该是一样的。然而,它的计算方式不同。取决于图表的分母中是否有日元。

已经遇到了这个问题--日元的小数位 较少。因此 "点 "将是不同的。还是别的什么?

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;
顺便说一下,建议使用Point() 或_Point
 
STARIJ:

我已经遇到过这种情况--日元的小数位 较少。因此,点将是不同的


尝试添加一个条件

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

并在此除以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++;
        }

但最终,在没有日元的情况下,一切都很清楚。

但对于日元,则是一团糟。


 
Sergey:

尝试添加一个条件

并在此除以Z^

但最终,在没有日元的情况下,一切都很清楚。

但对于日元,则是一团糟。


用 "SymbolInfoDouble(syb[k],SYMBOL_POINT) "代替Point

 
Vitaly Muzichenko:

用 "SymbolInfoDouble(syb[k],SYMBOL_POINT) "代替Point


谢谢你,现在到处都很清楚了,而且没有任何错误。

 
Sergey:

谢谢你,现在到处都很清楚了,不会再有什么差错了。

将代码优化一下,在一个字符上只调用一次计算。

      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:

将代码优化一下,在一个字符上只调用一次计算。

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

本着这种精神,把所有的代码减少到一个简洁的数组操作。任何相同逻辑的重复都应该被设计成循环。

 
你好,请你告诉我如何做到这一点?我怎样才能规定,跟踪止损不接近指标,而是分别低10点或高10点?
 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);
 

日安!

如何解决这个问题?我写了一个EA,在一个不成功的交易中下了一个增加手数的挂单(如2倍)。

但是当挂单被执行时(很少,10个案例中有1个),手数没有乘以系数,尽管它最初是按照算法放置的。

下面是一个例子。

一笔交易以0.4手成交,立即以0.8手挂单,当它被执行时,成交量变成了0.4手。


它可能是什么?


谢谢你。

 
yaaarik777:

日安!

如何解决这个问题?我写了一个EA,在一个不成功的交易中下了一个增加手数的挂单(如2倍)。

但是当挂单被执行时(很少,10个案例中有1个),手数没有乘以系数,尽管它最初是按照算法放置的。

下面是一个例子。

一笔交易以0.4手成交,立即以0.8手挂单,当它被执行时,成交量变成了0.4手。


它可能是什么?


谢谢你。

会不会是部分发生的呢?日志中的内容是什么?

原因: