【MQL5】MathSqrt関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク
  1. MathSqrt関数の働き・役割
    1. 平方根とは
  2. MathSqrt関数の引数について
  3. MathSqrt関数の戻り値について
  4. MathSqrt関数を使う際の注意点
  5. MathSqrt関数を使ったサンプルコード
  6. サンプルコード解説1: グローバル領域での定義
    1. 定義の詳細
      1. グラフの幅と高さの定義
      2. グラフィックライブラリのインクルード
      3. グラフィックオブジェクトの作成
  7. サンプルコード解説2: OnStart関数の中1
    1. 定義の詳細
      1. ベクトルXに0から10までの値を設定
        1. ベクトルとは
      2. ベクトルXの各値の平方根を計算
      3. 計算結果を配列に変換
  8. サンプルコード解説3: OnStart関数の中2
    1. 定義の詳細
      1. グラフを描画
      2. スクリプトが停止されるまで待機
      3. クリーンアップ
  9. サンプルコード解説4: ベクトルに値を設定するテンプレート関数
    1. テンプレート関数
      1. テンプレートを構成する各記述の意味と目的
    2. 関数の引数
      1. ループによる値の設定
  10. サンプルコード解説5: 停止キーが押されたかを確認する関数
    1. 関数の詳細
      1. ESCキーが押されたかを確認
      2. PgDnキーが押されたかを確認し、スクリーンショットを保存
      3. 停止キーが押されていない場合
    2. まとめ
  11. サンプルコード解説6: グラフを描画する関数 その1
    1. 関数の詳細
      1. グラフィックオブジェクトの作成
      2. 曲線を追加
      3. インデントを上げる
      4. 曲線をプロット
  12. サンプルコード解説7: グラフを描画する関数 その2
    1. 関数の詳細
      1. テキストを追加
      2. グラフを更新
  13. サンプルコード解説8: スクリーンショットを撮り、ファイルに保存する関数 その1
    1. 関数の詳細
      1. エラーステータスをリセット
      2. ファイルダイアログを表示して保存先を選択
      3. エラー処理
  14. サンプルコード解説9: スクリーンショットを撮り、ファイルに保存する関数 その2
    1. 関数の詳細
      1. 初期化
      2. チャート表示を一時的にオフにしてスクリーンショットを撮る
      3. チャート表示をオンに戻す
      4. 結果を返す

MathSqrt関数の働き・役割

MathSqrt関数は、指定した数値の平方根を計算するための関数です。平方根は、ある数値を二乗して得られる元の数値を求める演算です。たとえば、4の平方根は2であり、9の平方根は3です。

平方根とは

平方根とは、ある数値を二乗(自身を掛け合わせる)して得られる元の数値を指します。平方根の記号は√で表され、たとえば√9は3となります。これは、3を二乗すると9になるためです。平方根は数学や工学のさまざまな分野で重要な役割を果たします。

MathSqrt関数を使用すると、簡単に数値の平方根を計算できます。これにより、複雑な計算をプログラム内で効率よく実行することができます。

MathSqrt関数の引数について

double MathSqrt(
  double value      // 正の数値
);

valueは正の数値を指定します。この数値の平方根を計算します。例えば、16を指定すると、その平方根である4が返されます。

MathSqrt関数の戻り値について

MathSqrt関数は、指定された数値の平方根戻り値として返します。

valueが正の数値の場合、その平方根戻り値となります。例えば、valueが25であれば、戻り値は5となります。

一方、valueが負の数値の場合、戻り値はNaN(Not a Number、不定値)となります。負の数値の平方根は実数(虚数を含まない数値)では定義されないため、このような動作をします。NaNは計算が不可能であることを示す特別な値です。

MathSqrt関数を使う際の注意点

valueが負の数値である場合、戻り値がNaN(Not a Number、不定値)となります。そのため、負の数値を引数として渡す場合は、結果がNaNとなる可能性を考慮し、エラーチェックを行う必要があります。特に、後続の計算や処理においてNaNが含まれると予期せぬ動作を引き起こす可能性があります。

MathSqrt関数の代わりに標準ライブラリのsqrt関数を使用することも可能です。両者は同じ動作をするため、使い分けは好みやコーディングスタイルによりますが、一貫したコードスタイルを保つためにどちらか一方に統一することをお勧めします。

