English Русский 中文 Español Deutsch Português
シグナル計算機

シグナル計算機

MetaTrader 5統合 | 26 5月 2016, 09:19
2 395 0
Vladimir Karputov
Vladimir Karputov

目次


概論

『シグナルNNNを自分は購読できるのか?そしてどれ位のポジションボリュームが自分の取引口座にコピーされるのか?』というのが、購読者の中に最もよく沸いてくる疑問ではないでしょうか。この記事では、シグナル購読希望者の助っ人となる、シグナル計算機の作成をサポートします。また、この記事では、シグナル計算機の簡単な使用説明も行います。

計算機自体は、CDialogクラスをベースにしたパネルです。このパネルには、次の要素が使用されています。

  • CLabel
  • CEdit
  • CComboBox
  • CButton
  • CTableListView― これは新しい制御要素で、ターミナルで利用することができるシグナルが表示されているいくつかの列からなる表のことです。
  • CBmpButton
  • CCanvas — これはテキスト出力の為に使われるパネル内のキャンバスです。 

シグナル計算機は、ターミナルで利用可能なシグナルのデータベースを使用し動作します。ターミナルでは、いくつかの指標に基づいた追加のフィルタリングが行われ、このアプローチによって、シグナルとあなたの取引口座との間の最大限の互換性が確保されます。このフィルタリングの主な課題は、ユーザーの視界から、明らかに悪い指標を持つシグナルや、コピーすることが不可能なシグナルを除くことです。

この記事で紹介される計算機は、MetaTrader 5用、MetaTrader 4用共に、マーケットから無料でダウンロードすることができます。


1. 使用上の制限

ターミナルの『シグナル』タブでは、購読者の取引口座と最大限に互換性のあるシグナルのみが表示されているということを、はっきりと理解する必要があります。言い換えれば、サイト上のシグナルリストで利用できるシグナルの全てを、ターミナルでは見ることができないということです。また、ターミナルで1つの取引サーバー(取引口座)から他のものに切り替えると、ターミナルのシグナルリストが毎回変わるのが確認できます。


2. シグナル計算機の使用マニュアル

2.1. 作業開始

シグナル計算機の動作には、ターミナル内のトレードシグナルの実際のデータベースが必要です。この為には、『ツールボックス』ウィンドウの『シグナル』タブを有効にする必要があります(『シグナル』タブをクリックする)。

 『シグナル』タブの有効化

図1. 『シグナル』タブの有効化 

もしシグナルのデータベースに変更がある場合、3~5秒の間にダウンロードされます。

取引口座への接続後に『シグナル』タブを有効にする必要があり、これは他の取引口座に接続した際にも必要になります。


2.2. ユーザーインターフェース

シグナル計算機のインターフェイスには以下の要素が含まれます。

シグナル計算機のインターフェイス

