English Русский 中文 Español Deutsch Português
手動のチャート作成および取引ツールキット(第I部)準備: 構造の説明とヘルパークラス

手動のチャート作成および取引ツールキット(第I部)準備: 構造の説明とヘルパークラス

MetaTrader 5 | 5 10月 2020, 06:56
812 0
Oleh Fedorov
Oleh Fedorov

はじめに


私は手動トレーダーで、複雑な数式や指標を使用せずに、手動で、つまり目で見てチャートを分析することを好みます。これにより、取引の柔軟性が高まります。形式化が難しいものに気づき、動きが加速または減速している場合には時間枠を簡単に切り替え、取引に入るずっと前に予想される価格行動を知ることができるのです。

基本的に、私はトレンドラインのさまざまな組み合わせ(ピッチフォーク、ファン、レベルなど)を使用するので、文字通り1回のキーストロークでトレンドラインをすばやく描画できる便利なツールを作成しました。ここでは、このツールをコミュニティと共有したいと思います。

ビデオプレゼンテーション:仕組み



一般的な概念タスクの設定


さて、キーボードショートカットを使用して最も頻繁な操作を実行するのに役立つツールを作成しています。

どんなタスクを実装できるでしょうか。以下は例です。

  • H」キー(「Horizontal」)を押して単純な水平線を描画し、「i」(単に垂直線のように見えるため)を押して垂直線を描画する
  • チャートの任意のポイントから開始して、特定の長さ(無限ではない)の水平線を描画する
  • 開始点から特定の(任意の)距離で垂直レベルを描画する
  • キーを使用して、時間枠を切り替え、チャート上のレイヤーを再配置する
  • 最も近い極値で、プリセットレベルでフィボナッチファンを描画する
  • 最も近い極値にトレンドラインを描く(長さは極値間の距離の倍数である必要があり、場合によっては半直線)
  • さまざまなタイプのアンドリューピッチフォークを描画する(標準、Schiff、逆Schiffピッチフォーク(高速トレンド用))(ビデオを参照)
  • ピッチフォーク、ライン、ファンの極値の場合、極値の順序をカスタマイズする機能が必要(バーの数、左側と右側を別々に)
  • 設定ウィンドウを開かずに必要なラインと極値のパラメータをカスタマイズできるグラフィカルインターフェイス
  • 一連の注文管理機能: 預金の割合に基づいて注文を開き、成行注文またはストップレベルのトリガーがない指値注文を開くときに自動的にストップレベルを設定し、レベルによる部分的なポジション決済、トレーリングストップなどを有効にする

もちろん、ほとんどのタスクはスクリプトを使用して自動化できます。私もいくつか持っているので、以下の添付ファイルのところでご覧ください。しかし、私は別のアプローチを好みます。

エキスパートアドバイザーや指標では、任意のイベント( キーストローク、マウスの動き、グラフィカルオブジェクトの作成または削除など)への反応の説明を含むOnChartEventメソッドを作成できます。

そのため、インクルードファイルとしてプログラムを作成することにしました。すべての関数と変数は、アクセスしやすいように複数のクラスに分散されています。この時点では、関数を便利にグループ化するためのクラスのみが必要です。そのため、この最初の実装では、継承やファクトリなどの複雑なものは使用しません。ただのコレクションです。

さらに、MQL4とMQL5の両方で実行できるクロスプラットフォームクラスを作成したいと思います。

プログラムの構成

ファイルのリスト

ライブラリには、5つの関連ファイルが含まれています。すべてのファイルは、インクルードディレクトリの「Shortcuts」フォルダにあります。図にあるように、それらはGlobalVariables.mqh、Graphics.mqh、Mouse.mqh、Shortcuts.mqh、Utilites.mqhです。

メインのライブラリファイル(Shortcuts.mqh)

プログラムのメインファイルShortcuts.mqhです。キーストロークに対する反応のロジックは、このファイルに書き込まれます。これは、エキスパートアドバイザーに接続する必要があるファイルです。すべての補助ファイルもインクルードされます。

//+------------------------------------------------------------------+
//|                                                    Shortcuts.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                            https://www.mql5.com/ru/articles/7468 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/en/articles/7468"

#include "GlobalVariables.mqh"
#include "Mouse.mqh"
#include "Utilites.mqh"
#include "Graphics.mqh"

//+------------------------------------------------------------------+
//| The main control class of the program. It should be connected    |
//| to the Expert Advisor                                            |
//+------------------------------------------------------------------+
class CShortcuts
  {
private:
   CGraphics         m_graphics;   // Object for drawing m_graphics
public:
                     CShortcuts();
   void              OnChartEvent(const int id,
                                  const long &lparam,
                                  const double &dparam,
                                  const string &sparam);
  };
//+------------------------------------------------------------------+
//| Default constructor                                              |
//+------------------------------------------------------------------+
CShortcuts::CShortcuts(void)
  {
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
  }

//+------------------------------------------------------------------+
//| Event handling function                                          |
//+------------------------------------------------------------------+
void CShortcuts::OnChartEvent(
   const int id,
   const long &lparam,
   const double &dparam,
   const string &sparam
)
  {
//---

   // This will contain the description of the events related to keystrokes
   // and mouse movements

   //  ...

  }
}

CShortcuts shortcuts;

ファイルにはCShortcutsクラスが記述されます。

すべての補助クラスはファイルの冒頭で接続されます。

クラスにあるのは2つのメソッドだけです。1番目はOnChartEventイベントハンドラで、すべてのキーストロークとマウスの動きのイベントが処理されます。2番目はデフォルトのコンストラクタで、ここではマウスの動きが処理されます。

クラス記述の後、shortcuts変数が作成されます。この変数は、ライブラリが接続されたときに、メインのエキスパートアドバイザーのOnChartEventメソッドで使用する必要があります。

接続には2行が必要です。

//+------------------------------------------------------------------+
//| The main Expert (file "Shortcuts-Main-Expert.mq5")               |
//+------------------------------------------------------------------+
#include <Shortcuts\Shortcuts.mqh>


// ...

//+------------------------------------------------------------------+
//| The ChartEvent function                                          |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   shortcuts.OnChartEvent(id,lparam,dparam,sparam);
  }

最初の行はクラスファイルを接続します。2行目は、イベント処理制御をクラスに転送します。

