English Русский 中文 Español Deutsch Português
グラフィカルインタフェースXI:標準グラフィックライブラリの統合(ビルド16)

グラフィカルインタフェースXI:標準グラフィックライブラリの統合(ビルド16)

MetaTrader 5 | 30 10月 2017, 09:18
745 0
Anatoli Kazharski
Anatoli Kazharski

コンテンツ


はじめに

シリーズ初めのグラフィカルインタフェース I: ライブラリストラクチャの準備(チャプター 1)稿ではライブラリの目的が詳細に考察されました。各章の末尾では、記事へのリンクの完全なリストを参照し開発の現段階でのライブラリの完全版をダウンロードすることができます。ファイルはアーカイブと同じディレクトリに配置される必要があります。

シリーズ第9部グラフィカルインタフェースIX:プログレスバーと折れ線グラフコントロール(チャプター2)では、折れ線グラフを作成するためのクラスをライブラリにどのように組み込むことができるかを示しました。これは一時的な解決策でした。ライブラリのこの部分の能力はまったく欠けていました。グラフィックライブラリの科学的なグラフを作成するための新バージョン( CGraphicクラス)が最近発表されました。このクラスの関数のいくつかは可視化の可能性 Rのプロットに似たMQL5のグラフィックス ライブラリで説明されています。今回のアップデートでは、グラフィカルインターフェイス作成のために開発された当ライブラリにグラフを作成するための新しいコントロールを備えたバージョンが導入されます。さまざまな種類のデータを視覚化することがさらに簡単になりました。


ライブラリスキームの変更

以前、開発されたライブラリは、描画用に設計されたCCanvasクラスのコピーを使用していました。ライブラリのコードは最近全体的にリファクタリングされたため、このコピーは不要になり、標準ライブラリの元のバージョンに置き換えて削除することができます。これにより、ライブラリのボリュームは10%減少し、リファクタリング前にグラフィカルインターフェイスXI:ライブラリコードのリファクタリング稿で提示されたバージョンに対しては40%減少しました。

グラフの作成にはCGraphicクラスが使用されるようになったので、Graphic.mqhファイルをObjects.mqhファイルにインクルードしますCCanvasクラスのファイルはGraphic.mqhファイルに含まれているファイルの1つに既に含まれているため、ライブラリ全体で使用できるようになります。

//+------------------------------------------------------------------+
//|                                                      Objects.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include "Enums.mqh"
#include "Defines.mqh"
#include "Fonts.mqh"
#include "Colors.mqh"
#include <Graphics\Graphic.mqh>
#include <ChartObjects\ChartObjectSubChart.mqh>
...

CLineChartクラスの名前はCGraphになり、内部コンテンツも変更されています。このクラスには、コントロールの一般的なプロパティと状態を管理するメソッドしか含まれていません。 

class CGraph : public CElement
  {
public:
   //--- グラフイベントの処理
   virtual void      OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
   //--- コントロールの移動
   virtual void      Moving(const bool only_visible=true);
   //--- 管理
   virtual void      Show(void);
   virtual void      Hide(void);
   virtual void      Reset(void);
   virtual void      Delete(void);
   //--- 最新の変更を適用する
   virtual void      Update(const bool redraw=false);
   //---
private:
   //--- サイズ変更
   void              Resize(const int width,const int height);
   //| ウィンドウの右端の幅を変更する              |
   virtual void      ChangeWidthByRightWindowSide(void);
   //--- ウィンドウの下端で高さを変更する
   virtual void      ChangeHeightByBottomWindowSide(void);
  };

グラフのプロパティは CGraphic::GetGraphicPointer()メソッドを使用して CGraphicクラスのインスタンスへのポインタを取得することによって制御できます。

class CGraph : public CElement
  {
private:
   //--- コントロール作成のためのオブジェクト
   CGraphic          m_graph;
   //---
public:
   //--- グラフポインタを返す
   CGraphic         *GetGraphicPointer(void) { return(::GetPointer(m_graph)); }
  };


CGraphicクラスにはグラフ軸のプロパティを管理するクラス(CAxis)と曲線のプロパティを管理するクラス(CCurve)が含まれています。 CColorGeneratorクラスは曲線の色の生成のために設計されています。これらのクラスはすべて、Graphic.mqhファイルに含まれている別々のファイルに含まれています。

//+------------------------------------------------------------------+
//|                                                      Graphic.mqh |
//|                   Copyright 2016-2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Arrays\ArrayObj.mqh>
#include "Curve.mqh"
#include "Axis.mqh"
#include "ColorGenerator.mqh"
...

