English Русский 中文 Español Deutsch Português
CCanvas Classを使ったメーターの描写

CCanvas Classを使ったメーターの描写

MetaTrader 5 | 9 3月 2016, 08:56
1 002 0
Serhii Shevchuk
Serhii Shevchuk

コンテンツ一覧

イントロダクション

CCanvasクラスについて知ったとき、今回の件についてひらめきました。そして、もし実際に何かに利用するとしたら、メーターインジケーターを描写するというアイディアに至りました。最初に開発したものはひどいものでしたが、新要素などにより、次第に見た目も良くなりました。結果的に、インジケーターやEAに簡単に実装できるメーターの簡易なライブラリになりました。今回の記事では、メーターの構造の説明、ビジュアルの描写と設定の関数、強度の評価を行います。

メーター

図1. メーター


1. 座標とアンカー

チャートにメーターを表示する方法には2通りあります。: 絶対位置と相対位置。

絶対的なポジショニングの場合、角からのX軸、Y軸の距離での指定になります。

相対的なポジショニングの場合、座標の原点は、相対的な位置の指定されたタイプに応じて作成されます。鉛直タイプを選択すると、原点が基準オブジェクトの下または上に配置されます。(上部または下部アンカーがそれぞれ選択されている場合)水平タイプを選択すると、アンカーからの左または右に配置されます。この場合、指定された座標は元の原点からの差を表します。プラスの差は、関連のオブジェクトから遠ざけます。マイナスの差は、関連のオブジェクトの内部に入り込みます。

関連オブジェクトは他のメーターによって表示させます。どちらのオブジェクトも同じアンカーコーナーを使います。

図2 は相対配置の一例です。

相対配置

図2. メーターの相対配置

各メーターの設定を見てみましょう。:

  • "gg01" メーター: 相対位置はできません。水平オフセット — 40, 鉛直オフセット — 40.
  • "gg02" メーター: 相対配置 — 水平関連オブジェクト — "gg01". 座標のローカルの原点からの水平オフセット(ポイントA) — 15, 鉛直オフセット — 0.
  • "gg03" メーター: 相対配置 — 鉛直, 関連オブジェクト — "gg01". ローカルの座標原点からの水平オフセット (ポイントB) — 0, 鉛直オフセット — 15.
  • "gg04"メーター: 相対配置 — 鉛直, 関連オブジェクト — "gg02". 水平座標のローカル原点(点C)からのオフセット — 50, 垂直オフセット — 15.

相対的な位置決めを行うと、チャートの入力設定メーターを含むいくつかのインジケータがある場合、容易です。1ゲージのサイズを変更すると、他のゲージの座標も自動的に計算されます.

GaugeCreate()関数は、位置決めタイプと座標を設定します。


2. 計測器要素

ダイヤルゲージは2つのグラフィカルオブジェクトで構成されています。そのうちの1つは、スケールレイヤーと呼ばれています。もう一つはニードルレイヤーと呼ばれています。どちらのグラフィカルオブジェクトも、同じ座標を持っています。ニードルレイヤーはスケールレイヤーの上に配置されます。入力パラメータに設定されたメーターの名前は、両方のオブジェクトの名前の接頭辞として働きます. 例えば、メーターの名前が"Gauge01"の場合、スケールレイヤーは "Gauge01_s"となり、ニードルレイヤーは"Gauge01_n"となります。

図3は、メーターの構造です。

図3. メーターの構造

図3. メーターの構造

スケールレイヤーが含むもの:

  • ボーダー(1)
  • 目盛マーク (5, 6, 7)
  • 目盛のラベル (4)
  • 強調された範囲 (2, 12)
  • 文字 (3, 10, 11)

文字は意図に応じて区別します:

  • メーター表示 (3)
  • 単位(11)
  • 現在値 (10)
  • スケールラベルの倍率 (省略)

メモリは下記に分けます:

  • メジャー (7)
  • ミドル (5)
  • マイナー (6)

メジャー目盛りだけがラベル付きです。目盛り単位は、整数で設定します。ミドル単位は、メジャーの中間マークの指定した数に応じて計算されます。マイナー単位は、ミドルのものとの間のマイナーマークの指定した数に応じて計算されます。マイナーとミドルの目盛りは省略可能です。

ニードルレイヤーが含むもの:

  • 針 (8)
  • 針の中心 (9)


2.1. サイズ

図3は、いくつかのメーター要素の大きさを示しています。:

  • d — メーターの外部輪郭の直径に対応するメーターサイズ
  • b — ボーダーサイズ
  • g — ボーダーとスケール要素の間のスペースのサイズ
  • c — 針の中心のサイズ

NB. メーターの直径のサイズはピクセル単位で設定されています。("d" 図3). 他のすべての要素とフォントは、条件毎に設定され、その大きさは直径の割合として計算されます。サイズ変更を容易にするために行われます。直径を変更した場合、他のすべてのサイズが比例し再計算されます。. 演算係数は、マクロ置換セクションにリスト化され、ユーザーが後から変更することができます。


2.2. 形状

円形とセクター:メーターの本体形状には2つのタイプがあります。<A0>スケールの範囲</ A0>の角度が180度未満である場合に扇形の方が便利です。

メーターの形状

図4. メーターの形状

図4は、一周のメーター(a)と2つの扇形状のゲージを示しています(b、c)。GaugeSetCaseParameters() 関数は、望んだ形状を設定するために使用されます。


2.3. スケール

これは、メーターの最も重要な要素です。データの読みやすさは、その外観が重要です。メーターは過度に複雑だと困りますが、しかし、十分な情報を含む必要があります。メーターの極端な値はもちろん、メジャーマークには、特別な注意表示が必要です。GaugeSetScaleParameters() 関数は、スケールの範囲、その回転と極値(最小値と最大値)を設定することができます。最小値は左(ダイレクトオーダー)または右(逆順)に設定することができます.

スケールレンジは、両極の2つの値による角度です。これは、図5の通りです。

スケールレンジ

図5. スケールレンジ

スケールの回転は上向きと垂直ゲージの中心から来る線からのスケール範囲の角度二等分線の偏角です。これは図6の通りです。

回転角

図6. 回転角

スケール範囲の角度と回転角度を組み合わせることにより、非常に柔軟な方法でゲージ外観の設定をすることができます。図4(c)は、90度の範囲、45度の回転を実証したものです。

最大値と最小スケール値は、表示された変数の許容値の範囲に応じて選択される重要なパラメータです。ゼロマークは、利便性に応じて省略することができます。400から600までの範囲での変数が変わる場合、ゼロからスケールを描画しても意味がありません。図7は、いくつかの最大の例と最小スケール値です。

最大最小スケール

図7. 最大最小スケール

  • a) 0 から500までの値 ダイレクトオーダー
  • b) -200 から400までの値 ダイレクトオーダー
  • c) -400 から 0 までの値 ダイレクトオーダー
  • d) 500 から 0 までの値 逆順
  • e) 200 から 800 までの値 ダイレクトオーダー
  • f) 0 から -800 までの値 逆順


2.4. 目盛線

目盛り設定は、マークのサイズと整列メソッドの選択にあります。

整列は次のようにします:

  • スケールの内側
  • スケールの外側
  • センター