さらに、MathSqrt関数を含む計算の結果が極端に大きな値や小さな値になる場合、精度の問題が発生することがあります。そのため、特に金融計算など精度が求められる場面では、結果の確認を行うことが重要です。

MathSqrt関数を使ったサンプルコード

以下は、MathSqrt関数を使用して数値の平方根を計算し、その結果をグラフとして表示するサンプルコードです。

#define GRAPH_WIDTH 750    // グラフの幅を定義
#define GRAPH_HEIGHT 350   // グラフの高さを定義

#include <Graphics\Graphic.mqh>    // グラフィックライブラリのインクルード

CGraphic ExtGraph;    // グラフィックオブジェクトの作成

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                     |
//+------------------------------------------------------------------+
void OnStart()
{
  //--- ベクトルXに0から10までの値を設定
  vector X(11, VectorArange);
  Print("vector X = \n", X);
  
  //--- ベクトルXの各値の平方根を計算
  X = MathSqrt(X);
  Print("MathSqrt(X) = \n", X);

  //--- 計算結果を配列に変換
  double y_array[];
  X.Swap(y_array);

  //--- グラフを描画
  CurvePlot(y_array, clrDodgerBlue);

  //--- スクリプトが停止されるまで待機
  while(!IsStopped())
  {
    if(StopKeyPressed())
      break;
    Sleep(16);    // 少し待機してループを繰り返す
  }

  //--- クリーンアップ
  ExtGraph.Destroy();
}

//+------------------------------------------------------------------+
//| ベクトルに値を設定するテンプレート関数                           |
//+------------------------------------------------------------------+
template<typename T>
void VectorArange(vector<T> &vec, T value = 0.0, T step = 1.0)
{
  for(ulong i = 0; i < vec.Size(); i++, value += step)
    vec[i] = value;    // ベクトルの各要素に値を設定
}

//+------------------------------------------------------------------+
//| 停止キーが押されたかを確認する関数                               |
//+------------------------------------------------------------------+
bool StopKeyPressed()
{
  //--- ESCキーが押されたかを確認
  if(TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE) != 0)
    return true;
  
  //--- PgDnキーが押されたかを確認し、スクリーンショットを保存
  if(TerminalInfoInteger(TERMINAL_KEYSTATE_PAGEDOWN) != 0 && MakeAndSaveScreenshot(MQLInfoString(MQL_PROGRAM_NAME) + "_Screenshot"))
    return true;
  
  return false;    // 停止キーが押されていない場合はfalseを返す
}

//+------------------------------------------------------------------+
//| グラフを描画する関数                                             |
//+------------------------------------------------------------------+
void CurvePlot(double &y_array[], const color colour)
{
  //--- グラフィックオブジェクトの作成
  ExtGraph.Create(ChartID(), "Graphic", 0, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
  
  //--- 曲線を追加
  ExtGraph.CurveAdd(y_array, ColorToARGB(colour), CURVE_LINES);
  
  //--- インデントを上げる
  ExtGraph.IndentUp(30);
  
  //--- 曲線をプロット
  ExtGraph.CurvePlotAll();
  
  //--- テキストを追加
  string text1 = "Press ESC to delete the graph and stop the script, or";
  string text2 = "Press PgDn to create a screen, delete the graph and stop the script";
  ExtGraph.TextAdd(54, 9, text1, ColorToARGB(clrBlack));
  ExtGraph.TextAdd(54, 21, text2, ColorToARGB(clrBlack));
  
  //--- グラフを更新
  ExtGraph.Update();
}

//+------------------------------------------------------------------+
//| スクリーンショットを撮り、ファイルに保存する関数                 |
//+------------------------------------------------------------------+
bool MakeAndSaveScreenshot(const string file_name)
{
  string file_names[];
  ResetLastError();    // エラーステータスをリセット
  
  //--- ファイルダイアログを表示して保存先を選択
  int selected = FileSelectDialog("Save Picture", NULL, "All files (*.*)|*.*", FSD_WRITE_FILE, file_names, file_name + ".png");
  if(selected < 1)
  {
    if(selected < 0)
      PrintFormat("%s: FileSelectDialog() function returned error %d", __FUNCTION__, GetLastError());
    return false;    // エラーが発生した場合はfalseを返す
  }
 
  bool res = false;
  //--- チャート表示を一時的にオフにしてスクリーンショットを撮る
  if(ChartSetInteger(0, CHART_SHOW, false))
    res = ChartScreenShot(0, file_names[0], GRAPH_WIDTH, GRAPH_HEIGHT);
  
  //--- チャート表示をオンに戻す
  ChartSetInteger(0, CHART_SHOW, true);
  
  return res;    // スクリーンショットが成功したかを返す
}

サンプルコード解説1: グローバル領域での定義

以下のコードは、サンプルコードのグローバル領域で定義されている内容を示しています。このセクションでは、グラフの描画に必要な設定やライブラリのインクルード、オブジェクトの作成が行われています。

#define GRAPH_WIDTH 750    // グラフの幅を定義
#define GRAPH_HEIGHT 350   // グラフの高さを定義

#include <Graphics\Graphic.mqh>    // グラフィックライブラリのインクルード

CGraphic ExtGraph;    // グラフィックオブジェクトの作成

定義の詳細

グラフの幅と高さの定義

グラフの幅を750ピクセル(デジタル画像を構成する最小の単位)に、グラフの高さを350ピクセルに設定しています。defineディレクティブを使用して定数を定義することで、コード内でこれらの値を使用する際に簡単に参照できるようになります。

グラフィックライブラリのインクルード

includeディレクティブを使用して、グラフィック関連の機能を提供するライブラリファイル「Graphic.mqh」をインクルードしています。このライブラリには、グラフの描画や曲線の追加など、グラフィック操作に必要な関数クラスが定義されています。

グラフィックオブジェクトの作成

CGraphicクラスインスタンスであるExtGraphオブジェクトを作成しています。このオブジェクトは、グラフの描画や操作に使用されます。クラスはオブジェクト指向プログラミングの基本要素であり、特定の機能を持つオブジェクト(変数配列など)を作成するためのテンプレートです。

これらの設定と定義により、グラフの描画に必要な準備が整います。次のセクションでは、スクリプトの開始関数ベクトルの設定について解説します。

サンプルコード解説2: OnStart関数の中1

以下のコードは、OnStart関数の中で実行される処理の一部を示しています。このセクションでは、ベクトルXの設定、平方根の計算、結果の配列への変換が行われています。

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                     |
//+------------------------------------------------------------------+
void OnStart()
{
  //--- ベクトルXに0から10までの値を設定
  vector X(11, VectorArange);
  Print("vector X = \n", X);

  //--- ベクトルXの各値の平方根を計算
  X = MathSqrt(X);
  Print("MathSqrt(X) = \n", X);

  //--- 計算結果を配列に変換
  double y_array[];
  X.Swap(y_array);

定義の詳細

ベクトルXに0から10までの値を設定

vector X(11, VectorArange);
Print("vector X = \n", X);

ベクトルXを初期化し、0から10までの値を設定しています。vectorは、指定したサイズと初期化関数VectorArangeを使用して作成されます。Print関数を使用して、設定されたベクトルの内容をエキスパートログに出力しています。

ベクトルとは

ベクトルとは、複数の数値を一つのデータ構造にまとめたもので、配列と似ていますが、より高機能なデータ操作を可能にします。特に数値計算やデータ解析において便利に使用されます。ベクトルの要素には、それぞれインデックス(通し番号)が割り当てられ、順番にアクセスできます。ベクトルは、サイズの変更が可能で、柔軟なデータ管理が可能です。

ベクトルXの各値の平方根を計算

X = MathSqrt(X);
Print("MathSqrt(X) = \n", X);

ベクトルXの各値に対して、MathSqrt関数を使用して平方根を計算します。計算結果は再度ベクトルXに格納されます。Print関数を使用して、計算後のベクトルの内容をエキスパートログに出力しています。

計算結果を配列に変換

double y_array[];
X.Swap(y_array);

ベクトルXの内容を配列y_arrayに変換しています。Swapメソッドを使用することで、ベクトルの内容を配列に効率的に転送できます。

swapメソッドは、ベクトルの内容を指定した配列と入れ替えるメソッドです。このメソッドを使用することで、ベクトルのデータを効率的に配列に転送できます。結果として、ベクトルの内容が配列に移され、元のベクトルは空になります。

ベクトル配列に変換するのは、特定の関数や操作が配列形式のデータを要求する場合があるからです。グラフ描画関数や他のライブラリ関数は、データを配列形式で受け取ることが一般的です。そのため、ベクトルのデータを配列に変換することで、これらの関数を正しく利用できるようにします。Swapメソッドは、この変換を効率的に行うために使用されます。

この処理により、ベクトルに対する一連の操作が完了し、次のステップでグラフ描画などの追加処理を行う準備が整います。

サンプルコード解説3: OnStart関数の中2

以下のコードは、OnStart関数の中で実行される処理の後半部分を示しています。このセクションでは、グラフの描画、スクリプトの停止待機、クリーンアップが行われています。

//--- グラフを描画
  CurvePlot(y_array, clrDodgerBlue);

  //--- スクリプトが停止されるまで待機
  while(!IsStopped())
  {
    if(StopKeyPressed())
      break;
    Sleep(16);    // 少し待機してループを繰り返す
  }

  //--- クリーンアップ
  ExtGraph.Destroy();
}

定義の詳細

グラフを描画

CurvePlot関数を呼び出して、配列y_arrayのデータを使用してグラフを描画します。clrDodgerBlueはグラフの線の色を指定しています。

CurvePlot関数は、与えられたデータ配列を使ってグラフを描画する機能を持ちます。

スクリプトが停止されるまで待機

while(!IsStopped())
{
if(StopKeyPressed())
break;
Sleep(16); // 少し待機してループを繰り返す
}

このwhileループは、スクリプトが停止されるまで実行されます。IsStopped関数がtrueを返すまでループを継続し、StopKeyPressed関数がtrueを返すとループを終了します。Sleep関数は16ミリ秒間スリープしてループを繰り返します。※ミリ秒は1/1000秒です。

IsStopped関数は、スクリプトが停止されるかどうかを確認します。スクリプトが停止されるとtrueを返します。

StopKeyPressed関数は、特定のキー(例えばESCキー)が押されたかどうかを確認します。キーが押された場合にtrueを返します。

Sleep関数は、指定された時間(ミリ秒)だけスリープします。ここでは16ミリ秒スリープしています。

クリーンアップ

ExtGraph.Destroy();

グラフィックオブジェクトExtGraphを破棄してクリーンアップ(使用したリソースの解放)を行います。

サンプルコード解説4: ベクトルに値を設定するテンプレート関数

以下のコードは、ベクトルに値を設定するテンプレート関数を示しています。この関数は、任意の型のベクトルに対して、指定した値を順次設定するために使用されます。

//+------------------------------------------------------------------+
//| ベクトルに値を設定するテンプレート関数                           |
//+------------------------------------------------------------------+
template<typename T>
void VectorArange(vector<T> &vec, T value = 0.0, T step = 1.0)
{
  for(ulong i = 0; i < vec.Size(); i++, value += step)
    vec[i] = value;    // ベクトルの各要素に値を設定
}

テンプレート関数

template<typename T>
void VectorArange(vector<T> &vec, T value = 0.0, T step = 1.0)

この関数テンプレート関数として定義されています。

テンプレート関数とは、関数の定義時にデータ型を指定せず、呼び出し時に具体的なデータ型を指定することで、異なるデータ型に対して同じ関数ロジックを適用できる関数のことです。これにより、汎用性の高いコードを書くことができます。

テンプレート関数についての詳細は↓の記事及びYouTube動画をご参照ください。

テンプレートを構成する各記述の意味と目的

テンプレート関数とは、任意の型Tに対して動作する関数です。これにより、int型double型など様々な型のベクトルに対応することができます。

関数の引数

  • vector<T> &vec: 値を設定する対象のベクトル参照渡しで受け取ります。
  • T value: 初期値を指定します。デフォルトは0.0です。
  • T step: 各要素に設定する値の増分を指定します。デフォルトは1.0です。

※ちなみに、valuestep<>に囲まれていないのに対し、vectorだけが<T>になっているのは、valuestepが単なる変数として宣言されているのに対し、vector<T>はテンプレートクラスインスタンスを表している為です。
テンプレートクラスの場合、クラスがどのデータ型に対して動作するかを指定する必要があり、そのために<>が使用されます。<T>は、テンプレートクラスvector」が型Tに対して動作することを示しています。

ループによる値の設定

for(ulong i = 0; i < vec.Size(); i++, value += step) vec[i] = value; // ベクトルの各要素に値を設定

このループはベクトルのサイズ分だけ繰り返され、各要素に順次値を設定します。初期値から始まり、指定した増分ずつ値が増加(インクリメント)していきます。具体的には、ベクトルの各インデックス(通し番号)に対して、初期値からステップごとに増加する値を割り当てます。

※ちなみに、この記述のように、i++のさらに右側にループ処理が書かれているパターンのfor文になじみのない方も多いかと思うので、補足して解説します。

このfor文は以下のような構成になっています。

初期化部分:

ulong i = 0;

ここでは、ループカウンタ変数iを0に初期化しています。

条件部分:

i < vec.Size();

この条件がtrueである限り、ループが続きます。ここでは、iベクトルのサイズ未満である限り、ループを続けます。

増量部分:

i++, value += step

ここでは、ループが1回実行されるごとにiを1増加させ(i++)、valuestepを加算します(value += step)。

まとめると、このfor文は、以下の順序で実行されます:

  1. 条件部分が再び評価され、trueであれば再びループ本体が実行されます。
  2. 初期化部分が最初に一度だけ実行されます。
  3. 条件部分が評価され、trueであればループ本体が実行されます。
  4. ループ本体が実行されます。
  5. 増分部分が実行され、iが1増加し、valuestepが加算されます。

これが繰り返されます。

このfor文を日本語で表現すると次のようになります:

「ループカウンタiを0から始め、iベクトルのサイズより小さい間、ループを繰り返す。各ループの繰り返しごとに、iを1増やし、valuestepを加える。」

サンプルコード解説5: 停止キーが押されたかを確認する関数

以下のコードは、停止キーが押されたかどうかを確認する関数を示しています。この関数は、特定のキーが押されたかどうかをチェックし、条件に応じて適切な処理を行います。

//+------------------------------------------------------------------+
//| 停止キーが押されたかを確認する関数                               |
//+------------------------------------------------------------------+
bool StopKeyPressed()
{
  //--- ESCキーが押されたかを確認
  if(TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE) != 0)
    return true;

  //--- PgDnキーが押されたかを確認し、スクリーンショットを保存
  if(TerminalInfoInteger(TERMINAL_KEYSTATE_PAGEDOWN) != 0 && MakeAndSaveScreenshot(MQLInfoString(MQL_PROGRAM_NAME) + "_Screenshot"))
    return true;

  return false;    // 停止キーが押されていない場合はfalseを返す
}