CCanvasクラスのファイルはCurve.mqhファイルに含まれているため、ライブラリ全体で使用できるようになります。

//+------------------------------------------------------------------+
//|                                                        Curve.mqh |
//|                   Copyright 2016-2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Object.mqh>
#include <Canvas\Canvas.mqh>
...

上記のファイルとクラス間の相互接続は、すべて下の図に示されています。

 図1 標準ライブラリクラスと開発されたライブラリクラスの相互接続

図1 標準ライブラリクラスと開発されたライブラリクラスの相互接続


したがって、配列やファイルを扱うための標準ライブラリクラスは、それが使用されているアプリケーションのライブラリやファイルで自動的に利用できるようになります。本稿では、現在利用可能な新機能を理解するのに役立つように、いくつかのテストMQLアプリケーションをさらに詳しく説明します。


グラフプロパティをテストするアプリケーション

最初のMQLテストアプリケーションはCGraphic型グラフの特定のプロパティを管理するためのコントロールを備えたグラフィカルインタフェースを実装します。フォームの上部にはCTabs型のコントロールが位置します。この場合、これは4つのタブのグループです。ランダムに生成された値を持つ2つの曲線を持つグラフが、タブの作業領域の下に配置されます。

最初のタブ(背景)には、次のグラフプロパティを管理するコントロールがあります。

  • 背景色
  • グラフの主なテキスト(上部に表示)
  • グラフの補助テキスト(下部に表示)
  • 本文の色
  • 補助テキストの色
  • メインテキストのフォントサイズ
  • 補助テキストのフォントサイズ

CGraphicクラスはこれらのプロパティを設定/取得するためのpublicメソッドを提供します。

//+------------------------------------------------------------------+
//| CBackground構造体                                                 |
//| 使用法:二次元グラフィックの背景                                     |
//+------------------------------------------------------------------+
struct CBackground
  {
   uint              clr;
   uint              clr_main;
   uint              clr_sub;
   string            main;
   string            sub;
   int               size_main;
   int               size_sub;
  };
//+------------------------------------------------------------------+
//| CGraphicクラス                                                    |
//| 使用法:二次元グラフィック描画クラス                                 |
//+------------------------------------------------------------------+
class CGraphic
  {
protected:
   //--- グラフィック要素
   CBackground       m_background;           // 背景
   //---
public:
   //--- 背景プロパティを取得する
   uint              BackgroundColor(void)       const { return(m_background.clr);       }
   uint              BackgroundMainColor(void)   const { return(m_background.clr_main);  }
   uint              BackgroundSubColor(void)    const { return(m_background.clr_sub);   }
   string            BackgroundMain(void)        const { return(m_background.main);      }
   string            BackgroundSub(void)         const { return(m_background.sub);       }
   int               BackgroundMainSize(void)    const { return(m_background.size_main); }
   int               BackgroundSubSize(void)     const { return(m_background.size_sub);  }
   //--- 背景プロパティを設定する
   void              BackgroundColor(const uint clr)      { m_background.clr=clr;        }
   void              BackgroundMainColor(const uint clr)  { m_background.clr_main=clr;   }
   void              BackgroundSubColor(const uint clr)   { m_background.clr_sub=clr;    }
   void              BackgroundMain(const string main)    { m_background.main=main;      }
   void              BackgroundSub(const string sub)      { m_background.sub=sub;        }
   void              BackgroundMainSize(const int size)   { m_background.size_main=size; }
   void              BackgroundSubSize(const int size)    { m_background.size_sub=size;  }
  };

これは次のようになります。

 図2 テスト用MQLアプリケーションの最初のタブ(背景)のコントロール

図2 テスト用MQLアプリケーションの最初のタブ(背景)のコントロール


2番目のタブ(インデントと履歴)には、以下のプロパティを設定するためのコントロールが含まれます。

  • インデント(上下左右)
  • 凡例幅
  • 凡例のフォントサイズ
  • 凡例マーカーのサイズ
  • グラフのすべての要素に共通のインデント
  • グラフ軸の目盛りサイズ 

以下のCGraphicメソッドは、これらのプロパティを取得および設定するために使用できます。

//+------------------------------------------------------------------+
//| CCurveHistory構造体                                               |
//| 使用法:二次元グラフィックの曲線の履歴                                |
//+------------------------------------------------------------------+
struct CCurveHistory
  {
   int               name_width;
   int               name_size;
   int               symbol_size;
   int               count_total;
   int               count_points;
   int               count_lines;
   int               count_histogram;
   int               count_custom;
  };
