- 1 1. PositionGetIntegerとは何か
- 2 2. 基本構文と使い方(最短理解)
- 3 3. 主要プロパティ一覧と実務での使い分け
- 4 4. 複数ポジション対応(ループ処理と実務パターン)
- 5 5. PositionGetInteger / Double / Stringの違いと使い分け
- 6 6. 実践サンプル(EAでの活用パターン)
- 7 7. エラー・バグ・動かない原因と対処法(トラブルシューティング)
- 8 8. まとめ
- 9 FAQ
- 9.1 1. PositionGetIntegerは何を取得する関数ですか?
- 9.2 2. PositionGetIntegerだけで使ってはいけないのはなぜですか?
- 9.3 3. 値が常に0になるのはなぜですか?
- 9.4 4. POSITION_TYPEはどのように判定すればよいですか?
- 9.5 5. PositionGetDoubleやPositionGetStringとの違いは何ですか?
- 9.6 6. マジックナンバーはなぜ重要ですか?
- 9.7 7. 複数ポジションがある場合はどう処理すればよいですか?
- 9.8 8. POSITION_TIMEはどう扱えばよいですか?
- 9.9 9. MQL4のOrderSelectと同じ感覚で使えますか?
- 9.10 10. 初心者が最初に覚えるべき実践パターンは何ですか?
1. PositionGetIntegerとは何か
PositionGetIntegerは、MQL5で現在保有しているポジションの情報を取得するための関数です。特に、EA(自動売買プログラム)においては「今どんなポジションを持っているか」を判断するための中核的な役割を担います。
MQL5では、トレード関連のデータは大きく以下の2つに分かれます。
- Order(注文):まだ約定していない、または履歴の注文
- Position(ポジション):実際に保有している建玉
PositionGetIntegerは、このうちPosition(保有中のポジション)に関する整数型データを取得します。
1.1 PositionGetIntegerの概要
PositionGetIntegerの基本的な役割は以下です。
- ポジションの種類(買い / 売り)
- マジックナンバー(EA識別用のID)
- チケット番号(ポジション識別用の番号)
- 保有時間(ポジションが作られた時刻)
などの「整数データ(long型)」を取得できます。
基本構文は以下です。
long PositionGetInteger(ENUM_POSITION_PROPERTY_INTEGER property_id);
property_id:取得したい情報の種類(例:POSITION_TYPE)- 戻り値:long型(整数)
例えば、ポジションの売買方向を取得する場合:
long type = PositionGetInteger(POSITION_TYPE);
この値は以下のように解釈されます。
- POSITION_TYPE_BUY(買い)
- POSITION_TYPE_SELL(売り)
1.2 取得できる情報の種類(ENUM_POSITION_PROPERTY_INTEGER)
PositionGetIntegerで取得できる情報は、ENUM_POSITION_PROPERTY_INTEGERという列挙型(あらかじめ定義された定数群)で指定します。
代表的なものは以下です。
- POSITION_TYPE
→ 売買方向(BUY / SELL) - POSITION_MAGIC
→ マジックナンバー(EA識別用) - POSITION_TICKET
→ ポジションのチケット番号 - POSITION_TIME
→ ポジションのオープン時間(datetime型として扱う) - POSITION_TIME_UPDATE
→ 最終更新時間
これらを組み合わせることで、EAは以下のような判断が可能になります。
- 自分のEAが出したポジションか?
- 現在買いポジションを持っているか?
- いつエントリーしたか?
1.3 どんな処理で使うか(実務例)
PositionGetIntegerは、主に以下のような処理で使われます。
① ポジションの有無チェック
if(PositionSelect(Symbol()))
{
// ポジションが存在する
}
② 売買方向による分岐
long type = PositionGetInteger(POSITION_TYPE);
if(type == POSITION_TYPE_BUY)
{
// 買いポジション処理
}
else if(type == POSITION_TYPE_SELL)
{
// 売りポジション処理
}
③ EAのポジションだけ判定(重要)
long magic = PositionGetInteger(POSITION_MAGIC);
if(magic == 123456)
{
// 自分のEAのポジション
}
このように、PositionGetIntegerは「状態判定」に使われるため、
EAロジックの分岐の中心になる関数です。
■ つまずきポイント・注意点・よくある失敗
1. PositionSelectを忘れる
最も多いミスです。
PositionGetInteger(POSITION_TYPE); // ←これだけではNG
必ず事前に対象ポジションを選択します。
PositionSelect(Symbol());
2. ポジションが存在しない状態で呼ぶ
ポジションがない場合、値は正しく取得できません。
対策:
if(PositionSelect(Symbol()))
{
long type = PositionGetInteger(POSITION_TYPE);
}
3. Order系との混同
MQL4経験者に多いミスです。
- OrderSelect → 注文
- PositionGetInteger → ポジション
役割が違うため、置き換えでは動きません。
4. マジックナンバー未使用
複数EAや手動トレードが混在すると誤判定になります。
→ 必ずPOSITION_MAGICでフィルタする
2. 基本構文と使い方(最短理解)
PositionGetIntegerは単体では正しく機能せず、PositionSelectとセットで使うことが必須です。このセクションでは、最短で理解できる形で「動くコード」と「正しい手順」を示します。
2.1 基本構文
PositionGetIntegerの基本形は以下です。
long PositionGetInteger(ENUM_POSITION_PROPERTY_INTEGER property_id);
ただし実務では、必ず以下の流れになります。
基本手順(重要)
- ① 対象ポジションを選択する
- ② PositionGetIntegerで情報取得
- ③ 値に応じて処理分岐
コードで表すと:
if(PositionSelect(Symbol()))
{
long value = PositionGetInteger(POSITION_TYPE);
}
この「PositionSelect → 取得」の順序がすべてです。
2.2 最小サンプルコード(完全動作例)
まずは、ポジションの売買方向を取得する最小コードです。
void OnTick()
{
if(PositionSelect(Symbol()))
{
long type = PositionGetInteger(POSITION_TYPE);
if(type == POSITION_TYPE_BUY)
{
Print("買いポジション保有中");
}
else if(type == POSITION_TYPE_SELL)
{
Print("売りポジション保有中");
}
}
else
{
Print("ポジションなし");
}
}
このコードで確認できること:
- ポジションがあるかどうか
- 買いか売りか
- 条件分岐の基本構造
2.3 PositionSelectとの関係(必須知識)
PositionGetIntegerは、「現在選択されているポジション」に対してのみ動作します。
そのため、PositionSelectがない場合:
long type = PositionGetInteger(POSITION_TYPE); // 不定 or 0
→ 正しい値が取得できません
■ PositionSelectの役割
bool PositionSelect(string symbol);
- 指定シンボルのポジションを選択する
- 成功:true
- 失敗:false
■ 正しい使い方(テンプレ)
if(PositionSelect(Symbol()))
{
long type = PositionGetInteger(POSITION_TYPE);
}
■ なぜこの仕様なのか(構造理解)
MQL5では内部的に、
- 「現在選択されているポジション」
- 「そこから情報を取得する」
という設計になっています。
つまり:
PositionGetIntegerは「単体で対象を指定できない関数」
です。
■ つまずきポイント・注意点・よくある失敗
1. PositionSelectなしで使う
long type = PositionGetInteger(POSITION_TYPE); // NG
→ 必ずPositionSelectが必要
2. Symbol()を固定してしまう
PositionSelect(Symbol());
これは現在のチャートのみ対象です。
複数通貨対応EAでは:
PositionSelect("EURUSD");
のように明示指定が必要です。
3. long型の扱いミス
PositionGetIntegerの戻り値はlong型(64bit整数)です。
int type = PositionGetInteger(POSITION_TYPE); // 非推奨
→ 型不一致によるバグの原因
4. ポジションがないケースを考慮しない
long type = PositionGetInteger(POSITION_TYPE); // 危険
→ 必ずif(PositionSelect())で囲む
5. 成功・失敗を無視する
if(PositionSelect(Symbol()))
{
// 成功時のみ処理
}
このチェックを省略すると、誤判定の原因になります。
3. 主要プロパティ一覧と実務での使い分け
PositionGetIntegerで取得できる情報は多数ありますが、実務で重要なのは一部に限られます。このセクションでは、実際のEA開発で頻出するプロパティに絞って整理します。
3.1 よく使うプロパティ一覧(重要)
以下は実務でほぼ必須となるプロパティです。
| プロパティ | 内容 | 用途 |
|---|---|---|
| POSITION_TYPE | 売買方向 | BUY / SELL判定 |
| POSITION_MAGIC | マジックナンバー | EA識別 |
| POSITION_TICKET | チケット番号 | ポジション管理 |
| POSITION_TIME | オープン時間 | 保有時間計算 |
| POSITION_TIME_UPDATE | 更新時間 | トレーリング等 |
3.2 POSITION_TYPE(売買方向)
ポジションが買いか売りかを判定します。
long type = PositionGetInteger(POSITION_TYPE);
判定方法:
if(type == POSITION_TYPE_BUY)
{
// 買い
}
else if(type == POSITION_TYPE_SELL)
{
// 売り
}
■ 実務での使い方
- ナンピン方向の判定
- 逆方向エントリーの制御
- 利確・損切条件の分岐
3.3 POSITION_MAGIC(EA識別)
EAが発行したポジションかどうかを識別するためのIDです。
long magic = PositionGetInteger(POSITION_MAGIC);
■ 実務での使い方(重要)
if(magic == 123456)
{
// このEAのポジションのみ処理
}
■ なぜ重要か
- 手動トレードと混在する環境
- 複数EA稼働
この場合、マジックナンバーでフィルタしないと:
- 他EAのポジションを誤操作
- 手動ポジションをクローズ
→ 重大な事故につながる
3.4 POSITION_TICKET(ポジション識別)
ポジションごとの一意なIDです。
long ticket = PositionGetInteger(POSITION_TICKET);
■ 実務用途
- ログ出力
- デバッグ
- 個別ポジション管理
■ 注意点
MQL5では通常、ポジションはシンボルごとに1つ(ネットポジション)です。
→ チケット管理よりも「Symbolベース」が基本になることが多い
3.5 POSITION_TIME(エントリー時間)
ポジションの開始時刻を取得します。
long time = PositionGetInteger(POSITION_TIME);
datetimeに変換:
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
■ 実務での使い方
- 保有時間制限
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
if(TimeCurrent() - open_time > 3600)
{
// 1時間以上保有 → クローズ
}
3.6 POSITION_TIME_UPDATE(更新時間)
ポジションの最終更新時間です。
long update_time = PositionGetInteger(POSITION_TIME_UPDATE);
■ 実務用途
- トレーリングストップ管理
- 更新頻度の監視
- EAの動作確認
■ つまずきポイント・注意点・よくある失敗
1. マジックナンバー未チェック
if(PositionSelect(Symbol()))
{
// すべてのポジションを対象にしてしまう
}
→ 必ず:
if(PositionGetInteger(POSITION_MAGIC) == 自分のID)
2. datetime変換を忘れる
long time = PositionGetInteger(POSITION_TIME);
→ そのままでは扱いにくい
datetime t = (datetime)time;
3. ネットポジションの誤解
MQL4との違い:
- MQL4:複数ポジション
- MQL5:基本は1ポジション(通貨ごと)
→ ロジック設計が変わる
4. 更新時間とオープン時間の混同
- POSITION_TIME → エントリー時刻
- POSITION_TIME_UPDATE → 最終更新
用途が違うため混同するとバグの原因になります。
5. プロパティの型を誤認
PositionGetIntegerで取得できるのは:
- long型(整数)
価格などは取得できません:
- → PositionGetDoubleを使用
4. 複数ポジション対応(ループ処理と実務パターン)
MQL5では基本的に「シンボルごとに1ポジション(ネットポジション)」ですが、複数シンボル運用・複数EA・ヘッジ口座では複数ポジションを扱う必要があります。ここでは、PositionGetIntegerと組み合わせたループ処理の実務パターンを解説します。
4.1 ポジション数の取得(PositionsTotal)
まず、現在保有しているポジション数を取得します。
int total = PositionsTotal();
- 戻り値:現在のポジション数
- 0の場合:ポジションなし
4.2 PositionSelectByIndexによるループ
複数ポジションを処理する基本構造です。
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
long type = PositionGetInteger(POSITION_TYPE);
Print("タイプ: ", type);
}
}
■ 処理の流れ
- PositionsTotalで件数取得
- forループで順番にアクセス
- PositionSelectByIndexで対象選択
- PositionGetIntegerで情報取得
4.3 実務テンプレ(EA用)
実際のEAで使う「ほぼ完成形」のテンプレです。
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
string symbol = PositionGetString(POSITION_SYMBOL);
long magic = PositionGetInteger(POSITION_MAGIC);
long type = PositionGetInteger(POSITION_TYPE);
// 自分のEAのみ対象
if(magic != 123456) continue;
// シンボルフィルタ
if(symbol != Symbol()) continue;
if(type == POSITION_TYPE_BUY)
{
Print("BUYポジション検出");
}
else if(type == POSITION_TYPE_SELL)
{
Print("SELLポジション検出");
}
}
}
■ このテンプレでできること
- 全ポジションのスキャン
- EA単位でのフィルタ
- 通貨ペア単位でのフィルタ
- 売買方向の判定
→ ほぼすべてのEAロジックの基礎
4.4 ヘッジ口座とネット口座の違い
■ ネット口座(通常)
- 1シンボル = 1ポジション
- PositionsTotalは少ない
■ ヘッジ口座
- 同一シンボルで複数ポジション可能
- BUYとSELL同時保有可能
■ 影響
ヘッジ口座では:
for(int i = 0; i < PositionsTotal(); i++)
が必須になります。
4.5 よくある実務パターン
① 自分のEAのポジション数を数える
int count = 0;
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
if(PositionGetInteger(POSITION_MAGIC) == 123456)
{
count++;
}
}
}
② BUYだけカウント
int buy_count = 0;
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
buy_count++;
}
}
}
③ 特定条件でクローズ対象抽出
datetime now = TimeCurrent();
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
if(now - open_time > 3600)
{
Print("1時間以上経過 → クローズ候補");
}
}
}
■ つまずきポイント・注意点・よくある失敗
1. PositionSelectByIndexを忘れる
PositionGetInteger(POSITION_TYPE); // NG
→ 必ず選択が必要
2. ループ中にポジションが変化する
EAがクローズ・エントリーを行うと:
- PositionsTotalが変わる
- インデックスずれが発生
→ 対策:
for(int i = PositionsTotal() - 1; i >= 0; i--)
(逆順ループ)
3. フィルタなしで処理する
// 全ポジション対象 → 危険
→ 必ず:
- MAGIC
- SYMBOL
で絞る
4. ヘッジ口座を考慮していない
ネット口座前提で作ると:
- ロジック破綻
- 意図しない挙動
5. PositionGetStringとの併用忘れ
string symbol = PositionGetString(POSITION_SYMBOL);
→ シンボル判定に必須
5. PositionGetInteger / Double / Stringの違いと使い分け
MQL5では、ポジション情報を取得する関数が3種類に分かれています。
- PositionGetInteger(整数)
- PositionGetDouble(小数)
- PositionGetString(文字列)
この違いを理解していないと、取得ミス・型エラー・ロジックバグが発生します。ここでは、実務で迷わないための整理を行います。
5.1 3つの関数の役割
| 関数 | 取得できる型 | 主な用途 |
|---|---|---|
| PositionGetInteger | long(整数) | 種類・時間・識別情報 |
| PositionGetDouble | double(小数) | 価格・損益・ロット |
| PositionGetString | string(文字列) | シンボル名など |
5.2 PositionGetIntegerの対象
整数系の情報を扱います。
long type = PositionGetInteger(POSITION_TYPE);
主な取得対象:
- 売買方向(POSITION_TYPE)
- マジックナンバー(POSITION_MAGIC)
- 時間(POSITION_TIME)
- チケット番号(POSITION_TICKET)
5.3 PositionGetDoubleの対象
価格や数量など、小数データを扱います。
double price = PositionGetDouble(POSITION_PRICE_OPEN);
主な取得対象:
- エントリー価格
- 現在価格
- 損益(PROFIT)
- ロットサイズ
■ 実務例(損益取得)
double profit = PositionGetDouble(POSITION_PROFIT);
5.4 PositionGetStringの対象
文字列データを扱います。
string symbol = PositionGetString(POSITION_SYMBOL);
主な取得対象:
- 通貨ペア名(EURUSDなど)
- コメント
5.5 正しい使い分け(重要)
■ NG例(よくあるミス)
long price = PositionGetInteger(POSITION_PRICE_OPEN); // NG
→ 価格はdouble
■ 正しい例
double price = PositionGetDouble(POSITION_PRICE_OPEN);
5.6 実務での組み合わせ例(重要テンプレ)
3つを組み合わせて使うのが基本です。
if(PositionSelect(Symbol()))
{
string symbol = PositionGetString(POSITION_SYMBOL);
long type = PositionGetInteger(POSITION_TYPE);
double profit = PositionGetDouble(POSITION_PROFIT);
Print("シンボル:", symbol);
Print("タイプ:", type);
Print("損益:", profit);
}
■ この構造の意味
- Integer → 状態判断
- Double → 数値評価(損益など)
- String → 対象識別
→ 3つで1セット
■ つまずきポイント・注意点・よくある失敗
1. 型の取り違え
long profit = PositionGetInteger(POSITION_PROFIT); // NG
→ PROFITはdouble
2. ENUMの混同
- POSITION_TYPE → Integer
- POSITION_PRICE_OPEN → Double
→ 名前が似ているため混乱しやすい
3. キャスト忘れ(時間)
datetime t = PositionGetInteger(POSITION_TIME); // 非推奨
→ 明示的に:
datetime t = (datetime)PositionGetInteger(POSITION_TIME);
4. String取得を忘れる
複数シンボル運用で:
// Symbol()のみで判断 → 不十分
→ 必ず:
PositionGetString(POSITION_SYMBOL);
5. 全部Integerで取ろうとする
MQL4経験者に多い誤りです。
→ MQL5は型ごとに関数が分離されている
■ 実務での最適な設計指針
- 判定 → PositionGetInteger
- 数値 → PositionGetDouble
- 識別 → PositionGetString
このルールで設計すると、バグが大幅に減ります。
6. 実践サンプル(EAでの活用パターン)
ここでは、PositionGetIntegerを中心に、実際のEAでそのまま使えるレベルの実践コードを解説します。単なる取得ではなく、「エントリー制御」「クローズ条件」「保有制御」など、実務に直結するロジックに落とし込みます。
6.1 エントリー制御(ポジション重複防止)
最も基本かつ重要なパターンです。
すでにポジションがある場合は新規エントリーしない処理です。
bool HasPosition(string symbol, long magic)
{
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
if(PositionGetString(POSITION_SYMBOL) == symbol &&
PositionGetInteger(POSITION_MAGIC) == magic)
{
return true;
}
}
}
return false;
}
使用例:
if(!HasPosition(Symbol(), 123456))
{
// エントリー処理
}
■ 実務ポイント
- ナンピン防止
- 重複エントリー防止
- EAの暴走防止
6.2 売買方向によるロジック分岐
ポジションの方向によって処理を変えます。
if(PositionSelect(Symbol()))
{
long type = PositionGetInteger(POSITION_TYPE);
if(type == POSITION_TYPE_BUY)
{
// BUY専用処理
}
else if(type == POSITION_TYPE_SELL)
{
// SELL専用処理
}
}
■ 実務用途
- トレーリングストップの方向調整
- 利確・損切条件の変更
- 逆張り・順張り制御
6.3 保有時間によるクローズ(時間制御)
一定時間経過でポジションを閉じるロジックです。
void CheckTimeClose()
{
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
if(TimeCurrent() - open_time > 3600)
{
Print("1時間経過 → クローズ対象");
// クローズ処理(別途実装)
}
}
}
}
■ 実務用途
- スキャルピングの時間制限
- ロールオーバー回避
- 長期保有リスク回避
6.4 マジックナンバーでの完全フィルタ
EAごとにポジションを分離します。
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionSelectByIndex(i))
{
if(PositionGetInteger(POSITION_MAGIC) != 123456)
continue;
// 自分のEAのポジションのみ処理
}
}
■ 実務上の重要性
- 複数EA同時稼働
- 手動トレードとの共存
→ 必須レベル
6.5 統合テンプレ(実務でそのまま使える形)
以下は、実務でよく使う統合コードです。
void ManagePositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionSelectByIndex(i))
{
string symbol = PositionGetString(POSITION_SYMBOL);
long magic = PositionGetInteger(POSITION_MAGIC);
long type = PositionGetInteger(POSITION_TYPE);
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
// フィルタ
if(symbol != Symbol()) continue;
if(magic != 123456) continue;
// 時間制御
if(TimeCurrent() - open_time > 3600)
{
Print("時間経過クローズ対象");
}
// 方向別処理
if(type == POSITION_TYPE_BUY)
{
Print("BUY管理中");
}
else if(type == POSITION_TYPE_SELL)
{
Print("SELL管理中");
}
}
}
}
■ このテンプレの特徴
- 全ポジション対応
- フィルタあり
- 時間制御あり
- 方向分岐あり
→ 中級EAの基本骨格
■ つまずきポイント・注意点・よくある失敗
1. クローズ処理未実装
// Printだけで終わる
→ 実際にはOrderSendでクローズ処理が必要
2. 逆順ループを使っていない
for(int i = 0; i < PositionsTotal(); i++)
→ クローズ時にバグ発生
→ 対策:
for(int i = PositionsTotal() - 1; i >= 0; i--)
3. Symbolフィルタ忘れ
→ 他通貨ペアに干渉
4. Magic未使用
→ 他EAを巻き込む
5. 時間条件の誤解
TimeCurrent() - open_time
→ 秒単位(3600 = 1時間)
■ 実務視点のまとめ
PositionGetIntegerは単体ではなく、
- PositionSelect系
- PositionGetDouble
- PositionGetString
と組み合わせて、「状態判定エンジン」として使うのが本質です。
7. エラー・バグ・動かない原因と対処法(トラブルシューティング)
PositionGetIntegerはシンプルな関数ですが、前提条件を満たさないと正しく動作しません。このセクションでは、実務で頻出する「動かない原因」を体系的に整理し、再現性のある対処法を提示します。
7.1 値が取得できない(常に0や異常値)
■ 原因①:PositionSelectをしていない
long type = PositionGetInteger(POSITION_TYPE); // NG
→ 対処:
if(PositionSelect(Symbol()))
{
long type = PositionGetInteger(POSITION_TYPE);
}
■ 原因②:ポジションが存在しない
PositionSelect(Symbol()) == false
→ この場合、取得値は意味を持たない
■ 対策テンプレ
if(!PositionSelect(Symbol()))
{
Print("ポジションなし");
return;
}
7.2 条件分岐が効かない
■ 原因:型や値の誤認
if(PositionGetInteger(POSITION_TYPE) == 0)
→ 可読性が低く、ミスの原因
■ 正しい書き方
if(type == POSITION_TYPE_BUY)
■ 注意点
- POSITION_TYPE_BUY / SELL は定数
- 数値で比較しない(可読性・保守性が低下)
7.3 複数ポジションで意図しない動作
■ 原因:1ポジション前提のロジック
PositionSelect(Symbol());
→ 1つしか見ていない
■ 対策:ループ処理
for(int i = 0; i < PositionsTotal(); i++)
{
PositionSelectByIndex(i);
}
7.4 他EAや手動ポジションを誤操作
■ 原因:マジックナンバー未チェック
// フィルタなし
■ 対策
if(PositionGetInteger(POSITION_MAGIC) != 123456)
continue;
7.5 シンボルが一致しない
■ 原因
PositionSelect(Symbol());
→ 現在チャートのみ対象
■ 対策
string symbol = PositionGetString(POSITION_SYMBOL);
if(symbol != Symbol()) continue;
7.6 時間計算が正しく動かない
■ 原因:型変換ミス
long time = PositionGetInteger(POSITION_TIME);
→ そのままでは扱いにくい
■ 正しい方法
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
■ よくある誤解
- TimeCurrent()との差は秒単位
- 3600 = 1時間
7.7 ループ中にバグが出る(クローズ時)
■ 原因:順方向ループ
for(int i = 0; i < PositionsTotal(); i++)
→ クローズでインデックス崩壊
■ 対策(重要)
for(int i = PositionsTotal() - 1; i >= 0; i--)
7.8 デバッグができない
■ 原因:ログ不足
■ 対策(必須)
Print("type:", type);
Print("magic:", magic);
Print("symbol:", symbol);
■ 実務テクニック
- 重要変数は必ず出力
- 条件分岐前後でログを入れる
- テスターで検証
■ つまずきポイント総まとめ
| 問題 | 原因 | 対策 |
|---|---|---|
| 値が0 | PositionSelectなし | 事前選択 |
| 判定ミス | 定数未使用 | ENUM使用 |
| 誤操作 | Magic未チェック | フィルタ |
| 動作不安定 | ループ不備 | 逆順ループ |
| 時間バグ | 型ミス | datetime変換 |
■ 実務視点の結論
PositionGetIntegerのトラブルはほぼ以下に収束します。
- 選択していない(PositionSelect不足)
- フィルタしていない(Magic / Symbol)
- 型を理解していない
→ この3点を守れば、ほぼすべてのバグは回避可能
8. まとめ
PositionGetIntegerは、MQL5でポジションの整数系情報を取得するための基本関数です。単に値を読むだけの関数に見えますが、実際にはEAの状態判定、保有制御、誤発注防止、クローズ条件判定など、売買ロジックの中核で使われます。
本記事で押さえるべき実務上の要点は以下です。
- PositionGetIntegerは単体では使わず、必ずPositionSelectまたはPositionSelectByIndexと組み合わせる
- 取得対象は整数系の情報であり、価格や損益はPositionGetDouble、シンボル名はPositionGetStringを使う
- 実務では、POSITION_TYPE、POSITION_MAGIC、POSITION_TICKET、POSITION_TIMEあたりが最重要
- 複数ポジション対応では、PositionsTotalとループ処理が必要
- バグの大半は、未選択・未フィルタ・型誤認の3つで説明できる
特に初心者が最初に覚えるべき基本形は、以下のテンプレです。
if(PositionSelect(Symbol()))
{
long type = PositionGetInteger(POSITION_TYPE);
if(type == POSITION_TYPE_BUY)
{
Print("BUYポジション保有中");
}
else if(type == POSITION_TYPE_SELL)
{
Print("SELLポジション保有中");
}
}
else
{
Print("ポジションなし");
}
この形を起点にして、必要に応じて以下を追加していくのが安全です。
- マジックナンバー判定
- シンボル判定
- 保有時間判定
- 複数ポジションのループ処理
つまり、PositionGetIntegerは「何かを取得する関数」というより、EAが現在の保有状態を正しく認識するための基礎関数として捉えるのが適切です。ここを曖昧にすると、重複エントリー、他EAの誤操作、保有判定ミスが発生しやすくなります。
MQL5で安定した売買ロジックを組むなら、まずは
PositionSelect → PositionGetInteger → 条件分岐
の流れを確実に再現できることが重要です。
次章では、検索ユーザーが最も知りたい疑問に答えるFAQを整理します。
FAQ
1. PositionGetIntegerは何を取得する関数ですか?
ポジションに関する整数型の情報を取得する関数です。代表例は、売買方向、マジックナンバー、チケット番号、保有開始時刻などです。
2. PositionGetIntegerだけで使ってはいけないのはなぜですか?
PositionGetIntegerは、現在選択されているポジションを対象に動作するためです。事前にPositionSelectやPositionSelectByIndexで対象を選ばないと、正しい値を取得できません。
3. 値が常に0になるのはなぜですか?
主な原因は以下です。
- ポジションが存在しない
- PositionSelectを実行していない
- 対象シンボルが違う
まずは if(PositionSelect(Symbol())) で確認してください。
4. POSITION_TYPEはどのように判定すればよいですか?
以下のように定数で比較します。
long type = PositionGetInteger(POSITION_TYPE);
if(type == POSITION_TYPE_BUY)
{
// 買い
}
else if(type == POSITION_TYPE_SELL)
{
// 売り
}
数値の直接比較より、定数名で比較した方が安全です。
5. PositionGetDoubleやPositionGetStringとの違いは何ですか?
違いは取得できるデータ型です。
- PositionGetInteger:整数
- PositionGetDouble:価格・損益・ロットなどの小数
- PositionGetString:シンボル名やコメントなどの文字列
用途に応じて正しく使い分ける必要があります。
6. マジックナンバーはなぜ重要ですか?
複数EAや手動トレードが混在している環境で、自分のEAのポジションだけを識別するためです。未使用だと、他のポジションを誤って操作するリスクがあります。
7. 複数ポジションがある場合はどう処理すればよいですか?
PositionsTotal() で件数を取得し、PositionSelectByIndex() を使ってループ処理します。ヘッジ口座や複数通貨対応EAでは、この処理が必要になることがあります。
8. POSITION_TIMEはどう扱えばよいですか?
取得値は整数ですが、通常は datetime にキャストして使います。
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);
その後、TimeCurrent() との差分を取れば保有時間の判定に使えます。
9. MQL4のOrderSelectと同じ感覚で使えますか?
同じではありません。MQL5では、注文(Order)とポジション(Position)が明確に分かれています。MQL4の感覚のまま実装すると誤作動の原因になるため、構造差を前提に設計してください。
10. 初心者が最初に覚えるべき実践パターンは何ですか?
まずは以下の流れです。
- PositionSelectで対象を選ぶ
- PositionGetIntegerで種類を取得する
- BUY / SELLで分岐する
- 必要に応じてMAGICやTIMEで絞る
この基本形を正確に書けるようになると、EAの保有管理ロジックを安定して組み立てやすくなります。