MQL5 交易類別(CTrade)完整使用指南

📌 本文重點
學習使用 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 撰寫。內容僅供教育目的,不構成投資建議。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *