記事"Canvasクラスを使用したカスタム指標の開発"についてのディスカッション

 

新しい記事 Canvasクラスを使用したカスタム指標の開発 はパブリッシュされました:

本稿では、Canvasクラスのグラフィカルプリミティブを使用してカスタムグラフィカル指標を開発する方法について説明します。

単純な円弧表示とは異なり、分割指標は等間隔を分割するラベルを持つように見えます。この種の指標のレイアウトを作成するときは、10個のセクションを作成し、新要素、つまり内部フレームを追加することにしました。円弧分割指標を有する基本的な構造を図5に示します。


図5 円弧分割指標を有する円形指標の基本構造

作者: Alexander Fedosov

 

記事を書いてくれた著者に感謝する。私自身、シンプルな(しかし同時にエレガントな)解決策をたくさん思いついた。

 

ああ、なんと美しい!記念に追加しておきます。)
 

CustomGUIクラスを使用して実装された同じインジケータのコピーを複数適用する場合、Create() メソッド内の名前は異なるものでなければならないという事実に、もう一度注意を喚起したいと思います。 例として、実装を以下に示します。

#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//---
#include <CustomGUI\CustomGUI.mqh>
CCircleSection ind;
//+------------------------------------------------------------------+
//| インジケータの入力パラメータ|
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES   tf=PERIOD_CURRENT;
input int               period=10;
input int               indsize=50;
input ENUM_ORIENTATION  orient=VERTICAL;
input int               X=100;
input int               Y=100;
//---
int      IndHandle;
double   rsi[];
//+------------------------------------------------------------------+
//| カスタムインジケータ初期化関数
//+------------------------------------------------------------------+
int OnInit()
  {
//--- インジケーター・ハンドルを取得する
   IndHandle=iRSI(Symbol(),tf,period,PRICE_CLOSE);
   if(IndHandle==INVALID_HANDLE)
     {
      Print("Failed to get indicator handle");
      return(INIT_FAILED);
     }
   ArraySetAsSeries(rsi,true);
//---
   ind.Radius(indsize);
   ind.LabelSize(15);
   ind.LabelValue("RSI "+"("+IntegerToString(period)+")");
   ind.Orientation(orient);
   ind.Create("rsi_custom"+IntegerToString(MathRand()),X,Y);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| カスタム・インジケータ反復関数
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(CopyBuffer(IndHandle,0,0,1,rsi)<1)
      return(0);
   ind.NewValue(rsi[0]);
//--- 次の呼び出しのためにprev_calculatedの値を返す
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| カスタム・インジケータの初期化関数
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ind.Delete();
   ChartRedraw();
  }
//+------------------------------------------------------------------+

Create() メソッドの名前は一意です。

ファイル:
 

ありがとうございます。

MT4またはMT5で、インジケーターオブジェクトを選択 する機能を実装することは可能ですか?(例えば、ライン)。

例えば、線をダブルクリックすると、その線が太線で強調表示され、線の説明が表示されます。

 
Ilmir Galiev:

ありがとうございます。

MT4またはMT5で、インジケーターオブジェクトを選択 する機能を実装することは可能ですか?(例えば、ライン)。

例えば、線をダブルクリックすると、その線が太線で強調表示され、線の説明が表示され、その逆も同様です。

いいえ。この方法の本質は、何らかの条件が変化したときに再描画される であるということです。ホットキーやマウスクリックのイベントには反応しません。
 
Alexander Fedosov:
このメソッドの本質は、何らかの条件が変化したときに再描画される画像 であるということです。ホットキーやマウスクリックのイベントには反応しない。

おいおい。マウスクリックって何?何か条件が変わる」ことではない。イベントを発生させ、それを使ってキャンバスを本来あるべき姿に再描画するのだ。イルミル、あなたの質問に対する正しい答えは、もちろんできます。

 

良いトピックだ。著者に感謝し、キャンバスにティックインジケーターを 作るつもりだ......。

気づいたことがあります。

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CCanvasBase
  {
private:
   //--- キャンバス名
   string            m_canvas_name;
   //--- キャンバスの座標
   int               m_x;
   int               m_y;
   //--- キャンバスサイズ
   int               m_x_size;
   int               m_y_size;
protected:
   CCanvas           m_canvas;
   //--- オブジェクトのグラフィカル・リソースを作成します。
   bool              CreateCanvas(void);
   //--- グラフィックスリソースを削除する
   bool              DeleteCanvas(void);
public:
                     CCanvasBase(void);
                    ~CCanvasBase(void);
   //--- 座標を設定し、返す
   void              X(const int x)                         { m_x=x;                      }
   void              Y(const int y)                         { m_y=y;                      }
   int               X(void)                                { return(m_x);                }
   int               Y(void)                                { return(m_y);                }
   //--- 次元を設定し、返す
   void              XSize(const int x_size)                { m_x_size=x_size;            }
   void              YSize(const int y_size)                { m_y_size=y_size;            }
   int               XSize(void)                            { return(m_x_size);           }
   int               YSize(void)                            { return(m_y_size);           }
   //--- インジケータ作成時にインジケータ名を設定
   void              Name(const string canvas_name) { m_canvas_name=canvas_name;  }
  };

プライベート・ データ・メンバーm_canvas_nameが あるのに、その値を設定するメソッドName()パブリックになって いる。カプセル化の原則に違反している。このメソッドをprivateにしよう。

 
Dennis Kirichenko:

良いトピックだ。作者に感謝し、キャンバスにティックインジケーターを 作るつもりだ。

スケッチがあれば、スクリーンショットやビデオを送ってください。自分でもそのようなインジケーターを投稿したのですが、人々の手には届きませんでした。これ以上のものは見つかっていませんが。キャンバス上の他のソリューションを見るのは興味深い。

 
fxsaber:

私自身もそのようなインジケーターを投稿したが、人々の元には届かなかった。

投稿したんだ。

私はそれを基にティックスピードインジケーターを作ろうとしているくらいだ。

 
Andrey Khatimlianskii:
行け、行け、行け。

これを元にティックレートインジケーターを作ろうとしているくらいだ。

それはいいニュースだ!どういうこと?ティック履歴の 代わりにカスタム時系列を代用する?