エキスパートアドバイザーが動作する準備が整い、コンパイルすると、線を描画できるようになります。

マウスの動きを処理するクラス

クラスは、現在のカーソル位置のすべての基本パラメータ(ピクセル単位および価格/時間単位での座標X、Y、ポインタが配置されているバー番号など)をすべて「Mouse.mqh」ファイルに格納します。

//+------------------------------------------------------------------+
//|                                                        Mouse.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                            https://www.mql5.com/ru/articles/7468 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/en/articles/7468"
//+------------------------------------------------------------------+
//| Mouse movement handling class                                    |
//+------------------------------------------------------------------+
class CMouse
  {
   //--- Members
private:
   static int        m_x;           // X
   static int        m_y;           // Y
   static int        m_barNumber;   // Bar number
   static bool       m_below;       // Indication of a cursor above the price
   static bool       m_above;       // Indication of a cursor below the price

   static datetime   m_currentTime; // Current time
   static double     m_currentPrice;// Current price
   //--- Methods
public:

   //--- Remembers the main parameters of the mouse cursor
   static void       SetCurrentParameters(
      const int id,
      const long &lparam,
      const double &dparam,
      const string &sparam
   );
   //--- Returns the X coordinate (in pixels) of the current cursor position
   static int        X(void) {return m_x;}
   //--- Returns the Y coordinate (in pixels) of the current cursor position
   static int        Y(void) {return m_y;}
   //--- Returns the price of the current cursor position
   static double     Price(void) {return m_currentPrice;}
   //--- Returns the time of the current cursor position
   static datetime   Time(void) {return m_currentTime;}
   //--- Returns the bar number of the current cursor position
   static int        Bar(void) {return m_barNumber;}
   //--- Returns a flag showing that the price is below the Low of the current bar
   static bool       Below(void) {return m_below;}
   //--- Returns a flag showing that the price is above the High of the current bar
   static bool       Above(void) {return m_above;}
  };
//---

int CMouse::m_x=0;
int CMouse::m_y=0;
int CMouse::m_barNumber=0;
bool CMouse::m_below=false;
bool CMouse::m_above=false;
datetime CMouse::m_currentTime=0;
double CMouse::m_currentPrice=0;


//+------------------------------------------------------------------+
//| Remembers the main parameters for a mouse movement: coordinates  |
//| of cursor in pixels and price/time, whether the cursor is        |
//| above or below the price.                                        |
//|+-----------------------------------------------------------------+
static void CMouse::SetCurrentParameters(
   const int id,
   const long &lparam,
   const double &dparam,
   const string &sparam
)
  {
//---
   int window = 0;
//---
   ChartXYToTimePrice(
      0,
      (int)lparam,
      (int)dparam,
      window,
      m_currentTime,
      m_currentPrice
   );
   m_x=(int)lparam;
   m_y=(int)dparam;
   m_barNumber=iBarShift(
                  Symbol(),
                  PERIOD_CURRENT,
                  m_currentTime
               );
   m_below=m_currentPrice<iLow(Symbol(),PERIOD_CURRENT,m_barNumber);
   m_above=m_currentPrice>iHigh(Symbol(),PERIOD_CURRENT,m_barNumber);
  }

//+------------------------------------------------------------------+

このクラスでは、メソッドが静的として宣言されているため、プログラム内のどこからでも使用できます。クラスインスタンスを作成する必要はありません。

エキスパートアドバイザー設定ブロックの説明 - GlobalVariables.mqhファイル


使用できるすべての設定は、GlobalVariables.mqhファイルに保存されます。

次の記事では、描画用のオブジェクトをさらに追加するため、さらに多くの設定について説明します。

以下は、現在のバージョンで使用されている設定のコードです。

//+------------------------------------------------------------------+
//|                                              GlobalVariables.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                            https://www.mql5.com/ru/articles/7468 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/en/articles/7468"
//+------------------------------------------------------------------+
//| File describing parameters available to the user                 |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Key settings                                                     |
//+------------------------------------------------------------------+
input string   Keys="=== Key settings ===";
input string   Up_Key="U";            // Switch timeframe up
input string   Down_Key="D";          // Switch timeframe down
input string   Trend_Line_Key="T";              // Trend line
input string   Switch_Trend_Ray_Key="R";        // Indication of a trend line ray
input string   Z_Index_Key="Z";                 // Indication of the chart on top

//+------------------------------------------------------------------+
//| Size settings                                                    |
//+------------------------------------------------------------------+
input string   Dimensions="=== Size settings ===";
input int      Trend_Line_Width=2;        // Trend line width

//+------------------------------------------------------------------+
//| Display styles                                                   |
//+------------------------------------------------------------------+
input string   Styles="=== Display styles ===";
input ENUM_LINE_STYLE      Trend_Line_Style=STYLE_SOLID;       // Trend line style

//+------------------------------------------------------------------+
//| Other parameters                                                 |
//+------------------------------------------------------------------+
input string               Others="=== Other parameters ===";

input bool                 Is_Trend_Ray=false;                      // Trend line - ray
input bool                 Is_Change_Timeframe_On_Create = true;    // Hide objects on higher timeframes?
                                                                    //   (true - hide, false - show)
input bool                 Is_Select_On_Create=true;                // Select upon creation
input bool                 Is_Different_Colors=true;                // Change colors for times

// Number of bars on the left and on the right
// for trend line and fan extreme points
input int                  Fractal_Size_Left=1;                     // Size of the left fractal
input int                  Fractal_Size_Right=1;                    // Size of the right fractal

//+------------------------------------------------------------------+
//| Name prefixes of drawn shapes (can be change only in code,       |
//| not visible in EA parameters)                                    |
//+------------------------------------------------------------------+
// string   Prefixes="=== Prefixes ===";

string   Trend_Line_Prefix="Trend_";                     // Trend line prefix

//+------------------------------------------------------------------+
//| Colors for objects of one timeframe (can be changed only in code,|
//| not visible in EA parameters)                                    |
//+------------------------------------------------------------------+
// string TimeframeColors="=== Time frame colors ===";
color mn1_color=clrCrimson;
color w1_color=clrDarkOrange;
color d1_color=clrGoldenrod;
color h4_color=clrLimeGreen;
color h1_color=clrLime;
color m30_color=clrDeepSkyBlue;
color m15_color=clrBlue;
color m5_color=clrViolet;
color m1_color=clrDarkViolet;
color common_color=clrGray;

