ChartXYToTimePrice関数の働き・役割
ChartXYToTimePrice関数は、チャートの座標をXとYの座標から時間/価格表現に変換するために使用されます。
トレードチャートには時間軸(横軸)と価格軸(縦軸)があり、これらの軸上にローソク足やインジケータが表示されます。
例えば、マウスを使ってチャートの特定の位置をクリックしたとき、その位置はチャート上のピクセルで表されますが、実際の取引にはその位置が示す時間と価格が重要です。
ピクセル座標で表現されていた位置情報は↓
これを時間/価格表現として
- 時間: チャートの横軸に沿った特定の時刻
- 価格: チャートの縦軸に沿った特定の価格
に変換してしまおう、というのがこの関数が担う機能です。
これにより、ユーザーの操作に基づいて動的にチャートを操作したり、解析したりすることができます。
ChartXYToTimePrice関数の引数について
bool ChartXYToTimePrice(
long chart_id, // チャート識別子
int x, // チャートの X 座標
int y, // チャートの Y 座標
int& sub_window, // サブウィンドウ番号
datetime& time, // チャートの時間
double& price // チャートの価格
);
ChartXYToTimePrice関数は以下の6つの引数を取ります。
- chart_id
- x
- y
- sub_window
- time
- price
※第4引数から第6引数は、関数処理の結果を受け取る役割を担うものである点に注意が必要です。
下記参照渡しの記事も参考にしてください。
ChartXYToTimePrice関数の戻り値について
ChartXYToTimePrice関数は、チャートの座標を時間と価格に変換する操作が成功した場合にtrueを返します。変換に失敗した場合はfalseを返します。エラーが発生した場合は、GetLastError関数を使用してエラーの詳細を取得することができます。
ChartXYToTimePrice関数を使ったサンプルコード
// OnChartEvent関数は、チャート上で発生するイベントを処理するために使用されます
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
// イベントの詳細をエキスパートログに出力します
Comment(__FUNCTION__, ": id=", id, " lparam=", lparam, " dparam=", dparam, " sparam=", sparam);
// マウスクリックイベントかどうかを確認します
if(id == CHARTEVENT_CLICK)
{
// lparamからX座標を取得します
int x = (int)lparam;
// dparamからY座標を取得します
int y = (int)dparam;
// チャートの時間を格納する変数を初期化します
datetime dt = 0;
// チャートの価格を格納する変数を初期化します
double price = 0;
// サブウィンドウ番号を格納する変数を初期化します
int window = 0;
// ChartXYToTimePrice関数を使用してXとYの座標を時間と価格に変換します
if(ChartXYToTimePrice(0, x, y, window, dt, price))
{
// 変換に成功した場合、結果をエキスパートログに出力します
PrintFormat("Window=%d X=%d Y=%d => Time=%s Price=%G", window, x, y, TimeToString(dt), price);
// 逆変換を実行して(X,Y) => (Time,Price)から(Time,Price) => (X,Y)に戻します
if(ChartTimePriceToXY(0, window, dt, price, x, y))
PrintFormat("Time=%s Price=%G => X=%d Y=%d", TimeToString(dt), price, x, y);
else
Print("ChartTimePriceToXYがエラーコードを返しました: ", GetLastError());
// 既存の水平線と垂直線を削除します
ObjectDelete(0, "V Line");
ObjectDelete(0, "H Line");
// 十字線の水平線と垂直線を作成します
ObjectCreate(0, "H Line", OBJ_HLINE, window, dt, price);
ObjectCreate(0, "V Line", OBJ_VLINE, window, dt, price);
// チャートを再描画します
ChartRedraw(0);
}
else
Print("ChartXYToTimePriceがエラーコードを返しました: ", GetLastError());
// イベント処理の区切りをエキスパートログに出力します
Print("+--------------------------------------------------------------+");
}
}
サンプルコード解説1:OnChartEvent関数その1
// OnChartEvent関数は、チャート上で発生するイベントを処理するために使用されます
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
// イベントの詳細をエキスパートログに出力します
Comment(__FUNCTION__, ": id=", id, " lparam=", lparam, " dparam=", dparam, " sparam=", sparam);
解説
OnChartEvent関数について
OnChartEvent関数は、MetaTrader5プラットフォーム上で発生するさまざまなチャートイベントを処理するための関数です。この関数は、ユーザーがチャート上で行った操作(例えば、マウスクリック、キー入力など)に応じて自動的に呼び出されます。
関数の書式
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
- id (int型): イベントの種類を示す識別子です。CHARTEVENT_CLICK、CHARTEVENT_KEYDOWNなどの定数で表されます。
- lparam (long型): イベントに関連する追加情報を提供するパラメータです。具体的なイベントに応じて異なる情報を含みます。
- dparam (double型): 追加の詳細情報を提供するパラメータです。主にマウスのX座標やY座標などの情報が含まれます。
- sparam (string型): 文字列情報を提供するパラメータです。特定のイベントで必要となる文字列データを含みます。
イベントの詳細をエキスパートログに出力
Comment(__FUNCTION__, ": id=", id, " lparam=", lparam, " dparam=", dparam, " sparam=", sparam);
Comment関数を使用して、イベントの詳細をエキスパートログに出力しています。これにより、発生したイベントの種類や関連する情報をリアルタイムで確認することができます。
- __FUNCTION__: 現在実行中の関数名を示すマクロで、この場合は”OnChartEven“が出力されます。
- id: イベントの識別子。
- lparam: イベントに関連する追加情報。
- dparam: イベントに関連する追加の詳細情報。
- sparam: イベントに関連する文字列情報。
この部分は、デバッグや開発時に、どのイベントが発生しているのか、そしてそのイベントに関連するパラメータがどのような値を持っているのかを確認するのに非常に有用です。
サンプルコード解説2:OnChartEvent関数その2
// マウスクリックイベントかどうかを確認します
if(id == CHARTEVENT_CLICK)
{
// lparamからX座標を取得します
int x = (int)lparam;
// dparamからY座標を取得します
int y = (int)dparam;
// チャートの時間を格納する変数を初期化します
datetime dt = 0;
// チャートの価格を格納する変数を初期化します
double price = 0;
// サブウィンドウ番号を格納する変数を初期化します
int window = 0;
解説
マウスクリックイベントの確認
まず、発生したイベントがマウスクリックイベントかどうかを確認しています。イベントの識別子がCHARTEVENT_CLICKと等しい場合、そのイベントはマウスクリックイベントであることを示します。
X座標とY座標の取得
次に、lparamからX座標を取得し、dparamからY座標を取得します。これらの値はチャート上のクリック位置を示します。マウスクリックイベントが発生した場合、lparamにはX座標、dparamにはY座標が格納されています。
型変換(キャスト)について
型変換(タイプキャスト)とは、あるデータ型の値を別のデータ型に変換することを指します。ここでは、long型のlparamとdouble型のdparamを、それぞれint型に変換しています。これは、チャート上の座標を整数値として扱うためです。
int x = (int)lparam; // long型のlparamをint型に変換
int y = (int)dparam; // double型のdparamをint型に変換
変数の初期化
チャートの時間、価格、サブウィンドウ番号を格納するための変数を初期化します。
- 時間を格納する変数dtはdateTime型で初期値は0です。この変数には後ほどチャートの時間が格納されます。
- 価格を格納する変数priceはdouble型で初期値は0です。この変数には後ほどチャートの価格が格納されます。
- サブウィンドウ番号を格納する変数windowはint型で初期値は0です。この変数には後ほどチャートのサブウィンドウ番号が格納されます。
これらの変数は、後続の処理でChartXYToTimePrice関数を使用して、X座標とY座標から時間と価格を取得する際に使用されます。初期化することで、関数実行後に正しい値が格納される準備が整います。
サンプルコード解説3:OnChartEvent関数その3
// ChartXYToTimePrice関数を使用してXとYの座標を時間と価格に変換します
if(ChartXYToTimePrice(0, x, y, window, dt, price))
{
// 変換に成功した場合、結果をエキスパートログに出力します
PrintFormat("Window=%d X=%d Y=%d => Time=%s Price=%G", window, x, y, TimeToString(dt), price);
// 逆変換を実行して(X,Y) => (Time,Price)から(Time,Price) => (X,Y)に戻します
if(ChartTimePriceToXY(0, window, dt, price, x, y))
PrintFormat("Time=%s Price=%G => X=%d Y=%d", TimeToString(dt), price, x, y);
else
Print("ChartTimePriceToXYがエラーコードを返しました: ", GetLastError());
解説
ChartXYToTimePrice関数の使用
まず、ChartXYToTimePrice関数を使用して、取得したX座標とY座標を対応する時間と価格に変換します。この関数は、チャートの指定された位置(ピクセル単位)を、実際の時間と価格に変換するために使用されます。
if(ChartXYToTimePrice(0, x, y, window, dt, price))
- 0は現在のチャートIDを示します。
- xはクリック位置のX座標です。
- yはクリック位置のY座標です。
- windowはチャートのサブウィンドウ番号を受け取る変数です。
- dtは時間を受け取る変数です。
- priceは価格を受け取る変数です。
変換成功時の処理
変換が成功すると、結果として得られたサブウィンドウ番号、時間、価格の情報をエキスパートログに出力します。
PrintFormat("Window=%d X=%d Y=%d => Time=%s Price=%G", window, x, y, TimeToString(dt), price);
PrintFormat関数の説明
PrintFormat関数は、指定されたフォーマットに従って文字列を整形し、エキスパートログに出力する関数です。この関数を使用すると、複数の値をフォーマット指定子を使って一つの文字列にまとめ、出力することができます。
フォーマット指定子の仕組み
フォーマット指定子は、出力するデータの形式を指定するための特別な記号です。以下のように使用されます。:
この例では、以下のようにフォーマット指定子が使用されています:
PrintFormat("Window=%d X=%d Y=%d => Time=%s Price=%G", window, x, y, TimeToString(dt), price);
このPrintFormat関数では、次のように変変数数がフォーマット指定子に対応しています。
- %d: 整数値を出力します。ここでは、
window
、x
、y
がそれぞれ対応しています。- 最初の %d に
window
が格納されます。 - 次の %d に
x
が格納されます。 - その次の %d に
y
が格納されます。
- 最初の %d に
- %s: 文字列を出力します。ここでは、TimeToString(dt)が対応しています。
- %s に TimeToString(dt) が格納されます。
- %G: 浮動小数点数を出力します。ここでは、
price
が対応しています。- %G に
price
が格納されます。
- %G に
これにより、変数window
、x
、y
、TimeToString(dt)、price
の値がフォーマット指定子に従って整形され、エキスパートログに出力されます。具体的には、次のように表示されます。
※TimeToString関数は時刻を表す数字(UNIXタイム)を、私たちが普段使う日時の形式の文字列に変換するために使われます。
Window=0 X=100 Y=200 => Time=2022.01.01 00:00 Price=1.23456
逆変換の実行
次に、時間と価格から元のX座標とY座標に逆変換を実行します。この操作は、ChartTimePriceToXY関数を使用します。
if(ChartTimePriceToXY(0, window, dt, price, x, y))
PrintFormat("Time=%s Price=%G => X=%d Y=%d", TimeToString(dt), price, x, y);
else
Print("ChartTimePriceToXYがエラーコードを返しました: ", GetLastError());
- ChartTimePriceToXY関数は、時間と価格を元にX座標とY座標に変換します。
- 変換が成功した場合、結果をエキスパートログに出力します。
- 変換が失敗した場合、エラーメッセージとエラーコードをエキスパートログに出力します。エラーコードの特定にはGetLastError関数が使われます
これにより、ユーザーがチャート上でクリックした位置が具体的にどの時間と価格に対応するか、またそれを元の座標に戻すことができるかを確認することができます。
サンプルコード解説4:OnChartEvent関数その4
// 既存の水平線と垂直線を削除します
ObjectDelete(0, "V Line");
ObjectDelete(0, "H Line");
// 十字線の水平線と垂直線を作成します
ObjectCreate(0, "H Line", OBJ_HLINE, window, dt, price);
ObjectCreate(0, "V Line", OBJ_VLINE, window, dt, price);
// チャートを再描画します
ChartRedraw(0);
}
else
Print("ChartXYToTimePriceがエラーコードを返しました: ", GetLastError());
// イベント処理の区切りをエキスパートログに出力します
Print("+--------------------------------------------------------------+");
}
解説
水平線と垂直線の削除
まず、既存の水平線と垂直線を削除します。これにより、新しい十字線を作成する前に、古い線を取り除きます。
ObjectDelete(0, "V Line");
ObjectDelete(0, "H Line");
- ObjectDelete関数は、指定されたオブジェクトを削除します。
- 0は現在のチャートIDを示します。
- “V Line”と“H Line”は削除するオブジェクトの名前です。
十字線の水平線と垂直線の作成
次に、新しい十字線を作成します。水平線と垂直線を作成することで、クリックした位置に十字線を表示します。
ObjectCreate(0, "H Line", OBJ_HLINE, window, dt, price);
ObjectCreate(0, "V Line", OBJ_VLINE, window, dt, price);
- ObjectCreate関数は、新しいオブジェクトを作成します。
- 0は現在のチャートIDを示します。
- “H Line”と“V Line”は作成するオブジェクトの名前です。
- OBJ_HLINEとOBJ_VLINEは、それぞれ水平線と垂直線を示す定数です。
- windowはチャートのサブウィンドウ番号です。
- dtは時間です。
- priceは価格です。
チャートの再描画
新しいオブジェクトを作成した後、チャートを再描画して変更を反映させます。
ChartRedraw(0);
- ChartRedraw関数は、指定されたチャートを再描画します。
- 0は現在のチャートIDを示します。
エラー処理
もしChartXYToTimePrice関数が失敗した場合、エラーメッセージとエラーコードをエキスパートログに出力します。
else
Print("ChartXYToTimePriceがエラーコードを返しました: ", GetLastError());
- Print関数はメッセージをエキスパートログに出力します。
- GetLastError関数は最後に発生したエラーコードを返します。
イベント処理の区切り
イベント処理の区切りとして、エキスパートログに区切り線を出力します。これにより、ログが見やすくなります。
Print("+--------------------------------------------------------------+");
この部分のコードは、チャート上の特定の位置に対して十字線を表示し、ユーザーの操作に対して視覚的なフィードバックを提供します。これにより、ユーザーはクリックした位置がどの時間と価格に対応しているかを直感的に確認できます。
補足:そもそもピクセルとは?
ピクセルはデジタル画像を構成する最小単位であり、点のようなものです。ピクセル自体は物理的な大きさを持ちません。
この小さな点が集まって、文字や絵、写真など、さまざまなものが画面上に表示されます。ピクセルの数が多いほど、画像はより詳細で鮮明になります。
しかし、ピクセルが画面上に表示される際には、画面の解像度やサイズによって物理的な大きさが変わります。
例えば、同じ100ピクセルの画像でも、高解像度のディスプレイでは小さく表示され、低解像度のディスプレイでは大きく表示されます。
そのため、ピクセルをセンチメートルやミリメートルなどの長さの単位で直接表すことはできません。
ただし、画面の解像度(DPI)が分かっていれば、ピクセルと長さの単位をある程度関連付けることは可能です。DPIは1インチあたりのピクセル数を表すので、DPI値と画像のピクセル数から、画像のおおよその物理的なサイズを計算できます。
しかし、それでも正確な長さを表すことはできません。なぜなら、ディスプレイの表示サイズや設定によって、同じDPIでもピクセルの物理的な大きさが異なる場合があるからです。