Ваши вопросы по языку MQL4

alexshell

Элитный участник
А ещё проще задом на перёд перебрать. Я уже говорил номер в переборе соответсвует времени открытия(порядку).

Можно.Просто здесь вопрос стоит в том делать или не делать вычисления на выбранном ордере. Результат будет тот же. Но вычислений будет меньше. Хотя это мелочи конечно.:)
к сожалению нет,
смотря как список выстроен в мт, по какому полю сортировка, сталкивался с этим года два назад, попался на этом, тоже так думал, с тех пор если надо найти последний ордер делаю функцией перебора и проблем нет.

Может быть МТ что-то уже нахимичили переправили. Но года два назад - номер не соответствует последней сделке.

:facepalm:
То же так думал. Но eevviill доказал мне что сортировка не меняет очередность ордеров.
 

expforex

Программиров
Можно.Просто здесь вопрос стоит в том делать или не делать вычисления на выбранном ордере. Результат будет тот же. Но вычислений будет меньше. Хотя это мелочи конечно.:)

То же так думал. Но eevviill доказал мне что сортировка не меняет очередность ордеров.

я отстал :) o_o
но с точки зрения правильной проверки все же считаю что лучше перепроверять по времени. !
в любом случае в истори этот номер с последним ордером не прокатит.!
 

evgen_82

Активный участник
Добрый день ув. программисты. Подскажите, есть ли у кого-нить в наличии функция детектора круглых уровней для встройки в сову? В нете искал, так и не нашел. А для некоторых сов она очень нужная.
 

hoz

Активный участник
Отложка естественно не будет иметь лося или профит. Поэтому и задано в условиях что отложки пропускаем и не делаем лишних вычислений.Со временем там мы сравниваем с нулём только один раз на первом ордере.Потом время меняется на время ордера и уже следующий ордер сравнивается с этим временем.Вообще можно Times=0; тоже вынести за старт. Тогда у нас в программе всегда будет присутсвовать время последнего закрытого ордера. И в цикле будем сравнивать с этим временем.Соответственно вычислений будет меньше.

Со временем всё логично. Если вынести за функцию (в глобальные), то будет, с точки зрения оптимизации, очень даже резонно. Ведь все предыдущие ордера, которые закрылись раньше, чем Times будут отсекаться.
А вот с типом я всё-таки не согласен. Ведь ордера перебираются всё-равно все... если не изменили какие-то условия дефолтовые (например, вынесли ту же переменную Times в глобальные).
Так вот, ордера перебираются все... у каждого ордера есть свои какие-то данные (тип, профит, открытие, закрытие.. итд).
Если уж ордера перебираются все, то достаточно отбирать их согласно какого-то одного значения т.к. другие данные ордеров заданные те же самые.

Например, попалась отложка. Тут согласно двух предыдущих вариантов будет так:
1. Сова смотрит тип ордера.
2. Время закрытия смотреть не будет, т.к. ордер отсёкся (не подходит под условия)
Но откуда мы знает как компилятор будет их перебирать?

Если рыночный ордер в истории, то...
1. Проверяем тип.. (подходит)
2. Проверяем время закрытия (подходит)
Получается провериться 2 условия, вместо одного. Хотя перебор по времени даст тот же эффект.
Логично?
 

alexshell

Элитный участник
Со временем всё логично. Если вынести за функцию (в глобальные), то будет, с точки зрения оптимизации, очень даже резонно. Ведь все предыдущие ордера, которые закрылись раньше, чем Times будут отсекаться.
А вот с типом я всё-таки не согласен. Ведь ордера перебираются всё-равно все... если не изменили какие-то условия дефолтовые (например, вынесли ту же переменную Times в глобальные).
Так вот, ордера перебираются все... у каждого ордера есть свои какие-то данные (тип, профит, открытие, закрытие.. итд).
Если уж ордера перебираются все, то достаточно отбирать их согласно какого-то одного значения т.к. другие данные ордеров заданные те же самые.