//--- Auxiliary constant for displaying error messages
#define DEBUG_MESSAGE_PREFIX "=== ",__FUNCTION__," === "

//--- Constants for describing the main timeframes when drawing
#define PERIOD_LOWER_M5 OBJ_PERIOD_M1|OBJ_PERIOD_M5
#define PERIOD_LOWER_M15 PERIOD_LOWER_M5|OBJ_PERIOD_M15
#define PERIOD_LOWER_M30 PERIOD_LOWER_M15|OBJ_PERIOD_M30
#define PERIOD_LOWER_H1 PERIOD_LOWER_M30|OBJ_PERIOD_H1
#define PERIOD_LOWER_H4 PERIOD_LOWER_H1|OBJ_PERIOD_H4
#define PERIOD_LOWER_D1 PERIOD_LOWER_H4|OBJ_PERIOD_D1
#define PERIOD_LOWER_W1 PERIOD_LOWER_D1|OBJ_PERIOD_W1
//+------------------------------------------------------------------+


補助関数

このプログラムには、極値の検索、時間枠の切り替えなどに役立ち、チャート作成とは直接関係のない多くの関数があります。これらの関数はすべて、「Utilites.mqh」ファイルに実装されています。

Utilites.mqhファイルヘッダ

//+------------------------------------------------------------------+
//|                                                     Utilites.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                            https://www.mql5.com/ru/articles/7468 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/en/articles/7468"

//+------------------------------------------------------------------+
//| Class describing auxiliary functions                             |
//+------------------------------------------------------------------+
class CUtilites
  {
public:
   //--- Changes the timeframe to the next one on the toolbar
   static void       ChangeTimeframes(bool isUp);
   //--- Converts string command constants to keycodes
   static int        GetCurrentOperationChar(string keyString);
   //--- Switches layers in charts (the chart is on top of all objects)
   static void       ChangeChartZIndex(void);
   //--- Returns the number of the nearest extreme bar
   static int        GetNearestExtremumBarNumber(
      int starting_number=0,
      bool is_search_right=false,
      bool is_up=false,
      int left_side_bars=1,
      int right_side_bars=1,
      string symbol=NULL,
      ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT
   );

   //--- Returns the color for the current timeframe
   static color      GetTimeFrameColor(long allDownPeriodsValue);
   //--- Returns a list of all timeframes lower than the current one (including the current one)
   static long       GetAllLowerTimeframes(int NeededTimeframe=PERIOD_CURRENT);
   //--- Coordinates of the straight line. Writes numbers of extreme bars to points p1 and p2
   static void       SetExtremumsBarsNumbers(bool _is_up,int &p1, int &p2);
   //--- Converts a string to an array of floating point numbers
   static void       StringToDoubleArray(
      string _haystack,
      double &_result[],
      const string _delimiter=","
   );
   //--- Determines the name of the current object
   static string            GetCurrentObjectName(
      const string _prefix,
      const ENUM_OBJECT _type=OBJ_TREND,
      int _number = -1
   );
   //--- Obtains the number of the next object
   static int               GetNextObjectNumber(
      const string _prefix,
      const ENUM_OBJECT _object_type,
      bool true
   );
   //--- Returns the distance, in screen pixels, between adjacent bars
   static int               GetBarsPixelDistance(void);
   //--- Converts a numeric value of the timeframe to its string name
   static string            GetTimeframeSymbolName(
      ENUM_TIMEFRAMES _timeframe=PERIOD_CURRENT  // Desired timeframe
   );
  };

この関数は、チャートの期間を順番に変更します。

このファイルの最初の関数は単純です。たとえば、現在のチャートの期間を順番に変更する関数は、次のようになります。

//+------------------------------------------------------------------+
//| Sequentially changes the current chart period                    |
//|                                                                  |
//| In this implementation, only the timeframes shown in the         |
//| standard panel are used.                                         |
//|                                                                  |
//| Parameters:                                                      |
//|    _isUp - timeframe switch direction: up (true)                 |
//|            or down (false)                                       |
//+------------------------------------------------------------------+
static void CUtilites::ChangeTimeframes(bool _isUp)
  {
   ENUM_TIMEFRAMES timeframes[] =
     {
      PERIOD_CURRENT,
      PERIOD_M1,
      PERIOD_M5,
      PERIOD_M15,
      PERIOD_M30,
      PERIOD_H1,
      PERIOD_H4,
      PERIOD_D1,
      PERIOD_W1,
      PERIOD_MN1
     };
   int period = Period();
   int shift = ArrayBsearch(timeframes,period);
   if(_isUp && shift < ArraySize(timeframes)-1)
     {
      ChartSetSymbolPeriod(0,NULL,timeframes[++shift]);
     }
   else
      if(!_isUp && shift > 1)
        {
         ChartSetSymbolPeriod(0,NULL,timeframes[--shift]);
        }
  } 

まず、関数では、デフォルトツールバーに指定されたすべての時間枠の配列が記述されています。MetaTrader5で利用可能なすべての時間枠を切り替えたい場合は、適切な定数を配列に書き込む必要があります。ただし、この場合、互換性が失われ、ライブラリがMQL4で動作しなくなる可能性があります。

次に、標準関数を使用して、現在の期間を取得し、リストでそれを検索します。

次に、標準の ChartSetSymbolPeriod 関数を使用して、チャートの時間枠が切り替えられます。この関数には、現在のチャートの次の期間が渡されます。

コードで使用されている他の関数は、説明なしで明確にする必要があります。これは単なるコードです。

いくつかの簡単な関数

//+------------------------------------------------------------------+
//| Converts string command constants to keycodes                    |
//+------------------------------------------------------------------+
static int CUtilites::GetCurrentOperationChar(string keyString)
  {
   string keyValue = keyString;
   StringToUpper(keyValue);
   return(StringGetCharacter(keyValue,0));
  }
//+------------------------------------------------------------------+
//| Switch chart position to display on top of other objects         |
//+------------------------------------------------------------------+
static void CUtilites::ChangeChartZIndex(void)
  {
   ChartSetInteger(
      0,
      CHART_FOREGROUND,
      !(bool)ChartGetInteger(0,CHART_FOREGROUND)
   );
   ChartRedraw(0);
  } 
//+------------------------------------------------------------------+
//| Returns a string name for any standard timeframe                 |
//| Parameters:                                                      |
//|    _timeframe - ENUM_TIMEFRAMES numeric value for which we need  |
//|                 to find a string name                            |
//| Return value:                                                    |
//|   string name of the required timeframe                          |
//+------------------------------------------------------------------+
static string CUtilites::GetTimeframeSymbolName(
   ENUM_TIMEFRAMES _timeframe=PERIOD_CURRENT  // Desired timeframe
)
  {
   ENUM_TIMEFRAMES current_timeframe; // current timeframe
   string result = "";
//---
   if(_timeframe == PERIOD_CURRENT)
     {
      current_timeframe = Period();
     }
   else
     {
      current_timeframe = _timeframe;
     }
//---
   switch(current_timeframe)
     {
      case PERIOD_M1:
         return "M1";
      case PERIOD_M2:
         return "M2";
      case PERIOD_M3:
         return "M3";
      case PERIOD_M4:
         return "M4";
      case PERIOD_M5:
         return "M5";
      case PERIOD_M6:
         return "M6";
      case PERIOD_M10:
         return "M10";
      case PERIOD_M12:
         return "M12";
      case PERIOD_M15:
         return "M15";
      case PERIOD_M20:
         return "M20";
      case PERIOD_M30:
         return "M30";
      case PERIOD_H1:
         return "H1";
      case PERIOD_H2:
         return "M1";
      case PERIOD_H3:
         return "H3";
      case PERIOD_H4:
         return "H4";
      case PERIOD_H6:
         return "H6";
      case PERIOD_H8:
         return "H8";
      case PERIOD_D1:
         return "D1";
      case PERIOD_W1:
         return "W1";
      case PERIOD_MN1:
         return "MN1";
      default:
         return "Unknown";
     }
  }
//+------------------------------------------------------------------+
//| Returns the standard color for the current timeframe             |
//+------------------------------------------------------------------+
static color CUtilites::GetTimeFrameColor(long _all_down_periods_value)
  {
   if(Is_Different_Colors)
     {
      switch((int)_all_down_periods_value)
        {
         case OBJ_PERIOD_M1:
            return (m1_color);
         case PERIOD_LOWER_M5:
            return (m5_color);
         case PERIOD_LOWER_M15:
            return (m15_color);
         case PERIOD_LOWER_M30:
            return (m30_color);
         case PERIOD_LOWER_H1:
            return (h1_color);
         case PERIOD_LOWER_H4:
            return (h4_color);
         case PERIOD_LOWER_D1:
            return (d1_color);
         case PERIOD_LOWER_W1:
            return (w1_color);
         case OBJ_ALL_PERIODS:
            return (mn1_color);
         default:
            return (common_color);
        }
     }
   else
     {
      return (common_color);
     }
  }

極値検索関数とその応用

次の関数は、極値を見つけるのに役立ちます。パラメータに応じて、極値点はマウスポインタの右または左のいずれかになります。また、極値の左右で望まれるバーの数を指定できます。

//+------------------------------------------------------------------+
//| Returns the number of the nearest fractal in the selected        |
//|   direction                                                      |
//| Parameters:                                                      |
//|   starting_number - bar number at which the search starts        |
//|   is_search_right - search to the right (true) or left (false)   |
//|   is_up - if "true", search by High levels, otherwise - Low      |
//|   left_side_bars - number of bars on the left                    |
//|   right_side_bars - number of bars on the right                  |
//|   symbol - symbol name for search                                |
//|   timeframe - period for search                                  |
//| Return value:                                                    |
//|   the number of the extremum closest to starting_number,         |
//|   matching the specified parameters                              |                 |
//+------------------------------------------------------------------+
static int CUtilites::GetNearestExtremumBarNumber(
   int starting_number=0,              // Initial bar number
   const bool is_search_right=false,   // Direction to the right
   const bool is_up=false,             // Search by Highs
   const int left_side_bars=1,         // Number of bars to the left
   const int right_side_bars=1,        // Number of bars to the right
   const string symbol=NULL,           // The required symbol
   const ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT // The required timeframe
)
  {
//---
   int   i,
         nextExtremum,
         sign = is_search_right ? -1 : 1;

//--- If the starting bar is specified incorrectly
//--- (is beyond the current chart borders)
//--- and search - towards the border...
   if((starting_number-right_side_bars<0
       && is_search_right)
      || (starting_number+left_side_bars>iBars(symbol,timeframe)
          && !is_search_right)
     )
     { //--- ...it is necessary to display an error message
      if(Print_Warning_Messages)
        {
         Print(DEBUG_MESSAGE_PREFIX,
               "Can't find extremum: ",
               "wrong direction");
         Print("left_side_bars = ",left_side_bars,"; ",
               "right_side_bars = ",right_side_bars);
        }
      return (-2);
     }
   else
     {
      //--- otherwise - the direction allows you to select the correct bar.
      //---   check all bars in the required direction,
      //---   as long as we are beyond the known chart borders
      while((starting_number-right_side_bars<0
             && !is_search_right)
            || (starting_number+left_side_bars>iBars(symbol,timeframe)
                && is_search_right)
           )
        {
         starting_number +=sign;
        }
     }
//---
   i=starting_number;
 
   //--- Preparation is complete. Proceed to search
   while(i-right_side_bars>=0
         && i+left_side_bars<iBars(symbol,timeframe)
        )
     {
      //--- Depending on the level, check the required extremum
      if(is_up)
        { //--- either the upper one
         nextExtremum = iHighest(
                           Symbol(),
                           Period(),
                           MODE_HIGH,
                           left_side_bars+right_side_bars+1,
                           i-right_side_bars
                        );
        }
      else
        {  //--- or the lower one
         nextExtremum = iLowest(
                           Symbol(),
                           Period(),
                           MODE_LOW,
                           left_side_bars+right_side_bars+1,
                           i-right_side_bars
                        );
        }
      if(nextExtremum == i) // If the current bar is an extremum,
        {
         return nextExtremum;  // the problem is solved
        }
      else // Otherwise - continue to shift the counter of the checked candlestick to the desired direction
         if(is_search_right)
           {
            if(nextExtremum<i)
              {
               i=nextExtremum;
              }
            else
              {
               i--;
              }
           }
         else
           {
            if(nextExtremum>i)
              {
               i=nextExtremum;
              }
            else
              {
               i++;
              }
           }
     }
//--- If the edge is reached but no extremum has been found,
   if(Print_Warning_Messages)
     {
      //--- show an error message.
      Print(DEBUG_MESSAGE_PREFIX,
            "Can't find extremum: ",
            "an incorrect starting point or wrong border conditions.");
      Print("left_side_bars = ",left_side_bars,"; ",
            "right_side_bars = ",right_side_bars);
     }
   return (-1);
  } 