図8は、整列の目盛線の例です:

  • a — センター
  • b — 内側
  • c — 外側

GaugeSetMarkParameters()関数は、設定で使います。

マークのラベルの位置は、GaugeSetScaleParameters()関数を使用して調整されます。

図8(a)は、スケール内部図8(b)及び図8(c)の位置決めの例です。

ラベルはあまり多くのスペースを占有しないので、すべての表示する値は、分割される係数multiplierを使用することを推奨します。乗算値は、0.0001から10000までの値にすることができます。図4(c)は、1桁の数字の代わりに、3桁の数字を使かえる100に等しい乗数を適用した例です。図1は、ラベル内の小数点とゼロを使用することを許可されていないATRに、0.0001を使用する状況を示しています。GaugeSetScaleParameters()関数は乗算値をセットします。

マークとラベルの配置

図8. マークとラベルの配置


2.5. 凡例

文字は、補足情報を表示するためのものであり、四種類のものが可能です。:

  • メーター説明
  • 単位
  • 現在値
  • 乗算値

任意の文字を非表示にすることができます。メーターの説明はデフォルトで表示されます。

文字の位置決めは、角と半径で設定します。角は度数で設定し、その値はメーターの中心からくる上方向の鉛直にあるラインと、メーターの中心と文字の中心を結ぶ仮想セグメントの角に等しくなります。半径は、条件毎に設定します。0 から 10の値を取ります。0が針中心の半径に対応し、10はスケールの外側半径に対応します。

図9は、凡例です。

  • "利益"の文字(メーター説明)は次の座標があります。:角 - 0、半径 - 3。
  • "0.00"の文字(現在値)には、次の座標があります:角 - 225、半径 - 4.
  • "USD"の文字(測定単位)は、座標は次の通りです:角 - 215、半径 - 8。

GaugeSetLegendParameters()関数は、文字パラメータを設定するために使用します。

文字座標

図9. 文字座標

NB. 文字は、スケール上に固定されておらず、その角度は、スケール、回転角度と接続されていません。


2.6. ハイライト付き範囲s

強調表示されたデータ範囲は、任意のメーターの固有の要素を表します。値が異常な値または特別な範囲に入ったことを確認するために役立ちます。GaugeSetRangeParameters()関数は、4つの強調表示された範囲に設定することができます。このためには、ハイライト用に極端な値と色を設定する必要があります。図1は、二つの強調表示された範囲での利益の指標を示しています。:緑色の範囲は、400から200が利益を固定するための時間で、オレンジの範囲は-400-200から大きなドローダウンの警告です。


2.7. 針

GaugeSetNeedleParameters() 関数は、針の中心部の大きさや面積の塗りの種類を設定します。ニードルレイヤーが完全にデータ更新後に毎回再描画されるように、エリアタイプはインジケータの感度に影響を与えます。図10は、エリアの塗りつぶしの例を示しています。

  • アンチエイリアシアルゴリズムを使用して針を描写(a)
  • アンチエイリアスアルゴリズムを使用することなく、針を描写(b)
  • アンチエイリアスで針を満たさない(c)

針のエリアの塗りつぶし方法

図10. 針のエリアの塗りつぶし方法

それぞれの方法の長所と短所は、CCanvasクラスとリソースの感度評価のセクションで説明します。


3. 関数

テーブル1は、メーターを描写する関数と見た目の設定のリストです。

関数
見た目
GaugeCalcLocation
メーターの中心座標の計算
GaugeCreate
メーターの生成
GaugeDelete
メーターの削除
GaugeNewValue
針の位置と値を更新
GaugeRedraw
メーターの再描写
GaugeRelocation
チャート上のゲージオブジェクトの位置の変更
GaugeSetCaseParameters
メーターパラメータの設定
GaugeSetLegendParameters
文字パラメータの設定
GaugeSetMarkLabelFont
目盛りフォントの設定
GaugeSetMarkParameters
目盛りパラメーターの設定
GaugeSetNeedleParameters
針パラメータの設定
GaugeSetRangeParameters
範囲パラメータの設定
GaugeSetScaleParameters
スケールパラメータの設定

テーブル1. 関数リスト

それぞれの関数の詳細を見てみましょう。初期化時に、それらを呼び出す推奨の順番です。


3.1. GaugeCreate

メーターの生成

bool GaugeCreate(
   string name,              // メーター名
   GAUGE_STR &g,             // メーター構造の参照
   int x,                    // アンカーコーナーからの水平インデント
   int y,                    // アンカーコーナーからの鉛直インデント
   int size,                 // メーターサイズ
   string ObjRel,            //位置が設定されているグラフィカルオブジェクト名
   ENUM_REL_MODE rel_mode,   // 相対配置
   ENUM_BASE_CORNER corner,  // アンカーコーナー
   bool back,                //背景のオブジェクト
   uchar scale_transparency, //スケール透明度
   uchar needle_transparency //針透明度 
 );

パラメータ

 名称

   [in]  メーター名メーターを構成するグラフィカルオブジェクトの名前の接頭辞として使用

 g

   [out]  メーター構造の参照

 x

   [in]  X軸に沿ったアンカーコーナーからの距離(ピクセル単位)相対的な位置決めの場合 — 座標のローカル原点からの距離.

 y

   [in]  Y軸に沿ったアンカーコーナーからの距離(ピクセル単位)相対的な位置決めの場合 — 座標のローカル原点からの距離.

 size

   [in]  メーターのサイズ直径

 ObjRel

   [in]  位置が設定されている他のグラフィカルオブジェクトの名称. 相対的な位置が設定されている場合にのみ関連が残ります。

 rel_mode

   [in]  相対配置のメソッド. ENUM_REL_MODEのリストの値を持ちえます。

 コーナー

   [in]  グラフィカルオブジェクトをアンカーするチャートのコーナーENUM_BASE_CORNERのリストの値を持ちます。

 バック

   [in]  背景のオブジェクト

 scale_transparency

   [in]  スケール透明度0 から 255まで取ります。

 needle_transparency

   [in]  針の透明度0 から 255まで取ります。

Return value

  スケールレイヤーとニードルレイヤーのオブジェクトが作成されている場合はtrueを返します. それ以外の場合は falseを返します。


3.2. GaugeSetCaseParameters

メーターのパラメータの設定

