
MQL4 取引関数を体系的にまとめました。OrderSend()による成行・指値・逆指値注文、OrderClose()による決済、OrderModify()によるSL/TP変更、OrderSelect()とOrdersTotal()によるポジション管理ループ、ロット計算、トレーリングストップ、部分決済、マジックナンバーによる複数ロジック管理まで、MT4 EA開発に必要な取引処理のすべてをコード付きで解説します。

MQL4とMQL5の取引モデルの違い
MQL4の取引モデルはシンプルで直感的です。MQL5では構造体ベースの複雑なモデルに変わりましたが、MQL4では関数に引数を直接渡す方式です。
| 機能 | MQL4 | MQL5 |
|---|---|---|
| 発注 | OrderSend()に引数を直接渡す | MqlTradeRequest構造体を使用 |
| 決済 | OrderClose(ticket, lot, price, slippage) | 反対売買(CTrade.PositionClose) |
| SL/TP変更 | OrderModify(ticket, …) | MqlTradeRequest + TRADE_ACTION_SLTP |
| ポジション管理 | OrderSelect() + OrdersTotal()ループ | PositionGetTicket() + PositionsTotal() |
| 注文タイプ | OP_BUY, OP_SELL等(6種類) | ORDER_TYPE_BUY等(8種類) |
| マジックナンバー | OrderSendの引数 | MqlTradeRequest.magic |
| ヘッジング | 標準対応 | 口座設定による |
MQL4の取引関数はMQL5では全く異なる関数に置き換わっています。OrderClose()やOrderModify()はMQL5には存在しません。MQL4のコードをMQL5に移植する際は、取引部分を全面的に書き直す必要があります。
OrderSend:新規注文
MQL4のOrderSend()は1つの関数で成行注文・指値注文・逆指値注文すべてを処理します。
関数シグネチャ
int OrderSend(
string symbol, // 通貨ペア
int cmd, // 注文タイプ(OP_BUY等)
double volume, // ロット数
double price, // 注文価格
int slippage, // 許容スリッページ(ポイント)
double stoploss, // ストップロス価格
double takeprofit, // テイクプロフィット価格
string comment = NULL, // コメント(任意)
int magic = 0, // マジックナンバー(任意)
datetime expiration = 0, // 有効期限(任意、指値注文用)
color arrow_color = clrNONE // チャート上の矢印色(任意)
);
// 戻り値: 成功時はチケット番号、失敗時は-1注文タイプ一覧
| 定数 | 値 | 説明 |
|---|---|---|
| OP_BUY | 0 | 成行買い |
| OP_SELL | 1 | 成行売り |
| OP_BUYLIMIT | 2 | 指値買い(現在値より下で待機) |
| OP_SELLLIMIT | 3 | 指値売り(現在値より上で待機) |
| OP_BUYSTOP | 4 | 逆指値買い(現在値より上で待機) |
| OP_SELLSTOP | 5 | 逆指値売り(現在値より下で待機) |
成行買い注文
int BuyOrder(double lots, int slPoints, int tpPoints)
{
double ask = Ask; // またはMarketInfo(Symbol(), MODE_ASK)
double sl = NormalizeDouble(ask - slPoints * Point, Digits);
double tp = NormalizeDouble(ask + tpPoints * Point, Digits);
int ticket = OrderSend(Symbol(), OP_BUY, lots, ask, 3, sl, tp,"Buy Order", 12345, 0, clrBlue);
if(ticket < 0)
{
Print("買い注文失敗:", GetLastError());
return -1;
}
Print("買い注文成功: ticket=", ticket);
return ticket;
}成行売り注文
int SellOrder(double lots, int slPoints, int tpPoints)
{
double bid = Bid;
double sl = NormalizeDouble(bid + slPoints * Point, Digits);
double tp = NormalizeDouble(bid - tpPoints * Point, Digits);
int ticket = OrderSend(Symbol(), OP_SELL, lots, bid, 3, sl, tp,"Sell Order", 12345, 0, clrRed);
if(ticket < 0)
{
Print("売り注文失敗:", GetLastError());
return -1;
}
Print("売り注文成功: ticket=", ticket);
return ticket;
}指値注文(Buy Limit / Sell Limit)
// Buy Limit: 現在値より下で買い待機
int BuyLimitOrder(double lots, double entryPrice, int slPoints, int tpPoints)
{
double sl = NormalizeDouble(entryPrice - slPoints * Point, Digits);
double tp = NormalizeDouble(entryPrice + tpPoints * Point, Digits);
int ticket = OrderSend(Symbol(), OP_BUYLIMIT, lots,
NormalizeDouble(entryPrice, Digits),
3, sl, tp,"BuyLimit", 12345, 0, clrBlue);
if(ticket < 0)
Print("BuyLimit失敗:", GetLastError());
return ticket;
}
// Sell Limit: 現在値より上で売り待機
int SellLimitOrder(double lots, double entryPrice, int slPoints, int tpPoints)
{
double sl = NormalizeDouble(entryPrice + slPoints * Point, Digits);
double tp = NormalizeDouble(entryPrice - tpPoints * Point, Digits);
int ticket = OrderSend(Symbol(), OP_SELLLIMIT, lots,
NormalizeDouble(entryPrice, Digits),
3, sl, tp,"SellLimit", 12345, 0, clrRed);
if(ticket < 0)
Print("SellLimit失敗:", GetLastError());
return ticket;
}逆指値注文(Buy Stop / Sell Stop)
// Buy Stop: 現在値より上で買い待機(ブレイクアウト狙い)
int BuyStopOrder(double lots, double entryPrice, int slPoints, int tpPoints)
{
double sl = NormalizeDouble(entryPrice - slPoints * Point, Digits);
double tp = NormalizeDouble(entryPrice + tpPoints * Point, Digits);
int ticket = OrderSend(Symbol(), OP_BUYSTOP, lots,
NormalizeDouble(entryPrice, Digits),
3, sl, tp,"BuyStop", 12345, 0, clrBlue);
if(ticket < 0)
Print("BuyStop失敗:", GetLastError());
return ticket;
}
// Sell Stop: 現在値より下で売り待機(ブレイクダウン狙い)
int SellStopOrder(double lots, double entryPrice, int slPoints, int tpPoints)
{
double sl = NormalizeDouble(entryPrice + slPoints * Point, Digits);
double tp = NormalizeDouble(entryPrice - tpPoints * Point, Digits);
int ticket = OrderSend(Symbol(), OP_SELLSTOP, lots,
NormalizeDouble(entryPrice, Digits),
3, sl, tp,"SellStop", 12345, 0, clrRed);
if(ticket < 0)
Print("SellStop失敗:", GetLastError());
return ticket;
}- 成行注文のpriceにはAsk(買い)/ Bid(売り)を使う。逆にするとエラー(ERR_INVALID_PRICE)
- SL/TPはNormalizeDouble()で正規化が必須
- ECN口座ではSL/TPを0にして発注後、OrderModify()で設定する必要がある場合あり
- スリッページはポイント単位(5桁ブローカーなら3=0.3pips)
- expirationを指定する場合、ブローカーが有効期限付き注文をサポートしている必要がある
OrderClose / OrderCloseBy:ポジション決済
OrderClose
bool OrderClose(
int ticket, // 注文チケット番号
double lots, // 決済ロット数
double price, // 決済価格
int slippage, // 許容スリッページ
color arrow_color = clrNONE // 矢印色
);
// 戻り値: 成功=true, 失敗=false// 買いポジションの決済
bool CloseBuyOrder(int ticket)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
{
Print("チケット選択失敗:", ticket);
return false;
}
// 買いポジションはBidで決済
bool result = OrderClose(ticket, OrderLots(), Bid, 3, clrBlue);
if(!result)
Print("決済失敗:", GetLastError());
else
Print("決済成功: ticket=", ticket);
return result;
}
// 売りポジションの決済
bool CloseSellOrder(int ticket)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
return false;
// 売りポジションはAskで決済
return OrderClose(ticket, OrderLots(), Ask, 3, clrRed);
}OrderCloseBy:両建て決済
bool OrderCloseBy(
int ticket, // 決済する注文チケット
int opposite, // 反対ポジションのチケット
color arrow_color = clrNONE
);
// 同じ通貨ペアの反対ポジション同士を相殺決済するOrderCloseBy()はスプレッド節約に有効です。Closeでの決済はスプレッドが発生しますが、OrderCloseBy()での両建て決済はスプレッドが1回分で済みます。
OrderModify:SL/TP・待機注文の変更
bool OrderModify(
int ticket, // チケット番号
double price, // 新しい注文価格(成行ポジションの場合はOrderOpenPrice())
double stoploss, // 新しいSL
double takeprofit, // 新しいTP
datetime expiration, // 新しい有効期限(0=変更なし)
color arrow_color = clrNONE
);
// 戻り値: 成功=true, 失敗=false// 成行ポジションのSL/TPを変更
bool ModifySLTP(int ticket, double newSL, double newTP)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
return false;
// 成行ポジションではpriceにOrderOpenPrice()を渡す
bool result = OrderModify(ticket, OrderOpenPrice(),
NormalizeDouble(newSL, Digits),
NormalizeDouble(newTP, Digits),
0, clrYellow);
if(!result)
Print("SL/TP変更失敗:", GetLastError());
return result;
}
// 待機注文の価格を変更
bool ModifyPendingPrice(int ticket, double newPrice, double newSL, double newTP)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
return false;
return OrderModify(ticket, NormalizeDouble(newPrice, Digits),
NormalizeDouble(newSL, Digits),
NormalizeDouble(newTP, Digits),
0, clrYellow);
}- 成行ポジションのpriceにはOrderOpenPrice()を渡す(変更不可のため元の値を返す)
- SL/TPを変更しない場合も、現在の値を渡す必要がある(0にするとSL/TPが削除される)
- 同じ値で再度OrderModify()を呼ぶとERR_NO_RESULT(1)エラーになる
- StopLevel(MODE_STOPLEVEL)より近い位置にSL/TPは設定できない
OrderDelete:待機注文の削除
bool OrderDelete(
int ticket, // チケット番号
color arrow_color = clrNONE
);
// 待機注文(Limit/Stop)を削除する。成行ポジションには使用不可void DeleteAllPendingOrders(int magic)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != magic)
continue;
if(OrderType() > OP_SELL) // 2以上=待機注文
{
if(!OrderDelete(OrderTicket()))
Print("待機注文削除失敗:", GetLastError());
}
}
}OrderSelect / OrdersTotal:ポジション管理ループ
MQL4のポジション管理で基本となるパターンは、OrdersTotal()とOrderSelect()を使ったループです。
OrderSelect
bool OrderSelect(
int index, // インデックスまたはチケット番号
int select, // SELECT_BY_POS または SELECT_BY_TICKET
int pool = MODE_TRADES // MODE_TRADES(保有中)またはMODE_HISTORY(履歴)
);
// OrderSelect成功後に各種Order情報関数が使用可能になる保有ポジションのループ
void ScanOpenOrders(int magic)
{
int buyCount = 0, sellCount = 0;
double totalProfit = 0;
// 逆順ループ(決済時にインデックスがずれるのを防ぐ)
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
// 通貨ペアとマジックナンバーでフィルタ
if(OrderSymbol() != Symbol())
continue;
if(OrderMagicNumber() != magic)
continue;
// ポジション情報を取得
int type = OrderType();
int ticket = OrderTicket();
double lots = OrderLots();
double profit = OrderProfit() + OrderSwap() + OrderCommission();
double openPrice = OrderOpenPrice();
totalProfit += profit;
if(type == OP_BUY)
{
buyCount++;
Print("BUY: ticket=", ticket," lots=", lots," profit=", profit);
}
else if(type == OP_SELL)
{
sellCount++;
Print("SELL: ticket=", ticket," lots=", lots," profit=", profit);
}
}
Print("合計: Buy=", buyCount," Sell=", sellCount," Profit=", totalProfit);
}- 逆順ループ(i–)が必須:決済するとインデックスがずれるため、順方向ループだとポジションを飛ばしてしまう
- Symbol()とMagicNumber()のフィルタは必ず入れる(他のEAや手動注文を操作しないため)
- OrderProfit()だけでなく、OrderSwap()とOrderCommission()も加算して正確な損益を計算する
Order情報取得関数一覧
| 関数 | 戻り値 | 説明 |
|---|---|---|
| OrderTicket() | int | チケット番号 |
| OrderType() | int | 注文タイプ(OP_BUY=0, OP_SELL=1等) |
| OrderSymbol() | string | 通貨ペア |
| OrderLots() | double | ロット数 |
| OrderOpenPrice() | double | 約定価格 |
| OrderClosePrice() | double | 決済価格(保有中は現在価格) |
| OrderOpenTime() | datetime | 約定時刻 |
| OrderCloseTime() | datetime | 決済時刻(保有中は0) |
| OrderStopLoss() | double | SL価格 |
| OrderTakeProfit() | double | TP価格 |
| OrderProfit() | double | 損益(スワップ・手数料除く) |
| OrderSwap() | double | スワップポイント |
| OrderCommission() | double | 手数料 |
| OrderMagicNumber() | int | マジックナンバー |
| OrderComment() | string | コメント |
| OrderExpiration() | datetime | 有効期限 |
OrderHistoryTotal:取引履歴
void AnalyzeHistory(int magic, datetime fromDate)
{
int wins = 0, losses = 0;
double totalWin = 0, totalLoss = 0;
for(int i = OrdersHistoryTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
continue;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != magic)
continue;
if(OrderType() > OP_SELL) // 待機注文は除外
continue;
if(OrderCloseTime() < fromDate) // 期間フィルタ
continue;
double profit = OrderProfit() + OrderSwap() + OrderCommission();
if(profit >= 0)
{
wins++;
totalWin += profit;
}
else
{
losses++;
totalLoss += MathAbs(profit);
}
}
int total = wins + losses;
if(total > 0)
{
double winRate = (double)wins / total * 100.0;
double pf = (totalLoss > 0) ? totalWin / totalLoss : 0;
Print("勝率:", DoubleToStr(winRate, 1),"% (",
wins,"勝", losses,"敗) PF=", DoubleToStr(pf, 2));
}
}ロット計算
リスク管理の基本は、1トレードあたりの損失を口座残高の1〜2%に抑えることです。ロット数はSL幅(ポイント)とTickValueから逆算します。固定ロットは絶対に避け、必ずリスクベースで計算しましょう。
double CalcLotSize(double riskPercent, int slPoints)
{
double balance = AccountBalance();
double riskAmount = balance * riskPercent / 100.0;
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double tickSize = MarketInfo(Symbol(), MODE_TICKSIZE);
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
if(tickValue == 0 || slPoints == 0)
return minLot;
// 1ロットあたりのSL損失額を計算
double slMoney = slPoints * Point / tickSize * tickValue;
// リスク額からロット数を逆算
double lots = riskAmount / slMoney;
// ロットステップに丸める
lots = MathFloor(lots / lotStep) * lotStep;
// 範囲制限
if(lots < minLot) lots = minLot;
if(lots > maxLot) lots = maxLot;
return NormalizeDouble(lots, 2);
}トレーリングストップ
void TrailingStop(int magic, int trailPoints, int trailStart)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != magic)
continue;
double newSL;
double currentSL = OrderStopLoss();
int stopLevel = (int)MarketInfo(Symbol(), MODE_STOPLEVEL);
double minDist = stopLevel * Point;
if(OrderType() == OP_BUY)
{
// 含み益がtrailStart以上あるときだけ発動
if(Bid - OrderOpenPrice() < trailStart * Point)
continue;
newSL = NormalizeDouble(Bid - trailPoints * Point, Digits);
// 現在のSLより上にある場合のみ更新
if(newSL > currentSL + Point && Bid - newSL > minDist)
{
if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSL,
OrderTakeProfit(), 0, clrBlue))
Print("トレーリング失敗:", GetLastError());
}
}
else if(OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask < trailStart * Point)
continue;
newSL = NormalizeDouble(Ask + trailPoints * Point, Digits);
if((currentSL == 0 || newSL < currentSL - Point) && newSL - Ask > minDist)
{
if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSL,
OrderTakeProfit(), 0, clrRed))
Print("トレーリング失敗:", GetLastError());
}
}
}
}部分決済
bool PartialClose(int ticket, double closePercent)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
return false;
double totalLots = OrderLots();
double closeLots = NormalizeDouble(totalLots * closePercent / 100.0, 2);
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
// ロットステップに丸める
closeLots = MathFloor(closeLots / lotStep) * lotStep;
// 最小ロット未満なら全決済
if(closeLots < minLot)
closeLots = totalLots;
double price = (OrderType() == OP_BUY) ? Bid : Ask;
bool result = OrderClose(ticket, closeLots, price, 3, clrYellow);
if(!result)
Print("部分決済失敗:", GetLastError());
else
Print("部分決済成功:", closeLots," /", totalLots," lots");
return result;
}- 部分決済すると新しいチケット番号が発行される(残りのポジションは別チケットになる)
- closeLots が minLot 未満の場合は全決済にフォールバックする
- ブローカーによっては部分決済がサポートされていない場合がある
マジックナンバーによる複数ロジック管理
1つのEAで複数のロジックを管理する場合、マジックナンバーでポジションを識別します。
#define MAGIC_LOGIC_A 100001 // ロジックA
#define MAGIC_LOGIC_B 100002 // ロジックB
#define MAGIC_LOGIC_C 100003 // ロジックC
#define MAX_POSITIONS 3 // 全体の最大ポジション数
// 指定マジックナンバーのポジション数をカウント
int CountPositions(int magic)
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
if(OrderSymbol() != Symbol())
continue;
if(OrderMagicNumber() != magic)
continue;
if(OrderType() <= OP_SELL)
count++;
}
return count;
}
// 全ロジックの合計ポジション数
int CountAllPositions()
{
return CountPositions(MAGIC_LOGIC_A)
+ CountPositions(MAGIC_LOGIC_B)
+ CountPositions(MAGIC_LOGIC_C);
}
void OnTick()
{
// 最大ポジション数チェック
if(CountAllPositions() >= MAX_POSITIONS)
return;
// ロジックA: 条件チェック & エントリー
if(CountPositions(MAGIC_LOGIC_A) == 0 && LogicA_Signal())
{
OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, 0, 0,"LogicA", MAGIC_LOGIC_A, 0, clrBlue);
}
// ロジックB: 条件チェック & エントリー
if(CountPositions(MAGIC_LOGIC_B) == 0 && LogicB_Signal())
{
OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, 0, 0,"LogicB", MAGIC_LOGIC_B, 0, clrRed);
}
// ロジックC: 条件チェック & エントリー
if(CountPositions(MAGIC_LOGIC_C) == 0 && LogicC_Signal())
{
OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, 0, 0,"LogicC", MAGIC_LOGIC_C, 0, clrGreen);
}
}ECN口座対応パターン
ECN口座ではOrderSend時にSL/TPを同時に設定できないブローカーがあります。その場合はStep1: SL/TPなしで発注 → Step2: OrderModifyでSL/TP設定の2段階で処理します。STP口座でも同様のエラーが出る場合があるため、汎用的にこのパターンを実装するのがベストプラクティスです。
int BuyOrderECN(double lots, int slPoints, int tpPoints, int magic)
{
// Step 1: SL/TPなしで発注
int ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, 3,
0, 0,"ECN Buy", magic, 0, clrBlue);
if(ticket < 0)
{
Print("発注失敗:", GetLastError());
return -1;
}
// Step 2: SL/TPを後から設定
if(slPoints > 0 || tpPoints > 0)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
return ticket;
double openPrice = OrderOpenPrice();
double sl = (slPoints > 0) ? NormalizeDouble(openPrice - slPoints * Point, Digits) : 0;
double tp = (tpPoints > 0) ? NormalizeDouble(openPrice + tpPoints * Point, Digits) : 0;
// リトライ付きでSL/TP設定
for(int retry = 0; retry < 3; retry++)
{
if(OrderModify(ticket, openPrice, sl, tp, 0, clrBlue))
break;
Print("SL/TP設定リトライ:", GetLastError());
Sleep(500);
}
}
return ticket;
}取引関数一覧
| MQL4関数 | MQL5対応 | 説明 |
|---|---|---|
| OrderSend() | OrderSend() + MqlTradeRequest | 新規注文(成行/指値/逆指値) |
| OrderClose() | CTrade::PositionClose() | ポジション決済 |
| OrderCloseBy() | CTrade::PositionCloseBy() | 両建て決済 |
| OrderModify() | OrderSend() + TRADE_ACTION_SLTP/MODIFY | SL/TP・待機注文変更 |
| OrderDelete() | CTrade::OrderDelete() | 待機注文の削除 |
| OrderSelect() | PositionSelectByTicket() / OrderGetTicket() | 注文を選択 |
| OrdersTotal() | PositionsTotal() / OrdersTotal() | 保有注文数 |
| OrdersHistoryTotal() | HistoryOrdersTotal() | 履歴注文数 |
| OrderTicket() | PositionGetTicket() | チケット番号 |
| OrderType() | PositionGetInteger(POSITION_TYPE) | 注文タイプ |
| OrderLots() | PositionGetDouble(POSITION_VOLUME) | ロット数 |
| OrderOpenPrice() | PositionGetDouble(POSITION_PRICE_OPEN) | 約定価格 |
| OrderProfit() | PositionGetDouble(POSITION_PROFIT) | 損益 |
| OrderMagicNumber() | PositionGetInteger(POSITION_MAGIC) | マジックナンバー |
| OrderStopLoss() | PositionGetDouble(POSITION_SL) | SL価格 |
| OrderTakeProfit() | PositionGetDouble(POSITION_TP) | TP価格 |
まとめ
MQL4の取引関数はMQL5と比べてシンプルで直感的です。OrderSend()に引数を直接渡すだけで注文でき、OrderClose()で決済、OrderModify()でSL/TP変更と、関数名が処理内容をそのまま表しています。実際に試したところ、ポジションループをOrdersTotal()-1から逆順で回さないと、決済後にインデックスがずれて一部のポジションが処理されないケースがありました。
EA開発で押さえておきたいポイントは以下の3つです。
- ポジションループは逆順(i–)で回す:決済時のインデックスずれを防ぐ
- Symbol()とMagicNumber()で必ずフィルタする:他のEAや手動注文を誤操作しない
- NormalizeDouble()で価格を正規化する:浮動小数点の誤差によるエラーを防ぐ
次のステップとして、MQLリファレンス総合ガイドから他のカテゴリも学習しましょう。インジケーター関数と組み合わせることで、実用的なEAを開発できます。
MQL4取引関数 よくある質問
MQL4のOrderSend()の使い方は?
OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color)で注文を送信します。成功時は注文チケット番号を返し、失敗時は-1を返します。失敗後はGetLastError()でエラーコードを確認してください。
MQL4でポジション数を確認する方法は?
OrdersTotal()で全オープンオーダー数、OrderSelect()でループして各オーダーを選択し、OrderType()でOP_BUY/OP_SELLのポジションを確認します。マジックナンバーをOrderMagicNumber()と比較することで自分のEAのポジションのみカウントできます。
MQL4でOrderClose()を正しく使う方法は?
OrderClose(ticket, lots, price, slippage, arrow_color)でポジションをクローズします。priceにはBid(売りポジション)またはAsk(買いポジション)を使用します。一部決済の場合はlotsに決済量を指定します。失敗時はGetLastError()でエラーを確認します。
MQL4でストップロスを後から変更する方法は?
OrderModify(ticket, price, stoploss, takeprofit, expiration, arrow_color)でSL/TPを変更します。priceには現在のオープン価格(OrderOpenPrice())、stoplossには新しいストップロス価格を指定します。ストップロス変更にはMarketInfo()のMODE_STOPLEVELで最小距離の確認が必要です。
MQL4でマジックナンバーを使う目的は?
同一口座で複数EAを実行する際に、自分のEAの注文を識別するために使用します。OrderMagicNumber()で取得した値と比較して自EAの注文のみを操作します。マジックナンバーは一意の値(例:チャートの時間足+通貨ペアのハッシュ)を設定してください。
MQL4とMQL5の取引関数の主な違いは?
MQL5ではOrderSend()が1つの関数に統合され、MqlTradeRequest構造体でパラメータを設定します。ポジション管理もOrdersTotal()からPositionsTotal()/PositionSelect()に変わり、より型安全な設計になっています。MQL4のシンプルな関数形式に慣れている場合はラッパークラス(CTrade)の使用を推奨します。
MQL4リファレンス 関連記事
- MQL4 取引関数:OrderSend・OrderClose・ポジション管理
- MQL4 インジケーター関数:iMA・iRSI・iCustom
- MQL4 口座・マーケット情報:ロット計算
- MQL4 イベントハンドラ:OnInit・OnTick
- MQL4 エラーコード:リトライパターン
- MQL4 時間・日付関数:取引時間フィルター
- EA始め方ガイド:MT4へのEA設定手順





⚠ リスクに関する注意事項
本記事は情報提供を目的としており、特定の金融商品の売買を推奨するものではありません。FX取引はレバレッジ取引の特性上、預託した証拠金以上の損失が生じる可能性があります。取引の際は、ご自身の判断と責任において行ってください。詳しくは特定商取引法に基づく表記をご確認ください。






