【MQL4定数】チャート基準座標の定数(ENUM_BASE_CORNER​)

【辞書】MQLリファレンス

チャート基準座標の定数

チャート基準座標の定数は、チャートの基準座標を設定するときに使われます。

チャート基準座標とは、オブジェクトを表示するときに基準となるチャート上の座標のことです。

主に、ObjectSetInteger関数で使われます。

簡単に関数の説明です。

  • ObjectSetInteger関数:オブジェクトの状態を設定する

 

それぞれ、OBJPROP_CORNERの設定値として、チャート基準座標の定数が使われます。

 

チャート基準座標の定数(ENUM_BASE_CORNER​)

定数説明
CORNER_LEFT_UPPERチャートの左上を基準座標に設定
CORNER_LEFT_LOWERチャートの左下を基準座標に設定
CORNER_RIGHT_LOWERチャートの右下を基準座標に設定
CORNER_RIGHT_UPPERチャートの右上を基準座標に設定

 

チャート基準座標の定数の使い方

主に、ObjectSetInteger関数で使用されます。

それぞれ、OBJPROP_CORNERの設定値として、チャート基準座標の定数が使われます。

上記の定数を入力しましょう。

すると、その定数に対応した基準座標が設定されます。

例えば、以下のように使用します。

  //ObjectSetInteger関数
  //チャート上の左上を基準座標にする
   bool objectSetInteger = ObjectSetInteger(ChartID(), "自動売買を作ろう!", OBJPROP_CORNER, CORNER_LEFT_UPPER);

 

返り値はbool型です。

成功すればture、失敗すればfalseが返ってきます。

 

実用的なプログラム例

ここからは、チャート基準座標の定数を使った実用的なプログラム例を紹介します。

例1:チャート右上にスプレッド表示ラベルを作成する

チャートの右上にリアルタイムのスプレッドを表示するインジケーターです。CORNER_RIGHT_UPPERを使って右上を基準座標に設定しています。

//+------------------------------------------------------------------+
//| スプレッド表示インジケーター                                        |
//+------------------------------------------------------------------+
#property indicator_chart_window

// ラベルオブジェクトの名前を定義
string labelName = "SpreadLabel";

//+------------------------------------------------------------------+
//| 初期化関数                                                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // ラベルオブジェクトを作成する
   ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0);
   
   // チャートの右上を基準座標に設定する
   ObjectSetInteger(0, labelName, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
   
   // 基準座標からのX方向の距離(ピクセル)
   ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 20);
   
   // 基準座標からのY方向の距離(ピクセル)
   ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, 30);
   
   // フォントサイズを設定
   ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 14);
   
   // 文字色を設定(白色)
   ObjectSetInteger(0, labelName, OBJPROP_COLOR, clrWhite);
   
   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[])
{
   // 現在のスプレッドを取得(ポイント単位)
   int currentSpread = (int)MarketInfo(Symbol(), MODE_SPREAD);
   
   // ラベルのテキストにスプレッド値を表示する
   ObjectSetString(0, labelName, OBJPROP_TEXT, "Spread: " + IntegerToString(currentSpread) + " pts");
   
   // チャートを再描画して表示を更新する
   ChartRedraw();
   
   return(rates_total);
}

//+------------------------------------------------------------------+
//| 終了時にオブジェクトを削除する                                      |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // 作成したラベルオブジェクトを削除する
   ObjectDelete(0, labelName);
}

 

例2:4隅にラベルを配置して情報パネルを作成する

4つの基準座標定数をすべて使い、チャートの四隅にそれぞれ異なる情報を表示するEAの例です。

//+------------------------------------------------------------------+
//| 四隅情報パネルEA                                                   |
//+------------------------------------------------------------------+

// 4つのラベル名を定義
string labelLU = "InfoPanel_LU"; // 左上
string labelRU = "InfoPanel_RU"; // 右上
string labelLB = "InfoPanel_LB"; // 左下
string labelRB = "InfoPanel_RB"; // 右下

