MQL5零基础EA交易快速入门指南
从结构、指标到标准库下单的完整路径
为什么初学者需要这份MQL5简明路径
很多中文交易者在接触MetaTrader 5时,被MQL5的语法和文档厚度劝退。本文不堆术语,而是沿真实编写EA的顺序,把必须知道的概念、函数和坑一次讲清。你不需要有任何编程背景,只要装好MetaEditor 5,跟着做就能写出一个可回测的EA。本文示例源自官方社区入门文章,代码均可在MT5中直接编译运行。
EA交易的四大代码块与生命周期
EA交易是以MQL5编写、由终端自动加载执行的程序。MetaEditor新建文档后,默认生成的结构从视觉上可分为四个部分,每部分负责特定阶段的工作。理解它们的调用时机,是写出不崩EA的前提。
参数块位于文件头部,用#property描述版本、版权与链接,终端在EA属性框中展示这些信息。OnInit()在EA被加载进图表时执行一次,适合声明变量、获取指标句柄,不涉及下单。OnDeinit()与初始化反向,在EA移除或初始化失败时调用,负责释放数组与指标句柄占用的内存。OnTick()是EA的大脑,每次服务器推送该品种新报价时触发,所有交易判断与下单函数都应放在这里。
- OnInit: 只做初始化,返回-1可阻止EA启动
- OnDeinit: 必须清理句柄,否则内存泄漏
- OnTick: 避免写重计算,尽量用 OnInit 预取的句柄
- 参数块: 改了version终端会提示重新加载
指标的本质与缓冲区时间序列
指标是MQL5写的小型分析程序,分顺势与摆荡两类。顺势指标画在主图识别方向,摆荡指标在副图找进场点。无论哪种,核心都是指标缓冲区:一种按时间序列排列的数组,索引0是最右一根K线,索引1是右数第二根,依此类推。
用iMA()可拿到移动平均线句柄,句柄是指向指标实例的唯一指针。在MetaEditor输入iMA后按F1,会弹出参数说明:交易品种、周期、均值周期、平移、平均方法、应用价格。拿到句柄后,若想在主图显示,用ChartIndicatorAdd(ChartID(),0,handle);若要在副图显示,第二个参数填1。之后声明动态数组,ArraySetAsSeries设为时间序列,再用CopyBuffer把值拷进来即可参与逻辑判断。
int iMA_handle;
iMA_handle=iMA("EURUSD",PERIOD_H1,10,0,MODE_SMA,PRICE_CLOSE);
ChartIndicatorAdd(ChartID(),0,iMA_handle);
double iMA_buf[]; ArraySetAsSeries(iMA_buf,true); CopyBuffer(iMA_handle,0,0,3,iMA_buf);
订单、交易与持仓的真实区别
不少新手把这三个词混用。订单是发往服务器的请求,分市价单和挂单;市价单即时成交,挂单到价触发且有到期时间。交易是订单被执行后的结果,写入历史不可改。持仓是活动订单的累计成果:同品种同方向加仓会合并手数,不会显示两条。例如先买1手EURUSD再买1手,终端交易标签里看到一个2手长仓,而非两个订单。
若手写请求,需填充MqlTradeRequest结构,含action、symbol、volume、type、price、sl、tp等字段。任一带强制参数缺失或非法,服务器直接拒单。这也是为什么初学者应优先用标准库。
struct MqlTradeRequest
{
ENUM_TRADE_REQUEST_ACTIONS action;
ulong magic;
ulong order;
string symbol;
double volume;
double price;
double stoplimit;
double sl;
double tp;
ulong deviation;
ENUM_ORDER_TYPE type;
ENUM_ORDER_TYPE_FILLING type_filling;
ENUM_ORDER_TYPE_TIME type_time;
datetime expiration;
string comment;
};
止损获利为何不能独立下达
止损与获利是附加在持仓上的保险单,不是独立指令。它们只能修改已有仓位:价格不利时止损限亏,价格顺势时获利平仓。在MqlTradeRequest里填sl/tp字段随开仓单送出,或用CTrade的Buy/Sell参数一并带上。策略若不用止损,传0即可,但实盘强烈建议必设。
标准库如何大幅简化下单
标准库随终端自带,路径Include\Trade\。引入Trade.mqh和PositionInfo.mqh后,CTrade负责发单改单,CPositionInfo读持仓。相比手写结构,m_Trade.Buy(lot,symbol,price,sl,tp,comment)只需6参,仅lot必填。若策略用挂单,再包含OrderInfo.mqh。平仓可用m_Trade.PositionClose(symbol)整平,或用PositionInfo遍历筛选。
#include <Trade\Trade.mqh> #include <Trade\PositionInfo.mqh>
CTrade m_Trade; m_Trade.Sell(lot,symbol_name,price,sl,tp,comment);
CPositionInfo m_Position; m_Position.Select(symbol_name); m_Trade.PositionClose(symbol_name);
串起一个可运行的示例EA
把前述知识组合:OnInit取MA40句柄并加到主图,OnTick比较均线与收盘价做反向或突破判断,用CTrade下单。原文示例用EURUSD H1、仅开盘价测试,因取零柱外的值不重绘,速度更快。最终EA不足百行,虽非盈利保证,但证明基础扎实即可快速原型化。下方为节选框架,完整文件见原文ZIP。
//| fast-start-example.mq5 |
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
int iMA_handle;
double iMA_buf[];
double Close_buf[];
string my_symbol;
ENUM_TIMEFRAMES my_timeframe;
CTrade m_Trade;
CPositionInfo m_Position;
int OnInit()
{
my_symbol=Symbol();
my_timeframe=PERIOD_CURRENT;
iMA_handle=iMA(my_symbol,my_timeframe,40,0,MODE_SMA,PRICE_CLOSE);
if(iMA_handle==INVALID_HANDLE) { Print("Failed"); return(-1); }
ChartIndicatorAdd(ChartID(),0,iMA_handle);
return(0);
}
与其他方案的对比与后续进阶
对比纯手工填MqlTradeRequest,标准库少写几十行且不易错;对比MQ4的OrderSend,MQL5分离持仓与历史更清晰。若你后续要写复杂风控,可深入PositionInfo遍历、OrderInfo挂单管理,或接入CSymbolInfo取点值。本文对应原文地址 https://www.mql5.com/zh/articles/496 ,建议配合其ZIP中的mq5对照练习。