質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MQL4

MQL4とは、MT4(MetaTrader4)で用いられるプログラム言語です。MT4は無料で使えるチャートソフトあり、MQL4を使うことで分析ツールのオリジナルスクリプトの作成ができます。

Q&A

解決済

2回答

516閲覧

MQL4 インジケータの名前を作成する関数について

y_masa.teratail

総合スコア13

MQL4

MQL4とは、MT4(MetaTrader4)で用いられるプログラム言語です。MT4は無料で使えるチャートソフトあり、MQL4を使うことで分析ツールのオリジナルスクリプトの作成ができます。

0グッド

0クリップ

投稿2022/03/04 19:40

編集2022/03/07 15:16

プログラミング初学者です。
現在MQL4を学んでいます。下記処理はインジケータの名前を作成する関数で、下記のように理解しているのですが、誤った理解があればご指摘頂きたく、よろしくお願いします。
また、string name = target;の意味がうまく理解できず、アドバイス頂けると幸いです。

MQL4

1string GenerateIndicatorName(const string target) 2{ 3 string name = target; 4 int try = 2; 5 while (WindowFind(name) != -1) 6 { 7 name = target + " #" + IntegerToString(try++); 8 } 9 return name; 10}

●インジケータの名前を作成する関数
文字列targetを引数として渡し、GenerateIndicaterNameを返す関数。OnCalculate関数と同様の構文。
string型のnameを定義し、そこにtarget変数を代入。←この処理の意味がうまく理解できません。。
int型の変数tryを定義し、2を代入。
whileでインジケータの名前が見つかるまでループ。見つかったら文字列target#3(2をインクリメント)を返す。

備考
//WindowFind…インディケータのname(名前)を引数として渡し、指定されたインディケータを含んでいるウィンドウインデックス(ウィンドウ番号)を返す。それ以外の場合は、-1 を返す。
//IndicaterToString…int型のデータを指定した長さの文字列に変換する。

以下、xg63ex2bさんへの追記内容となります。

●引数について

”関数が受け取る変数が引数”、となるのですね。
string name = target;では、
”name変数にtargetを割り当てる処理”であるため、引数とはまた意味が違ってくるのだと解釈いたしました。

●while (WindowFind(name) != -1)の条件式について

(WindowFind(name) != -1)

-1(ウィンドウ番号が返されないとき)じゃないとき=ウィンドウ番号が返されるとき

ウィンドウ番号が返されるときに、
name = target + " #" + IntegerToString(try++);
が実行される。
否定の否定となるため、WindowFind()関数でインジケータの名前が見つかったら処理が実行されるということだと解釈しました。

●name = target + " #" + IntegerToString(try++);が実行される条件について

1回目の判断では、while (WindowFind(name) != -1)の条件式が実行される前の
string name = target;によってname変数が定義される。
(すでにmoving averageが存在しているものとする。)
従ってmoving averageが返される。
2回目の判断では、while (WindowFind(name) != -1)以降の条件式となる。
すでにmoving averageが存在しているため、
while (WindowFind(name) != -1)の条件式が実行される。
ここでname変数への再代入がされるが、この場合は後置インクリメントとなり、
まず最初にtry変数に代入されていた「2」を使ってname変数への再代入の処理を行う。
そのため、name変数は"moving average #2"となる。
インクリメントをはき違えて理解していました。
以降、xg63ex2bさんのご指摘の内容となるのですね。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

回答遅くなり申し訳ございません。前回に引きつづき回答頂き、ありがとうございます。

●string name = target;について
生成したい名前がmoving averegeだとすると、targetにmoving averageが代入され、
name変数にmoving averageが代入される。

targetが引数となり、nameが定義される。
初歩的なことかもしれませんが、string A = Bという文が、Bが引数となりAが
定義されるというように考えることができず、つまずいていました。

●while文について
while文は条件がtrueの場合はブロックを実行する。しかし今回の場合はwhileの否定の
条件のため、条件を満たさないとき、名前を生成する条件を実行する。

windowfindはインジケータの名前があるときはウィンドウ番号を返す関数なので、
-1となるのはインジケータの名前が見つからなかったとき。

インジケータの名前が見つからなかったとき(条件を満たさないとき)に
name = target + " #" + IntegerToString(try++);が実行される。
上記のように自分でもかみ砕いて理解してみました。

また、回答頂きました内容の、

name変数をデバッグすると次のような名前を探していくことになると思います。
"moving average"
"moving average #2"
"moving average #3"
"moving average #4"

について質問させて頂きます。回答頂けると幸いです。
int try = 2;が定義されているので実行結果としては
"moving average #3"
"moving average #4"
となると考えていたのですが、
"moving average"
"moving average #2"
"moving average #3"
"moving average #4"
となるのがうまく理解できず、ヒントを頂けないでしょうか。

お手数ですがよろしくお願いします。

投稿2022/03/06 13:44

y_masa.teratail

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/03/06 15:44