void GaugeSetCaseParameters(
   GAUGE_STR &g,                  // メーター構造の参照
   ENUM_CASE_STYLE style,         // ボディスタイル
   color ccol,                    // ボディカラー
   ENUM_CASE_BORDER_STYLE bstyle, // ボーダースタイル
   color bcol,                    // ボーダーカラー
   ENUM_SIZE border_gap_size      // ボーダーとスケール要素のサイズ);

パラメータ

 g

   [out]  メーター構造の参照

 style

   [in]  スタイルENUM_CASE_STYLEのリストの値を取ります。

 ccol

   [in]  ボディカラー

 bstyle

   [in]  ボーダースタイルENUM_CASE_BORDER_STYLEのリストの値を取ります。

 bcol

   [in]  ボーダーカラー

 gap_size

   [in]  境界線の内部ラインと最寄りのスケール要素(図3の"g")との間の領域. ENUM_SIZEのリストの値を取ります。


3.3. GaugeSetScaleParameters

スケールパラメータのセット.

void GaugeSetScaleParameters(
   GAUGE_STR &g,           // メーター構造の参照
   int range,              // スケールレンジ
   int rotation,           // ローテーションのアングル
   double min,             // 最小値 (左)
   double max,             // 最大値 (右)
   ENUM_MUL_SCALE mul,     // スケールラベルの乗算値
   ENUM_SCALE_STYLE style, // スケールのスタイル
   color col,              // スケールカラー
   bool display_arc        // スケールラインの表示
);

パラメータ

 g

   [out]  メーター構造の参照

 range

   [in]  スケールレンジ. スケールの極端な二つの値による角度として設定します。これは 30 から 320 まで取ります。 (図5).

 rotation

   [in]  スケールローテーションアングル (図6).

 min

   [in]  直接的に値を割りあてる場合の最小値。

 max

   [in]  直接的に値を割り当てる場合の最大値

 mul

   [in]  スケールラベルの乗算値ENUM_MUL_SCALEのリストの値を取ります。

 style

   [in]  スケールスタイルENUM_SCALE_STYLEのリストの値を取ります。

 col

   [in]  スケールカラー

 display_arc=false

   [in]  スケールラインの表示


3.4. GaugeSetMarkParameters

スケール目盛りパラメータの設定

void GaugeSetMarkParameters(  
   GAUGE_STR &g,          // メーター構造の参照
   ENUM_MARK_STYLE style, // スケールマークのスタイル
   ENUM_SIZE size,        // マークのサイズ
   double major_tmi,      // メジャーマーク間隔
   int middle_tmarks,     // メジャー間のミドルマークの数
   int minor_tmarks       // ミドル間のマイナーの数
);

パラメータ

 g

   [out]  メーター構造の参照

 style

   [in]  スケール目盛りのスタイルENUM_MARK_STYLEのリストの値を取ります。

 size

   [in]  マークサイズENUM_SIZEのリストの値を取ります。

 major_tmi

   [in]  メジャー目盛りのステップメジャーマークは、関連する値を持つラベルが付与されています。

 middle_tmarks

   [in]  メジャー間のミドルマークの数プラスの値を取ります。サイズに制限はありません。0に設定すると、ミドルマークは表示されません。

 minor_tmarks

   [in]  ミドル間のマイナーマークの数(ミドルのメジャーマーク間が表示されない場合)。プラスの値を取ります。サイズに制限はありません。0に設定した場合、マイナーマークは表示されません。


3.5. GaugeSetMarkLabelFont

目盛ラインのフォント設定

void GaugeSetMarkLabelFont(
   GAUGE_STR &g,        // メーター構造の参照
   ENUM_SIZE font_size, // フォントサイズ 
   string font,         // フォント
   bool italic,         // イタリック
   bool bold,           // ボールド
   color col            // カラー
);

パラメータ

 g

   [out]  メーター構造の参照

 font_size

   [in]  目盛りラベルのフォントサイズENUM_SIZEのリストの値を取ります。

 font

   [in]  フォント

 italic

   [in]  イタリック

 bold

   [in]  ボールド

 col

   [in]  フォントカラー


3.6. GaugeSetLegendParameters

文字パラメータの設定

void GaugeSetLegendParameters(
   GAUGE_STR &g,         // メーター構造の参照
   ENUM_GAUGE_LEGEND gl, // 文字タイプ
   bool enable,          // 文字の表示
   string str,           // string (補完的なパラメータ)
   int radius,           // 座標 - 半径
   double angle,         // 座標 - 角
   uint font_size,       // フォントサイズ
   string font,          // フォント
   bool italic,          // イタリック
   bool bold,            // ボールド
   color col             // カラー
);

パラメータ

 g

   [out]  メーター構造の参照

 gl

   [in]  文字タイプENUM_GAUGE_LEGENDの値を取ります。

 enable

   [in]  文字の表示

 str

   [in]  これは、LEGEND_DESCRIPTIONまたはLEGEND_UNITSの文字のために表示される文字列ですこのパラメータは、LEGEND_MUL型の文字では無視されます。LEGEND_VALUEの文字の小数点以下の桁数"0" から "8"の値を取ります。他の値を"0"として認識されます例として、"2"は、2つの小数点以下の桁数を意味します。"hello"という文字列は、0小数点以下の桁数です。

 radius

   [in]  半径座標単位の文字の中心とメーターの中心部からの距離(図9)

 angle

   [in]  アングル座標その値は上方と垂直にゲージの中心から来るラインと、ゲージの中心と文字のセンター(図9)を結ぶ仮想セグメント間の角度に等しいです。

 font_size

   [in]  文字のフォントサイズ

 font

   [in]  フォント

 italic

   [in]  イタリック

 bold

   [in]  ボールド

 col

   [in]  フォントカラー


3.7. GaugeSetRangeParameters

ハイライト領域のパラメータの設定

void GaugeSetRangeParameters(
   GAUGE_STR &g, // メーター構造の参照
   int index,    //レンジインデックス
   bool enable,  // レンジ表示
   double start, // 初期値
   double end,   // 最終値
   color col     // カラー
);

パラメータ

 g

   [out]  メーター構造の参照

 index

   [in]  レンジインデックス0 から 3の値を取ります。

 enable

   [in]  レンジの表示

 start

   [in]  初期値

 end

   [in]  最終値

 col

   [in]  レンジをハイライトする色


3.8. GaugeSetNeedleParameters

ニードルパラメータの設定

void GaugeSetNeedleParameters(
   GAUGE_STR &g,                     // メーター構造の参照
   ENUM_NCENTER_STYLE ncenter_style, //針のセンタースタイル
   color ncenter_col,                //針のセンターカラー
   color needle_col,                 //針の色
  ENUM_NEEDLE_FILL needle_fill       //針のメソッド
);

パラメータ

 g

   [out]  メーター構造の参照

 ncenter_style

   [in]  針のセンターのスタイルENUM_NCENTER_STYLEのリストの値を取ります。

 ncenter_col

   [in]  ニードルのセンターカラー

 needle_col

   [in]  針の色

 needle_fill

   [in]  針のメソッドENUM_NEEDLE_FILLのリストの値を取ります。


3.9. GaugeRedraw

メーターの再描写この関数は、変更を適用するために、任意のパラメータを変更した後に呼び出す必要があります。

void GaugeRedraw(
   GAUGE_STR &g       // メーターの構造の参照
); 

パラメータ

 g

   [in]  メーター構造の参照


3.10. GaugeNewValue

針と表示された値の更新

void GaugeNewValue(
   GAUGE_STR &g,     // メーター構造の参照
   double v          // 変数
);

パラメータ

 g

   [in]  メーター構造の参照

 v

   [in]  変数の現在値


3.11. GaugeDelete

メーターを構成するグラフィカルオブジェクトの削除OnDeinit() ハンドラから呼び出す関数のコール

void GaugeDelete(
   GAUGE_STR &g      // メーター構造の参照
);

パラメータ

 g

   [in]  メーター構造の参照


3.12. GaugeCalcLocation

メーターオブジェクトの座標の計算相対配置 が利用できない場合、常に同じ座標を返します。それ以外、参照オブジェクトがその位置やサイズを変更した場合、座標が以前の値と異なることがあります。

bool GaugeCalcLocation( 
   GAUGE_STR& g         // メーター構造の参照
);

パラメータ

 g

   [in]  メーター構造の参照

Return value

  値が前のものとは異なる場合trueを返します。それ以外の場合は falseを返します。関数がtrueを返した場合、計算されたパラメータを適用する関数GaugeRelocation()を呼び出します。


3.13. GaugeRelocation

チャートの指定されたスポットにメーターを構成するグラフィカルオブジェクトを配置します。相対的な位置が設定され、関数 GaugeCalcLocation()がtrueを返した場合に、必要です。

void GaugeRelocation(
   GAUGE_STR &g       // メーター構造の参照
);

パラメータ

 g

   [in]  メーター構造の参照


4. アナグラム

表2は関数のパラメータとして利用するリストです。

項目
説明
ENUM_CASE_BORDER_STYLEボーダースタイル
ENUM_CASE_STYLE
ボディスタイル
ENUM_GAUGE_LEGEND
文字タイプ
ENUM_MARK_STYLE
スケール目盛りのスタイル
ENUM_MUL_SCALE
目盛りラベルの乗算値
ENUM_NCENTER_STYLE針の中心部のスタイル
ENUM_NEEDLE_FILL針のエリアのメソッド
ENUM_REL_MODE相対配置のメソッド
ENUM_SCALE_STYLEスケールスタイル
ENUM_SIZEサイズ

表2. 項目リスト


4.1. ENUM_CASE_BORDER_STYLE

ボーダースタイル値は表3にリストしています。

識別子
説明
CASE_BORDER_NONE
ボーダーなし
CASE_BORDER_THIN細いボーダー
CASE_BORDER_THICK
太いボーダー

表3. ENUM_CASE_BORDER_STYLEの値

4.2. ENUM_CASE_STYLE

ボディスタイル値は表4にリストしています。

識別子
説明
CASE_ROUND
円のボディ
CASE_SECTOR
セクタータイプボディ

表4ENUM_CASE_STYLEの値

4.3. ENUM_GAUGE_LEGEND

文字タイプ値は表5にリストしています。

識別子
 説明
LEGEND_DESCRIPTIONメーター説明
LEGEND_UNITS目盛り単位
LEGEND_MULスケールラベルの乗算値
LEGEND_VALUE変数の現在値

表5. ENUM_GAUGE_LEGENDの値

4.4. ENUM_MARK_STYLE

スケールメモリのスタイル値は表6にリストしています。

識別子
 説明
MARKS_INNER内縁によってマークを揃える
MARKS_MIDDLE中心によってマークを揃える
MARKS_OUTER外枠によってマークを揃える

表6ENUM_MARK_STYLEの値

4.5. ENUM_MUL_SCALE

スケール目盛りラベルの乗算値値は表7にリストしています。

 識別子意味
表示
MUL_1000010000
 х10k
MUL_10001000
 х1k
MUL_100100
 х100
MUL_1010
 х10
MUL_11
 非表示
MUL_010.1
 /10
MUL_0010.01
 /100
MUL_00010.001
 /1k
MUL_000010.0001
 /10k

表7ENUM_MUL_SCALEの値

4.6. ENUM_NCENTER_STYLE

針の中心部のスタイル値は表8にリストされています。

識別子
説明
NDCS_NONE針の中心部を非表示
NDCS_SMALL小さく表示
NDCS_LARGE大きく表示

表8. ENUM_NCENTER_STYLEの値

4.7. ENUM_NEEDLE_FILL

針のエリアの塗り方値は表9にリストされています。.

 識別子 説明
NEEDLE_FILLアンチエイリアスを使わずに塗りつぶし
NEEDLE_FILL_AAアンチエイリアスを使って塗りつぶし
NEEDLE_NOFILL_AAアンチエイリアスを適用するが塗りつぶさない

表9. ENUM_NEEDLE_FILLの値

4.8. ENUM_REL_MODE

相対配置のやり方値は表10にリストされています。

 識別子 説明
RELATIVE_MODE_NONE相対配置をしない
RELATIVE_MODE_HOR水平
RELATIVE_MODE_VERT鉛直
RELATIVE_MODE_DIAG斜め

表10. ENUM_REL_MODEの値

4.9. ENUM_SCALE_STYLE

スケールスタイル値は表11にリストされています。

識別子
 説明
SCALE_INNERスケール内の目盛りラベル
SCALE_OUTERスケール外の目盛りラベル

表11. ENUM_SCALE_STYLEの値

4.10. ENUM_SIZE

サイズ値は表12にリストされています。

識別子
 説明
SIZE_SMALL小さい
SIZE_MIDDLE
SIZE_LARGE大きい

表12. ENUM_SIZEの値


5. マクロによる代用

サイズの係数:

#define DIAM_TO_NDCSL_RATIO   5   //直径のパーセンテージとしての針の中心径(小)
#define DIAM_TO_NDCSB_RATIO   7.5 //直径のパーセンテージとしての針の中心径(大)
//---
#define DIAM_TO_BD_SIZE_S     2 //直径のパーセンテージとしての境界線の幅(小)
#define DIAM_TO_BD_SIZE_B     5 //直径のパーセンテージとしての境界線の幅(大)
//---
#define DIAM_TO_BD_GAP_S      2.0 //直径のパーセンテージとして計(小)の内側の要素に対するボーダーからのスペース
#define DIAM_TO_BD_GAP_M      3.0 //直径のパーセンテージとしてのメーター (ミドル)の内側の要素に対すボーダーからスペース
#define DIAM_TO_BD_GAP_L      7.0 //直径のパーセンテージとしてのメーター (大)  (ミドル)の内側の要素に対すボーダーからスペース
//---
#define DIAM_TO_MSZ_MJ_S      3.3 //直径のパーセンテージとしてメジャースケール(小)の目盛りのサイズ
#define DIAM_TO_MSZ_MD_S      2.3 //直径のパーセンテージとして中規模(小)の目盛りのサイズ
#define DIAM_TO_MSZ_MN_S      1.3 //直径のパーセンテージとしてマイナースケール(小)の目盛りのサイズ
//---
#define DIAM_TO_MSZ_MJ_M      6.5 //直径のパーセンテージとしてメジャースケール(中央)の目盛りのサイズ
#define DIAM_TO_MSZ_MD_M      4.8 //直径のパーセンテージとして中規模(中央)の目盛りのサイズ
#define DIAM_TO_MSZ_MN_M      3.0 //直径のパーセンテージとしてマイナースケール(中央)目盛りのサイズ
//---
#define DIAM_TO_MSZ_MJ_L      10.0 //直径のパーセンテージとしてメジャースケール(大)の目盛りのサイズ
#define DIAM_TO_MSZ_MD_L      7.5  //直径のパーセンテージとして中規模(大)の目盛りのサイズ
#define DIAM_TO_MSZ_MN_L      5.0  //直径のパーセンテージとしてマイナースケール(大)の目盛りのサイズ
//---
#define DIAM_TO_MFONT_SZ_S    4   //直径の割合としてスケール(小)の目盛りのラベルのフォントサイズ
#define DIAM_TO_MFONT_SZ_M    6.5 //直径の割合としてスケール(中央)の目盛りのラベルのフォントサイズ
#define DIAM_TO_MFONT_SZ_L    10  //直径の割合としてスケール(大)の目盛りラベルのフォントサイズ

デフォルトカラー:

#define DEF_COL_SCALE      clrBlack
#define DEF_COL_MARK_FONT  clrBlack
#define DEF_COL_CASE       clrMintCream
#define DEF_COL_BORDER     clrLightSteelBlue
#define DEF_COL_LAB        clrDarkGray
#define DEF_COL_NCENTER    clrLightSteelBlue
#define DEF_COL_NEEDLE     clrDimGray


6. CCanvas Classの修正


6.1. アンチエイリアスアルゴリズムを用いたセグメントの描写

LineAA メソッドは、アンチエイリアシングアルゴリズムを使用してセグメントを描画することができます。しかし、円形目盛りを描画するときに、一つの問題が浮上します。直交座標系に極座標からセグメントの最初と最後の点の座標を変換すると、整数に切り上げなければならない小数が発生します。したがってマークは図11(b)に示されているように曲がって見えます。

このような理由により、x1、y1、x2、y2の入力パラメータの種類が倍に変更されているという事実によって、LineAAとは異なる方法LineAA2を追加しました。よって、座標の端数を出し、図11(c)のようにはっきりと見せ、問題を取り除くことができます。

//+------------------------------------------------------------------+
//| アンチエイリアスの線を引きます (with style) v.2                     |
//+------------------------------------------------------------------+
void CCanvas::LineAA2(const double x1,const double y1,const double x2,const double y2,const uint clr,const uint style)
  {
//--- ラインは、画像の境界の外にあります
   if((x1<0 && x2<0) || (y1<0 && y2<0))
      return;
   if(x1>=m_width && x2>=m_width)
      return;
   if(y1>=m_height && y2>=m_height)
      return;
//--- check
   if(x1==x2 && y1==y2)
     {
      PixelSet(int(x1),int(y1),clr);
      return;
     }
//--- 線のスタイルを設定
   if(style!=UINT_MAX)
      LineStyleSet(style);
//--- 試算
   double dx=x2-x1;
   double dy=y2-y1;
   double xy=sqrt(dx*dx+dy*dy);
   double xx=x1;
   double yy=y1;
   uint   mask=1<<m_style_idx;
//--- セットピクセル
   dx/=xy;
   dy/=xy;
   do
     {
      if((m_style&mask)==mask)
         PixelSetAA(xx,yy,clr);
      xx+=dx;
      yy+=dy;
      mask<<=1;
      if(mask==0x1000000)
         mask=1;
     }
   while(fabs(x2-xx)>=fabs(dx) && fabs(y2-yy)>=fabs(dy));
  } 

図11は、描画スケールマークの様々な方法の例です。:

スケールマークの描写方法

図11. スケールの描写方法 (200%倍)


6.2. アンチエイリアスエッジによる領域の描写

Fillメソッドは、アンチエイリアシングアルゴリズムを使用することなく、描画セグメントによって囲まれた領域を塗りつぶすように意図されています。LineAAメソッドで描かれた線分に囲まれた領域を埋めるために、この方法を使用する場合は、領域は図12に見られるように、不完全に塗りつぶされる(a)。

アンチエイリアスエッジによる領域の描写

図12. アンチエイリアスエッジによる塗りつぶし (倍率200%)

よって、Fill2の方法を追加します。違いは、異なる背景色で境界を塗りつぶすということです。これは、 Fillメソッドを使用して行うことができない、場所を埋めることができます. 図12(b)はその例です。

//+------------------------------------------------------------------+
//| 閉領域を塗りつぶす(v.2)                              |
//+------------------------------------------------------------------+
void CCanvas::Fill2(int x,int y,const uint clr)
  {
//--- チェック
   if(x<0 || x>=m_width || y<0 || y>=m_height)
      return;
//---
   int  index=y*m_width+x;
   uint old_clr=m_pixels[index];
//--- 交換が必要かどうかを確認
   if(old_clr==clr)
      return;
//--- 深くネストされた再帰呼び出しをシミュレートするために、擬似スタックを使用
   int  stack[];
   uint count=1;
   int  idx;
   int  total=ArraySize(m_pixels);
//--- スタック用のメモリを割り当て
   if(ArrayResize(stack,total)==-1)
      return;
   stack[0]=index;
   m_pixels[index]=clr;
   for(uint i=0;i<count;i++)
     {
      index=stack[i];
      x=index%m_width;
      //---左の隣接点
      idx=index-1;
      if(x>0 && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
      //--- トップ隣接点
      idx=index-m_width;
      if(idx>=0 && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
      //--- 右隣のポイント
      idx=index+1;
      if(x<m_width-1 && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
      //---下の隣接点
      idx=index+m_width;
      if(idx<total && m_pixels[idx]!=clr)
        {
         stack[count]=idx;
         if(m_pixels[idx]==old_clr)
            count++;
         m_pixels[idx]=clr;
        }
     }
//--- メモリの解放
   ArrayFree(stack);
  }  

しかし、この方法にも欠点があります。小さな鋭角が存在する場合、一部は図12(c)に示されているように、白色のままでです。しかし、この問題から抜け出す道を発見しました。

   1)まず、全体のキャンバス(ニードルレイヤー)は、針部分のために意図された色で満たされています:

n.canvas.Fill(10, 10, ColorToARGB(n.needle.c, n.transparency));

   2)その後、 LINEA A2メソッドを使用して、3つのセグメントで針を描きます:

n.canvas.LineAA2(db_xbuf[0], db_ybuf[0], db_xbuf[1], db_ybuf[1], 0);
n.canvas.LineAA2(db_xbuf[1], db_ybuf[1], db_xbuf[2], db_ybuf[2], 0);
n.canvas.LineAA2(db_xbuf[2], db_ybuf[2], db_xbuf[0], db_ybuf[0], 0);

  3)この後、 Fill2メソッドを使用して、透明色と針の周りの領域を塗りつぶします:

n.canvas.Fill2(10, 10, 0);

この方法は、最良のものではありませんが、適切な針を描画することができます.

針のエリアの塗りつぶし方法

図13. それぞれの手法による針の塗りつぶし

図13は、様々な方法を使用して塗りつぶされた針を示しています。

  • 3つのセグメントで、構成a)の針がLINEA A2メソッドを使用して描画され、 Fill2</ a1>の方法を用いて塗りつぶされています。
  • b) FillTriangleメソッドを使って描かれた針
  • c) LineA A2メソッドを使用して描かれた、3セグメントで構成された塗りつぶされていない針

ご覧のように、図13(b)に示す針は90度で割り切れる角度に近い角の場合、カクカクしています。加えて、極座標から直交座標系に変換する際の座標の四捨五入によって、針が中心からずれていることがわかります。しかし同時にこの方法は、リソースの意味では最も実用的です。(この件に関しては後述)。図13(c)に示された針は、上記の二つの方法でのトレードオフであります。 LineA A2メソッドが、エリア塗りつぶしなしを使用して描かれた三つのセグメントから構成されています。


7. アプリケーション例

それでは、いくつかの例を介して、メーターライブラリを適用してみましょう.


7.1. 現在の利益のインジケーター

最もシンプルな例から始めます。この例では、EAやインジケータにメーターを追加するための基本的なセットを示しています。

//+------------------------------------------------------------------+
//|                                       profit_gauge_indicator.mq5 |
//|                                         Copyright 2015, Decanium |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Decanium"
#property version   "1.00"
#property indicator_plots 0
#property indicator_chart_window

#include <Gauge\gauge_graph.mqh>

input string inp_gauge_name="gg01";                  // インジケーター名
input int inp_x = 40;                                //水平オフセット
input int inp_y = 40;                                // 鉛直オフセット
input int inp_size=300;                              // インジケーターサイズ
input string inp_ObjRel="";                          // 相対配置の場合にはベースとなるインジケーターの名前
input ENUM_REL_MODE inp_rel_mode=RELATIVE_MODE_NONE; // 相対配置モード
input ENUM_BASE_CORNER inp_corner=CORNER_LEFT_UPPER; // アンカーコーナー
input bool inp_back=false;                           // インジケータは、バックグラウンドで動作します
input uchar inp_scale_transparency=0;                // 透明度 level, 0..255
input uchar inp_needle_transparency=0;               // 針の透明度, 0..255