//+------------------------------------------------------------------+
//| CGraphicクラス                                                    |
//| 使用法:二次元グラフィック描画クラス                                  |
//+------------------------------------------------------------------+
class CGraphic
  {
protected:
   //--- グラフィック要素
   CCurveHistory     m_history;              // 履歴
   //---
public:
   //--- インデントの取得/設定
   int               IndentUp(void)               const { return(m_up0);     }
   void              IndentUp(const int up)             { m_up0=up;          }
   int               IndentDown(void)             const { return(m_down0);   }
   void              IndentDown(const int down)         { m_down0=down;      }
   int               IndentLeft(void)             const { return(m_left0);   }
   void              IndentLeft(const int left)         { m_left0=left;      }
   int               IndentRight(void)            const { return(m_right0);  }
   void              IndentRight(const int right)       { m_right0=right;    }
   //--- ギャップの取得/設定 
   int               GapSize(void)           const { return(m_gap); }
   void              GapSize(const int size)       { m_gap=size;    }
   //--- メージャーマークサイズのの取得/設定
   int               MajorMarkSize(void)           const { return(m_mark_size); }
   void              MajorMarkSize(const int size)       { m_mark_size=size;    }
   //--- 曲線履歴プロパティを取得する
   int               HistoryNameWidth(void)            const { return(m_history.name_width);  }
   int               HistoryNameSize(void)             const { return(m_history.name_size);   }
   int               HistorySymbolSize(void)           const { return(m_history.symbol_size); }
   //--- 曲線履歴プロパティを設定する
   void              HistoryNameWidth(const int width) { m_history.name_width=width; }
   void              HistoryNameSize(const int size)   { m_history.name_size=size;   }
   void              HistorySymbolSize(const int size) { m_history.symbol_size=size; }
  };

以下はそれがテストMQLアプリケーションのグラフィカルインタフェースでどのように表示されるかを示します。

 図3 テスト用MQLアプリケーションの2番目のタブ(インデントと履歴)のコントロール

図3 テスト用MQLアプリケーションの2番目のタブ(インデントと履歴)のコントロール


3番目のタブ(グリッド)には、以下のグリッドプロパティを設定するためのコントロールが含まれます。

  • グリッド線の色
  • 軸ゼロラインの色
  • グリッドの背景色
  • グリッドノード内のドットの描画
  • 点の半径
  • 点の色

CGraphicクラスにはこれらのプロパティを取得して設定するための適切なメソッドがあります(下記のコードを参照)。

//+------------------------------------------------------------------+
//| CGrid構造体                                                       |
//| 使用法:二次元グラフィック上のグリッド                                |
//+------------------------------------------------------------------+
struct CGrid
  {
   uint              clr_line;
   uint              clr_background;
   uint              clr_circle;
   uint              clr_axis_line;
   uint              clr_frame;
   int               r_circle;
   bool              has_circle;
  };
//+------------------------------------------------------------------+
//| CGraphicクラス                                                    |
//| 使用法:二次元グラフィック描画クラス                                  |
//+------------------------------------------------------------------+
class CGraphic
  {
protected:
   //--- グラフィック要素
   CGrid             m_grid;                 // グリッド
   //---
public:
   //--- グリッドプロパティを取得する
   uint              GridLineColor(void)        const { return(m_grid.clr_line);       }
   uint              GridAxisLineColor(void)    const { return(m_grid.clr_axis_line);  }
   uint              GridBackgroundColor(void)  const { return(m_grid.clr_background); }
   int               GridCircleRadius(void)     const { return(m_grid.r_circle);       }
   uint              GridCircleColor(void)      const { return(m_grid.clr_circle);     }
   bool              GridHasCircle(void)        const { return(m_grid.has_circle);     }
   //--- グリッドプロパティを設定する
   void              GridLineColor(const uint clr)        { m_grid.clr_line=clr;       }
   void              GridAxisLineColor(const uint clr)    { m_grid.clr_axis_line=clr;  }
   void              GridBackgroundColor(const uint clr)  { m_grid.clr_background=clr; }
   void              GridCircleRadius(const int r)        { m_grid.r_circle=r;         }
   void              GridCircleColor(const uint clr)      { m_grid.clr_circle=clr;     }
   void              GridHasCircle(const bool has)        { m_grid.has_circle=has;     }
  };

最終的には次のようになります。

 図4 テスト用MQLアプリケーションの3番目のタブ(グリッド)のコントロール

図4 テスト用MQLアプリケーションの3番目のタブ(グリッド)のコントロール


4番目のタブ()にはグラフ軸のプロパティを管理するコントロールが配置されます。タブの作業領域の左側にあるラジオボタンを使用すると、特定の軸の設定を切り替えることができます。これらのボタンとタブの他のコントロールは区切り線で区切られています。

