Ошибки, баги, вопросы - страница 1439

 
Здравствуйте.Я пытаюсь использовать MT5 для работы с фьючерсами через брокера "Открытие".
При обращении к функции SymbolInfoTick выяснилось, что два последних параметра структуры MqlTick
 - time_msc, flag отсутствуют. Можно ли решить данную проблему? Например, взяв MT5 c этого сайта,
попробовать подключить его к серверу брокера. Или можно получить требуемую информацию другим образом.
Меня интересует: кто был инициатором сделки, продавец или покупатель?
 
Alexander Puzanov:

Мне кажется или вы не работали с языками о которых речь? Индекс добавляемому элементу указывать не нужно вообще, он присваивается автоматом и размерность массива увеличивается также. У программиста просто нет шанса ошибиться в индексе при этой операции

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

Все эти "действия по умолчанию" - должны быть свойствами сложных объектов. Только классов.  Простые же объекты типа переменных, массивов и простых структур - должны иметь как можно меньше "умолчательных" свойств.

Например, при создании - в них должно храниться неопределенное значение, а вовсе не нуль.

Можно реализовать похожее поведение классами, добавить связанные с ним функции pop, shift, unshift итд. И таскать телегу классов из кода в код, при том что в каждом коде из неё используются %10..20 функций. Похоже это на правильное решение?

Это правильное решение с точки зрения логики. При работе с такими классами - их поведение прозрачно.

А насчет "таскать телегу классов" - при кодировании вы их не таскаете, просто подключаете библиотеку. А при компиляции - нормальный компоновщик не должен пихать в исполняемый модуль все методы из библиотеки подряд, а только те, что используются.

Пример правильного решения на моё имхо - добавление в функцию ObjectsDeleteAll возможности удалять по префиксу - это ещё микрон в сторону более высокоуровневого программирования - и у большинства кодеров улетела в корзину соотв самопальная функция. Увы, с массивами мы такого вряд ли дождёмсо..

А на мой взгляд - это тоже неверный подход, по той же причине. Функция нагружается несвойственными ей задачами, которые не следуют из логики ее применения. 

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

 
Demal:
Здравствуйте.Я пытаюсь использовать MT5 для работы с фьючерсами через брокера "Открытие".
При обращении к функции SymbolInfoTick выяснилось, что два последних параметра структуры MqlTick
 - time_msc, flag отсутствуют. Можно ли решить данную проблему? Например, взяв MT5 c этого сайта,
попробовать подключить его к серверу брокера. Или можно получить требуемую информацию другим образом.
Меня интересует: кто был инициатором сделки, продавец или покупатель?
  1. Какой билд терминала у Вас сейчас?
  2. Подключаетесь к какому серверу: демо- или реал?
 
version 5.0 build 1150, демо
 
Demal:
version 5.0 build 1150, демо

Обновите свой терминал (нужно подключится к демо-серверу MetaQuotes-Demo). Текущий билд:

Terminal        MetaTrader 5 build 1210 started (MetaQuotes Software Corp.)

Вот такой скрипт:

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                              Copyright © 2015, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   MqlTick last_tick;
//--- 
   if(SymbolInfoTick(Symbol(),last_tick))
     {
      Print("time = ",last_tick.time,"; bid = ",last_tick.bid,
            "; ask = ",last_tick.ask,"; volume = ",last_tick.volume,
            "; time_msc = ",last_tick.time_msc,"; flag = ",last_tick.flags);
     }
   else Print("SymbolInfoTick() failed, error = ",GetLastError());
  }
//+------------------------------------------------------------------+

 

даёт такой результат: 

Test (RTS-12.15,H1)     time = 2015.11.26 09:42:57; bid = 88360.0; ask = 88400.0; volume = 2; time_msc = 1448530977000; flag = 0

Файлы:
Test.mq5  2 kb
 
Karputov Vladimir:

Обновите свой терминал (нужно подключится к демо-серверу MetaQuotes-Demo). Текущий билд:

Вот такой скрипт:

 

даёт такой результат: 