図2. シグナル計算機のインターフェイス 

  • 取引口座残高(Trading account's balance) — 現時点で接続されている取引口座の残高。これは編集可能です。シグナル計算機をチャートに設置した後、または『取引口座』の編集欄でチャート期間の変更があった後に、現時点で接続されている取引口座の残高が表示されます。この欄では、0から9までの数字のみ入力することができます。
  • 取引口座通貨(Trading account's currency)ー現時点で接続されている取引口座の通貨で、リストに含まれる最も頻繁に見られる通貨です。チャートへのシグナル計算機の設置後、またはシグナル計算機のチャートの期間を変更した後に、現時点で接続されている取引口座の通貨名をリストの中で検索します。適したものが見つからなかった場合には、デフォルトで"USD"が選択されます。
  • 取引口座レバレッジ(Trading account's leverage)ー現時点で接続している取引口座の取引レバレッジで、リストに含まれる最も頻繁に見られる取引レバレッジです。チャートへのシグナル計算機の設置後、またはシグナル計算機のチャートの期間の変更後に、現時点で接続されている取引口座の取引レバレッジをリストの中で検索します。適したものが見つからなかった場合には、デフォルトで"1:100"のレバレッジが選択されます。
  • シグナルコピー時の証拠金負荷(Deposit load when copying a signal) — ターミナルの『サービス』ー『設定』-『シグナル』メニューから落とされるリストです。チャートへのシグナル計算機の設置後、またはシグナル計算機のチャート期間の変更後に現時点で接続されている取引口座の証拠金への負担をリストの中で検索します。適したものが見つからなかった場合には、デフォルトで"95%"の負荷が選択されます。
  • ターミナルで利用可能なシグナルの一覧(Table of signals available in the terminal) — ターミナルの『シグナル』タブのシグナルの一覧表です。一覧表は自動的に"コピー係数"の降順に並び替えられます。表の列:
    • "成長率(Growth, %)" — 口座上の取引操作結果の資金成長率。
    • "シグナル(Signal)" — トレードシグナル名。
    • "資金(Funds)" — 全ての債券を含めた、シグナル配信者の口座上の自己資金の量。
    • "通貨(Currency)" — シグナル配信者の取引口座の通貨。
    • "レバレッジ(Leverage)" — シグナル配信者の取引口座のレバレッジ。
    • "価格(Price, $)" — トレードシグナルの価格(ドル)
    • "コピー係数(Copy ratio)" — 設定での選択時に各シグナルに算出されたコピー係数: "取引口座の残高"、"取引口座の通貨"、"取引口座のレバレッジ"そして "シグナルコピー時の証拠金負荷"。
    • "最低証拠金*(Min. deposit)" — 95%の証拠金を使用する時の、1:1のコピーの為に必要な証拠金。つまりこれは、証拠金負荷率"95%"を選択した場合に、1:1の比率であなたの取引口座にシグナル配信者の取引をコピーする証拠金です。
  • コピー係数の詳細な計算 —選択したシグナルのコピー係数の段階的な詳細な計算です。
    • К1 — あなたの取引口座とシグナル配信者の取引口座の通貨の相関係数。
    • К2 — あなたの取引口座とシグナル配信者の残高の相関係数。
    • К3 — 証拠金使用係数。百分率から係数への換算。
    • К4 — 取引レバレッジの差に対する補正係数。
    • К — 最終係数。係数К1×К2×К3×К4の積として計算されます。
    • コピー ー 係数Кで、段階的システムに基づき四捨五入したもの

2.3. コピー係数の取得

シグナル一覧表の各シグナルの"コピー係数"の列では、設定での選択時に各シグナルに算出されたコピー係数を参照することができます。("取引口座残高"、"取引口座通貨"、"取引口座レバレッジ"、"シグナルコピー時の証拠金負荷") 

必要に応じて設定は変更することができます(取引口座残高"、"取引口座通貨"、"取引口座レバレッジ"、"シグナルコピー時の証拠金負荷")。これらの設定の変更によって、コピー係数の再計算と一覧表が更新されるので、"最低証拠金*"の列を降順で並び替えた後も、トレードシグナルが一覧表の元の位置に留まっているというわけではありません。したがって、リアルタイムで、取引口座の様々な設定下でトレードシグナルコピーの係数が、どのように変化するかを見ることができます。

2.4. コピー係数計算の詳細化

特定の信号の詳細なコピー係数を算出するには、シグナル一覧表の中の興味のあるシグナルの列をクリックする必要があります(アクション1)。その後で、シグナル一覧表の下に、選択したシグナルの詳細なコピー係数の計算が表示されます(アクション2)。

  コピー係数計算の詳細化

図3. コピー係数計算の詳細化 

2.5. マッピング不可

"取引口座の通貨"リストで他の通貨を選んだ後、コピー係数算出の為に、シグナル計算機は『気配値ウィンドウ』であなたの取引口座の通貨(または、"取引口座通貨"のリストで選択された通貨)を自身の名前に含む通貨ペアを検索します。例えば、あなたの取引口座の通貨が"USD"で、シグナル配信者の取引口座の通貨が"EUR"であるとします。このような場合、計算機は『気配値ウィンドウ』で"USDEUR"や"EURUSD"を検索します。通貨ペアが見つからない場合、ターミナルの『エキスパート』タブにエラーメッセージが表示されます。

"SGD"の通貨の"取引口座通貨"リストで選択を行った後のエラーメッセージの例:

Сalculator for signals (EURUSD,M5)      Error find symbols: (Account currency SGD, Signal currency RUB)
Сalculator for signals (EURUSD,M5)      Error find symbols: (Account currency SGD, Signal currency EUR)
Сalculator for signals (EURUSD,M5)      Error find symbols: (Account currency SGD, Signal currency EUR)

このメッセージは、『気配値ウィンドウ』に、"SGDRUB"、"SGDEUR"、"RUBSGD"、"EURSGD"の通貨ペアがないことを意味しています。これが本当にそうであるかを確かめてみましょう。『気配値ウィンドウ』で"SGD"という名前がある任意の通貨ペアを検索します。この為には、『気配値ウィンドウ』で『+クリックして追加』をクリックする必要があります。

 『気配値ウィンドウ』での『追加』コマンド

図4.  『気配値ウィンドウ』での『追加』コマンド

そして、開いた欄に"SGD"と入力します。


図5. "SGD"の名前を含む『気配値ウィンドウ』内の利用可能な通貨ペアの一覧   

ご覧のように、『気配値ウィンドウ』にはすでに一つの通貨ペア"USDSGD"があり、さらに"SGDJPY"も加えることができますが、"SGDRUB"、"SGDEUR"、"RUBSGD"、"EURSGD"の通貨ペアはありません。 

マッピングができない場合、シグナル一覧表の"コピー係数"タブに"n/d"が表示され、これは"データがない"ことを意味します。

シグナル計算機についての短いビデオ:



3. シグナル計算機の作成

3.1. インターフェイスを設計しましょう

シグナル計算機での制御要素は次のようになります。

 制御要素の配置
 

図6. 制御要素の配置 

配置やサイズ、そして要素の作成は、添付のファイル"Сalculator for signals Dialog.mqh"が行います。制御及び余白の要素の主なサイズは、マクロ置換ブロックを使用し設定されます。

//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
//--- indents and gaps
#define INDENT_LEFT                         (11)      // indent from left (with allowance for border width)
#define INDENT_TOP                          (11)      // indent from top (with allowance for border width)
#define CONTROLS_GAP_Y                      (5)       // gap by Y coordinate
//--- for combo boxes
#define COMBOBOX_WIDTH                      (60)      // size by X coordinate
#define COMBOBOX_HEIGHT                     (20)      // size by Y coordinate
//--- for list view
#define LIST_HEIGHT                         (102)     // size by Y coordinate
//--- for buttons
#define BUTTON_WIDTH                        (72)      // size by X coordinate
#define BUTTON_HEIGHT                       (20)      // size by Y coordinate
//--- for the indication area
#define EDIT_WIDTH                          (60)      // size by X coordinate
#define EDIT_HEIGHT                         (20)      // size by Y coordinate

制御オブジェクトはパネル上では5つの列で配置されています。

  1. 1列目 — Label1、Edit1、ComboBox1、Label2、ComboBox2、Label3、ComboBox2
  2. 2列目 — Label 4
  3. 3列目 — Button1からButton8までのボタン
  4. 4列目 — 新しい制御要素 — TableListView1表
  5. 5列目 — オン状態で要素を表示するbmpファイルとしてのBmpButton1は、CCanvasデータベースのグラフィックリソースが割り当てられます。
大事なことは、全ての制御オブジェクトは、ダイアログパネルに配置されるということを覚えておくことです(メインパネルはこちらで作成されます)。

//+------------------------------------------------------------------+
//| Create                                                           |
//+------------------------------------------------------------------+
bool CoSDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//---
   m_error=true;
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
//---

これはつまり、各制御オブジェクトは、作成後に必要な方法でCDialogクラスのAddを使用し、クライアント領域に追加する必要があるということです。Label4オブジェクト作成例で、これがどのようになるかを見てみましょう。

//+------------------------------------------------------------------+
//| Create the "Signals" Label                                       |
//+------------------------------------------------------------------+
bool CoSDialog::CreateLabel4(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+COMBOBOX_HEIGHT+CONTROLS_GAP_Y;
   int x2=x1+100;
   int y2=y1+COMBOBOX_HEIGHT;
//--- create
   if(!m_label4.Create(m_chart_id,m_name+"Label4",m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_label4.Text(m_languages.GetText(3)))
      return(false);
   if(!Add(m_label4))
      return(false);
//--- succeed
   return(true);
  }

まずLabel4オブジェクトを作成しましょう。

   if(!m_label4.Create(m_chart_id,m_name+"Label4",m_subwin,x1,y1,x2,y2))
      return(false);

そして、関数から離れる前に、Addメソッドを使用し、クライアント領域へ再び作成したLabel4オブジェクトを追加する必要があります。

   if(!Add(m_label4))
      return(false);

パネル作成と、このパネル上の制御要素の作成プロセスは、シグナル計算機のパネル作成の例の中で、スキームとしてご紹介することができます。

パネルオブジェクト作成スキーム

図7. パネルオブジェクト作成スキーム 

要約をすると、一般的には、パネル作成は次のプランに則って行われます。

  • パネル自体の作成(CAppDialog::Create)
  • 順番に制御要素を作成し、この時各制御要素は、次の順序で作成されます。
    • 要素作成(element_N.Create)
    • 要素の特性の変更
    • 要素のパネルへの必須追加(Add(elenemt_N))

3.2. パネルにキャンバスを作成しましょう

キャンバスの作成は、CoSDialog::CreateBmpButton1で行われます。

始めに短く、いくつかのステップで行われます。

ステップ1: チャートオブジェクトの参照がないグラフィックリソースを作成しましょう(CCanvasクラスのCreateを使用します)

ステップ2: CBmpButtonクラス(『グラフィックマーク』オブジェクトに基づいた簡単な制御要素のクラス)のm_bmp_button1制御要素を作成します

ステップ3: m_bmp_button1制御要素の為に、オン状態のbmpファイルとして(BmpOnNameメソッド)私達のキャンバスに設定します。

ステップ4: m_bmp_button1制御要素をパネルに追加します(CDialogクラスのAddメソッド)

ここで、各ステップについて詳しく解説します。

ステップ1 

//--- create canvas
   if(!m_canvas1.Create("Canvas1",x2,y2,COLOR_FORMAT_XRGB_NOALPHA))
     {
      Print("Error creating canvas: ",GetLastError());
      return(false);
     }
   m_canvas1.FontSet("Trebuchet MS",-100,FW_THIN);
   m_canvas1.Erase(ColorToARGB(C'0xF7,0xF7,0xF7',255));
   m_canvas1.Update(true);

キャンバス作成(m_canvas1.Create)時に、幅x2と高さy2が指定されるという点に注意してください(実際にこれは変化しないアイコンサイズになります)。

キャンバスサイズ
 

図8. キャンバスサイズ 

次にキャンバスの為のフォント(m_canvas1.FontSet)が指定され、パネルの内側の色でキャンバスが塗りつぶされ(m_canvas1.Erase)、そして必ず変更が画面に表示されます(m_canvas1.Update)。

ステップ2

//--- create
   if(!m_bmp_button1.Create(m_chart_id,m_name+"BmpButton1",m_subwin,x1,y1,x1+10,y1+10))
      return(false);

m_bmp_button1制御要素を10×10ピクセルのサイズで作成します。制御要素の小さいサイズは、重要ではありません。ここでは、x1y1の座標自体が重要です。この点はアンカーポイントです。つまり、制御要素のサイズがアイコンサイズの下で調整されるときに、座標を伴う角(x1; y1)が所定の位置に残ります。

ステップ3

//--- sets the name of bmp files of the control CBmpButton
   if(!m_bmp_button1.BmpOnName(m_canvas1.ResourceName()))
      return(false);

リソース名(m_canvas1.ResourceName())を取得し、オン状態のbmpファイルとして割り当てます(m_bmp_button1.BmpOnName)。この段階でm_bmp_button1制御要素が、キャンバスのサイズに基づいて引き伸ばされます。

ステップ4

制御要素の作成後に、この要素をパネルに追加するのを忘れないようにしましょう。 

   if(!Add(m_bmp_button1))
      return(false);

3.3. 二次元配列並べ替え

並び替えはCoSDialog::InitStructursメソッドの"Сalculator for signals Dialog.mqh"ファイルで行われます。 

シグナル計算機では一覧表のデータは、算出した指標(コピー係数)で並び替えられます。しかし、コピー係数の取得プロセスでは、シグナル名や算出されたコピー係数から構成されるリストは、並び替えはされません。これは以下のようになります。

Name Copy ratio
TestUSD 15.0
TradeLargeVolumes 120.0
Zeus PRO 15.0
CS Trading Co Beta Free Provider 1510.0
Mint blueberry ice cream 8.0
MT5Hedging 7.0
Forex Leos Trading 160.0
Hedge 1.0
Siksikawa 8770.0
Week H4 15.0
WGT Live Signal 45.0
Atrader 30.0
Trajecta Advisor FX491 30.0
MOsg style 6.0 

並び替えにはユーザーのVasiliy Sokolovにアドバイスされたものを適用しました。それは、各列をCObjectオブジェクトのように表示し、全ての表をCArrayObjオブジェクトのように表示します。このような表は線形と呼ばれ、仮想線形表のクラス(表はビジュアルインターフェイスを持たない為仮想です)は"LineTable.mqh"ファイルに配置されます。

線形表の並び替え結果は以下のようになります(複数の最初の線形表への挿入を例としています)。線形表に挿入されるパラメータが最初に表示されます(Insert : )。線形表の全ての要素は以下の通りです(row #)。

name rate  min_deposit
 Insert : MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #0: MyCorrelation EURUSD XAUUSD  7  133134.7143
 Insert : EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 row #0: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #1: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 Insert : EURUSD Daytrade  170  5482.017647
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: MyCorrelation EURUSD XAUUSD  7   133134.7143
 row #2: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 Insert : Exp TickSniper PRO FULL MT5  50  18638.86
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: Exp TickSniper PRO FULL MT5  50  18638.86
 row #2: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #3: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 Insert : Example1  3  310647.6667
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: Exp TickSniper PRO FULL MT5  50  18638.86
 row #2: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #3: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 row #4: Example1  3  310647.6667
 Insert : Big sale  80  11649.2875
 row #0: EURUSD Daytrade  170  5482.017647
 row #1: Big sale  80  11649.2875
 row #2: Exp TickSniper PRO FULL MT5  50  18638.86
 row #3: MyCorrelation EURUSD XAUUSD  7  133134.7143
 row #4: EA microPatience AvzPrecio v6 HG 10  7  133134.7143
 row #5: Example1  3  310647.6667

図では線形表への追加後に"rate"欄の並べ替えが行われていることがはっきりと分かり、これがまさに私達に必要なものです。次に、線形表の全ての要素が並び替えられたことを認識することで、これらの数値を新しい制御要素(таблицу CTableListView)へコピーすることができ、データが並び替えられて表示されることを確信できます。

段階的ソートの出力とこの表を取得する為には、CoSDialog::InitStructursメソッドの"Сalculator for signals Dialog.mqh"ファイルで列のコメントを外してください。 

         else
           {
            min_deposit=AccInfo.balance/rate*100.0;
           }
         //Print("Insert : ",name,"; ",rate,"; ",min_deposit); 
         m_table.InsertSort(new CLineTable(name,rate,min_deposit));
         //for(int m=0;m<m_table.Total();m++)
         //  {
         //   CLineTable *line=m_table.At(m);
         //   Print("row #",m,": ",line.Text(),"; ",line.Number(),"; ",line.Number1());
         //  }
        }
      else PrintFormat("Error in call of SignalBaseSelect. Error code=%d",GetLastError());
     }
//---
   return(true);
  }

3.4. 新しい制御要素―CTableListView表

シグナルやその特性、算出したデータを表示するには、制御の仮想要素(いくつかの列と行の表示をすることができる表)を作成します。この時、表の列数が表の高さよりも多い場合は、垂直のスクロールバーが出現します。検索後に、ベースとしてCListViewクラスの制御要素を使用することと、それを大幅にグレードアップすることを決めました。

CTableListView表の制御要素は、二つの部分を持っています。ユーザーが見て物理的に接触する可視部分と、表のセルのデータが保存される非可視部分です。

表の可視部分は、制御要素自体のサイズに条件づけられます。これは座標(x1; y1)と(x2; y2)を持つ長方形と、Createメソッドで要素を作成する時に指定されるcolumnsで制限されています。

   virtual bool      Create(const long chart,const string name,const int subwin,const int x1,
                            const int y1,const int x2,const int y2,const uchar columns,const ushort &columns_size[]);

可視部分は、CEdit制御要素から構成されています。 

CTableListView表の可視部分の構築

図9. CTableListView表の可視部分の構築

可視部分のCEdit制御要素は、m_arr_rows  ポインタの動的配列(CArrayObjクラスのオブジェクトの)で作成および管理されます。

   CArrayObj         m_arr_rows;             // array of pointer to objects-rows (CEdit) 

(ポインタの使用についての記事 MQL5でポインタを使用する必要がある時)

m_arr_rowsポインタ配列は、2つのレベルからなるマトリョーシカ(*翻訳注:ロシアの入れ子人形)です。第一レベルではrowオブジェクト・列のポインタが保存され、rowオブジェクト・列は表のオブジェクト・セル(CEdit要素)のポインタを保存します。

可視オブジェクトのポインタ

図10. 可視オブジェクトのポインタ 

非可視部分も、CArrayObjクラスを使用して実装されます。非可視部分は、m_arr_rows_str m_arr_rows_valの二つのポインタ動的配列が担っています。

   CArrayObj         m_arr_rows_str;         // array of pointer to objects-rows (CArrayString) 
   CArrayObj         m_arr_rows_val;         // array of pointer to objects-rows (CArrayLong) 

数値とセルのテキストをそれぞれ格納します。

m_arr_rows_str m_arr_rows_valのポインタ配列構造体は、m_arr_rowsポインタ配列構造体と類似していて、CArrayStringCArrayLongクラス配列はそれぞれ文字列として使用されます。

3.4.1. ポインタの動的配列の使用例

ポインタの動的配列の使用を、表/オブジェクト作成例で見てみましょう。

//+------------------------------------------------------------------+
//| Create a control                                                 |
//+------------------------------------------------------------------+
bool CTableListView::Create(const long chart,const string name,const int subwin,const int x1,
                            const int y1,const int x2,const int y2,const uchar columns,const ushort &columns_size[])
  {
   m_columns=columns;
   ArrayResize(m_columns_size,m_columns);
   if(ArraySize(columns_size)!=m_columns)
      return(false);
   ArrayCopy(m_columns_size,columns_size,0,0,WHOLE_ARRAY);
   m_columns_size[0]-=1;
   m_columns_size[m_columns-1]-=1;
   int y=y2;
//--- if the number of visible rows is previously determined, adjust the vertical size
   if(!TotalView((y2-y1)/m_item_height))
      y=m_item_height+y1+2*CONTROLS_BORDER_WIDTH;
//--- check the number of visible rows
   if(m_total_view<1)
      return(false);
//--- call method of the parent class
   if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y))
      return(false);
//--- set up
   if(!m_background.ColorBackground(CONTROLS_LIST_COLOR_BG))
      return(false);
   if(!m_background.ColorBorder(CONTROLS_LIST_COLOR_BORDER))
      return(false);
//--- create dependent controls
   CArrayObj *m_arr_cells;
   for(int i=0;i<m_total_view;i++)
     {
      m_arr_cells=new CArrayObj;
      if(CheckPointer(m_arr_cells)==POINTER_INVALID)
         return(false);
      for(int j=0;j<m_columns;j++)
        {
         CEdit *m_cell;
         m_cell=new CEdit;
         if(CheckPointer(m_cell)==POINTER_INVALID)
            return(false);
         m_arr_cells.Add(m_cell);
        }
      m_arr_rows.Add(m_arr_cells);
     }
//---
   for(int i=0;i<m_total_view;i++)
     {
      if(!CreateRow(i))
         return(false);
      if(m_height_variable && i>0)
        {
         // m_rows[i].Hide(); ///
         CArrayObj *m_arr_cells_i=m_arr_rows.At(i);
         if(CheckPointer(m_arr_cells_i)==POINTER_INVALID)
            return(false);
         for(int j=0;j<m_arr_cells_i.Total();j++)
           {
            CEdit *m_cell=m_arr_cells_i.At(j);
            if(CheckPointer(m_cell)==POINTER_INVALID)
               return(false);
            if(!m_cell.Hide())
               return(false);
           }
        }
     }
//--- succeed
   return(true);
  }

コードブロックでは

//--- if the number of visible rows is previously determined, adjust the vertical size
   if(!TotalView((y2-y1)/m_item_height))
      y=m_item_height+y1+2*CONTROLS_BORDER_WIDTH;

表示される行数を計算するTotalViewが呼び出されます。この数はm_total_view変数に格納されます。

次に、for(int i=0;i<m_total_view;i++)のサイクルでは、m_arr_cells列が作成され、for(int j=0;j<m_columns;j++) サイクルでは、行はm_cellのセルで埋められます。

//--- create dependent controls
   CArrayObj *m_arr_cells;
   for(int i=0;i<m_total_view;i++)
     {
      m_arr_cells=new CArrayObj;
      if(CheckPointer(m_arr_cells)==POINTER_INVALID)
         return(false);
      for(int j=0;j<m_columns;j++)
        {
         CEdit *m_cell;
         m_cell=new CEdit;
         if(CheckPointer(m_cell)==POINTER_INVALID)
            return(false);
         m_arr_cells.Add(m_cell);
        }
      m_arr_rows.Add(m_arr_cells);
     }
//---

for(int j=0;j<m_columns;j++)サイクルのフルクロール後、埋められた行はそれぞれ、 m_arr_rows主配列に追加されます。

      m_arr_rows.Add(m_arr_cells);

このように、for(int i=0;i<m_total_view;i++)サイクルのフルクロール後、私達は表の可視部分に対応する、埋められたm_arr_rowsポインタ配列を持つことになります。(図9を参照)

二つ目のfor(int i=0;i<m_total_view;i++)サイクルでポインタ配列を埋めた後、CreateRowの呼び出しを介して、表のビジュアル化(表の可視部分の作成)が行われます。

//---
   for(int i=0;i<m_total_view;i++)
     {
      if(!CreateRow(i))
         return(false);
      .
      .
      .
     }
//--- succeed
   return(true);

CreateRowメソッド。

//+------------------------------------------------------------------+
//| Create "row"                                                     |
//+------------------------------------------------------------------+
bool CTableListView::CreateRow(const int index)
  {
   .
   .
   .
//--- create
   CArrayObj *m_arr_cells=m_arr_rows.At(index);
   if(CheckPointer(m_arr_cells)==POINTER_INVALID)
      return(false);
   for(int i=0;i<m_arr_cells.Total();i++)
     {
      CEdit *m_cell=m_arr_cells.At(i);
      if(CheckPointer(m_cell)==POINTER_INVALID)
         return(false);
      x1+=x2;
      x2=m_columns_size[i];
      if(!m_cell.Create(m_chart_id,m_name+"_"+IntegerToString(index)+"_"+IntegerToString(i),
         m_subwin,x1,y1,x1+x2,y2))
         return(false);
      if(!m_cell.Text(""))
         return(false);
      if(!m_cell.ReadOnly(true))
         return(false);
      if(!Add(m_cell))
         return(false);
     }
   .
   .
   .
   return(true);
  }

コードのブロックでm_arr_rowsポインタ配列の中から、私達はm_arr_cells要素へのポインタ(m_arr_cells要素はCArrayObjタイプを持っています)を取得し、これはindexポジションに配置されています。m_arr_cells要素こそが、row表の行です(図10を参照)。CArrayObjクラスのAtメソッドを使用します。

   .
//--- create
   CArrayObj *m_arr_cells=m_arr_rows.At(index);
   if(CheckPointer(m_arr_cells)==POINTER_INVALID)
      return(false);
   for(int i=0;i<m_arr_cells.Total();i++)

次にfor(int i=0;i<m_arr_cells.Total();i++)サイクルで、m_arr_cells要素(ポインタ配列)を使ってみましょう。m_arr_cellsポインタ配列からm_cell要素へのポインタを取得します(m_cell要素はCEditタイプを持っています)。これはiポジションにあります。

      CEdit *m_cell=m_arr_cells.At(i);
      if(CheckPointer(m_cell)==POINTER_INVALID)
         return(false);

それから一意の名前を持つセルを作成します(CEditクラスの制御要素)。

      if(!m_cell.Create(m_chart_id,m_name+"_"+IntegerToString(index)+"_"+IntegerToString(i),
         m_subwin,x1,y1,x1+x2,y2))
         return(false);

作成した制御要素のいくつかのプロパティを変更します(制御要素の全テキストを削除し、制御要素を編集不可にします)。

      if(!m_cell.Text(""))
         return(false);
      if(!m_cell.ReadOnly(true))
         return(false);

そして最後かつとても重要なステップです。作成した制御要素を再び私達のパネルに追加します。

      if(!Add(m_cell))
         return(false);
     }

 

