【MQL5】DatabaseRead関数の使い方と自動売買実装コード

1. DatabaseRead関数の概要と実務での活用法

MQL5のDatabaseRead関数は、SQLクエリを実行して得られた結果セット(レコード群)から、「次の1行」を読み進めるための関数です。

実務レベルのEA(エキスパートアドバイザー)開発において、SQLiteデータベースの活用は非常に強力です。例えば、過去のトレード履歴の統計分析、複雑な外部パラメータの管理、あるいは複数のEA間でのデータ共有などに利用されます。

初心者が特につまずきやすいポイントは、「SQLを実行しただけではデータは取得できない」という点です。DatabasePrepareでクエリを準備し、このDatabaseReadを呼び出すことで初めて、データベース上の「カーソル(現在指し示している行)」が1行目に移動し、データにアクセス可能な状態になります。実務では、while文と組み合わせて、検索結果がなくなるまで全レコードをスキャンする処理が一般的です。

2. 構文と戻り値

DatabaseRead関数のインターフェースは非常にシンプルです。

bool DatabaseRead(
   int request      // DatabasePrepareで作成したリクエストハンドル
);

パラメーター

  • request: DatabasePrepare関数によって返された有効なリクエストハンドルを指定します。

戻り値

  • 成功した場合は true を返します。これは「読み込むべき次の行が存在し、正常に移動できた」ことを意味します。
  • 読み込む行がもう存在しない場合、またはエラーが発生した場合は false を返します。

※エラーの詳細を確認するには GetLastError() 関数を使用しますが、ループの終了判定として false を使うのが標準的な書き方です。

3. 具体的な使い方・実践サンプルコード

以下のコードは、データベース内に保存された「通貨ペアごとの目標利益(TakeProfit)」の設定値を読み取る実用的な例です。

// データベースから設定を読み込む例
void LoadSettingsFromDB(int db_handle) {
    string sql = "SELECT symbol, take_profit FROM strategy_settings";
    int request;

    // 1. SQLクエリの準備
    request = DatabasePrepare(db_handle, sql);

    if(request == INVALID_HANDLE) {
        Print("クエリの準備に失敗しました。エラーコード: ", GetLastError());
        return;
    }

    Print("--- 設定データの読み込み開始 ---");

    // 2. DatabaseReadを使用して1行ずつデータを取得
    // 最初のDatabaseReadで1行目に移動し、falseになるまで繰り返す
    while(DatabaseRead(request)) {
        string symbol;
        double tp;

        // カラムのインデックスを指定してデータを抽出(0:symbol, 1:take_profit)
        if(DatabaseColumnText(request, 0, symbol) && 
           DatabaseColumnDouble(request, 1, tp)) {

            PrintFormat("通貨ペア: %s, 目標利益: %.2f", symbol, tp);

            // ここでグローバル変数や構造体に値を格納するなどの実務処理を行う
        }
    }

    // 3. リソースの解放(これを忘れるとメモリリークやDBロックの原因になる)
    DatabaseFinalize(request);
    Print("--- 設定データの読み込み完了 ---");
}

4. 使用上の注意点とよくあるエラー

開発時に注意すべきは、以下の3点です。

  1. 最初の呼び出しを忘れない:
    DatabasePrepareの直後は、カーソルは「1行目の前」にあります。データが1件しかない場合でも、必ず一度はDatabaseReadを呼び出さないと、DatabaseColumn...関数で値を取得することはできません。

  2. DatabaseFinalizeによる解放:
    DatabaseReadでループを回した後は、必ずDatabaseFinalizeでリクエストハンドルを閉じてください。これを行わないと、データベースファイルが「使用中」のままロックされ、書き込み処理(INSERT/UPDATE)ができなくなるトラブルが頻発します。

  3. データ型の不一致:
    DatabaseRead自体は成功しても、その後のDatabaseColumnTextDatabaseColumnDoubleで指定するインデックス(列番号)や型が間違っていると、予期せぬゼロ値や空文字が返ってきます。SQL文でのSELECT順序と取得関数のインデックスが一致しているか常に確認しましょう。

5. 【重要】自動売買における約定スピードと環境の罠

どれほどデータベース操作を高速化し、洗練されたアルゴリズムを組み上げたとしても、EAを稼働させる「物理環境」が不適切であれば、その努力はすべて水の泡となります。FXの自動売買において、最も致命的な損失原因の一つは、自宅PC環境での運用による「ネットワーク遅延(レイテンシ)」です。

一般家庭のインターネット回線は、金融取引専用に最適化されておらず、プロバイダー経由の複雑な経路を通るため、数ミリ秒から数百ミリ秒の遅延が日常的に発生します。このわずかな遅延が、注文時のスリッページを引き起こし、バックテストでは利益が出ていたロジックを実運用で破綻させます。極限まで約定スピードを高め、ブローカーのサーバーに対して「最速」で注文を届けるには、金融データセンターに近い場所に設置された自動売買専用のVPS(仮想専用サーバー)の導入が不可欠です。安定した電源、24時間の稼働保証、そして超低遅延なネットワーク環境こそが、プロのクオンツエンジニアが最初に整えるべき「勝負の土俵」なのです。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

タイトルとURLをコピーしました