« 2005年10月 | メイン | 2006年01月 »

2005年11月26日

プログラムの作成 練習2-4 繰り返しフォー

次は繰り返し処理を行なう方法です。

"Hello"と10回表示させたい時、
Print("Hello"); を10回書いてもいいですが、このようにfor()を使うと楽にできます。

int i;
for(i=0; i<10; i++){
Print("Hello"); // *
}

*の行が10回繰り返し実行されます。

for(i=0; i<10; i++){  ~ } を翻訳(?)すると、
「①始めに i=0をセットします。そしてi<10なら、{}の処理を行いなさい。
 ②{}の処理が終わったら、i++(iを1増やす)を行ない、
 ③それでも i<10なら{}の処理を行いなさい。
 (以下、②③のくりかえし)

こんな感じです。

最初は、i=0なので i<10 ( 0<10 )となり、*のPrint文が実行されます。
それが終わったところで、i++ で iが1になりますが、それでも i<10 ( 1<10 )なので、*のPrint文が実行されます。
そして、i=2、3、4・・・と繰り返していって、iが9の時、*のPrint文を実行したあと最初に戻り、
i++をすると、iは10になります。
i=10だと i<10 の条件を満たさなくなるので、forの処理は終了です。

つまり、i=0からi=9まで合計10回、処理が行なわれるわけです。

この実行結果を見ると分かりやすいと思います。
int i;
Print("forの前");
for(i=0;i<10;i++){
Print("Hello i="+i);
}
Print("forの後");

結果は、
「forの前」
「Hello i=0」
「Hello i=1」
 ・・・
「Hello i=9」
「forの後」
となります。


for( ) は入れ子式にすることもできます。

int I,J;
for(I=0; I<10; I++){
 for(J=0; J<10; J++){
  Print("I="+I+ ",J="+J);
 }
}
Print("end");

結果は、
I=0,J=0
I=0,J=1
 ・・・
I=0,J=8
I=0,J=9
I=1,J=0
I=1,J=1
 ・・・
I=1,J=9
I=2,J=0
 ・・・
 ・・・
I=9,J=9
end

応用として、
このようにするとティック更新の度に、直近10足分の始値が出力されます。
int start(){
int i;
for(i=0; i<10; i++){
Print("Open["+i+"]="+ Open[i]);
}
}
結果は
Open[0]=114.40
Open[1]=114.23
Open[2]=114.30
...
Open[9]=114.89

Open[ ]はMT4に備わっている機能で、指定した本数分 前の足の始値を得るものです。
Open[0]は現在の足、Open[1]なら一つ前の足の始値になります。
上の例だと新しいものから順に出力されますが、古い順に出力したい場合には、

Print("Open["+i+"]="+ Open[i]);
iを下のように(9-i)に変えます。
Print("Open["+(9-i)+"]="+ Open[9-i]);

もしくは、

int start(){
int i;
for(i=9; i>-1; i--){
Print("Open["+i+"]="+ Open[i]);
}
}
のように、繰り返しのたびにiを減らしていくように、for文を変更するといいでしょう。
( i=9,8,7,,,1,0 と変化していきます)

結果
Open[9]=114.89
Open[8]=114.80
Open[7]=114.20
...
Open[0]=114.40


投稿者 kawarobo : 16:00 | コメント (0) | トラックバック

2005年11月20日

プログラムの作成 練習2-3 条件分岐

プログラミングに欠かせない処理、条件分岐を練習してみましょう。

条件分岐は、
「こういう状態なら○○の処理を、そうでないならxxの処理を実行せよ」
というふうに、条件に応じて処理内容を変えるものです。

mq4ではif()を使います。

int start(){
 int i;
 i=1;
 if(i==1){
  Print("OK");①
 } else{
  Print("NG");②
 }
}

if()は「もし()内の条件が真ならば、そのあとの{}内の処理を行い、偽ならば、else以下の処理を行え」というものです。
つまりこの例では, i が1なら①の処理を行い、iが1以外なら②の処理を行ないます。iには1を代入していますので、①が実行されて「OK」が出力されます。

i==1と「=」が二つ並んでいることに注意してください。=を一個だけにしているとエラーが出ます。

==は比較演算子と呼ばれるもので、両辺の値を比較するための記号です。

・A == B AとBが等しければtrue(真)
・A != B AとBが等しくないならtrue
・A > B Aのほうが大きいならtrue
・A >= B AがB以上ならtrue(A=Bの場合を含む)
・A < B
・A <= B