変更できるプロパティは次のとおりです。

  • 自動スケーリング
  • 最小軸値
  • 最大軸値
  • 最小軸の許容値
  • 最大軸の許容値
  • 軸番号のサイズ
  • 軸番号表示の最長
  • 軸名のフォントサイズ
  • 軸の初期ステップ値
  • 軸上の最大数
  • 軸名
  • 軸名のテキストの色

以下のリストは、上記のプロパティを取得および設定するためのCAxisクラスメソッドの名前を示しています。

//+------------------------------------------------------------------+
//| CAxisクラス                                                       |
//| 使用法:二次元グラフィックの軸を作成するクラス                         |
//+------------------------------------------------------------------+
class CAxis
  {
private:
   double            m_min;
   double            m_max;
   uint              m_clr;
   string            m_name;
   int               m_name_size;
   int               m_values_size;
   int               m_values_width;
   bool              m_auto_scale;
   double            m_default_step;   // デフォルトステップの長さ
   double            m_max_labels;     // 目盛りの最大数
   double            m_min_grace;      // 最小データ範囲に適用される猶予値
   double            m_max_grace;      //  最大データ範囲に適用される猶予値
   //---
public:
                     CAxis(void);
                    ~CAxis(void);
   //--- プロパティ
   double            Min(void)                  const { return(m_min);  }
   void              Min(const double min)            { m_min=min;      }
   double            Max(void)                  const { return(m_max);  }
   void              Max(const double max)            { m_max=max;      }
   string            Name(void)                 const { return(m_name); }
   void              Name(const string name)          { m_name=name;    }
   //--- デフォルトプロパティ 
   uint              Color(void)                        const { return(m_clr);            }
   void              Color(const uint clr)                    { m_clr=clr;                }
   bool              AutoScale(void)                    const { return(m_auto_scale);     }
   void              AutoScale(const bool auto)               { m_auto_scale=auto;        }
   int               ValuesSize(void)                   const { return(m_values_size);    }
   void              ValuesSize(const int size)               { m_values_size=size;       }
   int               ValuesWidth(void)                  const { return(m_values_width);   }
   void              ValuesWidth(const int width)             { m_values_width=width;     }
   int               NameSize(void)                     const { return(m_name_size);      }
   void              NameSize(const int size)                 { m_name_size=size;         }
   double            DefaultStep(void)                  const { return(m_default_step);   }
   void              DefaultStep(const double value)          { m_default_step=value;     }
   double            MaxLabels(void)                    const { return(m_max_labels);     }
   void              MaxLabels(const double value)            { m_max_labels=value;       }
   double            MinGrace(void)                     const { return(m_min_grace);      }
   void              MinGrace(const double value)             { m_min_grace=value;        }
   double            MaxGrace(void)                     const { return(m_max_grace);      }
   void              MaxGrace(const double value)             { m_max_grace=value;        }
  };

結果は下に示されています。

 図5 テスト用MQLアプリケーションの4番目のタブ(軸)のコントロール

図5 テスト用MQLアプリケーションの4番目のタブ(軸)のコントロール


本稿で紹介されたテストアプリケーションをさらに研究するためには、以下のリンクを使用してダウンロードしてください。


グラフ曲線プロパティをテストするアプリケーション

CGraphic型のグラフ曲線の特定の特性をテストするためには別のMQLアプリケーションが作成されています。グラフ曲線のプロパティを管理するコントロールは、このアプリケーションのフォームの最上部に配置され、真下には CGraphic型の2つのグラフ(CGraphコントロール) があります。最初のグラフはランダムなデータを含む系列を表示し、2番目のグラフはMomentum指標の式に基づいて計算されたその導関数をプロットします。

グラフ曲線のプロパティを管理するためのコントロールは次のとおりです。

  • Animateチェックボックス - グラフへのデータの自動入力を開始する
  • Array size スピンエディットボックス - グラフに表示されているデータ配列内の要素の現在の数
  • Randomボタン - グラフ上にランダムなデータシーケンスを連続して生成する
  • Period スピン編集ボックス - モーメンタム指標を計算する変数の値
  • Curve type コンボボックス - グラフ曲線の型
  • Point type コンボボックス - グラフ曲線をプロットするために使用されるデータポイントの型

アプリケーション (CProgram) iのカスタムクラスは、上記のコントロールに関連するメソッドを実装し、以下のタスクを実行します。

  • グラフに表示するデータ配列のサイズの設定
  • データによる配列の初期化
  • 最近の変更を反映するためのグラフの更新
  • 配列の最後に1つの要素を追加
  • 配列の最後の1つの要素を削除
  • グラフをタイマーで更新
  • 新しいデータの自動入力によるグラフのアニメーション化