トレンドラインを描画するには、マウスの右側にある2つの最も近い極値を見つける関数が必要です。この関数は前の関数を使用できます。

//+------------------------------------------------------------------+
//| Finds 2 nearest extreme points to the right of the current       |
//| mouse pointer position                                           |
//| Parameters:                                                      |
//|    _is_up - search by High (true) or Low (false)                 |
//|    int &_p1 - bar number of the first point                      |
//|    int &_p2 - bar number of the second point                     |
//+------------------------------------------------------------------+
static void CUtilites::SetExtremumsBarsNumbers(
   bool _is_up, // search by High (true) or by Low (false)
   int &_p1,    // bar number of the first point
   int &_p2     // bar number of second point
)
  {
   int dropped_bar_number=CMouse::Bar();
//---
   _p1=CUtilites::GetNearestExtremumBarNumber(
          dropped_bar_number,
          true,
          _is_up,
          Fractal_Size_Left,
          Fractal_Size_Right
       );
   _p2=CUtilites::GetNearestExtremumBarNumber(
          _p1-1, // Bar to the left of the previous found extremum
          true,
          _is_up,
          Fractal_Size_Left,
          Fractal_Size_Right
       );
   if(_p2<0)
     {
      _p2=0;
     }
  } 

オブジェクト名の生成

同じオブジェクトのシリーズを描画できるようにするには、オブジェクトに一意の名前を付ける必要があります。最も効率的な方法は、このオブジェクトタイプに対応するプレフィックスを使用し、それに一意の番号を追加することです。さまざまなオブジェクトタイプのプレフィックスは、GlobalVariables.mqhにリストされています。

数値は適切な関数によって生成されます。

//+------------------------------------------------------------------+
//| Returns the number of the next object in the series              |
//| Parameters:                                                      |
//|   prefix - name prefix for this group of objects.                |
//|   object_type - the type of objects to search in.                |
//|   only_prefixed - if "false", search in all objects              |
//|                      of this type, "true" - only the objects     |
//|                      with the specified prefix                   |
//| Return value:                                                    |
//|   number of the next object in series. If search by prefix,      |
//|      and the existing numbering has a gap, the next number       |
//|      will be at gap beginning.                                   |
//+------------------------------------------------------------------+
int               CUtilites::GetNextObjectNumber(
   const string prefix,
   const ENUM_OBJECT object_type,
   bool true
)
  {
   int count = ObjectsTotal(0,0,object_type),
       i,
       current_element_number,
       total_elements = 0;
   string current_element_name = "",
          comment_text = "";
//---
   if(only_prefixed)
     {
      for(i=0; i<count; i++)
        {
         current_element_name=ObjectName(0,i,0,object_type);
         if(StringSubstr(current_element_name,0,StringLen(prefix))==prefix)
           {
            current_element_number=
               (int)StringToInteger(
                  StringSubstr(current_element_name,
                               StringLen(prefix),
                               -1)
               );
            if(current_element_number!=total_elements)
              {
               break;
              }
            total_elements++;
           }
        }
     }
   else
     {
      total_elements = ObjectsTotal(0,-1,object_type);
      do
        {
         current_element_name = GetCurrentObjectName(
                                   prefix,
                                   object_type,
                                   total_elements
                                );
         if(ObjectFind(0,current_element_name)>=0)
           {
            total_elements++;
           }
        }
      while(ObjectFind(0,current_element_name)>=0);
     }
//---
   return(total_elements);
  } 

コードには2つの検索アルゴリズムが実装されています。1番目のアルゴリズム(このライブラリのメインアルゴリズム)は、タイプに対応し、指定されたプレフィックスを持つすべてのオブジェクトを確認します。アルゴリズムは見つけた空き番号をユーザに返すので、番号付けの「隙間」を埋めることができます。

ただし、このアルゴリズムは、同じ番号でサフィックスが異なる複数のオブジェクトが存在する可能性がある場合には適していません。以前のバージョンでは、スクリプトを使用してオブジェクトを描画するときに、ピッチフォークセットにそのような名前を使用していました。 

したがって、ライブラリには2番目の検索メソッドがあります。このアルゴリズムは、このタイプのオブジェクトの総数を取得し、同じプレフィックスで始まって同じインデックスを持つ名前があるかどうかを確認します。確認できた場合、空き値が見つかるまで数値が1ずつ増加します。

また、番号がある場合(または関数を使用して簡単に取得できる場合)、名前を簡単に作成できます。

//+------------------------------------------------------------------+
//| Generates the current element name                               |
//| Parameters:                                                      |
//|    _prefix - name prefix for this group of objects.              |
//|    _type - the type of objects to search in.                     |
//|    _number - the number of the current object if it is ready.    |
//| Return value:                                                    |
//|    current object name string.                                   |
//+------------------------------------------------------------------+
string            CUtilites::GetCurrentObjectName(
   string _prefix,
   ENUM_OBJECT _type=OBJ_TREND,
   int _number = -1
)
  {
   int Current_Line_Number;

//--- Addition to the prefix - current timeframe
   string Current_Line_Name=IntegerToString(PeriodSeconds()/60)+"_"+_prefix;

//--- Get the element number
   if(_number<0)
     {
      Current_Line_Number = GetNextObjectNumber(Current_Line_Name,_type);
     }
   else
     {
      Current_Line_Number = _number;
     }

//--- Generate the name
   Current_Line_Name +=IntegerToString(Current_Line_Number,4,StringGetCharacter("0",0));

//---
   return (Current_Line_Name);
  } 

隣接するバー間の距離(ピクセル単位)

将来のある地点までの距離を計算する必要がある場合があります。最も信頼できる方法の1つは、2つの隣接するバー間のピクセル単位の距離を計算し、それに必要な係数(インデントに必要なバーの数)を掛けることです。

