チャート基準座標の定数
チャート基準座標の定数は、チャートの基準座標を設定するときに使われます。
チャート基準座標とは、オブジェクトを表示するときに基準となるチャート上の座標のことです。
主に、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);
}


