1. GetPointer関数の概要と実務での活用法
MQL5におけるGetPointer関数は、一言で言えば「オブジェクトの場所(メモリアドレスの参照)」を取得するための関数です。C++などの言語に触れたことがある方には「ポインタの取得」と言えば通りが良いですが、MQL5においてはもう少し安全に管理された「オブジェクト操作用のハンドル」を得るためのものだと考えてください。
実務での活用シーン
EA開発が中級レベルに進むと、単一のファイルにすべてを書くのではなく、「クラス(Class)」を使って機能をモジュール化するようになります。この際、以下のような場面でGetPointerが不可欠になります。
- オブジェクトの受け渡し: あるクラスのインスタンス(実体)を、別の関数やクラスに渡して操作させたい場合。
- 動的なインスタンス管理: 実行中に
new演算子で生成したオブジェクトを、リストや配列に格納して管理する場合。 - 生存確認: そのオブジェクトが現在もメモリ上に正しく存在しているかを確認する際のトリガーとして使用。
初心者の方が最初につまずくのは、「変数名をそのまま使えばいいのではないか?」という点です。しかし、関数の引数に大きなクラスをそのまま渡すと「コピー」が発生し、動作が重くなったり、コピー先で値を書き換えても元のオブジェクトに反映されないという問題が起きます。GetPointerを使い「参照」を渡すことで、これらの問題を回避し、効率的なコードを書くことができます。
2. 構文と戻り値
GetPointer関数の使い方は非常にシンプルです。
構文
pointer GetPointer(
any_class_object any_object // オブジェクト(クラスのインスタンス)
);
パラメーター
- any_object: ポインタを取得したいクラスのオブジェクトを指定します。
戻り値
- 指定したオブジェクトのポインタ(型はクラス名*)を返します。
- もしオブジェクトが正しく生成されていない場合や、無効な場合は
POINTER_INVALIDを返します。
※注意:GetPointerは「クラス(構造体ではない)」に対してのみ使用可能です。
3. 具体的な使い方・実践サンプルコード
以下のコードは、トレード情報を管理するクラスを作成し、そのオブジェクトを別の関数にポインタ経由で渡して処理する実戦的な例です。
//+------------------------------------------------------------------+
//| クラス定義:簡易トレードマネージャー |
//+------------------------------------------------------------------+
class CTradeManager
{
private:
string m_symbol;
public:
CTradeManager(string symbol) { m_symbol = symbol; }
void PrintStatus() { Print("監視中の通貨ペア: ", m_symbol); }
};
//+------------------------------------------------------------------+
//| グローバル変数 |
//+------------------------------------------------------------------+
CTradeManager *g_manager; // クラスのポインタ変数を宣言
//+------------------------------------------------------------------+
//| エキスパートアドバイザーの初期化関数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 1. 動的にオブジェクトを生成(newを使用)
g_manager = new CTradeManager(_Symbol);
// 2. ポインタが有効かどうかを確認
if(CheckPointer(g_manager) == POINTER_INVALID)
{
Print("エラー:オブジェクトの生成に失敗しました");
return(INIT_FAILED);
}
// 3. ポインタを関数に渡して実行
ExecuteTask(GetPointer(g_manager));
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| ポインタを受け取って処理するカスタム関数 |
//+------------------------------------------------------------------+
void ExecuteTask(CTradeManager *ptr)
{
// ポインタの有効性をチェックしてから操作する(安全策)
if(CheckPointer(ptr) != POINTER_INVALID)
{
Print("関数内でポインタを受け取りました。");
ptr.PrintStatus();
}
}
//+------------------------------------------------------------------+
//| エキスパートアドバイザーの終了関数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 動的に生成したオブジェクトは必ずdeleteで破棄する
if(CheckPointer(g_manager) != POINTER_INVALID)
{
delete g_manager;
Print("オブジェクトを破棄しました。");
}
}
4. 使用上の注意点とよくあるエラー
1. 「new」で作成したものは必ず「delete」する
new 演算子と GetPointer を組み合わせて動的にオブジェクトを作った場合、そのオブジェクトはEAを停止してもメモリに残り続けることがあります(メモリリーク)。OnDeinit で必ず delete する習慣をつけましょう。
2. 静的オブジェクトへのGetPointer
CTradeManager manager; のように静的に宣言したオブジェクトに対しても GetPointer(manager) は使えます。ただし、この場合は delete を使ってはいけません。自動的にメモリが解放されるからです。
3. CheckPointer関数との併用
GetPointerで取得したポインタが「今も使える状態か」を常に意識してください。特に、オブジェクトを削除した後にそのポインタにアクセスしようとすると、EAはランタイムエラーを起こして停止します。
- POINTER_DYNAMIC:
newで作られた有効なポインタ - POINTER_AUTOMATIC: 静的に作られた有効なポインタ
- POINTER_INVALID: 無効なポインタ
これらを CheckPointer() で判定する癖をつけるのが、中級者への第一歩です。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムの論理構成がどれほど完璧であっても、実行環境が貧弱であればそのEAは「勝てる聖杯」から「資金を溶かす機械」へと変貌します。特に日本国内の自宅PCから海外の取引サーバーへ注文を出す場合、物理的な距離に起因するネットワーク遅延(レイテンシ)は避けて通れません。GetPointerを駆使してコードを数ミリ秒高速化したとしても、通信環境で数百ミリ秒をロスしていれば、スリッページによって期待値は無残に削り取られます。
クオンツエンジニアの視点から言えば、コンマ一秒を争う自動売買において、取引サーバーの目鼻の先に位置する専用VPS(バーチャル・プライベート・サーバー)の導入は、単なる「推奨」ではなく「絶対条件」です。安定した電源、24時間の稼働保証、そして何よりブローカーのデータセンターに極限まで近い低遅延なネットワーク環境。これらが揃って初めて、あなたの書いたアルゴリズムは本来のパフォーマンスを発揮します。本気でシストレを運用するなら、インフラへの投資を惜しむことは、約定拒否や価格乖離という致命的な損失を自ら招いているのと同義なのです。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント