MQL5 交易類別(CTrade)完整使用指南
📌 本文重點
學習使用 MQL5 標準庫的 CTrade 類別,簡化開倉、平倉、修改止損等交易操作,告別繁瑣的 MqlTradeRequest 結構體。
學習使用 MQL5 標準庫的 CTrade 類別,簡化開倉、平倉、修改止損等交易操作,告別繁瑣的 MqlTradeRequest 結構體。
什麼是 CTrade?
CTrade 是 MQL5 標準庫(Trade\Trade.mqh)中封裝好的交易類別,提供簡潔的方法來執行所有交易操作,無需手動填寫 MqlTradeRequest。
引入與初始化
#include <Trade\Trade.mqh>
CTrade g_trade; // 宣告全域交易物件
int OnInit()
{
g_trade.SetExpertMagicNumber(12345); // 設定魔術數字
g_trade.SetDeviations(10); // 允許滑點(點數)
g_trade.SetTypeFilling(ORDER_FILLING_FOK); // 成交類型
g_trade.LogLevel(LOG_LEVEL_ERRORS); // 只記錄錯誤
return INIT_SUCCEEDED;
}
開倉操作
void ExecuteTrades()
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double pt = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// 市價買入(含止損止盈)
if (g_trade.Buy(0.1, _Symbol, ask, ask - 50*pt, ask + 100*pt, "MA策略"))
Print("買入成功!票號: ", g_trade.ResultOrder());
else
Print("買入失敗!retcode=", g_trade.ResultRetcode(),
" 說明=", g_trade.ResultRetcodeDescription());
// 市價賣出
if (g_trade.Sell(0.1, _Symbol, bid, bid + 50*pt, bid - 100*pt, "MA策略"))
Print("賣出成功!");
// 限價買入掛單
double buyLimit = ask - 20*pt;
if (g_trade.BuyLimit(0.1, buyLimit, _Symbol, buyLimit-50*pt, buyLimit+100*pt, 0, 0, "限價買"))
Print("限價買掛單成功!");
// 限價賣出掛單
double sellLimit = bid + 20*pt;
if (g_trade.SellLimit(0.1, sellLimit, _Symbol, sellLimit+50*pt, sellLimit-100*pt, 0, 0, "限價賣"))
Print("限價賣掛單成功!");
}
平倉與修改
void ManagePositions()
{
for (int i = PositionsTotal()-1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if (!PositionSelectByTicket(ticket)) continue;
if (PositionGetInteger(POSITION_MAGIC) != 12345) continue;
if (PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
double profit = PositionGetDouble(POSITION_PROFIT);
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
double pt = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// 盈利超過 $50 時平倉
if (profit >= 50.0)
{
if (g_trade.PositionClose(ticket))
Print("獲利平倉 #", ticket, " 盈利=$", profit);
}
// 移動止損到保本
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double curPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
int posType = (int)PositionGetInteger(POSITION_TYPE);
if (posType == POSITION_TYPE_BUY && curPrice > openPrice + 30*pt && sl < openPrice)
{
// 移動止損到保本價
if (g_trade.PositionModify(ticket, openPrice, tp))
Print("止損移至保本 #", ticket);
}
}
}
// 一鍵平倉所有持倉
void CloseAll()
{
for (int i = PositionsTotal()-1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if (ticket > 0) g_trade.PositionClose(ticket);
}
}
CTrade vs 手動 OrderSend 比較
| 功能 | CTrade | 手動 OrderSend |
|---|---|---|
| 程式碼長度 | 1–2 行 | 10–15 行 |
| 錯誤處理 | 內建(ResultRetcode) | 需自行實作 |
| 靈活性 | 中(標準情境) | 高(完整控制) |
| 推薦場景 | 快速開發、標準策略 | 複雜邏輯、特殊需求 |
本文由 James Lee 撰寫。內容僅供教育目的,不構成投資建議。