Спасибо, а не знаете почему у флага значение 0 , как будто ничего не изменилось
 
Demal:
Спасибо, а не знаете почему у флага значение 0 , как будто ничего не изменилось
Используйте CopyTicks и будет Вам счастье. А SymbolInfoTick, вероятно, пока ещё не умеет работать с новой структурой тиков.
Файлы:
CopyTicks.mq5  4 kb
 

МТ 4. Генератор случайных чисел MathRand()  внутри OnTick().  При тестировании совы получаются разные результаты при повторном запуске на одинаковых настройках. Это естественно если сгенерированное число влияет на алгоритм.

При оптимизации почему-то выдаются одинаковые результаты при повторном запуске с теми-же настройками. Получается MathRand() не работает в режиме оптимизации?  

 
Сергей Таболин:

Второе (тут я боюсь ошибиться, надеюсь Alexander Puzanov меня поправит, если что), если программист по каким либо причинам решает добавить к динамическому массиву элемент с индексом 20, то ничего страшного не произойдёт. Массив примет эту размерность и запишет туда значение, а "недостающие" индексы проинициализирует нулевыми значениями.

Вот-вот. Почему "нулевыми" ??? А может быть, это должны быть EMPTY_VALUE ? Или WRONG_VALUE ?

Проблема подобных неявных присвоений именно в их неявности - компилятор вносит какой-то код, про который один программист думает одно, а другой - может думать другое.

Плюс неэффективность - далеко не всегда необходимо сразу инициализировать переменную, а инициализация большого массива, да в цикле - может достаточно заметно снижать скорость.

И трейтье, никто ведь не мешает программисту контролировать размерность и используемый индекс! Отличие только в том, что сейчас это делать вынуждают! ))) 

Если компилятор будет сам следить за размерностью массива - никакой класс не сможет убрать этот код. Эффективность может сильно падать.

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

Во втором случае - гибкость выше.

То есть, то, что предлагаете вы - это тоже вполне себе годное решение для многих случаев. Но оно может снижать эффективность, что не есть хорошо.

 
Сергей Таболин:

Это, в принципе, простой пример как по нормальному должен заполняться динамический массив. На С я очень давно не писал, не помню, но в php массивы именно так и заполняются! Всё логично и понятно. Если я добавляю элемент в массив (arr[] = x), то массив автоматически увеличивается, и элемент добавляется в конец массива. И не нужно самому растягивать его, и не нужно самому указывать индекс элемента. Здесь же нам приходится делать совершенно лишние движения:

разница очевидна...

на мой взгляд это, по меньшей мере, странно ))) 

Языки программирования делятся на строготипизированные и нет. К нестроготипизированным относится ваш PHP, R и другие функциональные языки. В строготипизированных языках как MQL или C# и Java подобные неоднозначные манипуляции с данными недопустимы. И сделано это специально для безопасности самого же программиста. Строгая типизация подразумевает что каждая ваша процедура предельно конкретна: "взять элемент по индексу 0 в массиве array" - конкретная и понятная процедура, Вы же предлагаете ее заменить на "взять что-нибудь из массива array и сложить с чем-нибудь, что первое решит вернуть компилятор". - Согласитесь, что далеко на этом не уедешь.

С другой стороны, конечно, хотелось бы простых высокоуровневых конструкций, без утомительных выяснений размеров массива и постоянных пользовательских переразметок. Вот именно для этого и существует стандартная библиотека. Вместо того, что бы использовать базовые массивы переходите на классы группы Array. Вот так например будет выглядеть добавление от нуля до 16 в массив CArrayInt:

#include <Arrays\ArrayInt.mqh>

void OnStart()
{
   CArrayInt array;
   for(int i = 0; i < 16; i++)
      array.Add(i);   
}

 Как видите, ничего сверх естественного нет. И ненужно голову ломать над текущем размером массива и прочими переразметками. Все делается за Вас, в рамках строгой типизации, а Вам предлагается сосредоточиться непосредственно над пользовательской задачей. В этом мощь и смысл ООП.