//--- メーター構造の宣言
GAUGE_STR g0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- メーターの生成
   if(GaugeCreate(inp_gauge_name,g0,inp_x,inp_y,inp_size,inp_ObjRel,inp_rel_mode,
      inp_corner,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- メーターの描写
   GaugeRedraw(g0);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- メーターの削除
   GaugeDelete(g0);
   ChartRedraw();
  }    
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- 読み込みの更新
   double profit=AccountInfoDouble(ACCOUNT_PROFIT);
   GaugeNewValue(g0,profit);
//---
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      if(GaugeCalcLocation(g0)==true)
         GaugeRelocation(g0);
     }
  }
//+------------------------------------------------------------------+

まず、メーターの構造を宣言する必要があります。 GaugeCreate()メソッドを使用してゲージを作成した初期化関数で、描画関数- GaugeRedraw()を呼び出します。GaugeNewValue() は、読み込みの更新に使います。この例では、OnCalculate()ハンドラからコールしています。

メーターは図14に示されているとおりです。

デフォルトパラメータでのインジケーターの外観

図14. メーターのデフォルトの外観

次に、スケールの範囲および回転角度を設定する機能を追加します。入力のリストに2つのパラメータを追加します。

input int inp_scale_range=270;   // スケール範囲, 30..320 度
input int inp_rotation=45;       // スケールローテーション, 0..359 度