以下は、これらの機能を実装するすべてのメソッドのコード一覧です。これらのメソッドのコードの詳細については、本稿末尾にあるファイルをダウンロードしてください。

class CProgram : public CWndEvents
  {
protected:
   //--- グラフの出力の配列データ
   double            data1[];
   double            data2[];
   //---
   double            data3[];
   double            data4[];
   //---
private:
   //--- 配列のサイズを変更する
   void              ResizeGraph1Arrays(void);
   void              ResizeGraph2Arrays(void);
   void              ResizeGraph1Arrays(const int new_size);
   void              ResizeGraph2Arrays(const int new_size);
   //--- 配列の初期化
   void              InitGraph1Arrays(void);
   void              InitGraph2Arrays(void);
   //--- 配列をゼロにする
   void              ZeroGraph1Arrays(void);
   void              ZeroGraph2Arrays(void);
   //--- 指定されたインデックスで乱数値を設定する
   void              SetGraph1Value(const int index);
   void              SetGraph2Value(const int index);
   //--- グラフの系列を更新する
   void              UpdateGraph(void);
   void              UpdateGraph1(void);
   void              UpdateGraph2(void);
   
   //--- グラフの系列を再計算する
   void              RecalculatingSeries(void);
   //--- 配列の最後にもう一つの値を加える
   void              AddValue(void);
   //--- 配列の最後の1つの要素を削除する
   void              DeleteValue(void);

   //--- グラフをタイマーで更新する
   void              UpdateGraphByTimer(void);
   //--- グラフの系列をアニメーション化する
   void              AnimateGraphSeries(void);
  };

これは次のようになります。

 図6 グラフ曲線のプロパティをテストするためのアプリケーションのグラフィカルインタフェース

図6 グラフ曲線のプロパティをテストするためのアプリケーションのグラフィカルインタフェース


本稿で紹介されたテストアプリケーションをさらに研究するためには、以下のリンクを使用してダウンロードしてください。


内サイクロイドのグラフをアニメーション化するアプリケーション

John Walkenbach氏はVBAプログラミングに関する著書の1つで、読者にテストファイルのCDを提供しています。ファイルの1つは、無限数の内サイクロイドを生成する図を実装します。 

参考のために、ウィキペディアでは次の定義が与えられています。

内サイクロイド(ギリシャ語で「下」を意味する ὑπό と 「円、円周」を意味するκύκλος から)は大きな円の中を転がる小さな円の定点の軌跡によって生成された特殊な平面曲線です。

John Walkenbach氏著作の本で与えられた定義は下記です。

内サイクロイド - 別の円の中を回転する円上の点によって形成される経路

MQLで同様のアプリケーションを実装して、パラメータ管理用のグラフィカルインタフェースを追加し、それがどのように機能するかを詳しく見てみましょう。

新しい内サイクロイドを生成するためには3つの、指定されたステップで数値シーケンスを初期化するためのパラメータが使用されます。次に、グラフ上の点の座標を得るために、これらのシーケンスの値に基づいて計算が実行されます。その後、得られた結果を正規化します。

カスタムクラスでは、複数の配列を宣言してシーケンスとフィールドを計算し、平均と標準偏差を計算します。

//+------------------------------------------------------------------+
//|                                                      Program.mqh |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Math\Stat\Stat.mqh>
#include <EasyAndFastGUI\WndEvents.mqh>
#include <EasyAndFastGUI\TimeCounter.mqh>
//+------------------------------------------------------------------+
//| アプリケーション作成のクラス                                        |
//+------------------------------------------------------------------+
class CProgram : public CWndEvents
  {
protected:
...
   //--- 計算データ配列
   double            a_inc[];
   double            b_inc[];
   double            t_inc[];
   double            x_source[];
   double            y_source[];
   //--- グラフの出力の配列データ
   double            x_norm[];
   double            y_norm[];
   //--- 平均と標準偏差の計算
   double            x_mean;
   double            y_mean;
   double            x_sdev;
   double            y_sdev;
...
  };
//+------------------------------------------------------------------+
//| コンストラクタ                                                     |
//+------------------------------------------------------------------+
CProgram::CProgram(void) : x_mean(0),
                           y_mean(0),
                           x_sdev(0),
                           y_sdev(0)
  {
...
  }