ご返信ありがとうございます。 回答欄は回答のためのものですので、回答へのコメントか、質問欄の編集の方が良いかもしれませんね。 > targetが引数となり、nameが定義される。 処理している内容の解釈は、ご記載いただいたもので合っていると思います。 ただ、引数という言葉の解釈がちょっと違うかもしれません。 > 「引数(ひきすう)、パラメータ(ー)(英語:parameter)は、数学における関数やコンピュータプログラムにおける手続きにおいて、その外部と値をやりとりするための特別な変数、あるいはその変数の値のことである。」 > https://ja.wikipedia.org/wiki/引数 wikiによるとこういうことなのですが、関数が受け取る変数のことを特別に「引数」と呼んでいる感じですかね。 `string GenerateIndicatorName(const string target) { ... }`という関数があるとしたら、targetのことを引数(仮引数)と呼びます。 すみません、私自身も漠然と解釈しているだけかもしれません・・ > インジケータの名前が見つからなかったとき(条件を満たさないとき)にname = target + " #" + IntegerToString(try++);が実行される。 これは逆になります。 インジケータの名前が見つかったとき(条件を満たすとき)に `name = target + " #" + IntegerToString(try++);` が実行されます。 認識が誤ってしまっているポイントは次の文です。 > 「しかし今回の場合はwhileの否定の条件のため、条件を満たさないとき、名前を生成する条件を実行する。」 「whileはtrueの場合に処理を実行する」この前提は変わりません。 変わるのは、カッコの中の条件です。 今回は、条件が`WindowFind(name) != -1`ですので、見つからない場合に`-1 != -1`(false:偽)となりますので、処理は実行されません。 見つかった場合は`2 != -1`(true:真)(ここでは仮に2のウィンドウで見つかったとしています)となりますので、処理は実行されます。 > となるのがうまく理解できず、ヒントを頂けないでしょうか。 ちょっと説明不足だったかもしれません・・ デバッグするポイントとしては、`while (WindowFind(name) != -1)`の行におけるname変数の内容のつもりで書いていました。 ●1回目の判断 まず、最初の"moving average"ですが、 これは、`string name = target;`で最初にname変数を定義した後に、 name変数への再代入がされることなく、`while (WindowFind(name) != -1)`の行までくることになります。 ですので、最初に判断するのは"moving average"になります。 (仮に既に"moving average"のインジケータが存在したとして、whileの中の処理に入るとします) ●2回目の判断 whileの中ではname変数への再代入がされています。 ここでポイントになるのは`try++`のインクリメントです。 > 後置の場合はインクリメントする前の値になる。 > https://ja.wikipedia.org/wiki/インクリメント try変数の値は最初に「2」が代入されていますので、「2」をインクリメントして「3」になり、name変数には"moving average #3"が再代入されることになりそうに思えますが、 ここでは++が変数の後ろについていますので、後置インクリメントとなり、まず最初にtry変数に代入されていた「2」を使ってname変数への再代入の処理を行います。 そのため、name変数は"moving average #2"となります。 name変数への再代入が終わった後、try変数がインクリメントされ、「3」になります。 そして、また`while (WindowFind(name) != -1)`の行に戻ってきます。 name変数の現在の内容は"moving average #2"です。 (仮に既に"moving average #2"のインジケータも存在したとして、whileの中の処理に入るとします)) ●3回目の判断 またwhileの中の処理に入ってきました。 whileの中の処理をする前の現在の状態を再確認しますと、name変数は"moving average #2"、try変数は「3」です。 上記「●2回目の判断」に記載したように、try変数を後置インクリメントして、name変数への再代入をします。 するとname変数は"moving average #3"になります。 name変数への再代入がされた後にtry変数の後置インクリメントによって、try変数は「4」になります。 そして、また`while (WindowFind(name) != -1)`の行に戻ってきます。 name変数の現在の内容は"moving average #3"です。 ここで仮に"moving average #3"のインジケータはどこのウィンドウでも使われていなかったとします。 すると、`while (WindowFind(name) != -1)`は`-1 != -1`(false:偽)となりますので、 whileの文を抜けて、`return name;`の行が実行されます。 関数の呼び出し側は"moving average #3"を受け取り、それを新しく作成するインジケータの名前として使うことができます。 伝えるのが上手くないため、伝わらないかもしれません・・すみません・・ 不十分でしたら、またコメントください。
y_masa.teratail

2022/03/07 15:17

ご連絡頂き、ありがとうございます。 内容を修正しましたので、ご確認いただけると幸いです。 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2022/03/09 09:12

ごめんなさい。 メールが届いていなかったため、コメントに気づけませんでした・・ > ●引数について OKだと思います。 > ●while (WindowFind(name) != -1)の条件式について > -1(ウィンドウ番号が返されないとき)じゃないとき=ウィンドウ番号が返されるとき OKだと思います。 「-1」も否定と言えば否定ですね。 「否定の否定となるため」とご記載いただいていますが、プログラミングのプラクティスとしてはこのような実装はできるだけしないほうが良いみたいです。 理解するのが大変でしたよね・・ できるだけ肯定文で理解しやすい実装をした方がメンテナンスしやすいみたいです。 > ●name = target + " #" + IntegerToString(try++);が実行される条件について > 従ってmoving averageが返される。 「返される」の表現が少し気になりましたが、OKだと思います。
y_masa.teratail

2022/03/10 13:52

ご連絡頂き、ありがとうございます。 xg63ex2bさんのおかげで自分の中に落とし込んで理解することができました。 本当にありがとうございました。
guest

0

ベストアンサー

string型のnameを定義し、そこにtarget変数を代入。←この処理の意味がうまく理解できません。。

target引数の内容が"moving average"だとすると、name変数に"moving average"を代入することになります。

whileでインジケータの名前が見つかるまでループ。見つかったら文字列target#3(2をインクリメント)を返す。

これは逆ですね。
whileは条件がtrue間はブロックを実行することになります。
否定の条件なので分かりづらいですが、その名前が見つかる間はループします。
見つからなくなったら、(それは新しい名前として使えることになるので、)その名前を返します。

target引数が"moving average"だとすると、
name変数をデバッグすると次のような名前を探していくことになると思います。
"moving average"
"moving average #2"
"moving average #3"
"moving average #4"

//IndicaterToString…

「IntegerToString」(int型のInteger)ですね。

投稿2022/03/05 00:42

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問