スケールのパラメータを設定するための関数の呼び出しで初期化コードを拡張します。

//--- スケールの設定 スケールのパラメータやマーク
   GaugeSetScaleParameters(g0,inp_scale_range,inp_rotation,-200,400,MUL_1,SCALE_INNER,clrBlack);

新しいパラメータの補充

  • 新しい最大値と最小値 (それぞれ-200、 400)
  • 目盛ラベルの乗数(MUL_1)
  • scale style (SCALE_INNER — graduation labels are inside)
  • ラベルの色 (clrBlack)

スケール極端な値を変更したので、メジャーマークのステップを修正することが望ましいです。テキストを除外して、100が最適値です。2つのメジャーと4つのマイナーマーク間に、1つのミドルマークを配置します。よって、10のマーク間の最小ステップになります。

   GaugeSetMarkParameters(g0,MARKS_INNER,SIZE_MIDDLE,100,1,4);

今、2つのデータ領域をハイライトしています。200で始まり、400で終わる範囲を有するインデックス0は、clrLimeGreenで強調表示されています。-100で始まり、-200で終わる範囲を有するインデックス1は、clrCoralで強調表示されます。

//--- スケールでの範囲を強調
   GaugeSetRangeParameters(g0,0,true,200,400,clrLimeGreen);
   GaugeSetRangeParameters(g0,1,true,-100,-200,clrCoral);

次に、表示文字を設定します。メーターの説明、測定単位と小数点以下1桁で現在の値を決定します。ひとつひとつ見てみましょう。

メーター説明:

   GaugeSetLegendParameters(g0,LEGEND_DESCRIPTION,true,"Profit",3,0,14,"Arial",false,false);

表示文字"Profit", 半径 3, 角 0, フォント 14

単位:

   GaugeSetLegendParameters(g0,LEGEND_UNITS,true,"USD",8,215,10,"Arial",true,false);

文字は "USD", 半径 8, 角 215, フォント10

現在値:

   GaugeSetLegendParameters(g0,LEGEND_VALUE,true,"1",4,225,20,"Arial",true,false);

文字"1"は表示の形式(小数点以下1桁)を意味します。座標: 半径4, 角255. フォントサイズ20

いくつかの追加設定を行った後、メーターは図15のようになります。

現在の利益のインジケーター

図15. 追加設定後のメーターの外観


7.2. ダッシュボードインジケーター

次に、より複雑な例、すなわちダッシュボードインジケーターに移ります。図1がそれです。このインジケーターは、現在利益、スプレッド、フリーマージンをパーセンテージで、さらに、ATRForce IndexRSI表示します。

まず、メーター構造配列を宣言します。 

//--- メーターの構造体配列の宣言
GAUGE_STR gg[6];

次に、ゲージを生成、調整します。

マージンレベルのインジケータが左下に配置されます。これは絶対座標を持つことになり、他のすべてのインジケーターが、このインジケータまたは隣接に係る配置にされます。

//--- gg00メーターの生成
   if(GaugeCreate("gg00",gg[0],5,-90,240,"",RELATIVE_MODE_NONE,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- ボディパラメータの設定
   GaugeSetCaseParameters(gg[0],CASE_SECTOR,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- スケールのパラメータやマークの設定
   GaugeSetScaleParameters(gg[0],120,35,800,2000,MUL_100,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[0],MARKS_INNER,SIZE_MIDDLE,200,1,4);
   GaugeSetMarkLabelFont(gg[0],SIZE_MIDDLE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- スケールを強調
   GaugeSetRangeParameters(gg[0],0,true,1400,2000,clrLimeGreen);
   GaugeSetRangeParameters(gg[0],1,true,1000,800,clrCoral);
//--- テキストラベルの設定
   GaugeSetLegendParameters(gg[0],LEGEND_DESCRIPTION,true,"Margin lvl",4,15,12,"Arial",false,false);
   GaugeSetLegendParameters(gg[0],LEGEND_VALUE,true,"0",3,80,16,"Arial",true,false);
   GaugeSetLegendParameters(gg[0],LEGEND_MUL,true,"",4,55,8,"Arial",true,false);
//--- 針パラメータの設定
   GaugeSetNeedleParameters(gg[0],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

一番下の行を配置します。次は現在損益インジケーターです。

//--- gg01メーターの生成
   if(GaugeCreate("gg01",gg[1],-80,20,320,"gg00",RELATIVE_MODE_HOR,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- ボディパラメータの設定
   GaugeSetCaseParameters(gg[1],CASE_SECTOR,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- スケールのパラメータやマークの設定
   GaugeSetScaleParameters(gg[1],200,0,-400,400,MUL_1,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[1],MARKS_INNER,SIZE_MIDDLE,100,1,4);
   GaugeSetMarkLabelFont(gg[1],SIZE_MIDDLE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- スケールの強調
   GaugeSetRangeParameters(gg[1],0,true,200,400,clrLimeGreen);
   GaugeSetRangeParameters(gg[1],1,true,-200,-400,clrCoral);
//--- テキストラベルの設定
   GaugeSetLegendParameters(gg[1],LEGEND_DESCRIPTION,true,"Profit",3,0,16,"Arial",false,false);
   GaugeSetLegendParameters(gg[1],LEGEND_UNITS,true,"USD",3,-90,10,"Arial",true,false);
   GaugeSetLegendParameters(gg[1],LEGEND_VALUE,true,"1",3,90,12,"Arial",true,false);
//--- 針パラメータの設定
   GaugeSetNeedleParameters(gg[1],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

スプレッドインジケータは下段に配置します。

//--- gg02メーターの生成
   if(GaugeCreate("gg02",gg[2],-80,-20,240,"gg01",RELATIVE_MODE_HOR,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- ボディパラメータの設定
   GaugeSetCaseParameters(gg[2],CASE_SECTOR,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- スケールのパラメータやマークの設定
   GaugeSetScaleParameters(gg[2],120,-35,60,0,MUL_1,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[2],MARKS_INNER,SIZE_MIDDLE,10,1,4);
   GaugeSetMarkLabelFont(gg[2],SIZE_MIDDLE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- スケールの強調
   GaugeSetRangeParameters(gg[2],0,true,35,10,clrLimeGreen);
   GaugeSetRangeParameters(gg[2],1,true,50,60,clrCoral);
//--- テキストラベルの設定
   GaugeSetLegendParameters(gg[2],LEGEND_DESCRIPTION,true,"Spread",4,-15,14,"Arial",false,false);
   GaugeSetLegendParameters(gg[2],LEGEND_VALUE,true,"0",3,-80,16,"Arial",true,false);
//--- 針パラメータの設定
   GaugeSetNeedleParameters(gg[2],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

ATRインジケーターは、 (左上) フリーマージンインジケーターの隣に配置します。

//---  gg03メーターの生成 ATR
   if(GaugeCreate("gg03",gg[3],30,0,180,"gg00",RELATIVE_MODE_VERT,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- ボディパラメータの設定
   GaugeSetCaseParameters(gg[3],CASE_ROUND,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- スケールのパラメータやマークの設定
   GaugeSetScaleParameters(gg[3],270,45,0.001,0.004,MUL_00001,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[3],MARKS_INNER,SIZE_LARGE,0.001,9,3);
   GaugeSetMarkLabelFont(gg[3],SIZE_LARGE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- highlighting ranges on the scale
   GaugeSetRangeParameters(gg[3],0,true,0.002,0.001,clrYellow);
//--- テキストラベルの設定
   GaugeSetLegendParameters(gg[3],LEGEND_DESCRIPTION,true,"ATR",7,-140,26,"Arial",false,false);
//GaugeSetLegendParameters(gg[3],LEGEND_UNITS,true,"USD",8,180,5,"Arial",true,false);
   GaugeSetLegendParameters(gg[3],LEGEND_VALUE,true,"5",2,180,14,"Arial",true,false);
   GaugeSetLegendParameters(gg[3],LEGEND_MUL,true,"",2,0,20,"Arial",true,false);
//--- 針パラメーターの設定
   GaugeSetNeedleParameters(gg[3],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

RSIインジケーターはスプレッドインジケーターの上に配置します。

//--- gg04メーターの生成 RSI
   if(GaugeCreate("gg04",gg[4],-30,0,180,"gg02",RELATIVE_MODE_VERT,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- ボディパラメーターの設定
   GaugeSetCaseParameters(gg[4],CASE_ROUND,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- スケールのパラメータやマークを設定
   GaugeSetScaleParameters(gg[4],270,45,0,100,MUL_10,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[4],MARKS_INNER,SIZE_LARGE,10,1,4);
   GaugeSetMarkLabelFont(gg[4],SIZE_LARGE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- テキストラベルの設定
   GaugeSetLegendParameters(gg[4],LEGEND_DESCRIPTION,true,"RSI",7,-140,26,"Arial",false,false);
   GaugeSetLegendParameters(gg[4],LEGEND_VALUE,true,"2",2,180,16,"Arial",true,false);
   GaugeSetLegendParameters(gg[4],LEGEND_MUL,true,"",2,0,20,"Arial",true,false);
//--- 針パラメーターの設定
   GaugeSetNeedleParameters(gg[4],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

フォースインジケーターは現在損益の上に配置します。

//--- gg05 メーターの生成, Force
   if(GaugeCreate("gg05",gg[5],-10,60,180,"gg03",RELATIVE_MODE_HOR,
      CORNER_LEFT_LOWER,inp_back,inp_scale_transparency,inp_needle_transparency)==false)
      return(INIT_FAILED);
//--- ボディパラメーターの設定
   GaugeSetCaseParameters(gg[5],CASE_ROUND,DEF_COL_CASE,CASE_BORDER_THIN,DEF_COL_BORDER,SIZE_MIDDLE);
//--- スケールのパラメータやマークを設定
   GaugeSetScaleParameters(gg[5],270,45,-4,4,MUL_1,SCALE_INNER,clrBlack);
   GaugeSetMarkParameters(gg[5],MARKS_INNER,SIZE_LARGE,1,1,4);
   GaugeSetMarkLabelFont(gg[5],SIZE_LARGE,"Arial",false,false,DEF_COL_MARK_FONT);
//--- スケールの強調
   GaugeSetRangeParameters(gg[5],0,true,-1,-4,clrMediumSeaGreen);
   GaugeSetRangeParameters(gg[5],1,true,1,4,clrCrimson);
//--- テキストラベルの設定
   GaugeSetLegendParameters(gg[5],LEGEND_DESCRIPTION,true,"Force",7,-140,20,"Arial",false,false);
   GaugeSetLegendParameters(gg[5],LEGEND_VALUE,true,"5",2,180,14,"Arial",true,false);
   GaugeSetLegendParameters(gg[5],LEGEND_MUL,true,"",3,0,10,"Arial",true,false);
//--- 針パラメーターの設定
   GaugeSetNeedleParameters(gg[5],NDCS_SMALL,DEF_COL_NCENTER,DEF_COL_NEEDLE,NEEDLE_FILL_AA);

メーターは定期的に再描写させることができます。

//--- メーターの描写
   for(int i=0; i<6;i++)
     {
      GaugeRedraw(gg[i]);
      GaugeNewValue(gg[i],0);
     }

OnCalculate()が起きたとき、現在値を再計算し、GaugeNewValue()インジケーターをコールします。

//--- 読み込みの更新
//--- スプレッド
   GaugeNewValue(gg[2],spread[rates_total-1]);
//--- 現在損益   
   double profit=AccountInfoDouble(ACCOUNT_PROFIT);
   GaugeNewValue(gg[1],profit);
//--- マージンレベル
   double margin_level=AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
   GaugeNewValue(gg[0],margin_level);
//--- ATRインジケーター
   calculated=BarsCalculated(handle_ATR);
   if(calculated>0)
     {
      double ival[1];
      if(CopyBuffer(handle_ATR,0,0,1,ival)<0)
         Print("ATR CopyBuffer error");
      else
         GaugeNewValue(gg[3],ival[0]);
     }
//--- RSI
   calculated=BarsCalculated(handle_RSI);
   if(calculated>0)
     {
      double ival[1];
      if(CopyBuffer(handle_RSI,0,0,1,ival)<0)
         Print("RSI CopyBuffer error");
      else
         GaugeNewValue(gg[4],ival[0]);
     }
//--- Force
   calculated=BarsCalculated(handle_Force);
   if(calculated>0)
     {
      double ival[1];
      if(CopyBuffer(handle_Force,0,0,1,ival)<0)
         Print("Force Index CopyBuffer error");
      else
         GaugeNewValue(gg[5],ival[0]);
     }

注意点として、OnChartEvent()からGaugeRelocation() を呼び出しても意味がありません。相対配置がここで使用されているが、位置または大きさが変更された場合、メーターが一斉に初期化されるように、メーターの座標を再計算する必要はありません。


8. リソース耐久評価

ニードルレイヤーは完璧に毎時、測定値の更新値を再描画します。いくつかのケースでは、非常に多く、毎秒に数回起こり得ます。針を描くリソース強度の問題は非常に深刻な問題です。様々な塗りつぶし方法を使用して針を描画するため、CPUのオーバーヘッドを評価するための小さなスクリプトを書きます。

//+------------------------------------------------------------------+
//|                                                    test_fill.mq5 |
//|                                         Copyright 2015, Decanium |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Decanium"
#property version   "1.00"

#include <Canvas/Canvas2.mqh>

CCanvas canvas;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Print("***** start test *****");
//---
   string ObjName="test";
   ObjectDelete(0,ObjName);
   canvas.CreateBitmapLabel(ObjName,10,10,400,400,COLOR_FORMAT_ARGB_NORMALIZE);
//---
   int x[3]={200,185,215};
   int y[3]={70, 250,250};
   int cycles=1000;
   uint col=ColorToARGB(clrRed,255);
   uint c1,c2;
//--- アンチエイリアシングエッジで塗りつぶすテスト
   canvas.Erase();
   c1=GetTickCount();
   for(int i=0; i<cycles; i++)
     {
      canvas.Fill(10, 10, col);
      canvas.LineAA2(x[0], y[0], x[1], y[1], 0);
      canvas.LineAA2(x[1], y[1], x[2], y[2], 0);
      canvas.LineAA2(x[2], y[2], x[0], y[0], 0);
      canvas.Fill2(10, 10, 0);
     }
   c2=GetTickCount();
   canvas.Update(true);
   Print("Filled AA: ",c2-c1," ms, ",cycles," cycles, ",
         DoubleToString(double(c2-c1)/double(cycles),2)," ms per cycle");
//--- 塗りつぶしなしのアンチエイリアスのテスト
   canvas.Erase();
   c1=GetTickCount();
   for(int i=0; i<cycles; i++)
     {
      canvas.LineAA2(x[0], y[0], x[1], y[1], col);
      canvas.LineAA2(x[1], y[1], x[2], y[2], col);
      canvas.LineAA2(x[2], y[2], x[0], y[0], col);
     }
   c2=GetTickCount();
   canvas.Update(true);
   Print("Not filled AA: ",c2-c1," ms, ",cycles," cycles, ",
         DoubleToString(double(c2-c1)/double(cycles),2)," ms per cycle");
//--- アンチエイリアスなしのテスト
   canvas.Erase();
   c1=GetTickCount();
   for(int i=0; i<cycles; i++)
     {
      canvas.FillTriangle(x[0],y[0],x[1],y[1],x[2],y[2],col);
      canvas.LineAA2(x[0], y[0], (x[1]+x[2])/2, y[1], col);
     }
   c2=GetTickCount();
   canvas.Update(true);
   Print("Filled: ",c2-c1," ms, ",cycles," cycles, ",
         DoubleToString(double(c2-c1)/double(cycles),2)," ms per cycle");
  }
//+------------------------------------------------------------------+

このスクリプトは、サイクル間に針を1000回の描画しするメソッドを起動し、このプロセスのために費やした時間をミリ秒単位で測定します。

リソース耐久テストResource Intensity Test

図16. リソース耐久テストの結果

結果からもわかるように、アンチエイリアスエッジかつ塗りつぶしの針は、アンチエイリアスなしの塗りつぶしの針よりも数百倍の量があり、塗りつぶしなしと比べて10倍の開きがあります。この場合、見た目の良さにはそれだの対価が必要になるということです。


結論

この記事では、メーターを表示させるのに必要な関数について記述しました。ライブラリ作成の主な目的は、図面と幾何の詳細を掘り下げることなく、EAやインジケータにメーターをシンプルに追加するということでした。しかし、この目的・目標に達したかどうかはあなた次第です。

リソース強度には特に注目が必要です。OnCalculate()で時間のかかる計算をすると、ターミナルが一時的に停止する瞬間が発生してしまいます。よって、針の描写には妥協案を採用することを推奨します。(塗りつぶしなしでアンチエイリアス).

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

添付されたファイル |
dashboard.mq5 (20.88 KB)
canvas2.mqh (159.02 KB)
gauge_graph.mqh (140.14 KB)
MQL5でのレジスタンス・サポートレベルの描写 MQL5でのレジスタンス・サポートレベルの描写
この記事では、サポートとレジスタンスのレベルを描画するための4つの極点を求める方法を説明します。通貨ペアのチャートの極値を見つけるために、RSIインジケータを使用します。例として、サポートとレジスタンスのレベルを表示するインジケータコードを掲載しています。
モスクワ証券取引所で取引をする際の、EAの安全性について モスクワ証券取引所で取引をする際の、EAの安全性について
この記事では、トレード執行時の安全性を確保する手法について考察します。例として、モスクワ証券取引所における低流動性の株式を扱います。この方法は、"モスクワ証券取引所の例によるトレードの原則"による、実践的なアプローチとなります。
ファイルの操作。重要な市場イベントの可視化例。 ファイルの操作。重要な市場イベントの可視化例。
この記事では、外国為替証拠金取引市場でのより生産的なMQL4の使用を検証します。
グラフィカルインタフェース I: 種々のプログラム及びメタトレーダー4ターミナルでのライブラリのテスト(チャプター 5) グラフィカルインタフェース I: 種々のプログラム及びメタトレーダー4ターミナルでのライブラリのテスト(チャプター 5)
このグラフィカルインターフェイスに関するシリーズの第一部の前章では、フォームクラスは、そのコントロールを押すしてフォームの管理を許可するメソッドによって改善されました。本稿では、インディケータやスクリプトなどの異なるMQLプログラムでのテストが行われます。ライブラリはすべてのMetaTraderプラットフォームで使用できるクロスプラットフォーム対応として設計されたので、MetaTrader 4でもテストを行います。