Например, попалась отложка. Тут согласно двух предыдущих вариантов будет так:
1. Сова смотрит тип ордера.
2. Время закрытия смотреть не будет, т.к. ордер отсёкся (не подходит под условия)
Но откуда мы знает как компилятор будет их перебирать?

Если рыночный ордер в истории, то...
1. Проверяем тип.. (подходит)
2. Проверяем время закрытия (подходит)
Получается провериться 2 условия, вместо одного. Хотя перебор по времени даст тот же эффект.
Логично?
Да всё логично. Только если отложку не отсекём то по ней то же сделается несколько операций:
Times==OrderCloseTime( );
profit= OrderProfit( )+OrderSwap()+OrderCommission( ) ;
что по времени будет лучше не знаю.А если в советнике используется много отложек которые периодично удаляются.Если знать всю логику совы тогда можно предметно об этом говорить.
Вот если б вообще избавиться от цикла перебора ордеров это была б революция в совостроении.
 

evgen_82

Активный участник
Добрый день. Имеется строковая переменная string key = "1-2;3-4"; Вопрос как можно вместо цифр 1,2,3,4 подпехнуть переменные а, b, с, d? И возможно ли такое?
 
Последнее редактирование:

ale002

::: __,,,^._.^,,,__ :::
Ничего проще

HTML:
string key = a + "-" + b;


Если переменные - вещественные (double), их лучше нормализовать, т.е. убрать лишние знаки после запятой

HTML:
string key = DoubleToStr(a, 0) + "-" + DoubleToStr(b, 0)

Или так:

HTML:
string key = StringConcatenate(DoubleToStr(a, 0), "-", DoubleToStr(b, 0));
 

evgen_82

Активный участник
Спасибо, переменные не вещественные. Я немного отредактировал свое первое сообщение, как в этом случае сделать
HTML:
string key = "1-2;3-4"
А кавычками обрамлять не надо?
HTML:
string key = a + "-" + b;

Мне эту строку надо отправить в длл, и она идет с кавычками. Или это не существенно? А ординарные кавычки допускаются?
HTML:
string key = "a + '-' + b";
 
Последнее редактирование:

ale002

::: __,,,^._.^,,,__ :::
Точно так же, по аналогии:

HTML:
string key = a + "-" + b + ";" + c + "-" + d;

А что вы делать с такой переменной собираетесь, лубопытно? Наверное в файл писать?

В кавычках это будет буква, а не переменная, т.е. значение вместо ней не подставится. Хоть в двойных, хоть в одинарных
 
Последнее редактирование:

evgen_82

Активный участник
В Dll пихать. Посмотрите мое сообщение чуть выше, я правильно там написал?
 

evgen_82

Активный участник
Использовал след вариант.
HTML:
string Tg = StringConcatenate(WT1 , "-" , WT2 , ";" , WT3)

Идут ошибки млин,
'StringConcatenate' - initialization expected E:\Fort\Test\Test.mq4 (54, 13)
'(' - comma or semicolon expected E:\Fort\Test\Test.mq4 (54, 30)
'WT1' - expression on global scope not allowed E:\Fort\Test\Test.mq4 (54, 31)
'WT2' - expression on global scope not allowed E:\Fort\Test\Test.mq4 (54, 42)
'WT3' - expression on global scope not allowed E:\Fort\Test\Test.mq4 (54, 53)
')' - unbalanced right parenthesis E:\Fort\Test\Test.mq4 (54, 56)
 

evgen_82

Активный участник
:hmm:Перед этим только:
HTML:
extern int WT1 = 20;
extern int WT2 = 115;
extern int WT3 = 22;

Если убрать все четыре строчки, то ошибок нет...
 
Последнее редактирование:

ale002

::: __,,,^._.^,,,__ :::
Дак операторы (StringConcatenate, + и т.д.) можно использовать только в функциях. start, init, пользовательских.. А там где extern - только объявление переменных или присвоение им значений и никаких вычислений
 