値はCProgram::InitArrays()メソッドで計算されます。1番目のループは初期データを計算します。その後、平均と標準偏差が得られ、2番目のループでデータが正規化されます。配列のサイズはCProgram::ResizeArrays()メソッドを使用して設定します。配列サイズの値は、アプリケーションのグラフィカルインタフェースのテキストボックスコントロール (CTextEdit) から取得されます。

class CProgram : public CWndEvents
  {
private:
   //--- 配列のサイズを変更する
   void              ResizeArrays(void);
   //--- 計算のための補助的な配列の初期化
   void              InitArrays(void);
  };
//+------------------------------------------------------------------+
//| 配列のサイズを変更する                                              |
//+------------------------------------------------------------------+
void CProgram::ResizeArrays(void)
  {
   int array_size =::ArraySize(x_norm);
   int new_size   =(int)m_array_size.GetValue();
//--- サイズが変わっていない場合は終了する
   if(array_size==new_size)
      return;
//--- 新しいサイズを設定する
   ::ArrayResize(a_inc,new_size);
   ::ArrayResize(b_inc,new_size);
   ::ArrayResize(t_inc,new_size);
   ::ArrayResize(x_source,new_size);
   ::ArrayResize(y_source,new_size);
   ::ArrayResize(x_norm,new_size);
   ::ArrayResize(y_norm,new_size);
  }
//+------------------------------------------------------------------+
//| 配列の初期化                                                      |
//+------------------------------------------------------------------+
void CProgram::InitArrays(void)
  {
//--- 配列のサイズを変更する
   ResizeArrays();
//--- 式を使って値を計算する
   int total=(int)m_array_size.GetValue();
   for(int i=0; i<total; i++)
     {
      if(i<1)
        {
         a_inc[i] =1+(double)m_animate.GetValue();
         b_inc[i] =1+(double)m_animate.GetValue();
         t_inc[i] =1+(double)m_animate.GetValue();
        }
      else
        {
         a_inc[i] =a_inc[i-1]+(double)m_a_inc.GetValue();
         b_inc[i] =b_inc[i-1]+(double)m_b_inc.GetValue();
         t_inc[i] =t_inc[i-1]+(double)m_t_inc.GetValue();
        }
      //---
      double a=a_inc[i];
      double b=b_inc[i];
      double t=t_inc[i];
      //---
      x_source[i] =(a-b)*cos(t)+b*cos((a/b-1)*t);
      y_source[i] =(a-b)*sin(t)+b*sin((a/b-1)*t);
     }
//--- 平均を計算する
   x_mean=MathMean(x_source);
   y_mean=MathMean(y_source);
//--- 標準偏差を計算する
   x_sdev=MathStandardDeviation(x_source);
   y_sdev=MathStandardDeviation(y_source);
//--- ゼロによる除算を無効にするための調整
   x_sdev =(x_sdev==0)?1 : x_sdev;
   y_sdev =(y_sdev==0)?1 : y_sdev;
//--- データを正規化する
   for(int i=0; i<total; i++)
     {
      x_norm[i] =(x_source[i]-x_mean)/x_sdev;
      y_norm[i] =(y_source[i]-y_mean)/y_sdev;
     }
  }

CGraphicクラスには、作成されたグラフの作業領域内の軸の目盛りにノッチ、線、テキストを追加できるメソッドが含まれています。

この場合CProgram::TextAdd() メソッドを使用して、図の左上隅のXおよびY シーケンスの平均と標準偏差の値を出力します。CGraphic::ScaleX()メソッドとCGraphic::ScaleY()メソッドは、図の極点(左上隅)の座標を取得するために使用されます。これらのメソッドは実際のグラフの値をピクセル座標にスケーリングするように設計されています。ここではX軸に沿った最小値とY軸に沿った最大値が実際の値として与えられます。 

class CProgram : public CWndEvents
  {
private:
   //--- グラフにテキストを追加
   void              TextAdd(void);
  };
//+------------------------------------------------------------------+
//| グラフにテキストを追加                                              |
//+------------------------------------------------------------------+
void CProgram::TextAdd(void)
  {
//--- グラフへのポインタを取得する
   CGraphic *graph=m_graph1.GetGraphicPointer();
//---  
   int  x     =graph.ScaleX(graph.XAxis().Min())+50;
   int  y     =graph.ScaleY(graph.YAxis().Max())+10;
   int  y2    =y+20;
   uint clr   =::ColorToARGB(clrBlack);
   uint align =TA_RIGHT;
//---
   string str[8];
   str[0] ="x mean:";
   str[1] ="y mean:";
   str[2] =::DoubleToString(x_mean,2);
   str[3] =::DoubleToString(y_mean,2);
   str[4] ="x sdev:";
   str[5] ="y sdev:";
   str[6] =::DoubleToString(x_sdev,2);
   str[7] =::DoubleToString(y_sdev,2);
//--- 座標を計算してグラフにテキストを出力する
   int l_x=0,l_y=0;
   for(int i=0; i<8; i++)
     {
      if(i<2)
         l_x=x;
      else if(i<6)
         l_x=(i%2==0)?l_x+50 : l_x;
      else
         l_x=(i%2==0)?l_x+60 : l_x;
      //---
      l_y=(i%2==0)?y : y2;
      //---
      graph.TextAdd(l_x,l_y,str[i],clr,align);
     }
  }

