MQL5教程 04 实战开发预备知识、脚本开发实战、指标开发基础

发布时间:2026/7/18 11:51:24

MQL5教程 04 实战开发预备知识、脚本开发实战、指标开发基础 文章目录一、实战开发预备知识1、基本概念2、常用取值方法(1)获取bid、ask值(2)获取K线高开低收价和开始时间(3)获取系统指标值(4)一根K线只开一个单(5)获取市价单信息(6)获取挂单信息(7)获取历史订单信息二、脚本开发实战1、给脚本设置快捷键2、运行时显示输入参数界面3、开市价单4、一键平仓5、修改止盈止损6、开立挂单7、修改挂单8、一键删除当前图表所有挂单9、格式化交易手数10、获取最后的市价单信息三、指标开发基础一、实战开发预备知识1、基本概念(1)在交易函数中,Position开头的函数为市价单函数,Order开头的函数为挂单函数,History开头的函数为历史单函数。(2)comment为订单注释,magic(幻数)为订单ID,可以用设定它们来区分订单。(3)挂单交易中,stop为挂单价格在盈利方向,limit为挂单价格在亏损方向。例如挂多单:当 挂单价格 ASK时,用stop方式;当 挂单价格 ASK时,用limit方式。(4)订单 (Order):订单是交易意图。它只是你向服务器递交的一张申请表,并不代表真正买到了东西。当调用 OrderSend 发送一个市价单交易(如 ORDER_TYPE_BUY)时,会先创建了一个订单。当挂一个限价单(如 ORDER_TYPE_BUY_LIMIT)时,这个订单会一直挂在服务器的表格里,静静地等待价格触发。特点:订单是有状态的。它可以是“等待中(Started/Placed)”、“已成交(Filled)”或者“已取消(Canceled)。(5)成交 (Deal):成交是已经发生的事实和历史记录。只要有资金和商品在底层发生了交换,就会诞生一个 Deal。它是不可更改的历史。订单被服务器撮合成功的那一瞬间,系统就会往账户历史(History)里写入一条 Deal 记录。特点:Deal 是过去式,是绝对不可更改的审计日志。开仓会产生一个 Deal,平仓同样也会产生一个全新的 Deal(代表把仓位卖回给市场)。(6)持仓 (Position):持仓是你当前手里握着的现货和风险敞口。当买入的 Deal 达成后,账户里就会多出一个 Position(如,持仓量:0.01 手,方向:多头)。随着市场价格的跳动,这个 Position 会实时显示浮动盈亏。(7)MqlTradeRequest(交易请求结构体)作用是在发起交易时,向服务器提交的请求,需要装在该结构体中。MqlTradeResult(交易请求结果结构体)作用是在发起交易时,服务器对交易请求响应,返回结果装在该结构体中。以下是这两个结构体的一些编号属性的解释:注:在 OrderSend() 发起开仓交易时,MqlTradeRequest 中的 order 和 position 这两个字段完全没有任何意义,必须保持为 0。市价单交易:挂单交易:2、常用取值方法(1)获取bid、ask值voidOnStart(){MqlTick A[];// 数组A的索引顺序默认从过去到现在,// 该句代码可以将索引顺序改为从现在到过去ArraySetAsSeries(A,true);// 将ticks值复制到数组A中CopyTicks(NULL,A);printf(DoubleToString(A[0].bid,Digits()));printf(DoubleToString(A[0].ask,Digits()));}(2)获取K线高开低收价和开始时间voidOnStart(){MqlRates rates[];ArraySetAsSeries(rates,true);CopyRates(NULL,PERIOD_CURRENT,0,100,rates);printf(DoubleToString(rates[1].open,Digits()));printf(DoubleToString(rates[1].close,Digits()));printf(DoubleToString(rates[1].high,Digits()));printf(DoubleToString(rates[1].low,Digits()));printf(TimeToString(rates[1].time));}(3)获取系统指标值voidOnStart(){doublebuffer[];ArraySetAsSeries(buffer,true);// 获取MA指标句柄intma_h=iMA(NULL,PERIOD_CURRENT,10,0,MODE_SMA,PRICE_CLOSE);CopyBuffer(ma_h,0,0,10,buffer);printf(DoubleToString(buffer[0],Digits()));}(4)一根K线只开一个单这里只演示开多单。datetime ot;intOnInit(){return(INIT_SUCCEEDED);}voidOnDeinit(constintreason){}voidOnTick(){datetime t[];ArraySetAsSeries(t,true);CopyTime(NULL,PERIOD_CURRENT,0,2,t);if(ot!=t[0]){// 结构体初始化,所有参数数字填充 0,字符串填充 NULL。MqlTradeRequest request={};MqlTradeResult result={};request.action=TRADE_ACTION_DEAL;// 交易操作类型request.symbol=Symbol();// 交易品种request.volume=0.01;// 0.01手交易量request.type=ORDER_TYPE_BUY;// 订单类型request.price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);// 持仓价格request.deviation=100;// 允许滑点数request.magic=123;// 订单幻数request.type_filling=ORDER_FILLING_IOC;// ICMarkets 只支持该方式if(OrderSend(request,result))// 执行交易操作操作{Print(result.deal);// 交易成功后,返回订单号码}ot=t[0];}}(5)获取市价单信息方法一(推荐):voidOnStart(){intpt=PositionsTotal();// 获取市价单总数for(inti=0;ipt;i++){// PositionGetTicket()不仅会获取订单号,还有预选功能// 订单被预选后,才能进行后续操作// PositionGetTicket()获取失败,则返回0// PositionGetTicket()的参数为索引值,顺序是按时间从过去到现在if(PositionGetTicket(i)0){// PositionGetTicket()预选后,方可使用PositionGetDouble()函数doubleop=PositionGetDouble(POSITION_PRICE_OPEN);Print(op);}}}方法二:voidOnStart(){// PositionSelect()为预选订单,通常是选择最早开立的订单if(PositionSelect(Symbol())==true){doubleop=PositionGetDouble(POSITION_PRICE_OPEN);Print(op);}}(6)获取挂单信息方法一(推荐):voidOnStart(){intordertotal=OrdersTotal();for(inti=0;iordertotal;i++){if(OrderGetTicket(i)0){doubleop=OrderGetDouble(ORDER_PRICE_OPEN);Print(op);}}}方法二:void

相关新闻