見出し画像

【MQL4】良いコードを書こう 〜リーダブルコードを目指して〜

こんにちは。もるふぉと申します。外資系IT会社のプログラマです。
今まで、PHP, Ruby, Python, Java, C++, GoLang などを利用して自社、他社問わず様々な企業のソフトウェアを構築してきました。
EAは自分用のものを作成してきました。
エンジニアリングの観点から皆様のお力になれるのではないかと思いEAに関する情報発信していきます。

この記事の対象となる方は、

✅ EA開発に興味がある方
✅ MQL4初学者
✅ 他人にコードレビューをしてもらったことがない方

となっています。

皆さん、読みやすいMQL4のコードを書いていますか?


MQL4のコードを書いている人はたくさんいると思いますが、
初めて触るプログラムがMQL4の方が意外と多いんじゃないかなと思います。そういった方のコードを読む機会がたまにあるのですが、

  • インデントが適切に設定されいない

  • 無駄なコードが多い

  • 変数名が適当

のようなコードが多いです。
そういったコードの場合、

  • メンテナンスしにくい

  • バグの温床

になっています。
今回の記事はなるべく読みやすくメンテナンスできるようなコードはどのようなものか、良いコード、悪いコードの例の具体例を15つ紹介したいと思います。

具体例

1. 意味のある変数名を使う

意味のある変数名を使用することで、コードの意図を明確にし、他の開発者や将来の自分にとっても理解しやすくなります。

悪いコード:

int a = 10; 
double b = 1.2345;

良いコード:

int maxRetries = 10; 
double accountBalance = 1.2345;

`a`と`b`は意味が不明瞭ですが、`maxRetries`と`accountBalance`は何を表すかが明確です。

2. コメントで意図を説明する

コードにコメントを付けることで、関数や変数が何をするのかを簡単に理解できます。ただし、コメントが冗長にならないように注意します。

悪いコード:

int r = CalculateR(10, 5);

良いコード:

// リスクを計算する 
int risk = CalculateRisk(10, 5);

ここでは、`r`が何を意味するか不明ですが、コメントとともに`risk`と命名することで意図が明確になります。

3. マジックナンバーの数字を避ける

定数に意味のある名前を付けることで、コードの意図を明確にし、将来的な変更が容易になります。

悪いコード:

if (x > 10) { 
    // do something 
}


良いコード:

const int MAX_RETRIES = 10;
if (x > MAX_RETRIES) {
    // do something 
}

`10`が何を意味するか不明ですが、`MAX_RETRIES`という定数名を使うことで意味が明確になります。

4. 長い関数を短くする

長い関数は理解しづらく、バグが発生しやすくなります。関数を小さく分割し、それぞれが一つの責務を持つようにします。

悪いコード:

void ProcessOrder() { 
    // long code 
}


良いコード:

void ProcessOrder() { 
    ValidateOrder();
    CalculateRisk();
    ExecuteOrder(); 
}

各関数が単一の役割を持つため、コードが読みやすくなります。

5. 見ただけで誰もわかるコメントは避ける

コメントはコードの補助として有用ですが、明らかなことをコメントするのは冗長です。必要な部分にのみコメントを追加します。

悪いコード:

// 変数を初期化する 
double sum_profit = 0;

良いコード:

double sum_profit = 0;

初期化は明らかであり、コメントは不要です。

6. 一貫性を持たせる

コードのスタイルや命名規則を一貫させることで、コード全体が読みやすくなり、保守が容易になります。

悪いコード:

double calc_risk(double x, double y) { 
    return x * y; 
}

double calcRisk(double x, double y) { 
    return x * y; 
}

関数名の命名規則が一貫していません。

良いコード:

double CalculateRisk(double x, double y) { 
    return x * y; 
}

統一された命名規則を使用しており、一貫しています。


一貫性のための具体的なポイント:

  • 命名規則: 変数や関数の名前に一貫した命名規則(キャメルケース、スネークケースなど)を使用します。

  • インデント: 全てのコードブロックで同じインデントスタイル(例えば、スペース4つやタブ)を使います。

  • コメントのスタイル: コメントの書き方も統一します。例えば、全てのコメントを英語で書くか、日本語で書くかを決めます。

  • コードのフォーマット: 括弧の位置や改行のタイミングなど、コードのフォーマットも統一します。

  • エラーメッセージ: エラーメッセージのフォーマットを統一し、ユーザーフレンドリーな内容にします。