//+------------------------------------------------------------------+
//| ラベルを作成する共通関数                                            |
//| corner : 基準座標の定数                                            |
//| name   : オブジェクト名                                            |
//| xDist  : X方向の距離(ピクセル)                                    |
//| yDist  : Y方向の距離(ピクセル)                                    |
//+------------------------------------------------------------------+
void CreateInfoLabel(ENUM_BASE_CORNER corner, string name, int xDist, int yDist)
{
   // ラベルオブジェクトを作成
   ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
   
   // 基準座標を設定(引数で渡された定数を使用)
   ObjectSetInteger(0, name, OBJPROP_CORNER, corner);
   
   // 基準座標からの距離を設定
   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, xDist);
   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, yDist);
   
   // フォントサイズを12に設定
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 12);
   
   // 文字色をライムグリーンに設定
   ObjectSetInteger(0, name, OBJPROP_COLOR, clrLime);
}

//+------------------------------------------------------------------+
//| 初期化関数                                                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // 左上:通貨ペア名を表示
   CreateInfoLabel(CORNER_LEFT_UPPER, labelLU, 15, 25);
   
   // 右上:現在時刻を表示
   CreateInfoLabel(CORNER_RIGHT_UPPER, labelRU, 15, 25);
   
   // 左下:口座残高を表示
   CreateInfoLabel(CORNER_LEFT_LOWER, labelLB, 15, 25);
   
   // 右下:現在のポジション数を表示
   CreateInfoLabel(CORNER_RIGHT_LOWER, labelRB, 15, 25);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| ティックごとの処理                                                 |
//+------------------------------------------------------------------+
void OnTick()
{
   // 左上に通貨ペア名を表示
   ObjectSetString(0, labelLU, OBJPROP_TEXT, "Symbol: " + Symbol());
   
   // 右上にサーバー時刻を表示
   ObjectSetString(0, labelRU, OBJPROP_TEXT, "Time: " + TimeToString(TimeCurrent(), TIME_MINUTES));
   
   // 左下に口座残高を表示
   ObjectSetString(0, labelLB, OBJPROP_TEXT, "Balance: " + DoubleToString(AccountBalance(), 2));
   
   // 右下に現在の保有ポジション数を表示
   ObjectSetString(0, labelRB, OBJPROP_TEXT, "Orders: " + IntegerToString(OrdersTotal()));
   
   // チャートを再描画して表示を更新する
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| 終了時にすべてのラベルを削除する                                     |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(0, labelLU);
   ObjectDelete(0, labelRU);
   ObjectDelete(0, labelLB);
   ObjectDelete(0, labelRB);
}

 

例3:左下に取引履歴サマリーを表示するインジケーター

チャートの左下(CORNER_LEFT_LOWER)を基準座標にして、当日の取引結果(勝敗数と損益)をリアルタイムで表示するインジケーターです。複数行のラベルを縦に並べて表示します。

//+------------------------------------------------------------------+
//| 取引履歴サマリー表示インジケーター                                    |
//+------------------------------------------------------------------+
#property indicator_chart_window

// 3行分のラベル名を定義
string lblLine1 = "TradeSummary_Line1"; // 1行目:タイトル
string lblLine2 = "TradeSummary_Line2"; // 2行目:勝敗数
string lblLine3 = "TradeSummary_Line3"; // 3行目:損益合計

//+------------------------------------------------------------------+
//| 左下基準でラベルを作成する関数                                       |
//| name  : オブジェクト名                                             |
//| yDist : Y方向の距離(ピクセル)                                     |
//| col   : 文字色                                                    |
//| fsize : フォントサイズ                                             |
//+------------------------------------------------------------------+
void CreateBottomLeftLabel(string name, int yDist, color col, int fsize)
{
   // ラベルオブジェクトを作成
   ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
   
   // 左下を基準座標に設定する
   ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER);
   
   // X方向の距離を15ピクセルに固定
   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, 15);
   
   // Y方向の距離(行ごとに異なる値を設定)
   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, yDist);
   
   // フォントサイズを設定
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, fsize);
   
   // 文字色を設定
   ObjectSetInteger(0, name, OBJPROP_COLOR, col);
}

//+------------------------------------------------------------------+
//| 初期化関数                                                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // 1行目(最も下から遠い位置):タイトル行(黄色・大きめ)
   CreateBottomLeftLabel(lblLine1, 75, clrYellow, 11);
   
   // 2行目:勝敗数の表示行(白色)
   CreateBottomLeftLabel(lblLine2, 55, clrWhite, 10);
   
   // 3行目(最も下に近い位置):損益合計の表示行(白色)
   CreateBottomLeftLabel(lblLine3, 35, clrWhite, 10);
   
   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[])
{
   // 当日の勝ち数・負け数・損益を集計する変数
   int wins   = 0;
   int losses = 0;
   double totalProfit = 0.0;
   
   // 当日の0時0分を取得する(比較用)
   datetime todayStart = StringToTime(TimeToString(TimeCurrent(), TIME_DATE));
   
   // 決済済みの注文履歴をループして集計する
   int totalHistory = OrdersHistoryTotal();
   for(int i = 0; i < totalHistory; i++)
   {
      // 注文履歴を選択する
      if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
         continue;
      
      // 決済時刻が当日より前の注文はスキップする
      if(OrderCloseTime() < todayStart)
         continue;
      
      // 売買注文のみ対象(残高操作などは除外)
      if(OrderType() != OP_BUY && OrderType() != OP_SELL)
         continue;
      
      // 損益を取得して集計する
      double profit = OrderProfit() + OrderSwap() + OrderCommission();
      totalProfit += profit;
      
      // 利益がプラスなら勝ち、マイナスなら負けとしてカウント
      if(profit >= 0)
         wins++;
      else
         losses++;
   }
   
   // 1行目:タイトルを設定
   ObjectSetString(0, lblLine1, OBJPROP_TEXT, "== Today's Summary ==");
   
   // 2行目:勝敗数を設定
   ObjectSetString(0, lblLine2, OBJPROP_TEXT,
      "Win: " + IntegerToString(wins) + " / Loss: " + IntegerToString(losses));
   
   // 3行目:損益合計を設定(色を損益に応じて変更)
   ObjectSetString(0, lblLine3, OBJPROP_TEXT,
      "P/L: " + DoubleToString(totalProfit, 2) + " " + AccountCurrency());
   
   // 損益がプラスなら緑色、マイナスなら赤色に変更する
   if(totalProfit >= 0)
      ObjectSetInteger(0, lblLine3, OBJPROP_COLOR, clrLime);
   else
      ObjectSetInteger(0, lblLine3, OBJPROP_COLOR, clrRed);
   
   // チャートを再描画する
   ChartRedraw();
   
   return(rates_total);
}

//+------------------------------------------------------------------+
//| 終了時にすべてのラベルを削除する                                     |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(0, lblLine1);
   ObjectDelete(0, lblLine2);
   ObjectDelete(0, lblLine3);
}

 

例4:右下にATRベースのリスク管理情報を表示するEA

チャートの右下(CORNER_RIGHT_LOWER)を基準座標にして、ATR(Average True Range)に基づくストップロス推奨値と推奨ロットサイズを表示するEAです。裁量トレードの補助ツールとして活用できます。

//+------------------------------------------------------------------+
//| ATRリスク管理パネルEA                                              |
//+------------------------------------------------------------------+

// 外部パラメータ
extern int    ATR_Period   = 14;    // ATRの計算期間
extern double RiskPercent  = 1.0;   // 1トレードあたりのリスク(口座残高に対する%)
extern double SL_ATR_Multi = 1.5;   // ATRに対するストップロスの倍率

// ラベル名の定義
string lblATR   = "RiskPanel_ATR";    // ATR値の表示
string lblSL    = "RiskPanel_SL";     // ストップロス推奨値の表示
string lblLot   = "RiskPanel_Lot";    // 推奨ロットサイズの表示
string lblTitle = "RiskPanel_Title";  // タイトルの表示

