1. 前言
MQL4(MetaQuotes Language 4)是一種在 MetaTrader 4(MT4)平台上運行的程式語言,用於在外匯、股票等金融市場中創建自動交易系統和自訂指標。其中,OrderSend 函式扮演著極為重要的角色。
OrderSend 函式提供了從程式直接發送買賣訂單的基本功能。使用此函式即可實現交易自動化,並根據特定條件下單。無論是初學者還是進階使用者,正確理解此功能都是學習 MQL4 程式設計不可或缺的一步。
本文將從 OrderSend 函式的基本機制說起,逐步說明其參數的詳細說明、實際使用範例與注意事項。閱讀本文後,您將能夠牢固掌握使用 MQL4 OrderSend 函式的基礎。
2. OrderSend 函式是什麼
OrderSend 函式是用於在 MQL4 中發送買賣訂單的函式。在 MetaTrader 4 的自動交易系統中,它負責以程式方式發出買賣指令。無論是初學者還是進階交易者,這都是在構建交易自動化與高階策略時極為重要的函式。
以下將說明 OrderSend 函式的基本結構與概述。
OrderSend 函式的基本結構
OrderSend 函式的語法(構文)如下所示。
int OrderSend(
string symbol, // 通貨對
int cmd, // 買賣類型(訂單類型)
double volume, // 手數
double price, // 訂單價格
int slippage, // 滑點
double stoploss, // 止損價格
double takeprofit, // 止盈價格
string comment, // 訂單備註
int magic, // 魔術號
datetime expiration, // 有效期限
color arrow_color // 矢印顏色
);
基本回傳值
OrderSend 函式在訂單成功時會回傳「票號(int 型)」;若失敗則回傳 -1,並設定錯誤碼。可使用 GetLastError 函式取得該錯誤碼。
OrderSend 函式的作用
-
交易自動化
透過使用 OrderSend 函式,交易者可將手動執行的買賣操作以程式方式自動化。這樣可避免人為錯誤,並實現快速且高效的交易。 -
策略執行
在程式內設定條件,並根據條件執行訂單,可提升交易策略的精準度。例如,當價格達到特定值或在特定時間段發出訂單等實作皆可。 -
多頭/空頭頭寸管理
透過使用魔術號(magic參數),可識別並管理多個頭寸,從而能同時執行不同策略。
3. OrderSend 函式的參數詳細說明
為了正確運用 OrderSend 函式,必須充分理解各參數的含義與作用。本節將逐一說明 OrderSend 函式的參數,並提供具體使用方法。
各參數的詳細說明
1. symbol(貨幣對)
說明
指定交易所使用的貨幣對。例如,使用 "EURUSD" 或 "USDJPY" 等字串。
注意事項
- 請務必使用平台上顯示的貨幣對。
- 亦可指定與目前圖表不同的貨幣對。
範例
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "", 0, 0, Blue);
2. cmd(買賣類型/訂單類型)
說明
指定交易類型。以下為可使用的常數:
OP_BUY:市價買入訂單OP_SELL:市價賣出訂單OP_BUYLIMIT:限價買入訂單OP_SELLLIMIT:限價賣出訂單OP_BUYSTOP:止損買入訂單OP_SELLSTOP:止損賣出訂單
範例
OrderSend("USDJPY", OP_BUY, 1.0, Ask, 3, 0, 0, "", 0, 0, Blue);
3. volume(手數)
說明
以手數(lot)指定交易量。例如,「1.0」代表 1 手。
注意事項
- 各券商的最低手數可能不同,請事先確認。
- 考慮保證金與風險管理,設定適當的手數大小很重要。
範例
OrderSend("GBPUSD", OP_SELL, 0.1, Bid, 2, 0, 0, "", 0, 0, Red);
4. price(訂單價格)
說明
指定下單價格。一般市價訂單使用 Ask 或 Bid;限價或止損訂單則需明確指定價格。
注意事項
- 對於限價或止損訂單,請以當前價格上下適當設定價格。
範例
OrderSend("EURUSD", OP_BUYLIMIT, 1.0, 1.1000, 3, 0, 0, "", 0, 0, Blue);
5. slippage(滑點)
說明
指定執行訂單時允許的價格偏差(滑點)範圍。單位為點(非點數)。
注意事項
- 在價格波動劇烈時,滑點易發生,請適當設定允許範圍。
範例
OrderSend("USDJPY", OP_SELL, 1.0, Bid, 5, 0, 0, "", 0, 0, Green);
6. stoploss(止損價格)
說明
設定止損(Stop Loss)價格。須設置於訂單價格的相反方向。
注意事項
- 若不設定,請輸入
0。 - 依據使用者的資金管理策略,建議適當設定。
範例
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 1.0950, 0, "", 0, 0, Blue);
7. takeprofit(止盈價格)
說明
設定止盈(Take Profit)價格。須設置於訂單價格相同方向。
注意事項
- 若不設定,請輸入
0。 - 適當設定利潤確保線,可自動化交易策略。
範例
OrderSend("GBPUSD", OP_SELL, 1.0, Bid, 3, 0, 1.2500, "", 0, 0, Red);
8. comment(訂單備註)
說明
可為訂單加入任意備註。此備註會顯示於交易歷史。
範例
OrderSend("USDJPY", OP_BUY, 1.0, Ask, 3, 0, 0, "Test Order", 0, 0, Yellow);
9. magic(魔術號)
說明
指定程式發出的訂單識別號碼。對於不同 EA(專家顧問)執行的訂單管理非常方便。
範例
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "", 123456, 0, Blue);
10. expiration(有效期限)
說明
設定訂單的有效期限。若設定此值,逾期訂單將自動刪除。
注意事項
- 若不設定,請輸入
0。
範例
OrderSend("GBPUSD", OP_BUYLIMIT, 1.0, 1.3000, 3, 0, 0, "", 0, TimeCurrent() + 3600, Green);
11. arrow_color (箭頭顏色)
說明
指定在圖表上顯示的訂單箭頭顏色。
範例
OrderSend("USDJPY", OP_SELL, 1.0, Bid, 3, 0, 0, "", 0, 0, Blue);
了解 OrderSend 函數的參數,可以創建更靈活、更高效的交易程式。下一節將說明「訂單類型詳細」。
4. 訂單類型詳細
在使用 MQL4 的 OrderSend 函數時,正確理解並適當設定訂單類型(cmd 參數)非常重要。本節將詳細說明各訂單類型的特點與使用方法。
訂單類型種類
1. 成行訂單(Market Orders)
成行訂單是以目前市場價格即時執行的訂單類型。
種類
OP_BUY:以目前市場價格(Ask)發出買入訂單OP_SELL:以目前市場價格(Bid)發出賣出訂單
使用範例
成行訂單用於想快速進入市場的情況。例如,想跟隨特定趨勢時非常有效。
程式碼範例
// 成行買入訂單
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "Market Buy", 123456, 0, Blue);
// 成行賣出訂單
OrderSend("EURUSD", OP_SELL, 1.0, Bid, 3, 0, 0, "Market Sell", 123456, 0, Red);
2. 指價訂單(Limit Orders)
指價訂單用於想以比目前市場價格更有利的價格執行訂單時。
種類
OP_BUYLIMIT:以低於目前價格的價格發出買入訂單OP_SELLLIMIT:以高於目前價格的價格發出賣出訂單
使用範例
適用於想執行逆勢策略或想在特定價格區間尋找回撤時。
程式碼範例
// 買入指價訂單
OrderSend("USDJPY", OP_BUYLIMIT, 1.0, 135.50, 3, 135.00, 136.00, "Buy Limit Order", 123456, 0, Green);
// 賣出指價訂單
OrderSend("USDJPY", OP_SELLLIMIT, 1.0, 136.50, 3, 137.00, 135.00, "Sell Limit Order", 123456, 0, Yellow);
3. 逆價訂單(Stop Orders)
逆價訂單用於想以比目前市場價格更不利的價格執行訂單時。
種類
OP_BUYSTOP:以高於目前價格的價格發出買入訂單OP_SELLSTOP:以低於目前價格的價格發出賣出訂單
使用範例
適用於想執行順勢策略或想突破特定價格線時。
程式碼範例
// 買入逆價訂單
OrderSend("GBPUSD", OP_BUYSTOP, 1.0, 1.3100, 3, 1.3000, 1.3200, "Buy Stop Order", 123456, 0, Blue);
// 賣出逆價訂單
OrderSend("GBPUSD", OP_SELLSTOP, 1.0, 1.2900, 3, 1.3000, 1.2800, "Sell Stop Order", 123456, 0, Red);
訂單類型選擇標準
成行訂單的適用場景
- 想跟隨市場勢頭時
- 想快速突破重要價格區間的時機
指價訂單的適用場景
- 預期從目前價格回撤時
- 預測趨勢反轉點並進場時
逆價訂單的適用場景
- 預期趨勢持續時
- 想突破特定價格線的動向時
實際情境中的選擇範例
情境1:趨勢的回檔買入
當目前價格處於上升趨勢,且價格短暫下跌後預計再次上升時:
- 訂單類型 :指價訂單(
OP_BUYLIMIT)
情境2:突破策略
預計價格突破重要阻力線時:
- 訂單類型 :逆價訂單(
OP_BUYSTOP或OP_SELLSTOP)
5. OrderSend 函數的使用範例
此處將示範使用 OrderSend 函數的具體程式碼範例,並說明在各種交易情境中的使用方法。這將幫助您清晰了解在實際 MQL4 程式中使用 OrderSend 函數的情形。
使用範例 1:成行訂單(Market Orders)
買入訂單的程式碼範例
以下程式碼示範以目前 Ask 價格發出成行買入訂單。
程式碼範例
int ticket = OrderSend(
"EURUSD", // 通貨對
OP_BUY, // 買入訂單
1.0, // 手數
Ask, // 目前價格
3, // 滑點
0, // 止損價格
0, // 止盈價格
"Market Buy Order", // 註解
0, // 魔術號
0, // 有效期限
Blue // 箭頭顏色
);
if(ticket < 0) {
Print("訂單失敗。錯誤碼: ", GetLastError());
} else {
Print("訂單成功。票號: ", ticket);
}
賣出訂單的程式碼範例
以下程式碼示範以目前 Bid 價格發出成行賣出訂單。
程式碼範例
int ticket = OrderSend(
"USDJPY", // 通貨對
OP_SELL, // 賣出訂單
0.5, // 手數
Bid, // 目前價格
2, // 滑點
0, // 止損價格
0, // 止盈價格
"Market Sell Order", // 註解
123456, // 魔術號
0, // 有效期限
Red // 箭頭顏色
);
使用範例 2:指價訂單(Limit Orders)
買入指價訂單的程式碼範例
以低於目前價格發出買入訂單。例如,當目前價格為 1.1200,且跌至 1.1150 時下單。
程式碼範例
OrderSend(
"EURUSD",
OP_BUYLIMIT,
1.0,
1.1150, // 指價價格
3,
1.1100, // 止損價格
1.1200, // 止盈價格
"Buy Limit Order",
0,
0,
Green
);
賣出指價訂單的程式碼範例
現在價格之上發出賣單。例如,當目前價格為1.1200,達到1.1250時發出訂單。
程式碼範例
OrderSend(
"GBPUSD",
OP_SELLLIMIT,
0.5,
1.1250, // 指價價格
2,
1.1300, // 損失止損價格
1.1200, // 利潤止盈價格
"Sell Limit Order",
0,
0,
Yellow
);
使用範例 3:反向止損訂單(Stop Orders)
買入反向止損訂單程式碼
以高於目前價格的價格發出買單。例如,當目前價格為1.1200,突破1.1250時發出訂單。
程式碼範例
OrderSend(
"USDJPY",
OP_BUYSTOP,
1.0,
135.00, // 反向止損價格
3,
134.50, // 損失止損價格
135.50, // 利潤止盈價格
"Buy Stop Order",
0,
0,
Blue
);
賣出反向止損訂單程式碼
以低於目前價格的價格發出賣單。例如,當目前價格為1.1200,跌破1.1150時發出訂單。
程式碼範例
OrderSend(
"EURUSD",
OP_SELLSTOP,
0.5,
1.1150, // 反向止損價格
2,
1.1200, // 損失止損價格
1.1100, // 利潤止盈價格
"Sell Stop Order",
0,
0,
Red
);
使用範例 4:訂單的錯誤處理
若訂單失敗,需取得錯誤碼並確認原因。以下程式碼使用 GetLastError 函式取得錯誤資訊。
程式碼範例
int ticket = OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "Error Test", 0, 0, Blue);
if(ticket < 0) {
int errorCode = GetLastError();
Print("訂單失敗。錯誤碼: ", errorCode);
// 根據特定錯誤進行處理
if(errorCode == 134) {
Print("保證金不足。請減少手數。");
} else if(errorCode == 130) {
Print("無效的止損水平。請重新確認價格。");
}
}
可根據上述使用範例將實際交易策略編寫進程式。下一節將詳細說明「6. 錯誤處理」。
6. 錯誤處理
使用 MQL4 的 OrderSend 函式時,訂單可能無法正常處理。在此情況下,正確識別錯誤並採取適當措施非常重要。錯誤處理是提升程式穩定性與可靠性的關鍵要素。
錯誤偵測方法
在 MQL4 中,檢查 OrderSend 函式的回傳值,若發生錯誤則使用 GetLastError 函式取得錯誤碼。
基本錯誤檢查結構
int ticket = OrderSend(
"EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "Order Test", 0, 0, Blue
);
if(ticket < 0) {
int errorCode = GetLastError();
Print("訂單失敗。錯誤碼: ", errorCode);
}
ticket 若為負值,表示訂單失敗。接著根據錯誤碼判斷原因。
主要錯誤碼與處理方法
130: 無效的止損水平
原因
- 指定的止損價格(
stoploss)或止盈價格(takeprofit)超出可交易範圍。
解決方法
- 確認券商提供的最小止損水平,並調整價格。
- 使用 NormalizeDouble 函式將價格正規化以確保精度。
修正後程式碼範例
double stopLoss = NormalizeDouble(Ask - 0.0010, Digits);
double takeProfit = NormalizeDouble(Ask + 0.0020, Digits);
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, stopLoss, takeProfit, "Normalized Price Test", 0, 0, Blue);
131: 無效的手數
原因
- 手數超出券商允許範圍(過小或過大)。
解決方法
- 確認券商的最小/最大手數,並指定範圍內的值。
修正後程式碼範例
double lotSize = 0.1;
if(lotSize < MarketInfo("EURUSD", MODE_MINLOT) || lotSize > MarketInfo("EURUSD", MODE_MAXLOT)) {
Print("無效的手數。請設定適當的值。");
} else {
OrderSend("EURUSD", OP_BUY, lotSize, Ask, 3, 0, 0, "Lot Size Test", 0, 0, Blue);
}
134: 保證金不足
原因
- 執行訂單所需保證金不足。
解決方法
- 減少手數或增加保證金。
- 使用
AccountFreeMargin函式確認可用保證金。
修正後程式碼範例
double freeMargin = AccountFreeMargin();
double requiredMargin = MarketInfo("EURUSD", MODE_MARGINREQUIRED) * 1.0;
if(freeMargin < requiredMargin) {
Print("保證金不足。請減少手數。");
} else {
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "Margin Test", 0, 0, Blue);
}
146: 市場已關閉
原因
- 在市場關閉時嘗試發出訂單。
解決方法
- 確認市場營業時間,並於可交易時間內發出訂單。
- 使用
MarketInfo函式確認市場狀態。
通用錯誤處理範例
以下為根據錯誤碼顯示適當錯誤訊息的通用錯誤處理程式碼。
通用錯誤處理範例
int ticket = OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "Error Handling Test", 0, 0, Blue);
if(ticket < 0) {
int errorCode = GetLastError();
switch(errorCode) {
case 130:
Print("無效的停損水平。請重新確認價格。");
break;
case 131:
Print("無效的手數。請指定適當的值。");
break;
case 134:
Print("保證金不足。請調整手數。");
break;
case 146:
Print("市場已關閉。請確認可交易時間。");
break;
default:
Print("發生未知錯誤。錯誤碼: ", errorCode);
break;
}
}
錯誤處理重點
- 不要忽略錯誤 當發生錯誤時,適當處理可提升程式可靠性。
- 事前檢查 在發送訂單前確認手數、停損水平等,可預防錯誤發生。
- 利用日誌輸出 使用
Print函數將錯誤細節寫入日誌,便於故障排除。
7. OrderSend 函數使用時的注意事項
OrderSend 函數是 MQL4 中發送交易訂單的強大工具,但使用時需謹慎。本節將說明使用 OrderSend 函數時應注意的重點,以及防止常見錯誤的具體對策。
注意事項 1:價格正規化(NormalizeDouble 函數)
問題點
在 MQL4 中,不同貨幣對或商品的價格小數位數(Digits)可能不同。若價格計算結果與平台規範不符,訂單可能被拒絕。
對策
使用 NormalizeDouble 函數將價格正規化(調整小數位數)即可避免此問題。
範例
double stopLoss = NormalizeDouble(Ask - 0.0010, Digits);
double takeProfit = NormalizeDouble(Ask + 0.0020, Digits);
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, stopLoss, takeProfit, "Normalized Price Test", 0, 0, Blue);
注意事項 2:滑點設定
問題點
市場急劇波動時,滑點(下單時價格偏差)可能發生。若滑點超過允許範圍,訂單可能被拒絕。
對策
設定適當的滑點值可降低交易失敗風險。若預期市場將大幅波動(如經濟指標發布時),建議將滑點設定較寬或暫停交易。
範例
int slippage = 5; // 允許 5 點滑點
OrderSend("USDJPY", OP_BUY, 0.1, Ask, slippage, 0, 0, "Slippage Test", 0, 0, Green);
注意事項 3:伺服器回應時間與請求限制
問題點
若證券商伺服器擁擠,訂單回應時間可能延長。部分證券商在短時間內發送大量請求時,亦可能產生錯誤。
對策
- 連續發送多筆訂單時,請留足適當間隔。
- 建議實作伺服器回應監控邏輯,並在逾時時重試。
注意事項 4:最小停損水平確認
問題點
忽略各證券商設定的「最小停損水平」可能導致止損或止盈價格被視為無效。
對策
使用 MarketInfo 函數取得最小停損水平,並在事前檢查。
範例
double minStopLevel = MarketInfo("EURUSD", MODE_STOPLEVEL) * Point;
if((Ask - minStopLevel) < NormalizeDouble(Ask - 0.0010, Digits)) {
Print("止損價格未達最小停損水平。");
} else {
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, Ask - 0.0010, Ask + 0.0020, "Stop Level Check", 0, 0, Blue);
}
注意事項 5:使用魔術號碼
問題點
若多個 EA 同時運行,若未設定魔術號碼,將無法區分哪個 EA 發出的訂單。
對策
為每個 EA 設定唯一的魔術號碼,以便管理持倉。
範例
int magicNumber = 123456; // 唯一的魔術號碼
OrderSend("GBPUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "Magic Number Test", magicNumber, 0, Yellow);
注意事項 6:時間段與流動性
問題點
流動性低的時間段(如日本時間凌晨)或週末收盤前,可能出現點差擴大或訂單難以成交。
對策
- 在程式中指定可交易時間段,避免在特定時間段發送訂單。
- 使用
TimeCurrent函數取得伺服器時間,並根據條件限制交易。
範例
datetime currentTime = TimeCurrent();
if(TimeHour(currentTime) >= 22 || TimeHour(currentTime) < 2) {
Print("目前為避免交易的時間段。");
} else {
OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, 0, 0, "Time Restriction Test", 0, 0, Blue);
}
注意事項 7:除錯與日誌記錄
問題點
若程式未按預期運作,難以定位問題原因。
對策
- 利用
Print函數將重要變數或函數輸出記錄至日誌。 - 在
Experts標籤或Journal標籤檢查日誌,確認是否有異常。
範例
double stopLoss = NormalizeDouble(Ask - 0.0010, Digits);
Print("止損: ", stopLoss);
int ticket = OrderSend("EURUSD", OP_BUY, 1.0, Ask, 3, stopLoss, 0, "Debug Test", 0, 0, Blue);
if(ticket < 0) {
Print("訂單失敗。錯誤碼: ", GetLastError());
}
為了適當使用 OrderSend 函數,需考慮上述注意事項並進行設計。下一節「8. 總結」將總結至今的內容。
8. 總結
MQL4 的 OrderSend 函數是 MetaTrader 4 中交易自動化的核心功能,對實現高效交易策略不可或缺。本篇文章將詳細說明 OrderSend 函數的基礎到進階,並涵蓋構建成功自動交易程式所需的知識。
OrderSend 函數的要點
1. OrderSend 函數的基本結構
- OrderSend 函數是從程式發出買賣訂單的函數,可透過各種參數靈活設定訂單內容。
- 例如需要設定貨幣對(
symbol)、訂單類型(cmd)、手數(volume)、價格(price)等。
2. 訂單類型的種類與使用情境
- 市價單 適合於以市場價格即時成交。
- 限價單 適用於逆勢策略,止損單 則適用於順勢策略或突破策略。
3. 參數的詳細理解
- 適當設定各參數(例如
stoploss或takeprofit)可更精細地控制策略。 - 使用
NormalizeDouble函數來確保價格設定的精確度非常重要。
4. 使用範例與實務程式碼
- 介紹了市價單、限價單、止損單的具體程式碼範例。
- 示範各種情境下的應用,並提供實際交易中有用的知識。
5. 錯誤處理
- 利用
GetLastError函數辨識錯誤,並根據錯誤碼實作適當的處理方式。 - 針對常見錯誤(手數、止損層級、保證金不足等)提供具體範例說明如何避免。
6. 使用時的注意事項
- 說明價格正規化、滑點設定、伺服器回應時間等實務中需注意的重點。
- 介紹魔術號、交易時間管理等,確保程式穩定性的實務對策。
使用 OrderSend 函數的建議
- 規劃性設計
- 使用 OrderSend 函數的程式必須在考慮交易策略與風險管理的前提下,謹慎設計。
- 日誌與除錯
- 定期檢查交易紀錄與日誌,若發生錯誤,能迅速處理。
- 市場理解
- 事先確認券商的交易條件(點差、止損層級、手數等),並依此設計程式。
- 持續改進
- 隨著市場環境與策略變化,定期更新程式,以追求更佳成果。
透過本文,希望能加深對 OrderSend 函數的理解,並為構建實務 MQL4 程式奠定基礎。下一步,請將本文所示程式碼應用於自己的交易策略,打造符合個人需求的 EA(專家顧問)。
祝您成功打造自動交易生活!