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

 
Знающие люди, подскажите! У меня есть кастомный символ, созданный на основе реального. Как сделать, чтобы торговля была доступна с графика этого символа? Или такого функционала нет в МТ5?
 
Vladimir Karputov:

Вот так: Custom Moving Average Input Color

То есть фактически надо написать свой индикатор. Переписывать стандартные индикаторы - не выход.

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

Существует ли другой способ?

 
В последних версиях МТ, в рамках изменения парадигмы по работе со строками видится отказ от использования NULL-terminated strings.
Однако работа функции StringSetLength вызывает ряд вопросов.

С помощью StringSetLength можно только обрезать длину строки, но ни как не увеличить, что, как-то бессмысленно.
Это запланированное поведение?

#define PRINT(x) Print(#x, ":", string(x))

void OnStart(){  
  string str = "123456789";
  PRINT(str);
  PRINT(StringLen(str));
  
  
  PRINT(StringSetLength(str, StringLen(str)-1));
  PRINT(str);
  PRINT(StringLen(str));
  
  PRINT(StringSetLength(str, StringLen(str)+2));
  PRINT(str);
  PRINT(StringLen(str));
}

Результат:
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      str:123456789
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      StringLen(str):9
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      StringSetLength(str,StringLen(str)-1):true
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      str:12345678
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      StringLen(str):8
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      StringSetLength(str,StringLen(str)+2):false
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      str:12345678
2019.05.15 01:22:08.208 StringFormat_1 (EURUSD,H1)      StringLen(str):8
 
Пользователю прще застрелиться, чем реализовать "полноценный" StringSetLength, с инициализацией "новых" characters как 0х0000.

#define PRINT(x) Print(#x, ":", string(x))

void OnStart(){  
  string str = "123\x0000\x0000\x0000\x0000456789";
  PRINT(str);
  PRINT(StringLen(str));                                                  // StringLen(str):13      StringLen поддерживает работу с 0х0000 short value
  
  PRINT(StringSetLength_using_StringInit(str, 100));                      // false                  StringInit           не поддерживает работу с 0х0000 short value
  PRINT(StringSetLength_using_ShortArrayToString(str, 100));              // false                  ShortArrayToString   не поддерживает работу с 0х0000 short value
  PRINT(StringSetLength_using_StringInit_with_StringFill(str, 100));      // false                  StringFill           не поддерживает работу с 0х0000 short value
}


bool StringSetLength_using_StringInit(string &string_var, int new_length){
   bool result = false;

   int prev_length = StringLen(string_var);
   if(new_length == prev_length){
      result = true;
      return result;
   }
   
   string data = string_var;   
   if(new_length < prev_length){
      StringSetLength(data, new_length);
   }else{
      string string_tail;
      StringInit(string_tail, new_length - prev_length, 0x0000);
      data += string_tail;
   }
   
   if(StringLen(data) == new_length){
      string_var = data;
      result = true;
   }
   return result;
}

bool StringSetLength_using_ShortArrayToString(string &string_var, int new_length){
   bool result = false;

   int prev_length = StringLen(string_var);
   if(new_length == prev_length){
      result = true;
      return result;
   }
   
   string data = string_var;   
   if(new_length < prev_length){
      StringSetLength(data, new_length);
   }else{    
      short data_array[];
      StringToShortArray(data, data_array);
      ArrayResize(data_array, new_length);
      ArrayFill(data_array, prev_length, new_length - prev_length, 0x0000);
      data = ShortArrayToString(data_array, 0, new_length);
   }
   
   if(StringLen(data) == new_length){
      string_var = data;
      result = true;
   }
   return result;
}

bool StringSetLength_using_StringInit_with_StringFill(string &string_var, int new_length){
   bool result = false;

   int prev_length = StringLen(string_var);
   if(new_length == prev_length){
      result = true;
      return result;
   }
   
   string data = string_var;   
   if(new_length < prev_length){
      StringSetLength(data, new_length);
   }else{    
      string string_tail;
      StringInit(string_tail, new_length - prev_length, 0x1111);
      StringFill(string_tail, 0x0000);
      data += string_tail;
   }
   
   if(StringLen(data) == new_length){
      string_var = data;
      result = true;
   }
   return result;
}
 