関数の詳細

ESCキーが押されたかを確認

if(TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE) != 0)
  return true;

この部分では、ESCキーが押されたかどうかを確認しています。TerminalInfoInteger関数を使用して、ESCキーの状態を取得します。もしESCキーが押されている場合、この関数はtrueを返します。

PgDnキーが押されたかを確認し、スクリーンショットを保存

if(TerminalInfoInteger(TERMINAL_KEYSTATE_PAGEDOWN) != 0 && MakeAndSaveScreenshot(MQLInfoString(MQL_PROGRAM_NAME) + "_Screenshot"))
  return true;

この部分では、PgDnキーが押されたかどうかを確認し、さらにMakeAndSaveScreenshot関数を呼び出してスクリーンショットを保存します。
MakeAndSaveScreenshot関数引数として使用されているMQLInfoString関数は、MQL5プログラムの情報を取得するための関数です。この関数に渡されている引数「MQL_PROGRAM_NAME」は、実行中のMQL5プログラムの名前を取得するための識別子です。
そして、TerminalInfoInteger関数を使用してPgDnキーの状態を取得し、もしPgDnキーが押されている場合、スクリーンショットを保存し、この関数はtrueを返します。

停止キーが押されていない場合

return false;

この部分では、ESCキーもPgDnキーも押されていない場合、この関数はfalseを返します。

まとめ

この関数は、特定の停止キー(ESCキーやPgDnキー)が押されたかどうかを確認し、押されていればtrueを返し、押されていなければfalseを返します。これにより、スクリプトがユーザーによって停止されるかどうかを判断できます。

サンプルコード解説6: グラフを描画する関数 その1

以下のコードは、グラフを描画する関数の一部を示しています。この関数は、指定されたデータを使用してグラフを描画します。

//+------------------------------------------------------------------+
//| グラフを描画する関数                                             |
//+------------------------------------------------------------------+
void CurvePlot(double &y_array[], const color colour)
{
  //--- グラフィックオブジェクトの作成
  ExtGraph.Create(ChartID(), "Graphic", 0, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);

  //--- 曲線を追加
  ExtGraph.CurveAdd(y_array, ColorToARGB(colour), CURVE_LINES);

  //--- インデントを上げる
  ExtGraph.IndentUp(30);

  //--- 曲線をプロット
  ExtGraph.CurvePlotAll();

関数の詳細

グラフィックオブジェクトの作成

ExtGraph.Create(ChartID(), "Graphic", 0, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);

この部分では、グラフィックオブジェクトを作成します。Createメソッドを使用して、新しいグラフィックオブジェクトを初期化し、描画領域を設定します。ChartID関数は、現在のチャートの識別子を返します。”Graphic”はオブジェクトの名前です。GRAPH_WIDTHとGRAPH_HEIGHTはグラフの幅と高さを指定します。

曲線を追加

ExtGraph.CurveAdd(y_array, ColorToARGB(colour), CURVE_LINES);

この部分では、y_arrayのデータを使用してグラフに曲線を追加します。CurveAddメソッドは、指定されたデータ配列をグラフに追加し、ColorToARGB関数を使用して色を設定します。CURVE_LINESは、曲線の描画方法を指定します。

インデントを上げる

ExtGraph.IndentUp(30);

この部分では、インデント(表示位置の調整)を30ピクセル(デジタル画像を構成する最小の単位)上げます。IndentUpメソッドは、グラフの表示位置を調整するために使用されます。

曲線をプロット

ExtGraph.CurvePlotAll();

この部分では、CurvePlotAllメソッドを使用して、追加されたすべての曲線をプロットします。これにより、グラフが画面に描画されます。

この関数は、グラフを作成し、指定されたデータと色を使用して曲線を描画します。

サンプルコード解説7: グラフを描画する関数 その2

以下のコードは、グラフを描画する関数の後半部分を示しています。このセクションでは、グラフにテキストを追加し、グラフを更新する処理が行われます。

//--- テキストを追加
string text1 = "Press ESC to delete the graph and stop the script, or";
string text2 = "Press PgDn to create a screen, delete the graph and stop the script";
ExtGraph.TextAdd(54, 9, text1, ColorToARGB(clrBlack));
ExtGraph.TextAdd(54, 21, text2, ColorToARGB(clrBlack));

//--- グラフを更新
ExtGraph.Update();
}

関数の詳細

テキストを追加

string text1 = "Press ESC to delete the graph and stop the script, or";
string text2 = "Press PgDn to create a screen, delete the graph and stop the script";
ExtGraph.TextAdd(54, 9, text1, ColorToARGB(clrBlack));
ExtGraph.TextAdd(54, 21, text2, ColorToARGB(clrBlack));

この部分では、グラフにテキストを追加しています。まず、追加するテキスト内容をそれぞれtext1とtext2の変数に格納しています。その後、TextAddメソッドを使用して、指定した位置にテキストを追加します。

  • ExtGraph.TextAdd(54, 9, text1, ColorToARGB(clrBlack)); は、位置 (54, 9) にtext1を黒色で追加します。
  • ExtGraph.TextAdd(54, 21, text2, ColorToARGB(clrBlack)); は、位置 (54, 21) にtext2を黒色で追加します。

グラフを更新

ExtGraph.Update();

この部分では、Updateメソッドを使用してグラフを更新します。これにより、追加されたテキストや曲線などの変更が画面に反映されます。

この関数の後半部分では、ユーザーへの指示を示すテキストをグラフに追加し、最終的にグラフの表示を更新して画面に反映させています。

サンプルコード解説8: スクリーンショットを撮り、ファイルに保存する関数 その1

以下のコードは、スクリーンショットを撮影し、ファイルに保存する関数の一部を示しています。この関数は、ユーザーに保存先を選択させ、スクリーンショットをファイルに保存する処理を行います。