7. デバッグメッセージを明確にする

デバッグメッセージは問題の原因を迅速に特定するために重要です。具体的なメッセージを提供することで、問題解決が容易になります。

悪いコード:

Print("Error!");

良いコード:

Print("Order processing error: invalid order ID.");

エラーメッセージが具体的で、問題の特定が容易です。

8. 適切なデータ構造を使う

データ構造を適切に選択することで、コードの効率性と可読性が向上します。

悪いコード:

double data[10];

良いコード:

double[] data; 
ArrayResize(data, 10);

配列のサイズ変更が可能になり、柔軟性が増します。

9. 冗長なコードを排除する

冗長なコードは可読性を下げ、バグの温床になります。不要な部分を排除することで、コードがシンプルで理解しやすくなります。

悪いコード:

if (condition == true) {
    // do something
}

良いコード:

if (condition) {
    // do something
}

`== true`は不要であり、シンプルな表現に置き換えられます。

10. 関数の引数を明確にする

関数の引数名はその役割を明確に示すべきです。これにより、関数の使い方が直感的に理解できます。

悪いコード:

void Calculate(int a, int b, int c) {
    // do something
}

良いコード:

void Calculate(int width, int height, int depth) {
    // do something
}

引数名が具体的で、関数の目的が明確になります。

11. 適切なスコープを使用する

変数のスコープを適切に設定することで、コードの意図を明確にし、バグを減らすことができます。

悪いコード:

int x;
void foo() {
    x = 10;
}

良いコード:

void foo() {
    int x = 10;
}

変数`x`のスコープを制限することで、他の部分での誤用を防ぎます。

12. 短縮形を避ける

短縮形は意味が曖昧になることが多く、可読性を低下させます。フルネームを使うことで意図が明確になります。

悪いコード:

double bal = AccountBalance();

良いコード:

double accountBalance = AccountBalance();

短縮形を避けることで、変数の意味が明確になります。

13. エラーハンドリングをしっかり行う

エラーハンドリングはコードの信頼性を高めるために重要です。エラーが発生した場合の対処方法を明確にします。

悪いコード:

if (!OrderSend(symbol, type, volume, price, slippage, stopLoss, takeProfit, comment, magicNumber, expiration, arrowColor)) {
    return;
}

良いコード:

if (!OrderSend(symbol, type, volume, price, slippage, stopLoss, takeProfit, comment, magicNumber, expiration, arrowColor)) {
    Print("OrderSend failed with error code: ", GetLastError());
    return;
}

エラーが発生した場合の対処方法が明確で、問題の特定が容易です。

14. コードを整形する

整形されたコードは読みやすく、理解しやすいです。インデントや改行を適切に使用します。

悪いコード:

if(condition){
doSomething();
}

良いコード:

if (condition) {
    doSomething();
}

15. アーリーリターンを使用する

アーリーリターンは、関数の途中で特定の条件が満たされた場合に、すぐに関数を終了させる手法です。これにより、ネストが深くなるのを防ぎ、コードがシンプルで読みやすくなります。

悪いコード:

void ProcessOrder() {
    if (IsValidOrder()) {
        if (HasSufficientFunds()) {
            if (IsMarketOpen()) {
                // Order processing logic
            } else {
                Print("Market is closed.");
            }
        } else {
            Print("Insufficient funds.");
        }
    } else {
        Print("Invalid order.");
    }
}

良いコード:

void ProcessOrder() {
    if (!IsValidOrder()) {
        Print("Invalid order.");
        return;
    }

    if (!HasSufficientFunds()) {
        Print("Insufficient funds.");
        return;
    }

    if (!IsMarketOpen()) {
        Print("Market is closed.");
        return;
    }

    // Order processing logic
}

アーリーリターンを使用することで、条件を満たさない場合にはすぐに関数を終了させ、メインのロジックが深いネストに包まれないようにします。

まとめ

これらの例を参考に、MQL4コードの可読性とメンテナンス性を向上させましょう。リファクタリングは一度に全てを行う必要はなく、少しずつ改善していくことが大切です。リーダブルコードを目指して、質の高いプログラムを書いていきましょう。

おまけ

コードのメンテナンス性を高めるためのいろはが学べるおすすめの本です。


ここから下なにも記事ありません(投げ銭用)

ここから先は

0字

¥ 500

この記事が気に入ったらサポートをしてみませんか?