//+------------------------------------------------------------------+
//| 右下基準でラベルを作成する関数                                       |
//| name  : オブジェクト名                                             |
//| yDist : Y方向の距離(ピクセル)                                     |
//+------------------------------------------------------------------+
void CreateRiskLabel(string name, int yDist)
{
   // ラベルオブジェクトを作成
   ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
   
   // 右下を基準座標に設定する
   ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_LOWER);
   
   // X方向の距離を20ピクセルに設定
   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, 20);
   
   // Y方向の距離を設定(行ごとに変える)
   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, yDist);
   
   // フォントサイズを10に設定
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
   
   // 文字色をアクア色に設定
   ObjectSetInteger(0, name, OBJPROP_COLOR, clrAqua);
}

//+------------------------------------------------------------------+
//| 初期化関数                                                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // タイトル行(一番下から遠い位置)
   CreateRiskLabel(lblTitle, 100);
   ObjectSetInteger(0, lblTitle, OBJPROP_COLOR, clrGold);
   ObjectSetInteger(0, lblTitle, OBJPROP_FONTSIZE, 11);
   
   // ATR値の表示行
   CreateRiskLabel(lblATR, 80);
   
   // ストップロス推奨値の表示行
   CreateRiskLabel(lblSL, 60);
   
   // 推奨ロットサイズの表示行
   CreateRiskLabel(lblLot, 40);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| ティックごとの処理                                                 |
//+------------------------------------------------------------------+
void OnTick()
{
   // ATRインジケーターの値を取得する(現在の確定足)
   double atrValue = iATR(Symbol(), 0, ATR_Period, 1);
   
   // ATRにSL倍率を掛けてストップロス幅を計算する(価格単位)
   double slDistance = atrValue * SL_ATR_Multi;
   
   // ストップロス幅をポイント単位に変換する
   double slPoints = slDistance / Point;
   
   // 1ロットあたりのストップロス金額を計算する
   double tickValue   = MarketInfo(Symbol(), MODE_TICKVALUE);
   double tickSize    = MarketInfo(Symbol(), MODE_TICKSIZE);
   double lossPerLot  = (slDistance / tickSize) * tickValue;
   
   // 許容損失額を計算する(口座残高 × リスク%)
   double riskAmount = AccountBalance() * RiskPercent / 100.0;
   
   // 推奨ロットサイズを計算する(許容損失額 ÷ 1ロットあたり損失額)
   double recommendedLot = 0.0;
   if(lossPerLot > 0)
      recommendedLot = NormalizeDouble(riskAmount / lossPerLot, 2);
   
   // 最小ロットを下回る場合は最小ロットに調整する
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);
   if(recommendedLot < minLot)
      recommendedLot = minLot;
   
   // タイトルを設定
   ObjectSetString(0, lblTitle, OBJPROP_TEXT,
      "== Risk Panel (ATR " + IntegerToString(ATR_Period) + ") ==");
   
   // ATR値を小数点以下5桁で表示する
   ObjectSetString(0, lblATR, OBJPROP_TEXT,
      "ATR: " + DoubleToString(atrValue, (int)MarketInfo(Symbol(), MODE_DIGITS)));
   
   // ストップロス推奨値を表示する(pips換算)
   // 3桁・5桁のブローカーに対応するため10で割る
   double slPips = slPoints;
   if(Digits == 3 || Digits == 5)
      slPips = slPoints / 10.0;
   ObjectSetString(0, lblSL, OBJPROP_TEXT,
      "SL: " + DoubleToString(slPips, 1) + " pips (x" + DoubleToString(SL_ATR_Multi, 1) + ")");
   
   // 推奨ロットサイズを表示する
   ObjectSetString(0, lblLot, OBJPROP_TEXT,
      "Lot: " + DoubleToString(recommendedLot, 2) + " (Risk " + DoubleToString(RiskPercent, 1) + "%)");
   
   // チャートを再描画する
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| 終了時にすべてのラベルを削除する                                     |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(0, lblTitle);
   ObjectDelete(0, lblATR);
   ObjectDelete(0, lblSL);
   ObjectDelete(0, lblLot);
}

 

例5:基準座標をボタンで切り替えるデモインジケーター

