void Timing() { //Здесь вызываем функции которые необходимо вызывать каждый тик //... //Здесь вызываем функции которые необходимо вызывать каждую минуту if(IsNewMinute()==true){ } //Здесь вызываем вункции которые достаточно вызывать каждый новый бар if(IsNewBar()==true){ CheckForClosed(); CheckForOpen(); } //Здесь вызываем функции которые необходимо вызывать каждый новый день, например функцию для расчета свопов if(IsNewDay()==true){ } }
ここでは、2つのうちどちらかを選択する必要があります。
1) コードの書きやすさ、読みやすさ
2)プログラムの実行 速度。
個人的には、2番目の選択肢が好きなので、すべての変数をグローバルに宣言し、できれば関数も使わないようにしています(計算速度への影響には、ずいぶん前に気づきました)。Expert Advisorは24時間コンピュータ上で動作し、時には最適化などが必要になることを認識する必要があります。そのため、計算の速さとリソースの低消費が非常に重要です。
そして今度は、さまざまなプログラミング言語を外から見てみましょう。例えば、Basicはコーディングしやすく、読みやすいのですが、計算速度が...。では、C++と比較してみましょう。ここではすでに、コーディングは難しくなった(コードの可読性が悪くなった)が、計算速度は大幅に向上した、というように極論が変わっている。また、アセンブラをとると、ほぼ読めないコードになります。
もうひとつは、同じ言語で書かれたプログラムが、この基準に該当し、コードの読みやすさとプログラムの実行速度のどちらかを選ばなければならない場合、奇妙なことになる(変数を宣言するのに時間がかかる、関数を呼び出してパラメータを渡すのに時間がかかる、というのは何も不思議なことではないけれど)。しかし、それは事実であり、ちなみにmql4だけでなく気づかれたことでもある...。
おそらくMQL4では、計算が膨大になり、読みやすさと速さのどちらかを選ばなければならないケースにまだ遭遇していないからでしょう。ティックで遊んでいるわけではないので、おかしな計算速度は必要ない。
逆に、後で修正する必要がないEAというのは考えにくいですね。
ダニを演じない。
ここにきて、いくつかの特徴が出始めています。オープニング・プライスでプレイするのであれば、プログラム・アーキテクチャを変えなければなりません。例えば、始値でプレイする場合、グローバルレベルで変数を宣言し、次のバーが表示されるまでメモリに保持することは意味がありません。
プログラムのコーディングスタイルは、その使用目的に応じて適切でなければなりません。コーディングルールはどこでも同じですが(関数、変数など)、プログラムコードの中でこれらのルールを使用する頻度やスタイルは、具体的なエンドタスク、つまりプログラムがどんな計算に使われるのかによって異なります。コーディングルールを使用する場合、それぞれ異なるアプローチが必要です。
highly recommended:http://astyle.sourceforge.net/ は C-text formatter ですが、MQ4 で素晴らしい仕事をします。
AStyle.exe -b -t -p before.mq4 は、「パックされた」テキストをキャンディに変えるコマンドです。
似たようなユーティリティが、ずいぶん前にこのフォーラムのオーナーによって、ここかmetaquotesで提供されていました。でも、これからは探さなくていいんです。そして、デザインスタイルは、私自身が好んでいるものと同じです。
一時期は「どのプログラミングスタイルを選ぶべきか」と悩んだこともありました。経験の浅い私は、FreeBSDのソースコードを開き、オールドスクールのプログラマーがどのようなスタイルを使っているかをよく観察することで問題を解決したのです。当時は不便に感じることもありましたが、今となってはなぜそのような解決策を選んだのかがわかります。
そこで、私が執筆する際のルールをご紹介します。
int main()
{
int sum;
for(int i=0;i<100;i++){
sum+=i;
Print("Число равно:", i);
}
return(0);
}
1.関数では、中括弧は必ず別行動にします。ループ/条件では、最初の中括弧を1行目に入れる。
2.私は、このように中括弧をつける、ごく一般的なスタイルが嫌いです。
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
コメント //---- - 全く理解できない。
3.ループ自体の中で繰り返し用の変数を宣言しようとすると
4.私は関数を使うのが好きで、プログラムを多くの部分に分割するように心がけています。しかし、1機能につき20行という厳密な縛りはないんです。私は、関数はローカルなタスクを実行するものでなければならないと考えています。タスクは大きい時もあれば、そうでない時もあり、機能も様々です。
5.関数の中で関数を使っている。
res=OrderSend(Symbol(),OP_BUY,GetVolume(GetPrice(OP_BUY),GetStopLossLevel(GetPrice(OP_BUY))),GetPrice(OP_BUY),3,GetStopLossLevel(GetPrice(OP_BUY)),GetTakeProfitLevel(GetPrice(OP_BUY)),"",GetMagicNumber(OP_BUY),0,Blue);
6.timing()関数を使用しています。
void Timing()
{
//Здесь вызываем функции которые необходимо вызывать каждый тик
//...
//Здесь вызываем функции которые необходимо вызывать каждую минуту
if(IsNewMinute()==true){
}
//Здесь вызываем вункции которые достаточно вызывать каждый новый бар
if(IsNewBar()==true){
CheckForClosed();
CheckForOpen();
}
//Здесь вызываем функции которые необходимо вызывать каждый новый день, например функцию для расчета свопов
if(IsNewDay()==true){
}
}
このように、ティックワイズ・モデリング方式でも、全計算ブロックが毎ティック 設定されるわけではなく、本当に必要な時にだけ呼び出される。
7.なぜかわからないが、ほとんどいつもwhile()の代わりにfor()ループを使う。
8.ネストされた条件を使うのは嫌だ。
if(param1==1){
if(param2==2){
if(param3==3){
if(param4==4){
if(param5==5){
Print("Наконец-то дошли!");
}
}
}
}
}
私は代わりにこんなコードを使っています。
if(param1!=1)return;
if(param2!=2)return;
...
if(param5!=5)return;
Print("Наконец-то дошли!");
if(param1!=1)return;
if(param2!=2)return;
...
if(param5!=5)return;
Print("Наконец-то дошли!");
基本的には、ネストされたif構文と同じ計算を行う通常のコードです。しかし、どこかで関数のreturnは1つであるべきだと聞いたことがあります。おそらく、それらに巻き込まれないようにするためにやっているのでしょう。私はこのルールを厳格に守っているわけではありません。
あとは、細かい点を除けば、私の考え方はC-4 さんとほぼ同じです。
2.私は、このようなブレースを置くごく一般的なスタイルが嫌いです。
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
コメント //---- - 全く理解できない。
一方、私はこのスタイルが好きです。行末の中括弧を探す必要がありませんから。まさにこの理由(閉じ括弧の付け忘れ)で括弧をなくしたり、逆に閉じ括弧を余分に作ったりする人が多いのです。しかし、一般的には好みの問題で、紙に書く筆跡は人それぞれです。また、ノートの書き方は人それぞれです(脚注をつける人、アンダーラインを引く人、インデントする人)。このノートの著者は、一目で情報を把握しやすいことが大きなポイントでした。 言語の構文では、中括弧をどこにでも、たとえ1行の中であっても入れることができます。しかし、なぜか誰もこのように閉じ中括弧をつけない。
そのため、コードの独立した行のためのスペースを確保しないのです。すべての括弧(開閉両方)は互いに左側にあり(次の囲まれたブロックごとにインデントがあり、ヘリンボーン式)、一目で複合演算子(ブロック)の始まりと終わりが推定でき、それがどんなにスマートで高度なプログラムの一部であっても、そのことが分かります。:)--------
結局、括弧は複合演算子(ブロック)を指定するためだけに使われ、ループの本体を指定するためのものではありません。演算子が複合でないところでは、括弧を使わない。また、右側のどこかに開き括弧があり、左側に閉じ括弧を置く複合演算子を選択した場合
---------------
コードの書き方、括弧の位置など。- は、人それぞれの好みの問題です。主な内容は、プログラムが読みやすく、エラーがなく、システムに負荷をかけないこと(アルゴリズムが最適であること)、そのプログラムが書かれた基準を満たすことである。
似たようなツールは、ずいぶん前にフォーラムのオーナーがここかmetaquotesで提供していました。でも、今は探さなくていいんです。そして、デザインのスタイルも、私の好みで同じです。
ええ、ありますよ。:)
コードのクリーンアップには、この リンクからダウンロードできる2つのファイルからMetaQuotes Stylerを使用し、/Windows/System32ディレクトリに配置します。
コマンドでスタイラスを実行することができます。
mqstyler.exe /file:filename.mq4
mqstyler.exe /file: "long filename with spaces.mq4" (名前にスペースがある場合)
。
私自身は、Visual Studio(VC++)を持ち出し、そこにMQLのコードをコピーし、ツールなしで、Microsoftの慣習に従ってフォーマットしています。コードエディタとしてもVSの方がカッコイイ(コード折りたたみ?)コンパイルコマンドをねじ込むことも可能かもしれませんが、まだ試していません。