隣接するバー間の距離は、次の関数を使用して計算できます。

//+------------------------------------------------------------------+
//| Calculates a distance in pixels between two adjacent bars        |
//+------------------------------------------------------------------+
int        CUtilites::GetBarsPixelDistance(void)
  {
   double price; // arbitrary price on the chart (used for
                 // standard functions calculating coordinates
   datetime time1,time2;  // the time of the current and adjacent candlesticks
   int x1,x2,y1,y2;       // screen coordinates of two points
                          //   on adjacent candlesticks
   int deltha;            // result - the desired distance

//--- Initial settings
   price = iHigh(Symbol(),PERIOD_CURRENT,CMouse::Bar());
   time1 = CMouse::Time();

//--- Get the time of the current candlestick
   if(CMouse::Bar()<Bars(Symbol(),PERIOD_CURRENT)){ // if at the middle of the chart,
      time2 = time1+PeriodSeconds();                // take the candlestick on the left
   }
   else {                                           // otherwise
      time2 = time1;
      time1 = time1-PeriodSeconds();                // take the candlestick on the right
   }

//--- Convert coordinates form price/time values to screen pixels
   ChartTimePriceToXY(0,0,time1,price,x1,y1);
   ChartTimePriceToXY(0,0,time2,price,x2,y2);

//--- Calculate the distance
   deltha = MathAbs(x2-x1);
//---
   return (deltha);
  } 

文字列をdoubleの配列に変換する関数

EAパラメータを使用してフィボナッチレベルを設定する最も便利な方法は、カンマ区切りの値で構成される文字列を使用することです。ただし、MQLでは、レベルの設定に2倍の数値を使用する必要があります。

次の関数は、文字列から数値を抽出するのに役立ちます。

//+------------------------------------------------------------------+
//| Converts a string with separators to an array of double          |
//|    numbers                                                       |
//| Parameters:                                                      |
//|    _haystack - source string for conversion                      |
//|    _result[] - resulting array                                   |
//|    _delimiter - separator character                              |
//+------------------------------------------------------------------+
static void CUtilites::StringToDoubleArray(
   string _haystack,             // source string
   double &_result[],            // array of results
   const string _delimiter=","   // separator
)
  {
//---
   string haystack_pieces[]; // Array of string fragments
   int pieces_count,         // Number of fragments
       i;                    // Counter
   string current_number=""; // The current string fragment (estimated number)

//--- Split the string into fragments
   pieces_count=StringSplit(_haystack,StringGetCharacter(_delimiter,0),haystack_pieces);
//--- Convert
   if(pieces_count>0)
     {
      ArrayResize(_result,pieces_count);
      for(i=0; i<pieces_count; i++)
        {
         StringTrimLeft(haystack_pieces[i]);
         StringTrimRight(haystack_pieces[i]);
         _result[i]=StringToDouble(haystack_pieces[i]);
        }
     }
   else
     {
      ArrayResize(_result,1);
      _result[0]=0;
     }
  } 

描画クラス: ユーティリティ関数の使用例

記事が長くなってしまったので、ほとんどの描画機能については次の記事で説明します。ただし、作成された関数のいくつかをテストするために、(最も近い2つの極値に基づいて)単純な直線を描画するコードをここに追加します。

Graphics.mqhファイルヘッダ

//+------------------------------------------------------------------+
//|                                                     Graphics.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                            https://www.mql5.com/ru/articles/7468 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/en/articles/7468"

//+------------------------------------------------------------------+
//| Class for plotting graphic objects                               |
//+------------------------------------------------------------------+
class CGraphics
  {
   //--- Fields
private:
   bool              m_Is_Trend_Ray;
   bool              m_Is_Change_Timeframe_On_Create;
   //--- Methods
private:
   //--- Sets general parameters for any newly created object
   void              CurrentObjectDecorate(
      const string _name,
      const color _color=clrNONE,
      const int _width = 1,
      const ENUM_LINE_STYLE _style = STYLE_SOLID
   );
public:
   //--- Default constructor
                     CGraphics();
   //--- Universal function for creating trend lines with specified parameters
   bool              TrendCreate(
      const long            chart_ID=0,        // chart ID
      const string          name="TrendLine",  // line name
      const int             sub_window=0,      // subwindow number
      datetime              time1=0,           // time of the first point
      double                price1=0,          // price of the first point
      datetime              time2=0,           // time of the second point
      double                price2=0,          // price of the second point
      const color           clr=clrRed,        // line color
      const ENUM_LINE_STYLE style=STYLE_SOLID, // line style
      const int             width=1,           // line width
      const bool            back=false,        // in the background
      const bool            selection=true,    // if the line is selected
      const bool            ray_right=false,   // ray to the right
      const bool            hidden=true,       // hide in the list of objects
      const long            z_order=0          // Z-Index
   );
   //--- Plots a trend line based on the two nearest (to the right of the mouse) extreme points
   void              DrawTrendLine(void);
   //--- Checks if the straight line is a ray
   bool              IsRay() {return m_Is_Trend_Ray;}
   //--- Sets the ray indication (whether the line should be extended to the right)
   void              IsRay(bool _is_ray) {m_Is_Trend_Ray = _is_ray;}
   //--- Checks if the display of objects created by the program should be changed on higher timeframes
   bool              IsChangeTimeframe(void) {return m_Is_Change_Timeframe_On_Create;}
   //--- Sets flags for the display of objects created by the program on higher timeframes
   void              IsChangeTimeframe(bool _is_tf_change) {m_Is_Change_Timeframe_On_Create = _is_tf_change;}
  };

  

新しく作成されたオブジェクトの一般的なパラメータを設定する関数