A==B かつ A > C というような条件を調べるには、
&&をつかって、 
A==B && A > C
というふうに書きます。
この場合、A=2、B=2、C=1ならば真、A=2、B=2、C=3ならば偽になります。

「または」は|| (Shift+¥キーで出る「|」を2つ)です。
A==B || A < C
AとBが等しい、または、AよりCが大 なら真
 A=2,B=2,C=3は真、A=2,B=3,C=1も真、A=2,B=2,C=1も真です。
 A=2,B=1,C=3は偽になります。

()でくくればさらに複雑な条件を調べることが出来ます。
(A==B && A > C) || A < D
AがBと等しくてCより大きい、または、AがDより小さいなら真
A=2、B=2、C=1、D=3ならば真、A=2、B=2、C=3、D=1の場合も真、A=2、B=2、C=3、D=3は偽になります。


真や偽のときの処理が一行で終わる場合には{}を省略することが出来ます。
if( i==1) Print("OK");
else Print("NG");

入れ子式に使うこともできます。
if( i==1 ){
 if( j==2 ){
  Print("OK");
 } else {
  Print("NG j");
 }
} else Print("NG i");

偽の場合に何もしないのなら、elseは省略できます。

int start(){
int i,j;
i=1;
j=2;
if( i==1) {
 Print("i ==1");
}

if( j==1) Print("j=1");
else Print("j !=1");

return(0);
}
//結果、「i==1」と 「j !=1」が表示される


投稿者 kawarobo : 00:40 | コメント (2) | トラックバック

2005年11月19日

プログラムの作成 練習2-2 演算

前回のコードに少し手を加えてこのようにしてみました。
結果はどうなるでしょうか。

int i;
int start(){
string mojiretsu; //文字列変数mojiretsuを宣言
i++;
mojiretsu ="i="+i ;
Print(mojiretsu);
return(0);
}
結果は「i=1」、「i=2」、、、となります。
太字の部分で、変数mojiretsuには文字列「i=」にiの値をくっつけたものが代入されているからです。

*ここではわざわざ変数を使っていますが、print()内に直接入れてしまっても構いません。
Print(mojiretsu); → Print("i="+i);

数値同士の場合は、その計算結果が表示されます。
int i,j;
i=1;
j=2;
Print(i+j);//結果「3」が表示される

つまり、「文字列+文字列」や「文字列+数値」は文字列になり、「数値+数値」は数値になります。

ではこうするとどうなるでしょう?
int i,j;
i=1;
j=2;
Print("i+j="+i+j);

結果は「i+j=12」になります。
これはまず文字列"i+j="+数値iが行なわれて文字列"i+j=1"になり、続いて文字列"i+j=1"+数値jが行なわれるからです。
i+jを数値として計算したい場合は、()でくくって
Print("i+j="+(i+j) );
とします。

プログラム内では算数の演算と同じ優先順位があります。
( )内が最優先、次が*(掛ける)や/(割る)、そのあとで+や-、という順番です。
例えば、1*2+3は5で 、1+2*3=7、(1+2)*3=9 となります。

ということは
Print("i*j="+ i * j );
とすると、i*jの部分が先に計算されますので、結果は「i*j=2」になります。


投稿者 kawarobo : 13:36 | コメント (0) | トラックバック

2005年11月17日

プログラムの作成 練習2-1

変数についてさらに練習してみましょう。

その前に気をつけておくことがあります。
変数名はできるだけ自分で分かりやすいように名づければよいのですが、
予約語とかぶらないように気をつけてください。
エディタで入力した時に色が変わって表示されるものは、システム上ですでに予約されている単語なので、新たな変数名としては使えません。
一部の小文字を大文字に変えるなどして無理やり使い分けることもできますが、おすすめはしません。

さて、変数をつかった次のプログラムを見てください。
int start()
{
int i; // 変数i を整数として宣言
print(i); // iの中身(=0)を表示
return(0);// 終了
}
前回までのHello.mq4とほとんど同じですね。
これはティックが更新されるたびに「0」と表示されます。
変数iは宣言をしただけで、何も代入していません。
何も値を入れていない変数の中身は0になります。
(stringの場合は空っぽの状態(=NULL)になります)

