🤖
MQL5 标准交易类库:CTrade、CAccountInfo 与 CPositionInfo
标准类库交易类MQL5
标准交易类库能省多少事
早期 EA 要手写交易请求结构体、填十几个字段、处理异步回执,几百行代码还容易错。MQL5 标准库(MQL5\Include\Trade 与 MQL5\Include\Chart 等)把这些封装成了 CTrade、CAccountInfo、CPositionInfo、COrderInfo、CSymbolInfo 等类。用它们,下单、查持仓、校验账户状态都变成一两行调用。本文聚焦交易类。
核心类职责
- CTrade:执行开仓、挂单、改单、平仓,封装了交易请求与回执读取。
- CAccountInfo:账户属性——登录号、杠杆、余额、可用预付款、是否允许交易。
- CSymbolInfo:品种属性——买/卖价、点差、止损水平、合约大小、小数位。
- CPositionInfo:当前持仓字段——开仓时间、类型、手数、开仓价、SL/TP。
- COrderInfo:挂单字段——类型、状态、价格、SL/TP,需 Select(ticket)。
- CDealInfo:历史成交记录。
CTrade 关键方法
最常用的是市价单与持仓操作。注意 MQL5 交易是异步的:函数返回 true 只代表请求已发出,最终是否成交要看 ResultDeal()。
- Buy(volume, symbol, price=0, sl=0, tp=0, comment) / Sell(...):市价单,price=0 用当前 Ask/Bid。
- PositionOpen(symbol, ORDER_TYPE_BUY/SELL, volume, price, sl, tp) :更通用的建仓。
- PositionModify(symbol, sl, tp) / PositionClose(symbol, deviation) :改/平持仓。
- OrderOpen / OrderModify / OrderDelete :挂单的增改删。
- ResultRetcode() / ResultRetcodeDescription() / ResultDeal() / PrintRequest() :诊断用。
下单前必须做的校验
直接 Buy() 很容易因为“市场关闭”“保证金不足”“止损太近”而失败。标准库提供了下单前的检查点:
CSymbolInfo mysymbol; CAccountInfo myaccount; CTrade mytrade;
mysymbol.Name(_Symbol);
mytrade.SetExpertMagicNumber(EA_Magic);
mytrade.SetDeviationInPoints(dev);
if(!mysymbol.RefreshRates()) { Alert("报价错误"); return; }
if(!(myaccount.TradeAllowed() && myaccount.TradeExpert() && mysymbol.IsSynchronized()))
{ Alert("不可交易"); return; }
double price = NormalizeDouble(mysymbol.Ask(), _Digits);
double sl = NormalizeDouble(mysymbol.Ask() - STP*_Point, _Digits);
if(mytrade.Buy(Lot, _Symbol, price, sl, tp))
Alert("成交单号:", mytrade.ResultDeal());
else
Alert("失败:", mytrade.ResultRetcodeDescription());
读持仓与读挂单
平仓或改单前,先用 CPositionInfo::Select(_Symbol) 选中当前品种持仓,再用 Volume()/StopLoss()/TakeProfit()/PriceOpen() 读字段。挂单则用 COrderInfo::Select(ticket) 按单号选中。注意一个品种可能同时有多笔挂单,要遍历 OrderGetTicket(j) 逐个处理。
常见错误与排查
⚠ 下单失败先查这三处
1) Retcode:每次操作后必须看 ResultRetcodeDescription(),Invalid Stops 常见原因是 SL/TP 距离小于 StopsLevel 或未 NormalizeDouble。2) 异步成交:函数返回 true 不等于已成交,要用 ResultDeal() 或等 OnTrade 确认;价格跳变用 SetDeviationInPoints 容差。3) 市场状态:TradeAllowed()/TradeExpert()/IsSynchronized() 任一为 false 都应中止下单,RefreshRates() 返回 false 说明报价获取失败。
常见问题
不是。MQL5 交易请求是异步的,Buy() 返回 true 只表示请求已成功发出。是否真正成交要看 ResultDeal() 是否为有效单号,或在 OnTrade/OnTradeTransaction 里确认。
最常见两个原因:一是 SL/TP 距离小于品种的 StopsLevel(最小止损水平点数);二是价格没用 NormalizeDouble(..., _Digits) 对齐小数位。下单前用 CSymbolInfo::StopsLevel() 检查距离,价格务必标准化。
有必要。下单前必须刷新拿到最新 Ask/Bid,否则可能用陈旧报价下单导致滑点过大或拒绝。同样,TradeAllowed/TradeExpert/IsSynchronized 也应在下单前确认,避免在市场关闭或数据未同步时发单。