Вопросы (Yerkin Sagandykov)

 

Всем привет !


возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов

 
Yerkin Sagandykov:
чтоб в глобальных переменной хранить

Тут либо в глобальной  переменной, либо а глобальных  переменных. Если первое, то - нет; если  второе - да.
 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Нужны ли глобальные переменные терминала типа 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);
}

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

 
Yerkin Sagandykov:

возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов

Я храню строковые переменные как имена файлов. Макс. длина больше 100 (не помню точно, да и можно увеличить правкой в реестре). Работает очень быстро (каталог имён кешируется в памяти) и не занимает место (файл нулевой длины, а минимальный блок - 4К, вроде).

Только надо следить (кроме длины строки) за неразрешёнными в именах символами (: / \) и перекодировать, если используешь.

Код fxsaber тоже использую, но не для строк, а для других простых данных, и даже массивов.
 
Еще вариант хранения.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотеки: TradeTransactions

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) // Получили структуру  
}
 
Yerkin Sagandykov:

Всем привет !


возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов

если символы [a-z][A-Z][0-9] то да, со свистом поместятся в 8 байт double

можно в sqlite хранить, в базе :memory: это будет быстрее чем вы реализуете битовые операции упаковки текста. Заодно можно не ограничиваться 10 символов и вовсю использовать json (не тестил, если MQ не обрубили фичу)

 
Edgar Akhmadeev #:

Я храню строковые переменные как имена файлов. Макс. длина больше 100 (не помню точно, да и можно увеличить правкой в реестре). Работает очень быстро (каталог имён кешируется в памяти) и не занимает место (файл нулевой длины, а минимальный блок - 4К, вроде).

Только надо следить (кроме длины строки) за неразрешёнными в именах символами (: / \) и перекодировать, если используешь.

Код fxsaber тоже использую, но не для строк, а для других простых данных, и даже массивов.

что то новое, надо юзать

 
Maxim Kuznetsov #:

если символы [a-z][A-Z][0-9] то да, со свистом поместятся в 8 байт double

можно в sqlite хранить, в базе :memory: это будет быстрее чем вы реализуете битовые операции упаковки текста. Заодно можно не ограничиваться 10 символов и вовсю использовать json (не тестил, если MQ не обрубили фичу)

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

 
Yerkin Sagandykov #:
но почему при декодирвоке другое выходило
Потому, что ошибка в программе.
🤷‍♂️
 
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);
}

в чем ошибка ?

 
Yerkin Sagandykov:

Всем привет !


возможно реализовать чтоб в глобальных переменной хранить текст ? не больше 10 символов

Глобальнве переменные клиентского терминала хранят числа типа double. То есть, 8 байт информации. То есть, можно сохранить как есть строку из 8 символов. Если нужно хранить более 8 символов (в Вашем случае - 10), то следует иметь в виду, что в тех же 8 байтах можно сохранить целое число от 0 до

1844674407370955161 - в 19-значном числе может быть закодировано любое слово