これに少し手を加えます。
int start()
{
int i; // 変数i を整数として宣言
i=i+1;
print(i); // iの中身を表示
return(0);// 終了
}
i=i+1は、「i+1の値を iに代入する」という意味です。「iの値を1増やす」と考えるほうが自然でしょうか。
ここではiは0+1で1になります。
このように変数の値を1増やすという処理はよく使われるので、特別に「変数++」 というふうに省略して書くことができます。i=i+1ならi++というようにです。
i--というのもあって、これはi=i-1のことです。

似たような感じで、i +=1 というのもあります。これもi=i+1の意味ですが、最後の数字を変えればi=i+2や3などの代わりにもできます。
+=だけじゃなく、-=、 *=、 /=、などもできます。例えばi *=3はi=i*3の意味です。

さてプログラムに戻ります。
この場合の結果は毎回「1」が表示されます。なぜなら、start(){~}の中で宣言された変数は毎回、リセットされてしまうからです。
リセットされて0になっているところへ1を足したものが出力されるので結果は常に1です。

では回数を重ねるごとに数を増やしていきたい場合はどうすればいいでしょうか?
実はこんなふうに、変数の宣言をstart(){~}の外に出してしまえばいいのです。

int i; // 変数i を整数として宣言
int start()
{
i=i++; // i=i+1の意味
print(i); // iの中身を表示
return(0);// 終了
}
これで変数iがリセットされることはなくなりますので、1,2,3,4と、毎回値が1ずつ増えていくようになります。
このように変数の値を保存しておきたいものは、start()の外で宣言するようにしてください。


投稿者 kawarobo : 11:55 | コメント (0) | トラックバック

2005年11月16日

コンパイル時エラーの対処方法

mql4プログラムをコンパイルした時に出てくるエラーの見方です。
エラーメッセージは左側にエラー内容、右側にエラーが発生した場所が記されています。

'printstring' - variable not defined
  C:\Program Files\MetaTrader 4\experts\Hello.mq4 (2, 1)
発生場所の()内は行数と文字数を表します。この例だと2行目の1文字目に問題があることになります。

現在のカーソル位置(行数、文字数)がエディタ画面の右下に出ているので、それを見ながらエラー箇所に移動し、修正します。

主なエラーと対処方法をざっとあげてみます。

'変数名' - variable not defined
 変数が宣言されていません。
 変数が宣言されているか確認、変数名のタイプミス(特に大文字小文字の別)が無いか確認

'\end_of_program' - ending bracket '}' expected
 } が足りません。{ に対する }をどこかに書き忘れています。
 エラー発生場所はプログラムの最後になっていますが、実際にはどこか途中で足りない部分があるのでプログラム全体を見直す必要があります。

'\end_of_program' - unbalanced left parenthesis
 ) が足りません。( に対する )をどこかに書き忘れています。
 エラー発生場所はプログラムの最後になっていますが、実際にはどこか途中で足りない部分があるのでプログラム全体を見直す必要があります。

'return' - semicolon expected
 ; セミコロンが抜けています。
 指定行前後の行末を確認。

';' - semicolon unexpected
 ;セミコロンが変なところにあります。
 指定行前後に不必要なセミコロンがないか確認

')' - wrong parameters count
 関数のパラメータ数が足りません。
 指定行にある関数の書式を確認

'=' - illegal assignment use
 =の使い方が間違っています。
 if分などの条件式で「==」と間違ってないか確認


投稿者 kawarobo : 11:09 | コメント (0) | トラックバック

プログラムの作成 練習1-4

つづいて、変数の使い方を練習してみましょう。

前回のプログラムで
Print("Hello World");
となっていた部分を
printstring="Hello World";//①
Print(printstring);//②
と置き換えてみます。
①はprintstring という変数に文字列「Hello World」を代入せよ という意味、
②は変数printstringを画面に出力せよ という意味です。このとき変数printstringには①で指定した文字列が入っていますので、「Hello World」と表示されることになります。

Print("printstring")ではないことに注意して下さい。
" "で囲むと、この部分は変数ではなくただの文字列ですよ、という意味になるので、「Hello World」ではなく「printstring」という文字列が表示されることになります。

ではプログラム全体を見て見ましょう。上に書いたように置き換えるとこのようになります。
int start(){
printstring="Hello World";
Print(printstring);
return(0);
}

しかし、このままだとエラーが出てきます。
printstringというのは私が勝手に名づけた変数です。ルールのところでも書いていますが、そういう自分で作った変数は、使う前に必ず「こういう変数を使います」ということを宣言しておかなくてはいけません。
今回のprintstringには文字列をいれることにしていますので、
string printstring;
と最初に書いて、printstringは文字列変数です!と宣言します。