必要なデータがすべてグラフに設定された場合、最新の変更を反映するための再描画が必要です。これはCProgram::UpdateSeries()メソッドで行われます。ここでは初めにグラフに系列があるかどうかを確認します。ある場合は最後に計算されたデータを設定します。さらに、曲線のプロパティは、グラフィカルインターフェイスのコントロールを使用して設定されます。ここでは (1) ラインの平滑化、 (2) 点の種類 、(3) 曲線の種類です。テキストは、他のすべてのプロパティとデータが設定されレンダリングされた後にグラフに適用されるべきであることに注意してください。最後に、結果を見るためにグラフを更新する必要があります。

class CProgram : public CWndEvents
  {
private:
   //--- グラフで系列を設定して更新する
   void              UpdateSeries(void);
  };
//+------------------------------------------------------------------+
//| グラフで系列を設定して更新する                                       |
//+------------------------------------------------------------------+
void CProgram::UpdateSeries(void)
  {
//--- グラフへのポインタを取得する
   CGraphic *graph=m_graph1.GetGraphicPointer();
//--- グラフで系列を設定して更新する
   int total=graph.CurvesTotal();
   if(total>0)
     {
      //--- 曲線ポインタを取得するr
      CCurve *curve=graph.CurveGetByIndex(0);
      //--- データ配列を設定する
      curve.Update(x_norm,y_norm);
      //--- 曲線プロパティの値を取得する
      ENUM_CURVE_TYPE curve_type =(ENUM_CURVE_TYPE)m_curve_type.GetListViewPointer().SelectedItemIndex();
      ENUM_POINT_TYPE point_type =(ENUM_POINT_TYPE)m_point_type.GetListViewPointer().SelectedItemIndex();
      //--- プロパティを設定する
      curve.LinesSmooth(m_line_smooth.IsPressed());
      curve.PointsType(point_type);
      curve.Type(curve_type);
     }
//--- 適用 
   graph.Redraw(true);
//--- テキストを出力する
   TextAdd();
//--- グラフをリフレッシュする
   graph.Update();
  }

CProgram::RecalculatingSeries() メソッドを使用して、取得した結果を1回の呼び出しで計算して適用します。

class CProgram : public CWndEvents
  {
private:
   //--- グラフの系列を再計算する
   void              RecalculatingSeries(void);
  };
//+------------------------------------------------------------------+
//| グラフの系列を再計算する                                            |
//+------------------------------------------------------------------+
void CProgram::RecalculatingSeries(void)
  {
//--- 値を計算して配列を初期化する
   InitArrays();
//--- 系列を更新する
   UpdateSeries();
  }

これらの式に基づいてプロットされた図は、アニメーション化されるともっと面白く見えます。計算されたシーケンスを動かして設定するには、これらのシーケンスの初期値を変更する必要があります。これは、スピンエディットボックスで値を入力するか、プロセスを自動モードで実行することで実現できます。自動モードでは、このエディットボックスの値はCProgram::AnimateGraphSeries()メソッドでインクリメントまたはデクリメントされます。このメソッドは、アプリケーションタイマーで呼び出されるCProgram::UpdateGraphByTimer()メソッドで呼び出されます。

class CProgram : public CWndEvents
  {
private:
   //--- グラフをタイマーで更新する
   void              UpdateGraphByTimer(void);
   //--- グラフの系列をアニメーション化する
   void              AnimateGraphSeries(void);
  };
//+------------------------------------------------------------------+
//| タイマー                                                          |
//+------------------------------------------------------------------+
void CProgram::OnTimerEvent(void)
  {
   CWndEvents::OnTimerEvent();
//--- グラフをタイマーで更新する
   if(m_counter1.CheckTimeCounter())
     {
      UpdateGraphByTimer();
     }
...
  }
