ライブラリ: TypeToBytes - ページ 5

 
fxsaber:
同じ結果の2行
ArrayCompare(Array1, Array2) == 0
_R(Array1) == Array2
 
// 単純構造体のプライベート・フィールドの読み書き

#include <TypeToBytes.mqh>

template <typename T>
struct STRUCT
{
private:
  T Data; // プライベート・フィールド
  
public:
  T GetData( void ) const
  {
    return(this.Data);
  }
};

void OnStart()
{    
  STRUCT<int> Struct = {0};  
  
  _W(Struct) = 2;          // プライベート・フィールドへの書き込みアクセス
  Print(Struct.GetData()); // であることを確認する。
  
  Print(_R(Struct)[0]);    // プライベート・フィールドへの読み取りアクセス
}
 
このライブラリでは、変数やその他の単純な型の配列を、指定された型の配列に格納するコンテナ・クラスを規定している。
// コンテナの使用例
#include <TypeToBytes.mqh>

#define  PRINT(A) Print(#A + " = " + (string)(A));

void OnStart()
{
  // サンプル用の任意のデータ
  string Str[] = {"123", "Hello World!"};
  double Num = 5;
  MqlTick Tick = {0};
  Tick.bid = 1.23456;
  
  CONTAINER<long> Container;  // コンテナを作成する - すべてを単純な型の配列に格納する(例ではlongを選択)。
  
  // 異なるデータでコンテナを満たす
  Container[0] = Str;
  Container[1] = Num;
  Container[2] = Tick;
  
  ArrayPrint(Container.Data); // コンテナがすべてのデータを格納する配列の内容を出力する。
  
  // コンテナに格納されているデータの種類を表示する。
  for (int i = 0; i < Container.GetAmount(); i++)
    PRINT(Container[i].GetType())
    
  // データそのものを取得しよう 
  string Str2[];
  Container[0].Get(Str2);                // 配列を取得
  ArrayPrint(Str2);
  
  PRINT(Container[1].Get<double>())      // 数字が出た
  PRINT(Container[2].Get<MqlTick>().bid) // 構造体ができた
  
  Container[1] = "Replace";   // インデックスでデータを置換
  
  // 交換が行われたことを確認する 
  PRINT(Container[1].GetType())
  PRINT(Container[1].Get<string>())
}
 
fxsaber:
このライブラリには、変数やその他の単純な型の配列を、指定された型の配列に格納するコンテナ・クラスが含まれている。

Report-bibleでの 実用例

異なるデータを持つフレームを送信する

        string Str;
        REPORT::ToString(Str);

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

      #ifdef __TYPETOBYTES__
        CONTAINER<uchar> Container;

        Container[0] = Str;     // コンテナにレポート文字列を入れる
        Container[1] = Balance; // 残高変更履歴の二重配列をコンテナにも追加。

        ::FrameAdd(NULL, 0, ::AccountInfoDouble(ACCOUNT_BALANCE), Container.Data); // 文字列レポートと残高配列を含むフレームを送信
      #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); // フレームから対応するダブル配列を取得

// .....
Report
Report
  • 2017.07.19
  • fxsaber
  • www.mql5.com
Библиотека для MetaTrader 4/5, которая позволяет формировать отчеты по истории торгов.
 
コンテナ・アプリケーションのもう一つの例

取引、自動取引システム、取引戦略のテストに関するフォーラム

MQL5 MT5 MetaTrader 5初心者からの質問

fxsaber, 2017.08.23 14:10

フレームモードを使って、エージェントデータを1つのファイルに書き込む必要があります。

// エージェントデータ(クラウドエージェントを含む)を1つのファイルに記録する例
input int Range = 0;

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

// Single RunまたはFrameモードでのみファイルを開く。
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); // 最後の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/ja/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); // データはエージェントのMQL5Filesフォルダに書き込まれます(ターミナルではありません)
    
    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); // データはターミナルのMQL5Filesフォルダに書き込まれます。
    }
  }
}
 
標準的なデータ・コーディングの例(赤 - ライブラリの使い方)

取引、自動取引システム、取引戦略のテストに関するフォーラム

MetaTrader 5ビルド1640の新バージョン:独自の金融商品の作成とテスト

fxsaber, 2017.10.10 07:51

// MqlRatesのデータとパッキング/アンパッキングの速度をどれだけ絞るか
#include <TypeToBytes.mqh> //https://www.mql5.com/ja/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/ja/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
}
 
簡単な使用例

取引、自動取引システム、取引戦略のテストに関するフォーラム

MetaTrader 5 build 1995のベータ版:経済カレンダー、サービスとしてのMQL5プログラム、R言語用API

fxsaber, 2019.02.18 16:36

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

int StringToShortArray2( const string Str, ushort &Array[], const int = 0, const int = 0 )
{
  const int Size = ArrayResize(Array, StringLen(Str));
  
  for (int i = 0; i < Size; i++)
    _W(Array[i]) = Str[i];
  
  return(Size);
}
 

やあ、うまくいっているんだね。

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

#include <Exchange_Data.mqh>

#define  AMOUNT 100

EXCHANGE_DATA<Message>ExchangeTicks(AMOUNT,true);
//+------------------------------------------------------------------+
//| カスタムインジケータ初期化関数
//+------------------------------------------------------------------+
int OnInit()
  {
//--- インジケータ・バッファのマッピング
   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);
//+------------------------------------------------------------------+
//| カスタムインジケータ初期化関数
//+------------------------------------------------------------------+
int OnInit()
  {
//--- インジケータ・バッファのマッピング
   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);
  }

MT4はここから入手しました。

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;
  };