Sergey Dzyublik:
В последних версиях МТ, в рамках изменения парадигмы по работе со строками видится отказ от использования NULL-terminated strings.

Вот эту мысль могли бы озвучить подробнее?

 
rsrozhkov:
Знающие люди, подскажите! У меня есть кастомный символ, созданный на основе реального. Как сделать, чтобы торговля была доступна с графика этого символа? Или такого функционала нет в МТ5?

Ответ самоочевиден. Кастомный символ получается путем неких преобразований из реальных символов. Кто-то (советник, скрипт или вручную) должен сделать обратное преобразование и отправить ордера для реальных символов.

 
fxsaber:

Вот эту мысль могли бы озвучить подробнее?

Ниже мое субъективное мнение, если где-то не прав, буду рад помощи.


StringLen раньше работал O(n) до первого NULL символа (0x0000) в строке, сейчас работает O(1).
Длину строки всегда можно было обрезать через StringSetCharacter(str, pos, 0x00), но зачем-то вводят StringSetLength.

Скорее всего решали задачу ускорения кода при работе со строками.
Задачу ускорения решили, а то что половина функционала теперь работает с NULL символами в строке, а другая нет - ни кого не заботит.

#define PRINT(x) Print(#x, ":", string(x))

void OnStart(){  
   string str = "123456789";
   PRINT(str);
   PRINT(StringLen(str));
   
   PRINT(StringSetCharacter(str, 7, 0x00));
   PRINT(StringLen(str));
   
   str += "\x00" + str;
   PRINT(StringLen(str));
   
   str += str;
   PRINT(str);
   PRINT(StringLen(str));
   
   ushort array[];
   PRINT(StringToShortArray(str, array));
   ArrayPrint(array);
   
   PRINT(StringLen(str));
   PRINT(StringLen(ShortArrayToString(array)));
   PRINT(StringLen(ShortArrayToString(array, 0, StringLen(str))));
} 

Результат:

2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      str:123456789
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringLen(str):9
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringSetCharacter(str,7,0x00):true
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringLen(str):7
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringLen(str):15
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      str:1234567
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringLen(str):30
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringToShortArray(str,array):31
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      49 50 51 52 53 54 55  0 49 50 51 52 53 54 55 49 50 51 52 53 54 55  0 49 50 51 52 53 54 55  0
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringLen(str):30
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringLen(ShortArrayToString(array)):7
2019.05.15 14:02:11.895 StringFormat_1 (EURUSD,H1)      StringLen(ShortArrayToString(array,0,StringLen(str))):7
 
Sergey Dzyublik:

Ниже мое субъективное мнение, если где-то не прав, буду рад помощи.


StringLen раньше работал O(n) до первого NULL символа (0x0000) в строке, сейчас работает O(1).
Длину строки всегда можно было обрезать через StringSetCharacter(str, pos, 0x00), но зачем-то вводят StringSetLength.

Скорее всего решали задачу ускорения кода при работе со строками.
Задачу ускорения решили, а то что половина функционала теперь работает с NULL символами в строке, а другая нет - ни кого не заботит.


Результат:

Сдерживайте пожалуйста эмоции.
В следующий раз за матерщинные намёки придётся банить - не в кабаке мы тут. Да и в кабаке - уже не модно материться.
 
Sergey Dzyublik:

StringLen раньше работал O(n) до первого NULL символа (0x0000) в строке, сейчас работает O(1)

Просто частично исправили ошибки ... почему бы и нет!? На моей памяти StringLen всегда работал правильно (по крайней мере в x32)
 
Sergey Dzyublik:
Разработчикам:
Прошу добавить возможность указания принудительной генерации кода для оператора присвоения (конструктор копирования) по умолчанию:

Что то как-то сложно. Проще по аналогии с конструктором по умолчанию:

1) любой оператор присваивания отменяет оператор присваивания по умолчанию

2) любой оператор копирования отменяет оператор копирования по умолчанию