//+------------------------------------------------------------------+
//| グラフをタイマーで更新する                                          |
//+------------------------------------------------------------------+
void CProgram::UpdateGraphByTimer(void)
  {
//---  (1) フォームが最小化されているかまたは (2) アニメーションが無効な場合は終了する
   if(m_window.IsMinimized() || !m_animate.IsPressed())
      return;
//--- グラフの系列をアニメーション化する
   AnimateGraphSeries();
//--- グラフの配列と系列を更新する
   RecalculatingSeries();
  }
//+------------------------------------------------------------------+
//| グラフの系列をアニメーション化する                                   |
//+------------------------------------------------------------------+
void CProgram::AnimateGraphSeries(void)
  {
//--- 配列のサイズを変更する方向を指定する
   static bool counter_direction=false;
//--- 最小に達した場合は方向を切り替える
   if((double)m_animate.GetValue()<=(double)m_animate.MinValue())
      counter_direction=false;
//--- 最大に達した場合は方向を切り替える
   if((double)m_animate.GetValue()>=(double)m_animate.MaxValue())
      counter_direction=true;
//--- 指定された方向に配列をサイズ変更する
   string value="";
   if(!counter_direction)
      value=string((double)m_animate.GetValue()+m_animate.StepValue());
   else
      value=string((double)m_animate.GetValue()-m_animate.StepValue());
//--- 新しい値を設定してテキストボックスを更新する
   m_animate.SetValue(value,false);
   m_animate.GetTextBoxPointer().Update(true);
  }

得られた結果は下に示されています。

 図7 内サイクロイドのアニメーション化の実証

図7 内サイクロイドのアニメーション化の実証


本稿で紹介されたテストアプリケーションをさらに研究するためには、以下のリンクを使用してダウンロードしてください。


以前のアップデートのテストアプリケーションの新バージョン

グラフィカルインタフェースIX:プログレスバーと折れ線グラフコントロール(チャプター2)本稿で実証されたテストアプリケーションは、こんかいのアップデートに従って更新されました。

以下に、更新されたグラフィカルインタフェースを持つこのMQLアプリケーションの新しいバージョンを示します。

 図8 以前のアップデートのテストアプリケーションの新しいバージョン

図8 以前のアップデートのテストアプリケーションの新しいバージョン


本稿で紹介されたテストアプリケーションをさらに研究するためには、以下のリンクを使用してダウンロードしてください。


おわりに

本稿では、科学的なグラフをプロットするための標準ライブラリの一部を、グラフィカルインターフェイスを作成するために開発されたライブラリに統合しました。実証されたすべての例は、本稿に添付されたファイルからダウンロードして、ソースコードを詳しく調べることができます。

ライブラリは現在の開発段階では下図のようになります。

 図9 開発の現段階でのライブラリの構造

図9 開発の現段階でのライブラリの構造


提示されたライブラリのコードは無料です。プロジェクト(商用目的のものを含む)での使用が可能で、記事の執筆や受注製品における使用も可能です。

本稿の資料の使用について質問がある場合は、コメント欄でお問い合わせください。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/3527

添付されたファイル |
CGraphic ライブラリを使用したスキャルピング相場深度の実装 CGraphic ライブラリを使用したスキャルピング相場深度の実装
この記事では、スキャルピング相場深度ツールの基本的な関数を作成します。 また、CGraphic ライブラリーをベースにしたティック・チャートを開発し、オーダーブックと統合します。 記述された相場深度を使用して、短期トレードの強力なアシスタントツールを作成することが可能になります。
ユニバーサルEA: CUnIndicator と予約オーダーの使用 (その 9) ユニバーサルEA: CUnIndicator と予約オーダーの使用 (その 9)
この記事では、ユニバーサル CUnIndicator クラスを通じたインジケーターのタスクについて説明します。 さらに、予約オーダーを処理する新しいメソッドを考慮します。 注意: この時点でCStrategy プロジェクトの構造は、実質的な変更を受けています。 すべてのファイルは、ユーザーの利便性のため単一のディレクトリに配置されています。
クロスプラットフォームEA: カスタムストップ、ブレイクイーブン、トレーリング クロスプラットフォームEA: カスタムストップ、ブレイクイーブン、トレーリング
この記事では、クロスプラットフォームEAでのカスタムストップレベルの設定方法について説明します。 また、時間の経過とともにストップレベルを設定するメソッドについても説明します。
ディープニューラルネットワーク(その4)ニューラルネットワークモデルの作成、訓練、テスト ディープニューラルネットワーク(その4)ニューラルネットワークモデルの作成、訓練、テスト
本稿では、darchパッケージ(v.0.12.0)の新しい機能について考察し、異なるデータタイプ、構造及び訓練シーケンスを有するディープニューラルネットワーク訓練を説明します。訓練結果も含まれています。