まとめ

シグナル計算機が、シグナルを選択する時のお役に立つことを願っています。重要なのは計算機が、あなたの取引口座のレバレッジまたは証拠金額を(計算機で)変えた場合に、コピー係数がどのように変化するかを理解する一助となることです。


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

添付されたファイル |
MQL5言語でのTelegram用ボットの作成 MQL5言語でのTelegram用ボットの作成
この記事では、MQL5言語でのTelegram用ボットの作成を順を追って説明していきます。この資料は、トレードロボットを自分のモバイルデバイスに繋げたい人にとって、興味深いものになると思います。記事では、トレードシグナルのリンクの実行、サイト上の情報の検索、取引口座の状態や相場、チャートのスクリーンショットをあなたのモバイルデバイスへ送信するボットの例をご紹介します。
取引システムのコンポーネントを分析することによる有効性の評価 取引システムのコンポーネントを分析することによる有効性の評価
本稿では、個々の構成要素を分析することで、複合取引システムの有効性を検証していきます。グラフィックであれ、インディケータや何かしらのものをベースにしたものであれ、どんな分析も金融市場取引で成功を収めるための重要な要素の一つです。この記事では、いくつかの独立した簡単な取引システムの検証のようなものと、それらの有効性や並行利用の有用性を分析します。
グラフィカルインタフェース V: 縦横のスクロールバー(チャプター 1) グラフィカルインタフェース V: 縦横のスクロールバー(チャプター 1)
MetaTrader環境でのグラフィカルインタフェースを作成するためのライブラリの開発の検討が続きます。シリーズの第一部の最初の記事では、縦横のスクロールバーを作成するためのクラスを作成します。
GUIコントロールのレイアウトとコンテナの使用:CGrid クラス GUIコントロールのレイアウトとコンテナの使用:CGrid クラス
この記事では、1つのレイアウトマネージャを使用して、レイアウトやコンテナに基づいて、GUI作成の代替方法を提示しています。CGridクラスは、グリッドレイアウトを使用して、他のコンテナやコントロールのコンテナとして機能する補助コントロールです。