Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1876

 
Maksim Emeliashin #:

Возвращаясь к StringToEnum, нашел относительно универсальное решение для случаев, когда перечисления пронумерованы последовательно (1, 2, 3, ...).

Для явной нумерации последовательностей большими значениями работать не будет (например, ENUM_TIMEFRAMES). Но, если вы используете свои собственные enum без явной нумерации (ну или, хотя бы, последовательной) - решение подойдет.

Для всех остальных случаев нужны велосипеды, типа, статических массивов наименований каждого из возможных значений и поиск по строке в этом массиве.

Для MQL функция будет работать некорректно

template<typename T>
bool StringToEnum(const string i_str, T &o_val)
{
   for(int i = 0; i < 256; i++)
      {
         o_val = (T)i;
         if(StringCompare(EnumToString(o_val), i_str, false) == 0)
            return(true);
      }
   o_val = WRONG_VALUE;
   return(false);
}

https://www.mql5.com/ru/docs/strings/stringcompare

Параметры

string1

[in]  Первая строка.

string2

[in]  Вторая строка.

case_sensitive=true

[in]  Режим учета регистра букв. Если значения равно true, то "A">"a". Если значение равно false, то "A"="a". По умолчанию значение параметра равно true.

Если в enum будет две константы, например ENUM1 и enum1, то при i_str: "enum1" функция может вернуть значение константы ENUM1. И вообще зачем  StringCompare ? Если можно сделать следующим образом:

template<typename T>
bool StringToEnum(const string i_str, T &o_val)
{
   for(int i = INT_MIN; i <= INT_MAX && !IsStopped(); i++) // перебор всех возможных значений int
      {
         o_val = (T)i;
         if(i_str == EnumToString(o_val))
            return(true);
      }
   o_val = WRONG_VALUE;
   return(false);
}
 
Amon1953 #:

Всем Добрый день. 

  Переписываю  советника с MQL4 на MQL5. Не понимаю как получить причину закрытия позиции по SL.

Это нужно для того чтобы принять решение что делать дальше.

В терминале MT5 в окне истории можно выбирать сделку,ордер или позиция.

Вам нужно в торговой истории искать СДЕЛКУ у которой DEAL_REASON равен DEAL_REASON_SL.


Добавлено: можно всё упростить - достаточно в OnTradeTransaction отлавливать транзакцию TRADE_TRANSACTION_DEAL_ADD и обращаясь к торговой истории смотреть СДЕЛКУ, которая породила эту транзакцию. А затем тот же рецепт: ...  DEAL_REASON равен DEAL_REASON_SL

 
Mihail Matkovskij #:

Для MQL функция будет работать некорректно

https://www.mql5.com/ru/docs/strings/stringcompare

Если в enum будет две константы, например ENUM1 и enum1, то при i_str: "enum1" функция может вернуть значение константы ENUM1. И вообще зачем  StringCompare ? Если можно сделать следующим образом:

И более быстрый вариант:

template<typename T>
bool StringToEnum(const string i_str, T &o_val, int i_min_enum, int i_max_enum)
{
   for(int i = i_min_enum; i <= i_max_enum && !IsStopped(); i++) 
      {
         o_val = (T)i;
         if(i_str == EnumToString(o_val))
            return(true);
      }
   o_val = WRONG_VALUE;
   return(false);
}

bool StringToEnum(const string i_str, T &o_val) { return StringToEnum(i_str, o_val, INT_MIN, INT_MAX); } // медленный вариант
 
Alexey Viktorov #:

А зачем всё это надо? Вы хотите заменить числовые значения ENUM_TIMEFRAMES на свои? Или что?

Ну конкретно сейчас, мне нужна запись настроек индикаторов и параметров советника в БД. При этом хотелось бы иметь:

1. человекочитаемые записи

2. машиночитаемые записи

3. устойчивость к добавлению в свои кастомные enum новых значений, и не обязательно в конец.

С записью проблем нет - EnumToString, а вот обратную функцию разработчики не сделали, в отличии от всех других типов.

 
Mihail Matkovskij #:

И более быстрый вариант:

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

А вот если для ENUM_TIMEFRAMES запустить вот этот вариант:

bool StringToEnum(const string i_str, T &o_val) { return StringToEnum(i_str, o_val, INT_MIN, INT_MAX); } // медленный вариант
можно успеть попить кофе, пока он подберет, например, для PERIOD_MN1 :)
 
Valeriy Yastremskiy #:

Получить цены с прямых на каждом баре и сравнить или разницу найти, в местах смены знаков разниц пересечения) Там кстати может равенств и не быть на баре.

А какая функция для этого используется? MqlRates? А если через ObjectGet то там я должен указать свойство объекта, если взять OBJPROP_PRICE то как сделать что бы он получал цену до текущего бара. 
 
12345678902003 #:
Помогите пожалуйста, провожу две линии Ганна и они пересекаются в определенной точке, мне нужно узнать координаты точки пересечения этих линий. 
Если сможешь определить цену второй точки линии Ганна, то дальше KimIV тебе поможет
 
Maksim Emeliashin #:

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

А вот если для ENUM_TIMEFRAMES запустить вот этот вариант:

можно успеть попить кофе, пока он подберет, например, для PERIOD_MN1 :)

Ну в  ENUM_TIMEFRAMES минимальное и максимальное значение известны. Поэтому их можно задать явно.

С остальными enum, достаточно знать их примерный диапазон значений. Если в объявлении enum константы не заданы, то значения там обычно идут от 0. i_max_enum можно задать любым двузначным или трёхзначным числом: 50, 100, 255.

 
Maksim Emeliashin #:

Ну конкретно сейчас, мне нужна запись настроек индикаторов и параметров советника в БД. При этом хотелось бы иметь:

1. человекочитаемые записи

2. машиночитаемые записи

3. устойчивость к добавлению в свои кастомные enum новых значений, и не обязательно в конец.

С записью проблем нет - EnumToString, а вот обратную функцию разработчики не сделали, в отличии от всех других типов.

А вы когда ни будь пробовали распечатать перечисление?

Print(PERIOD_M5);

как вы думаете что будет напечатано?


А вот создать перечисление программно… это, да. Было-бы интересно.

 
x572intraday #:
 Ну почему нельзя input-парамерты перебрать в цикле? За что вы нас так наказываете???
Это конечно костыль, но я его использую: через какой-нибудь заданный разделитель ввести все нужные данные в строковую input-переменную, а затем с помощью StringSplit перегнать их в массив.
Причина обращения: