Библиотеки: TypeToBytes - страница 5

 
fxsaber:
В библиотеке прописан класс-контейнер, который в массиве заданного типа хранит переменные и массивы любых других простых типов.

Пример практического применения в Report-библе

Отправляем фрейм с разными данными

        string Str;
        REPORT::ToString(Str);

        double Balance[];
        REPORT::GetBalanceHistory(Balance);

      #ifdef __TYPETOBYTES__
        CONTAINER<uchar> Container;

        Container[0] = Str;     // поместили в контейнер строку с отчетом
        Container[1] = Balance; // добавили в контейнер еще и double-массив истории изменения баланса

        ::FrameAdd(NULL, 0, ::AccountInfoDouble(ACCOUNT_BALANCE), Container.Data); // Отправили фрейм со string-отчетом и массивом баланса
      #else  // __TYPETOBYTES__

Принимаем фрейм с разными данными

 CONTAINER<uchar> Container;

    while (::FrameNext(Pass, Name, ID, Value, Container.Data))
    {
        string Str;
        Container[0].Get(Str);     // Получили из фрейма строку-отчет

        double Balance[];
        Container[1].Get(Balance); // Получили из фрейма соответствущий double-массив

// .....
Report
Report
  • 2017.07.19
  • fxsaber
  • www.mql5.com
Библиотека для MetaTrader 4/5, которая позволяет формировать отчеты по истории торгов.
 
Еще пример применения Контейнера

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

Вопросы от начинающих MQL5 MT5 MetaTrader 5

fxsaber, 2017.08.23 14:10

Для записи данных Агентов в один файл нужно использовать Фрейм-режим.

// Пример записи данных Агентов (включая Облачные) в один файл
input int Range = 0;

void OnTick()
{
// ....
}

// Файл открываем только в режимах одиночночного прогона или Фрейма.
const int handle = ((MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_OPTIMIZATION)) || MQLInfoInteger(MQL_FRAME_MODE)) ?
                   FileOpen(__FILE__, FILE_WRITE | FILE_TXT) : INVALID_HANDLE;

// Подготовка данных
void GetData( string &Str, MqlTick &Ticks[], double &Balance )
{
  Str = "Hello World!";
  
  CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, 0, 2); // Последние два тика (пример)
  
  Balance = AccountInfoDouble(ACCOUNT_BALANCE);
}

// Запись данных
void SaveData( const string &Str, const MqlTick &Ticks[], const double Balance )
{
  FileWrite(handle, Str);
  
  for (int i = 0; i < ArraySize(Ticks); i++)
    FileWrite(handle, Ticks[i].bid);
    
  FileWrite(handle, Balance);
}

void OnTesterDeinit()
{
  if (handle != INVALID_HANDLE)  
    FileClose(handle);
    
  ChartClose();
}

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

double OnTester()
{
  string Str;
  MqlTick Ticks[];
  double Balance;
  
  GetData(Str, Ticks, Balance); // Подготовка данных для записи

  if (MQLInfoInteger(MQL_OPTIMIZATION)) // Оптимизация
  {
    CONTAINER<uchar> Container; // https://www.mql5.com/ru/forum/95447/page4#comment_5464205
    
    Container[0] = Str;
    Container[1] = Ticks;
    Container[2] = Balance;
  
    FrameAdd(NULL, 0, 0, Container.Data); // Отправили данные из Агента на Терминал
  }
  else // Одиночный прогон
  {    
    if (handle != INVALID_HANDLE)
      SaveData(Str, Ticks, Balance); // Данные будут записаны в MQL5\Files-папку Агента (не Терминала)
    
    FileClose(handle);
  }
  
  return(0);
}

void OnTesterPass()
{    
  if (handle != INVALID_HANDLE)
  {
    ulong Pass;
    string Name;
    long ID;
    double Value;
  
    CONTAINER<uchar> Container; // https://www.mql5.com/ru/forum/95447/page4#comment_5464205
  
    while (FrameNext(Pass, Name, ID, Value, Container.Data))
    {
      string Str;
      MqlTick Ticks[];
      double Balance;
      
      // Получили данные от Агента
      Container[0].Get(Str);
      Container[1].Get(Ticks);
      Container[2].Get(Balance);
      
//      FileWrite(handle, Pass);     // Если хочется записать номер прохода
      SaveData(Str, Ticks, Balance); // Данные будут записаны в MQL5\Files-папку Терминала (не Агента)
    }
  }
}
 
Пример штатного кодирования данных (красное - использование библиотеки)

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

Новая версия платформы MetaTrader 5 build 1640: создание и тестирование собственных финансовых инструментов

fxsaber, 2017.10.10 07:51

// Насколько жмутся MqlRates-данные и скорость упаковки/распаковки
#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

#define TOSTRING(A) #A + " = " + (string)(A) + "\n"

void OnStart()
{
  MqlRates Rates[];
  uchar Tmp[];  
  
  const int Amount = CopyRates(_Symbol, PERIOD_CURRENT, 0, Bars(_Symbol, PERIOD_CURRENT), Rates) * sizeof(MqlRates);  
  
  // Архивируем
  const ulong StartTime1 = GetMicrosecondCount();
  const int AmountZIP = CryptEncode(CRYPT_ARCH_ZIP, _R(Rates).Bytes, Tmp, Tmp);
  
  Print(TOSTRING(Amount) + TOSTRING(AmountZIP) + TOSTRING((double)Amount / AmountZIP) + TOSTRING(GetMicrosecondCount() - StartTime1));
  
  uchar Tmp2[];
  
  // Разархивируем
  const ulong StartTime2 = GetMicrosecondCount();
  CryptDecode(CRYPT_ARCH_ZIP, Tmp, Tmp2, Tmp2);
  Print(TOSTRING(GetMicrosecondCount() - StartTime2));
  
  Print(TOSTRING(_R(Rates) == Tmp2)); // Совпадают ли данные?
}
 
