EAを作っていて、 「if文の条件が合っているはずなのに動かない」 「数値比較がどう見てもおかしい」 と感じたことはありませんか?
その原因、変数の型(string / int / double)の違いかもしれません。
はじめに
EAを作成していると、何気なくint型やstring型の変数を使っていると思います。
今回はその何気ない型選びのせいで、EAがうまく動かなくなりハマった問題について記載しています。
※初心者向けです
ハマった内容
まず、ハマった内容を率直にいうと「6>4」のような数値の比較がうまくいかないといった感じです。
//+------------------------------------------------------------------+
//| test.mq4 |
//| Copyright 2020, mef Software. |
//| https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link "https://fx-prog.com/"
#property version "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
int start()
{
//---
string strBuff;
int intBuff;
strBuff = "6";
intBuff = 4;
if(strBuff > intBuff){
Print("でかいよ" +strBuff+ ">" +intBuff);
}else{
Print("でかくないよ " +strBuff+ "<=" +intBuff);
}
return(0);
}
このコードを実行した結果が

ちゃんとなってるやん!何がハマったの?という感じです。
が「strBuff = “6”」を「strBuff = “10”」にしてみてください。
すると・・・、

あれ?10が4より大きくないってなっちゃいましたね・・・。いやいや4より10の方が大きいでしょう!ってなっちゃいますよね。
これが最初全然わからなくてハマりました。初心者にありがちなミスです。※私初心者です( ;∀;)
原因
うまく数値比較できない原因は簡単で、10をセットしている変数が「string型」だからです。
「6>4」がうまく比較できたのは何故?って思うかもしれませんが、これは確かうろ覚えですが「string型」だと文字の先頭部分で見てたと思うので「6>4」は成立しますが、「10>4」は「1>4」ってなっちゃうので「1(0)<4」となります。
試しに「39」「40」「50」で見てみるとこうなります。

「39」だけおかしいですよね。先頭の3で比較されているためです。
※「string型・int型ってそもそも何?」という方は、 変数の基本から解説しているこちらの記事を先に読むと理解しやすくなります。
解決策
解決策は超簡単で、数値比較するときはちゃんとどちらも合わせて数値(intやdouble型)で比較してあげましょうという事です。
間違ってもサンプルのように「string型とint型」で比較することのないようにしましょう。
途中までは文字(String型)として扱っていたけど、比較する時だけは数値にしたいといったときは
※ 小数を扱う場合は StringToDouble() を使います。
上記のような感じで文字(String型)を数値(int型)に変換してあげましょう。
こんな感じに。
//+------------------------------------------------------------------+
//| test.mq4 |
//| Copyright 2020, mef Software. |
//| https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link "https://fx-prog.com/"
#property version "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
int start()
{
//---
string strBuff;
int intBuff;
strBuff = "10";
intBuff = 4;
//ちゃんと型を合わせよう
if(StringToInteger(strBuff) > intBuff){
Print("でかいよ" +StringToInteger(strBuff)+ ">" +intBuff);
}else{
Print("でかくないよ " +StringToInteger(strBuff)+ "<=" +intBuff);
}
return(0);
}

ちゃんと数値比較できましたね!
未然に型の違いの問題を防ぎたい場合
上記のような問題はそもそもコンパイル段階で防ぐことができます。それは「#property strict」!
このコードをソースコードの先頭につけてあげるだけでコンパイル時に注意してくれるようになります。

注意文「implicit conversion from ‘number’ to ‘string’」型の暗黙変換ですかね、こんな感じで注意してくれるようになります。
「#property strict」については以下の記事でも紹介しています。
▶ #property strictとは?初心者向けにわかりやすく解説
❓ MQL4の型違い・数値比較に関するよくある質問【初心者向けQ&A】
💬 EA開発中に起こりやすい「数値比較がおかしい問題」や、string・int・doubleの違いについての疑問をまとめました。
文字列(string型)と数値(intやdouble型)を、そのまま比較してしまうことが最も多い原因です。
見た目は数値でも、string型のまま比較すると「文字」として判定され、意図しない結果になります。
比較している変数がstring型の場合、
数値ではなく「文字列の先頭文字」で比較されるためです。
その結果、「10」は「1」として扱われ、「1 > 4」がfalseになります。
比較する前に、string型を数値型へ変換してください。
整数なら StringToInteger()、
小数を含む場合は StringToDouble() を使います。
int型は整数のみを扱い、double型は小数点を含む数値を扱います。
pipsや価格、ロットなど小数を扱う場合はdouble型を使うのが基本です。
ソースコードの先頭に #property strict を記述することで、
コンパイル時に型の暗黙変換や不整合を警告してくれるようになります。
初心者ほど有効な対策です。
変数名の先頭や末尾に、
str(string)、int、dbl(double)などを付けると、
型の取り違えによるミスを防ぎやすくなります。
Print()で変数の中身と型を意識してログ出力するか、
#property strictを有効にしてコンパイル警告を確認すると、
原因を特定しやすくなります。
さいごに
以上が、『【EA開発初心者向け】変数の型はしっかり合わせよう!』です。
サンプルプログラムのように簡単なコードの場合はまず文字と数値で比較なんてしないと思いますが、なが~いコードになってくるとやりがちです。サンプルのように変数の最初や最後にstrやint等を付けた名前付けをしていると回避できる事も多いので変数の名前はしっかりつけましょう!
もしかしたら、あなたが動かしているEAでもうまく動いているようで実は比較がおかしくなっているところもあるかもしれません。
変数の型を正しく扱えるようになると、 次は処理をまとめて書く「関数」を理解することで、 EAのコードは一気に読みやすくなります。
※今回のような「型の違いによるミス」を コンパイル段階で防ぎたい場合は、 #property strict を理解しておくと非常に便利です。










コメント