ボタンをクリックするたびに、ラベルの基準座標が左上→右上→右下→左下と順番に切り替わるデモインジケーターです。ENUM_BASE_CORNERの4つの定数がどのように動作するかを視覚的に確認できます。

//+------------------------------------------------------------------+
//| 基準座標切り替えデモインジケーター                                    |
//+------------------------------------------------------------------+
#property indicator_chart_window

// オブジェクト名の定義
string lblDemo   = "CornerDemo_Label";   // 移動するデモラベル
string btnSwitch = "CornerDemo_Button";  // 切り替えボタン

// 現在の基準座標のインデックス(0〜3)
int currentCornerIndex = 0;

// 4つの基準座標を配列で管理する
ENUM_BASE_CORNER corners[4] = {
   CORNER_LEFT_UPPER,   // インデックス0:左上
   CORNER_RIGHT_UPPER,  // インデックス1:右上
   CORNER_RIGHT_LOWER,  // インデックス2:右下
   CORNER_LEFT_LOWER    // インデックス3:左下
};

// 基準座標の名前(表示用)
string cornerNames[4] = {
   "LEFT_UPPER",
   "RIGHT_UPPER",
   "RIGHT_LOWER",
   "LEFT_LOWER"
};

//+------------------------------------------------------------------+
//| 初期化関数                                                        |
//+------------------------------------------------------------------+
int OnInit()
{
   // デモ用ラベルを作成する
   ObjectCreate(0, lblDemo, OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, lblDemo, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, lblDemo, OBJPROP_XDISTANCE, 30);
   ObjectSetInteger(0, lblDemo, OBJPROP_YDISTANCE, 60);
   ObjectSetInteger(0, lblDemo, OBJPROP_FONTSIZE, 16);
   ObjectSetInteger(0, lblDemo, OBJPROP_COLOR, clrYellow);
   ObjectSetString(0, lblDemo, OBJPROP_TEXT, "Corner: LEFT_UPPER");
   
   // 切り替えボタンを作成する(左上に固定配置)
   ObjectCreate(0, btnSwitch, OBJ_BUTTON, 0, 0, 0);
   ObjectSetInteger(0, btnSwitch, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, btnSwitch, OBJPROP_XDISTANCE, 30);
   ObjectSetInteger(0, btnSwitch, OBJPROP_YDISTANCE, 25);
   
   // ボタンのサイズを設定(幅150、高さ25ピクセル)
   ObjectSetInteger(0, btnSwitch, OBJPROP_XSIZE, 150);
   ObjectSetInteger(0, btnSwitch, OBJPROP_YSIZE, 25);
   
   // ボタンのテキストを設定
   ObjectSetString(0, btnSwitch, OBJPROP_TEXT, "Switch Corner");
   
   // ボタンのフォントサイズを設定
   ObjectSetInteger(0, btnSwitch, OBJPROP_FONTSIZE, 10);
   
   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[])
{
   return(rates_total);
}

//+------------------------------------------------------------------+
//| チャートイベント処理関数                                            |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   // ボタンクリックイベントを検出する
   if(id == CHARTEVENT_OBJECT_CLICK)
   {
      // クリックされたオブジェクトが切り替えボタンか確認する
      if(sparam == btnSwitch)
      {
         // インデックスを1つ進める(3の次は0に戻る)
         currentCornerIndex++;
         if(currentCornerIndex > 3)
            currentCornerIndex = 0;
         
         // デモラベルの基準座標を新しい値に変更する
         ObjectSetInteger(0, lblDemo, OBJPROP_CORNER, corners[currentCornerIndex]);
         
         // ラベルのテキストを現在の基準座標名に更新する
         ObjectSetString(0, lblDemo, OBJPROP_TEXT, "Corner: " + cornerNames[currentCornerIndex]);
         
         // ボタンの押下状態を解除する
         ObjectSetInteger(0, btnSwitch, OBJPROP_STATE, false);
         
         // チャートを再描画する
         ChartRedraw();
      }
   }
}

//+------------------------------------------------------------------+
//| 終了時にすべてのオブジェクトを削除する                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(0, lblDemo);
   ObjectDelete(0, btnSwitch);
}