//+------------------------------------------------------------------+
//| スクリーンショットを撮り、ファイルに保存する関数                 |
//+------------------------------------------------------------------+
bool MakeAndSaveScreenshot(const string file_name)
{
  string file_names[];
  ResetLastError();    // エラーステータスをリセット

  //--- ファイルダイアログを表示して保存先を選択
  int selected = FileSelectDialog("Save Picture", NULL, "All files (*.*)|*.*", FSD_WRITE_FILE, file_names, file_name + ".png");
  if(selected < 1)
  {
    if(selected < 0)
      PrintFormat("%s: FileSelectDialog() function returned error %d", __FUNCTION__, GetLastError());
    return false;    // エラーが発生した場合はfalseを返す
  }

関数の詳細

エラーステータスをリセット

ResetLastError();    // エラーステータスをリセット

この部分では、関数の実行前にResetLastError関数を使って、エラーステータスをリセットします。これにより、前回のエラーが残っていても影響を受けないようにします。

ファイルダイアログを表示して保存先を選択

int selected = FileSelectDialog("Save Picture", NULL, "All files (*.*)|*.*", FSD_WRITE_FILE, file_names, file_name + ".png");

この部分では、ファイルダイアログを表示してユーザーに保存先を選択させます。FileSelectDialog関数を使用して、保存先のファイル名を取得します。

  • “Save Picture”はダイアログのタイトルです。
  • NULLは初期ディレクトリを指定しないことを示します。
  • “All files (.)|.“はファイルフィルタを示します。すべてのファイルが表示されます。
  • FSD_WRITE_FILEは、ファイルを保存するためのダイアログであることを示します。
  • file_namesは選択されたファイル名を格納する配列です。
  • file_name + “.png”はデフォルトのファイル名です。

エラー処理

if(selected < 1)
{
  if(selected < 0)
    PrintFormat("%s: FileSelectDialog() function returned error %d", __FUNCTION__, GetLastError());
  return false;    // エラーが発生した場合はfalseを返す
}

この部分では、ファイルダイアログでの操作結果を確認します。選択がキャンセルされた場合やエラーが発生した場合に、エラーメッセージをエキスパートログに出力し、関数はfalseを返します。これにより、スクリーンショットの保存が正常に行われなかったことを示します。

サンプルコード解説9: スクリーンショットを撮り、ファイルに保存する関数 その2

以下のコードは、スクリーンショットを撮影し、ファイルに保存する関数の後半部分を示しています。この関数は、チャート表示を一時的にオフにしてスクリーンショットを撮影し、保存した後にチャート表示をオンに戻します。

bool res = false;
//--- チャート表示を一時的にオフにしてスクリーンショットを撮る
if(ChartSetInteger(0, CHART_SHOW, false))
  res = ChartScreenShot(0, file_names[0], GRAPH_WIDTH, GRAPH_HEIGHT);

//--- チャート表示をオンに戻す
ChartSetInteger(0, CHART_SHOW, true);

return res;    // スクリーンショットが成功したかを返す
}

関数の詳細

初期化

bool res = false;

この部分では、スクリーンショットの成否を示す変数resを初期化しています。初期値falseです。

チャート表示を一時的にオフにしてスクリーンショットを撮る

if(ChartSetInteger(0, CHART_SHOW, false))
  res = ChartScreenShot(0, file_names[0], GRAPH_WIDTH, GRAPH_HEIGHT);

この部分では、以下の処理を行います:

  1. ChartSetInteger関数を使用して、チャート表示を一時的にオフにします。ChartSetInteger(0, CHART_SHOW, false)は、チャートIDが0のチャートの表示をオフにします。
  2. チャート表示がオフに成功した場合、ChartScreenShot関数を使用してスクリーンショットを撮影し、指定したファイルに保存します。resにはスクリーンショットの成否が格納されます。
  • 引数0はチャートIDを指定します。
  • file_names[0]は保存するファイル名を指定します。
  • GRAPH_WIDTHとGRAPH_HEIGHTはスクリーンショットの幅と高さを指定します。

チャート表示をオンに戻す

ChartSetInteger(0, CHART_SHOW, true);

この部分では、ChartSetInteger関数を使用して、チャート表示をオンに戻します。ChartSetInteger(0, CHART_SHOW, true)は、チャートIDが0のチャートの表示をオンにします。

結果を返す

return res;    // スクリーンショットが成功したかを返す

最後に、スクリーンショットの成否を示すresを返します。スクリーンショットが成功した場合はtrue、失敗した場合はfalseが返されます。

この関数の後半部分では、チャートの表示状態を制御しながらスクリーンショットを撮影し、指定されたファイルに保存する処理が行われます。

コメント

タイトルとURLをコピーしました