hoz

Активный участник
Мне нужно сделать, вроде как простую вещь. Но я что-то стопорнулся.
Есть диапазон быстрых сигнальных машек разных периодов и одна машка медленная.
Нужно чтоб при пересечении любой из быстрых сигнальных машек выше или ниже медленной появлялось условие для покупки или продажи, соответственно.
Дальше когда цена откатывается к той быстрой машке, которая пересекла медленную происходит соответственно вход в рынок.
Так как тут пачка машек, то работать удобнее будет через массив. Вот моя функция проверки пересечения машек, которая не возвращает верный результат почему-то:
PHP:
//+-------------------------------------------------------------------------------------+
//| Получение значений МА на двух соседних барах                                        |
//+-------------------------------------------------------------------------------------+
double GetCurAndPrevMA(int maPeriod, double& prevMA)
{
   prevMA = iMA(NULL, i_TF, maPeriod, 0, MODE_EMA, MODE_CLOSE, 1);
   return (iMA(NULL, i_TF, maPeriod, 0, MODE_EMA, MODE_CLOSE, 0));
}
//+-------------------------------------------------------------------------------------+
//| Получение положения машек между собой                                               |
//+-------------------------------------------------------------------------------------+
void GetStateMa(int& crossDir[])
{
   double ema365_1;
   double ema365_0 = GetCurAndPrevMA(365, ema365_1);

   Print("g_maPeriod[0] = ", g_maPeriod[0]);
   Print("g_maPeriod[1] = ", g_maPeriod[1]);
   Print("g_maPeriod[2] = ", g_maPeriod[2]);
   Print("g_maPeriod[3] = ", g_maPeriod[3]);
   
   for (int i=0; i<4; i++)
   {
      double ema1;
      double ema0 = GetCurAndPrevMA(g_maPeriod[i], ema1);

      crossDir[i] = CROSS_NO;

//      Print("ema1 < 365_1 ", ema1 ," < ", ema365_1);
      if (/*ema1 < ema365_1 && */ema0 > ema365_0)
      {
//         Print("ema1 < 365_1 ___ ", ema1 ," < ", ema365_1);
         Print("ema0 > 365_0 ___ ", ema0 ," > ", ema365_0);
         crossDir[i] = CROSS_UP;
      }
      if (/*ema1 > ema365_1 && */ema0 < ema365_0)
      {
//         Print("ema1 > 365_1 ___", ema1 ," > ", ema365_1);
         Print("ema0 < 365_0 ___ ", ema0 ," < ", ema365_0);
         crossDir[i] = CROSS_DN;
      }
   }
}
В глобальных вот что есть касательно данного вопроса:
PHP:
extern int i_TF = 0;
int g_maPeriod[3] = {6, 25, 150, 250},             // Периоды обрабатываемых МА
    g_singMa[3] = {1,2,3,4};                     // признаки машек, добавляемые к основному мэйджику
extern string ___H1 = " ________ Параметры ордера _________";
int crossDir[3];
#define CROSS_UP             0                                 // Признак нахождения быстрой средней
                                                               // ..над медленной
#define CROSS_DN             1                                // Признак нахождения медленной..
                                                               // ..средней над быстрой
#define CROSS_NO            -1                                 // Признак равенства двух средних
Вот принт из старта результатов:
Код:
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: crossDir[3] = 0
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: crossDir[2] = -1
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: crossDir[1] = -1
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: crossDir[0] = -1
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: g_maPeriod[3] = 250
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: g_maPeriod[2] = 150
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: g_maPeriod[1] = 25
2013.04.11 18:34:53	2009.01.26 00:04  Base150_New EURUSD,H1: g_maPeriod[0] = 6

Хотя, судя по скрину всё понятно, что все машки ниже самой жирной, значит должен быть результат -1 т.к. там дефайн в глобальных.

0_93f13_1dff2aa8_orig.jpg


Как лучше поступить? Почему не правильно возвращаются значения элементов массива crossDir[]
 