//+------------------------------------------------------------------+
//| Sets general parameters for all new objects                      |
//| Parameters:                                                      |
//|    _name - the name of the object being modified                 |
//|    _color - the color of the object being modified. If not set,  |
//|             standard color of the current period is used         |
//|    _width - object line width                                    |
//|    _style - object line type                                     |
//+------------------------------------------------------------------+
void CGraphics::CurrentObjectDecorate(
   const string _name,            // the name of the object being modified
   const color _color=clrNONE,    // the color of the object being modified
   const int _width = 1,          // object line width
   const ENUM_LINE_STYLE _style = STYLE_SOLID  // object line style
)
  {
   long timeframes;         // timeframes on which the object will be displayed
   color currentColor;      // object color
//--- Specify timeframes on which the object will be displayed
   if(Is_Change_Timeframe_On_Create)
     {
      timeframes = CUtilites::GetAllLowerTimeframes();
     }
   else
     {
      timeframes = OBJ_ALL_PERIODS;
     }
//--- Specify the object color
   if(_color != clrNONE)
     {
      currentColor = _color;
     }
   else
     {
      currentColor = CUtilites::GetTimeFrameColor(timeframes);
     }
//--- Set attributes
   ObjectSetInteger(0,_name,OBJPROP_COLOR,currentColor);            // Color
   ObjectSetInteger(0,_name,OBJPROP_TIMEFRAMES,timeframes);         // Periods
   ObjectSetInteger(0,_name,OBJPROP_HIDDEN,true);                   // Hide in the list of objects
   ObjectSetInteger(0,_name,OBJPROP_SELECTABLE,true);               // Ability to select
   ObjectSetInteger(0,_name,OBJPROP_SELECTED,Is_Select_On_Create);  // Stay selected after creation?
   ObjectSetInteger(0,_name,OBJPROP_WIDTH,_width);                  // Line width
   ObjectSetInteger(0,_name,OBJPROP_STYLE,_style);                  // Line style
  } 

直線をプロットする関数

//+------------------------------------------------------------------+
//| Universal function for creating trend lines with specified       |
//|    parameters                                                    |
//| Parameters:                                                      |
//|    chart_ID - chart ID                                           |
//|    name - line name                                              |
//|    sub_window - subwindow number                                 |
//|    time1 - time of the first point                               |
//|    price1 - price of the first point                             |
//|    time2 - time of the second point                              |
//|    price2 - price of the second point                            |
//|    clr - line color                                              |
//|    style - line style                                            |
//|    width - line width                                            |
//|    back - in the background                                      |
//|    selection - if the line is selected                           |
//|    ray_right - ray to the right                                  |
//|    hidden - hide in the list of objects                          |
//|    z_order - priority of mouse clicks (Z-Index)                  |
//| Return value:                                                    |
//|    indication of success. If line drawing failed,                |
//|    false is returned, otherwise - true                           |
//+------------------------------------------------------------------+
bool              CGraphics::TrendCreate(
      const long            chart_ID=0,        // chart ID
      const string          name="TrendLine",  // line name
      const int             sub_window=0,      // subwindow number
      datetime              time1=0,           // time of the first point
      double                price1=0,          // price of the first point
      datetime              time2=0,           // time of the second point
      double                price2=0,          // price of the second point
      const color           clr=clrRed,        // line color
      const ENUM_LINE_STYLE style=STYLE_SOLID, // line style
      const int             width=1,           // line width
      const bool            back=false,        // in the background
      const bool            selection=true,    // if the line is selected
      const bool            ray_right=false,   // ray to the right
      const bool            hidden=true,       // hide in the list of objects
      const long            z_order=0          // Z-Index
)
  {

//--- Reset the last error message
   ResetLastError();
//--- Create a line
   if(!ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2))
     {
      if(Print_Warning_Messages) // if failed, show an error message
        {
         Print(__FUNCTION__,
               ": Can't create trend line! Error code = ",GetLastError());
        }
      return(false);
     }

//--- Set additional attributes
   CurrentObjectDecorate(name,clr,width,style);

//--- line in the foreground (false) or in the background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- ray to the right (true) or exact borders (false)
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- mouse click priority (Z-index)
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- Update the chart image
   ChartRedraw(0);
//--- Everything is good. The line has been drawn successfully.
   return(true);
  }

この共通の関数を基礎として使用し、2つの隣接する極値によって直線を描く別の関数を作成しましょう。

//+------------------------------------------------------------------+
//| Draws a trend line by nearest extreme points in the right        |
//+------------------------------------------------------------------+
void              CGraphics::DrawTrendLine(void)
  {
   int dropped_bar_number=CMouse::Bar(); // candlestick number under the mouse
   int p1=0,p2=0;                        // numbers of the first and seconds points
   string trend_name =                   // trend line name
      CUtilites::GetCurrentObjectName(Trend_Line_Prefix,OBJ_TREND);
   double
      price1=0,   // price of the first point
      price2=0,   // price of the second point
      tmp_price;  // variable for temporary storing of the price
   datetime
      time1=0,    // time of the first point
      time2=0,    // time of the second point
      tmp_time;
   int x1,x2,y1,y2;   // Point coordinates
   int window=0;      // Subwindow number

//--- Setting initial parameters
   if(CMouse::Below()) // If a mouse cursor is below the candlestick Low
     {
      //--- Find two extreme points below
      CUtilites::SetExtremumsBarsNumbers(false,p1,p2);

      //--- Determine point coordinates
      time1=iTime(Symbol(),PERIOD_CURRENT,p1);
      price1=iLow(Symbol(),PERIOD_CURRENT,p1);
      time2=iTime(Symbol(),PERIOD_CURRENT,p2);
      price2=iLow(Symbol(),PERIOD_CURRENT,p2);
     }
   else // otherwise
      if(CMouse::Above()) // If a mouse cursor is below the candlestick High
        {
         //--- Find two extreme points above
         CUtilites::SetExtremumsBarsNumbers(true,p1,p2);
        
         //--- Determine point coordinates
         time1=iTime(Symbol(),PERIOD_CURRENT,p1);
         price1=iHigh(Symbol(),PERIOD_CURRENT,p1);
         time2=iTime(Symbol(),PERIOD_CURRENT,p2);
         price2=iHigh(Symbol(),PERIOD_CURRENT,p2);

        }
//--- Draw the line
   TrendCreate(0,trend_name,0,
               time1,price1,time2,price2,
               CUtilites::GetTimeFrameColor(CUtilites::GetAllLowerTimeframes()),
               0,Trend_Line_Width,false,true,m_Is_Trend_Ray
              );

//--- Redraw the chart
   ChartRedraw(0);
  } 

ポイント1と2のバー番号を取得するCUtilites::SetExtremumsBarsNumbers関数呼び出しに注目してください。コードは以前に説明しました。残りは明確なので、ここでは長々と説明しないことにします。