int start(){
string printstring;
printstring="Hello World";
Print(printstring);
return(0);
}

次は変数の使い方をもう少し掘り下げてみましょう。


投稿者 kawarobo : 10:12 | コメント (0) | トラックバック

2005年11月05日

プログラムの作成 練習1-3

[サンプルコード:Hello World]

では、これをベースにプログラミングをしてみましょう。
Print("Hello World");
この一文を3行目に入れてください。

int start()
{
 Print("Hello World");
return(0);
}

Print( )は()内の値を画面に表示するものです。
int start() { から } はティックの更新ごとに実行されるので、為替のレートが変わるたびに「HelloWorld」と表示が出るはずです。


実際にどのようになるか見てみましょう。
Complileボタンを押すと、プログラムファイルが上書き保存され、エラーがないかチェックされます。
エラーが無ければ下の画面に「0 error(s). 0 warning(s)」と表示され、完成です。


MetaTraderボタンを押し、MT4の画面に戻ると、ExpertAdvisorsの中に「Hello」が追加されています。
これをチャートにドラッグして適用します。

「Allow live trading」にチェックを入れてOK。

「Enable Expert Advisors」ボタンを押すとマークが変わり、エキスパートが実行開始します。

TerminalウィンドウのExperts画面を開いてみてください。
為替レートが変わるたびにHelloWorldという文字列が表示されるはずです。


投稿者 kawarobo : 03:28 | コメント (2) | トラックバック

2005年11月02日

プログラムの作成 練習1-2

[自動作成されるコードの内容]
初めてみると何だかわけの分からないコードがずらずらと並んでいるように見えますが、内容は非常に単純です。
//で始まる行はコメントなのでプログラムには直接関係しません。
このコメント行と、空行を除くと、プログラムは以下のように4つに分けられます。

①ヘッダー
 #property copyright "kawarobo"
 #property link "http://kawarobo.com/"

②開始時の処理
 int init()
 {
  return(0);
 }
③終了時の処理
 int deinit()
 {
   return(0);
 }
④メイン
 int start()
 {
   return(0);
 }

たったこれだけです。

①ヘッダーでは、パラメーターの定義やグローバル変数の宣言などを行ないます。意味がわからなければとりあえず読み飛ばしてください。
②このinit( ) { ~ } 内に書かれた処理は、このエキスパートプログラムをチャートに適用した時、最初に一回だけ実行されます。
③deinit( ){ ~ }は、エキスパートの使用を停止(チャートから削除)した時に最後に一回だけ実行されます。
④ここがプログラムのメインです。start( ){ ~ } ここに書かかれた処理は、チャートのデータが更新されるたびに実行されます。

つまり、プログラム実行の流れはこのようになります。
②チャートへの適用時に一回だけ実行
④・・・④ ティック更新ごとに繰り返し実行(自動売買のメイン)
③チャートから削除した時に一回だけ実行

ただ②、③の処理はどういう使い道があるのか、あまり思い浮かびません。。
不要な場合は削除してしまって構いません。
①の#property copyright "~"や#property link"~"もネットで配布したりしないのであれば不要です。

実は、必要最小限の簡潔なプログラムにするには、自動作成されたコードを全て消して、
int start()
{

return(0);
}

とだけ書けばOKなのです。^-^;


投稿者 kawarobo : 01:25 | コメント (0) | トラックバック

2005年11月01日

プログラムの作成 練習1-1

【プログラム作成の練習】

[準備]
metaopen.jpg
とりあえず実際にやってみましょう。
MT4のMetaEditorボタンから、MetaEditorを開きます。

newedit.jpg
Newボタンで新規プログラムを作成。


どのタイプのプログラムにするか選択肢が表示されます。ここでは自動売買をするための「ExpertAdvisorProgram」を選びます。

作成するプログラムの名前、作成者名などの入力欄があらわれますので、プログラム名を「Hello」、作者名は自分の名前を入れてください。
下にパラメーター作成用の欄がありますが、今はそのままで「完了」ボタンを押します。

これで「Hello.mq4」というプログラムが自動的に作成されます。
自動的に作成されるのは単なる雛型だけなので、このままでは当然何も起こりません。
この雛型をもとに、プログラムを追加していきましょう。
-- -- -- --

-- -- -- --


投稿者 kawarobo : 03:13 | コメント (0) | トラックバック