Использование библиотеки для помещения/извлечения любых данных в/из строки
// Кроссплатформенный пример передачи произвольных данных через пользовательское событие

#include <fxsaber\HistoryTicks\Data_String.mqh> // https://www.mql5.com/ru/code/20298

// Печать произвольных данных
template <typename T>
bool MyPrint( const T &Value )
{
  T Array[1];
  
  Array[0] = Value;
  
  ArrayPrint(Array, _Digits, NULL, 0, WHOLE_ARRAY, ARRAYPRINT_HEADER | ARRAYPRINT_ALIGN);
  
  return(true);
}

void OnChartEvent( const int id, const long &lparam, const double&, const string &sparam )
{
  // Распечатали полученные данные
  if ((id == CHARTEVENT_CUSTOM) &&
      (lparam ?  MyPrint(DATA_STRING::FromString<MqlDateTime>(sparam)) // Получили MqlDateTime
              : !MyPrint(DATA_STRING::FromString<MqlTick>(sparam))))   // Получили MqlTick
    ExpertRemove(); // Вышли из примера
}

void OnInit()
{
  MqlTick Tick;  
  MqlDateTime DateTime;
  
  // Заполнили значения
  SymbolInfoTick(_Symbol, Tick);  
  TimeCurrent(DateTime);

  // Передали
  EventChartCustom(0, 0, 0, 0, DATA_STRING::ToString(Tick));     // Передали MqlTick
  EventChartCustom(0, 0, 1, 0, DATA_STRING::ToString(DateTime)); // Передали MqlDateTime
}
 

Привет так все работает 

struct Message
  {
   int               cnt;
   bool              res;
   int               ter;
  };

#include <Exchange_Data.mqh>

#define AMOUNT 100

EXCHANGE_DATA<Message>ExchangeTicks(AMOUNT,true);
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   static Message Ticks[1];
   Ticks[0].cnt=1;
   Ticks[0].res=true;
   Ticks[0].ter=1;
   ExchangeTicks.DataSave(Ticks);
//---
   return(INIT_SUCCEEDED);
  }

так ерроры

struct Message
  {
   int               cnt;
   bool              res;
   int               ter;
   string            str;
  };

#include <Exchange_Data.mqh>

#define AMOUNT 1000

EXCHANGE_DATA<Message>ExchangeTicks(AMOUNT,true);
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   static Message Ticks[1];
   Ticks[0].cnt=1;
   Ticks[0].res=true;
   Ticks[0].ter=1;
   Ticks[0].str = "SDf";
   ExchangeTicks.DataSave(Ticks);
//---
   return(INIT_SUCCEEDED);
  }

взял отсюда для МТ4

https://www.mql5.com/ru/forum/5905/page11#comment_6134460
 
Aleksei Beliakov:

так ерроры

#define DEFINE_STRING(A)                        \
  struct STRING##A                              \
  {                                             \
  private:                                      \
    short Array[A];                             \
                                                \
  public:                                       \
    void operator =( const string Str )         \
    {                                           \
      ::StringToShortArray(Str, this.Array);    \
                                                \
      return;                                   \
    }                                           \
                                                \
    string operator []( const int = 0 ) const   \
    {                                           \
      return(::ShortArrayToString(this.Array)); \
    }                                           \
  };                                            
  
DEFINE_STRING(128) // Аналог строки, у которой максимум 128 символов.

#undef DEFINE_STRING

struct Message
  {
   int               cnt;
   bool              res;
   int               ter;
   STRING128         str;
  };
 

Код конветрирует структуру в строку

#include <Data_String.mqh>
#define DEFINE_STRING(A)                        \
  struct STRING##A                              \
  {                                             \
  private:                                      \
    short Array[A];                             \
                                                \
  public:                                       \
    void operator =( const string Str )         \
    {                                           \
      ::StringToShortArray(Str, this.Array);    \
      return;                                   \
    }                                           \
                                                \
    string operator []( const int = 0 ) const   \
    {                                           \
      return(::ShortArrayToString(this.Array)); \
    }                                           \
  };
DEFINE_STRING(120) // Аналог строки, у которой максимум 128 символов.
#undef DEFINE_STRING

struct str_Message
  {
   int               cnt;
   bool              res;
   double            ter;
   STRING120          str;
  };
void OnStart()
  {
//---
   str_Message a;
   a.cnt = 10;
   a.res = false;
   a.ter = 20.0123;
   a.str = "hello world";
   Print(DATA_STRING::ToString(str1););
  }

// Результат
//2020.03.31 10:43:18.320	StructTest2 (EURUSD,H1)	CgAAAAClvcEXJgM0QGgAZQBsAGwAbwAgAHcAbwByAGwAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Как сделать обратную конвертацию?  (из строки в структуру)

 
Sergey Likho:

Код конветрирует структуру в строку

Как сделать обратную конвертацию?  (из строки в структуру)

const string Str = DATA_STRING::ToString(a); // Перевели структуру в строку.

str_Message Tmp[1];

// Получили массив структур из строки
if (DATA_STRING::FromString(Str, Tmp))   
{
  ArrayPrint(Tmp);
  Print(Tmp[0].str[]);   
  
  Print(_R(Tmp) == a); // Убедились, что данные совпадают с исходными.
}

// Получили структуру из строки.
//   Tmp[0] = DATA_STRING::FromString<str_Message>(Str); // Так можно, если нет оператора присваивания (см. STRING120::operator =).
 
Еще одно применение возможностей библиотеки.