最後の関数は、2点に基づいて単純な線を描画します。Is_Trend_Rayグローバルパラメータ(GlobalVariables.mqhファイルで説明)に応じて、線は右に伸びる半直線か、2つの極値間の短い線分になります。

 Is_Trend_Ray = true  Is_Trend_Ray = false

キーボードを使用して線を延長する可能性を追加しましょう。


制御ブロックの作成: OnChartEventメソッドの設定

基本的な機能の準備ができたので、キーボードショートカットをカスタマイズできます。

Shortcuts.mqhで、CShortcuts::OnChartEventメソッドを書きます。

//+------------------------------------------------------------------+
//| Event handling function                                          |
//+------------------------------------------------------------------+
void CShortcuts::OnChartEvent(
   const int id,
   const long &lparam,
   const double &dparam,
   const string &sparam
)
  {
//---
   switch(id)
     {
      //--- Save the coordinates of the mouse cursor
      case CHARTEVENT_MOUSE_MOVE:
         CMouse::SetCurrentParameters(id,lparam,dparam,sparam);
         break;

      //--- Handle keystrokes
      case CHARTEVENT_KEYDOWN:
         //--- Change the timeframe 1 level up
         if(CUtilites::GetCurrentOperationChar(Up_Key) == lparam)
           {
            CUtilites::ChangeTimeframes(true);
           };
         //--- Change the timeframe 1 level down
         if(CUtilites::GetCurrentOperationChar(Down_Key) == lparam)
           {
            CUtilites::ChangeTimeframes(false);
           };
         //--- Change the Z Index of the chart (chart on top of all objects)
         if(CUtilites::GetCurrentOperationChar(Z_Index_Key) == lparam)
           {
            CUtilites::ChangeChartZIndex();
           }
         //--- Draw a trend line
         if(CUtilites::GetCurrentOperationChar(Trend_Line_Key) == lparam)
           {
            m_graphics.DrawTrendLine();
           }
         //--- Switch the Is_Trend_Ray parameter
         if(CUtilites::GetCurrentOperationChar(Switch_Trend_Ray_Key) == lparam)
           {
            m_graphics.IsRay(!m_graphics.IsRay());
           }

         break;
         //---

     }
  } 

現在のライブラリ実装で使用されているキー

アクション
 キー 説明
 メインのTFの時間枠を長くする(TFパネルから) U  Up
 時間枠を短くする  D  Down
 チャートのZレベルを変える(チャートが他のすべてのオブジェクトの上になるかどうか)  Z  Z order
 マウスに最も近い2つの一方向の極値点に基づいて傾斜した傾向線を描画する  T  Trend line
 新しいラインを線分モードに切り替える
 R  Ray

終わりに

添付ファイルには、ライブラリの現在のバージョンが含まれています。また、添付ファイルには3つのスクリプトが含まれています。

  • 1つ目はDel-All-Graphicsです。これは、現在のウィンドウからすべてのグラフィックオブジェクトを削除します。私の端末では、このスクリプトにCtrl+A(All)キーボードショートカットを設定しました。
  • 2番目のスクリプトはDel-All-Prefixedです。これは、プレフィックスが付いたすべてのオブジェクト(たとえば、H1で始まるすべてのトレンドラインまたはオブジェクト)を削除できます。Alt+R(Remove)で呼び出します。
  • 最後に、3番目のスクリプト(DeselectAllObjects)を使用すると、現在のウィンドウ内のすべてのオブジェクトの選択を解除できます。私のキーボードショートカットはCtrl+Dです(Photoshop同様にDeselect)。

ライブラリを指標ではなくエキスパートアドバイザーに接続することをお勧めします。指標に接続してこの指標を他のエキスパートアドバイザーと一緒に使用しようとすると、深刻な速度低下が発生する可能性があるためです。少なくとも私の場合は速度低下でしたが、もちろん、他のエラーだった可能性もあります。

今後の実装

ライブラリの2番目のバージョンでは、ビデオに示されている便利なオブジェクトの実装について説明します。一部のオブジェクトはプリミティブ(垂直線や水平線など)で、特定の長さの線などの他のオブジェクトは、より多くの労力を必要としました。「出力エラー」などの理由で、正常に動作しないものもあります。私の決定について説明しますが、もちろん、フィードバックは大歓迎です。

3番目のバージョンには、パラメータを構成するためのグラフィカルインターフェイスが含まれます。

4番目のバージョンでは、あるとしたら、手動取引を容易にする本格的なアシスタントEAを提示します。コミュニティからのアドバイスが必要です。既存のソリューションと比較して、新しいアイデアを適用するかどうかはわかりません。もちろん、インターフェイスは私が描きますが、これはすべて手動取引に適用されます。この開発は何に役に立つと思いますか?

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

添付されたファイル |
DoEasyライブラリの時系列(第44部): 指標バッファオブジェクトのコレクションクラス DoEasyライブラリの時系列(第44部): 指標バッファオブジェクトのコレクションクラス
この記事では、指標バッファオブジェクトのコレクションクラスの作成について説明しています。指標用の任意の数のバッファを作成して操作する機能をテストします(MQL指標で作成できるバッファの最大数は512です)。
ネイティブTwitterクライアント: 第2部 ネイティブTwitterクライアント: 第2部
MQLクラスとして実装した、写真付きのツイートを送信できるようにするTwitterクライアントです。1つの自己完結型インクルードファイルを含めるだけで、すぐにすべての素晴らしいチャートとシグナルをツイートできるようになります。
取引におけるニューラルネットワークの実用化(実践編) 取引におけるニューラルネットワークの実用化(実践編)
本稿では、Matlabプラットフォームでニューラルネットワークモジュールを実際に使用するための説明と手順を説明します。また、ニューラルネットワークモジュールを使用した取引システム作成の主な側面についても説明します。1つの記事で複合体を紹介できるようにするには、複数のニューラルネットワークモジュール機能を1つのプログラムに組み合わせるように変更する必要がありました。
DLLなしのMT4およびMT5用ネイティブTwitterクライアント DLLなしのMT4およびMT5用ネイティブTwitterクライアント
ツイートにアクセスしたり、Twitterに取引シグナルを投稿したりしたかったことがおありですか?検索をおやめください。この連載では、DLLを使用せずにそれを行う方法を示します。MQLを使用してTweeter APIを実装する旅をお楽しみください。この第1部では、Twitter APIにアクセスする際の認証と承認の栄光の道をたどります。