Последнее редактирование:

AlexeyVik

Программист mql4 mql5
Сначала объяви массивы правильно. Потом будем думать, если не пропадёт ошибка.
Ты объявляешь массив из трёх элементов, а сам массив имеет 4 элемента...???
int g_maPeriod[3] = {6, 25, 150, 250},
g_singMa[3] = {1,2,3,4};
 
  • Like
Реакции: hoz

hoz

Активный участник
Сначала объяви массивы правильно. Потом будем думать, если не пропадёт ошибка.
Ты объявляешь массив из трёх элементов, а сам массив имеет 4 элемента...???
int g_maPeriod[3] = {6, 25, 150, 250},
g_singMa[3] = {1,2,3,4};

С массивами у меня ещё маловато опыта работы, сразу не верно объявил.. Но ещё до Вашего ответа исправил. Так же исправил косяк. В общем по ходу, всё-таки mq4 кривоватый язык.
Ситуация решилась так:
Если массивы объявить глобально без размера, например, в случае с crossDir[] так:
PHP:
int crossDir[];
потом через ресайз изменить размер массив, а в данном случае его задать т.к. при инициализации, как я понял, его размер будет не иметь длины, то всё заработало.
В функции я дописал вот так:
PHP:
//+-------------------------------------------------------------------------------------+
//| Получение положения машек между собой                                               |
//+-------------------------------------------------------------------------------------+
void GetStateMa(int& crossDir[])
{
   double ema365_1;
   double ema365_0 = GetCurAndPrevMA(365, ema365_1);

   Print("g_maPeriod[0] = ", g_maPeriod[0]);
   Print("g_maPeriod[1] = ", g_maPeriod[1]);
   Print("g_maPeriod[2] = ", g_maPeriod[2]);
   Print("g_maPeriod[3] = ", g_maPeriod[3]);
   
   for (int i=0; i<4; i++)
   {
      ArrayResize(crossDir,i);
      double ema1;
      double ema0 = GetCurAndPrevMA(g_maPeriod[i], ema1);

      crossDir[i] = CROSS_NO;

      if (ema1 < ema365_1 && ema0 > ema365_0)
      {
         Print("ema1 < 365_1 ___ ", ema1 ," < ", ema365_1);
         Print("ema0 > 365_0 ___ ", ema0 ," > ", ema365_0);
         crossDir[i] = CROSS_UP;
      }
      if (ema1 > ema365_1 && ema0 < ema365_0)
      {
         Print("ema1 > 365_1 ___", ema1 ," > ", ema365_1);
         Print("ema0 < 365_0 ___ ", ema0 ," < ", ema365_0);
         crossDir[i] = CROSS_DN;
      }
   }
}
Но опять же почему такая чушь происходит так и не понял. То ли баг языка, то ли..
Ведь явно объявлять размер массива никто не запрещал, да и частяком такое встречаю и всё работает исправно.
Может есть у мысли по этому поводу? Мне даже очень интересно стало..
 

qqmber

Почетный гражданин
С массивами у меня ещё маловато опыта работы, сразу не верно объявил.. Но ещё до Вашего ответа исправил. Так же исправил косяк. В общем по ходу, всё-таки mq4 кривоватый язык.
Код:
      ArrayResize(crossDir,i);
      double ema1;
      double ema0 = GetCurAndPrevMA(g_maPeriod[i], ema1);

      crossDir[i] = CROSS_NO;
Но опять же почему такая чушь происходит так и не понял. То ли баг языка, то ли..
Ведь явно объявлять размер массива никто не запрещал, да и частяком такое встречаю и всё работает исправно.
Может есть у мысли по этому поводу? Мне даже очень интересно стало..
Имея маловатый опыт, не торопитесь обвинять язык в кривости и баговости.
Вы продолжаете обращаться к несуществующему элементу массива, несмотря на совет Алексея. В массиве длиной i последний элемент имеет индекс i-1.
 
Верх