Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Нужны ли глобальные переменные терминала типа string?
fxsaber, 2017.04.10 18:25
Как вариант, таким образом можно записывать и считывать из глобальных переменных строки, простые структуры и даже массивы (например, обмениваться результатами CopyTicks)
// MQL4&5-code #property strict #include <TypeToBytes.mqh> #define POSTFIX "___" string GetName( const string Name, const int Num, const string PostFix = POSTFIX ) { return(Name + PostFix + (string)Num); } bool _GlobalVariableDel( const string Name ) { return(GlobalVariableDel(Name) && (GlobalVariablesDeleteAll(Name + POSTFIX) >= 0)); } #define GLOBAL_VARIABLE_SET(A) \ template <typename T> \ datetime _GlobalVariableSet( const string Name, const T A ) \ { \ _GlobalVariableDel(Name); \ \ double Array[]; \ \ const datetime Res = GlobalVariableSet(Name, _ArrayCopy(Array, _R(Value).Bytes)); \ const int Size = ArraySize(Array); \ \ for (int i = 0; i < Size; i++) \ GlobalVariableSet(GetName(Name, i), Array[i]); \ \ return(Res); \ } GLOBAL_VARIABLE_SET(Value) GLOBAL_VARIABLE_SET(&Value) GLOBAL_VARIABLE_SET(&Value[]) #define GLOBAL_VARIABLE_GET(A) \ { \ double Array[]; \ \ const int Amount = (int)Tmp; \ const int Size = ArrayResize(Array, Amount / sizeof(double) + \ ((Amount % sizeof(double) == 0) ? 0 : 1)); \ \ for (int i = 0; i < Size; i++) \ Array[i] = GlobalVariableGet(GetName(Name, i)); \ \ uchar Bytes[]; \ \ _ArrayCopy(Bytes, Array, 0, 0, Amount); \ \ _W(A) = Bytes; \ } template <typename T> const T _GlobalVariableGet( const string Name ) { T Res; // https://www.mql5.com/ru/forum/1111/page1869#comment_4854112 double Tmp; if (GlobalVariableGet(Name, Tmp)) GLOBAL_VARIABLE_GET(Res) return(Res); } template <typename T> bool _GlobalVariableGet( const string Name, T &Value ) { double Tmp; const bool Res = GlobalVariableGet(Name, Tmp); if (Res) GLOBAL_VARIABLE_GET(Value) return(Res); } void OnStart() { string Name = "Name"; // Записываем/считываем строки _GlobalVariableSet(Name, "Hello World!"); Print(_GlobalVariableGet<string>(Name)); // Записываем/считываем простые структуры MqlTick Tick; SymbolInfoTick(_Symbol, Tick); _GlobalVariableSet(Name, Tick); Print(_GlobalVariableGet<MqlTick>(Name).time); // Записываем/считываем массивы MqlTick Ticks[2]; Ticks[0] = Tick; Ticks[1] = Tick; _GlobalVariableSet(Name, Ticks); MqlTick NewTicks[]; // if (_GlobalVariableGet(Name, NewTicks)) // https://www.mql5.com/ru/forum/1111/page1868#comment_4853867 // Print(NewTicks[1].time); _GlobalVariableDel(Name); }
Возможно, стоит причесать в виде библиотеки.
возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов
Я храню строковые переменные как имена файлов. Макс. длина больше 100 (не помню точно, да и можно увеличить правкой в реестре). Работает очень быстро (каталог имён кешируется в памяти) и не занимает место (файл нулевой длины, а минимальный блок - 4К, вроде).
Только надо следить (кроме длины строки) за неразрешёнными в именах символами (: / \) и перекодировать, если используешь.
Код fxsaber тоже использую, но не для строк, а для других простых данных, и даже массивов.Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
fxsaber, 2018.12.17 23:48
Можно обмениваться чем угодно через Ресурсы.
// Пример обмена любыми данными (включая строковые массивы). #include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/ru/code/22166 #define PRINT(A) Print(#A + " = " + (string)(A)); void OnStart() { // Произвольные данные для примера string Str[] = {"123", "Hello World!"}; double Num = 5; MqlTick Tick = {0}; Tick.bid = 1.23456; const RESOURCEDATA<uint> Resource; // Ресурс для обмена данными CONTAINER<uint> Container; // Создаем контейнер - все будет храниться в массиве простого типа (в примере выбран uint) // Заполняем контейнер разными данными Container[0] = Str; Container[1] = Num; Container[2] = Tick; // Распечатаем типы хранимых в контейнере данных for (int i = 0; i < Container.GetAmount(); i++) PRINT(Container[i].GetType()) Resource = Container.Data; // Отправили данные на обмен CONTAINER<uint> Container2; // Сюда будем получать данные Resource.Get(Container2.Data); // Получили данные // Получим данные в исходном виде string Str2[]; Container[0].Get(Str2); // Получили массив ArrayPrint(Str2); PRINT(Container[1].Get<double>()) // Получили число PRINT(Container[2].Get<MqlTick>().bid) // Получили структуру }
Всем привет !
возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов
если символы [a-z][A-Z][0-9] то да, со свистом поместятся в 8 байт double
можно в sqlite хранить, в базе :memory: это будет быстрее чем вы реализуете битовые операции упаковки текста. Заодно можно не ограничиваться 10 символов и вовсю использовать json (не тестил, если MQ не обрубили фичу)
Я храню строковые переменные как имена файлов. Макс. длина больше 100 (не помню точно, да и можно увеличить правкой в реестре). Работает очень быстро (каталог имён кешируется в памяти) и не занимает место (файл нулевой длины, а минимальный блок - 4К, вроде).
Только надо следить (кроме длины строки) за неразрешёнными в именах символами (: / \) и перекодировать, если используешь.
Код fxsaber тоже использую, но не для строк, а для других простых данных, и даже массивов.что то новое, надо юзать
если символы [a-z][A-Z][0-9] то да, со свистом поместятся в 8 байт double
можно в sqlite хранить, в базе :memory: это будет быстрее чем вы реализуете битовые операции упаковки текста. Заодно можно не ограничиваться 10 символов и вовсю использовать json (не тестил, если MQ не обрубили фичу)
пробовал так - символы кодировать но почему при декодирвоке другое выходило. пример кода не подскажите
ulong EncodeStringToNumber(const string value) { ulong encoded = 0; int length = StringLen(value); if(length > 8) // Ограничение длины строки (макс. 8 символов) { Print("Error: String too long to encode."); return 0; } for(int i = 0; i < length; i++) { encoded = (encoded << 8) | (uchar)value[i]; } return encoded; } string DecodeNumberToString(ulong encoded) { string decoded = ""; for(int i = 0; i < 8; i++) { uchar charCode = (uchar)(encoded & 0xFF); decoded = CharToString(charCode) + decoded; encoded >>= 8; // Сдвиг вправо на 8 бит } return StringTrim(decoded); } void OnStart() { string globalVarName = "MyStringVar"; string originalString = "Hello"; ulong encodedValue = EncodeStringToNumber(originalString); if(encodedValue == 0) return; GlobalVariableSet(globalVarName, encodedValue); double readValue = GlobalVariableGet(globalVarName); string decodedString = DecodeNumberToString((ulong)readValue); Print("Original string: ", originalString); Print("Decoded string: ", decodedString); }
в чем ошибка ?
Всем привет !
возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов
Глобальнве переменные клиентского терминала хранят числа типа double. То есть, 8 байт информации. То есть, можно сохранить как есть строку из 8 символов. Если нужно хранить более 8 символов (в Вашем случае - 10), то следует иметь в виду, что в тех же 8 байтах можно сохранить целое число от 0 до
1844674407370955161 - в 19-значном числе может быть закодировано любое слово
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Всем привет !
возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов