// MT4交易函数常量定义#defineOP_BUY0//Buy #defineOP_SELL1//Sell #defineOP_BUYLIMIT2//Pending order of BUY LIMIT type #defineOP_SELLLIMIT3//Pending order of SELL LIMIT type #defineOP_BUYSTOP4//Pending order of BUY STOP type #defineOP_SELLSTOP5//Pending order of SELL STOP type //+------------------------------------------------------------------+//| MT4交易函数原型在MT5上的实现 |//+------------------------------------------------------------------+intOrderSendMQL4(string symbol,// symbol int cmd,// operation double volume,// volume double price,// price int slippage,// slippage double sl,// stop loss double tp,// take profit
string comment=NULL,// comment int magic=0,// magic number
datetime expiration=0,// pending order expiration
color arrow_color=clrNONE)export// color {
MqlTradeRequest request ={};
MqlTradeResult result ={};
request.action = TRADE_ACTION_DEAL;//if(cmd == OP_BUY)
request.type = ORDER_TYPE_BUY;if(cmd == OP_SELL)
request.type = ORDER_TYPE_SELL;if(cmd == OP_BUYLIMIT)
request.type = ORDER_TYPE_BUY_LIMIT;if(cmd == OP_SELLLIMIT)
request.type = ORDER_TYPE_SELL_LIMIT;if(cmd == OP_BUYSTOP)
request.type = ORDER_TYPE_BUY_STOP;if(cmd == OP_SELLSTOP)
request.type = ORDER_TYPE_SELL_STOP;
request.magic = magic;//
request.symbol = symbol;//
request.volume = volume;//
request.sl = sl;// Stop Loss
request.tp = tp;// Take Profit
request.price = price;//
request.deviation = slippage;//
request.comment = comment;//
request.expiration = expiration;//// 检查订单填充if(!FillingCheck(symbol, request, result))return(-1);// 检查止损止损盈if(!CheckStopLoss_Takeprofit(request.type, request.price, request.sl, request.tp, symbol))return(0);if(OrderSend(request, result))return((int)result.deal );elsereturn(-1);}//+------------------------------------------------------------------+//| 关闭仓位函数的实现 |//+------------------------------------------------------------------+boolOrderClose(long ticket,double lots,double price,int slippage, color arrow_color=clrNONE)export{//-- 声明交易请求和交易请求结果
MqlTradeRequest request;
MqlTradeResult result;//--- 归零请求和结果值ZeroMemory(request);ZeroMemory(result);// 无法选择仓位订单,或许订单不存在if(PositionSelectByTicket(ticket))return(false);
ENUM_POSITION_TYPE pos_type =(ENUM_POSITION_TYPE)::PositionGetInteger(POSITION_TYPE);//--- 根据持仓类型设置价格和订单类型 if(pos_type == POSITION_TYPE_BUY){
request.price =SymbolInfoDouble(request.symbol, SYMBOL_BID);
request.type = ORDER_TYPE_SELL;}elseif(pos_type == POSITION_TYPE_SELL){
request.price =SymbolInfoDouble(request.symbol, SYMBOL_ASK);
request.type = ORDER_TYPE_BUY;}double volume =::PositionGetDouble(POSITION_VOLUME);// 成交量
request.action = TRADE_ACTION_DEAL;// 交易操作类型
request.position = ticket;// 仓位ID
request.symbol =::PositionGetString(POSITION_SYMBOL);// 交易品种
request.volume = volume<=lots ? volume: lots;// 持仓交易量
request.deviation = slippage;// 允许价格偏差//if(!FillingCheck(request.symbol, request, result))return(false);//--- 发送请求if(!OrderSend(request, result)){PrintFormat("OrderSend error %d",GetLastError());PrintFormat("retcode=%u deal=%I64u order=%I64u", result.retcode, result.deal, result.order);return(false);}// 如果不能发送请求,输出错误代码return(true);}//+------------------------------------------------------------------+//| 删除挂单函数的实现 |//+------------------------------------------------------------------+boolOrderDelete(long ticket, color arrow_color=clrNONE)export{
MqlTradeRequest request;
MqlTradeResult result;//--- 归零请求和结果值ZeroMemory(request);ZeroMemory(result);// 如果挂单不存在,直接返回if(!OrderSelect(ticket))return(false);//
request.action = TRADE_ACTION_REMOVE;
request.order = ticket;if(!OrderSend(request, result)){PrintFormat("OrderSend error %d",GetLastError());PrintFormat("retcode=%u deal=%I64u order=%I64u", result.retcode, result.deal, result.order);return(false);}//return(true);}//+------------------------------------------------------------------+//| 订单填充的检查,无此函数检查,MT5发送订单可能会报错 |//+------------------------------------------------------------------+boolFillingCheck(const string symbol, MqlTradeRequest &request, MqlTradeResult &result){
ENUM_ORDER_TYPE_FILLING type_filling = ORDER_FILLING_FOK;//--- get execution mode of orders by symbol
ENUM_SYMBOL_TRADE_EXECUTION exec=(ENUM_SYMBOL_TRADE_EXECUTION)SymbolInfoInteger(symbol,SYMBOL_TRADE_EXEMODE);//--- check execution modeif(exec==SYMBOL_TRADE_EXECUTION_REQUEST || exec==SYMBOL_TRADE_EXECUTION_INSTANT){//--- neccessary filling type will be placed automaticallyreturn(true);}//--- get possible filling policy types by symbol
uint filling=(uint)SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE);//--- check execution mode againif(exec==SYMBOL_TRADE_EXECUTION_MARKET){//--- for the MARKET execution mode//--- analyze orderif(request.action!=TRADE_ACTION_PENDING){//--- in case of instant execution order//--- if the required filling policy is supported, add it to the requestif((filling&SYMBOL_FILLING_FOK)==SYMBOL_FILLING_FOK){
type_filling=ORDER_FILLING_FOK;
request.type_filling=type_filling;return(true);}if((filling&SYMBOL_FILLING_IOC)==SYMBOL_FILLING_IOC){
type_filling=ORDER_FILLING_IOC;
request.type_filling=type_filling;return(true);}//--- wrong filling policy, set error code
result.retcode=TRADE_RETCODE_INVALID_FILL;return(false);}return(true);}//--- EXCHANGE execution modeswitch(type_filling){case ORDER_FILLING_FOK://--- analyze orderif(request.action==TRADE_ACTION_PENDING){//--- in case of pending order//--- add the expiration mode to the requestif(!ExpirationCheck(symbol, request))
request.type_time=ORDER_TIME_DAY;//--- stop order?if(request.type==ORDER_TYPE_BUY_STOP || request.type==ORDER_TYPE_SELL_STOP ||
request.type==ORDER_TYPE_BUY_LIMIT || request.type==ORDER_TYPE_SELL_LIMIT){//--- in case of stop order//--- add the corresponding filling policy to the request
request.type_filling=ORDER_FILLING_RETURN;return(true);}}//--- in case of limit order or instant execution order//--- if the required filling policy is supported, add it to the requestif((filling&SYMBOL_FILLING_FOK)==SYMBOL_FILLING_FOK){
request.type_filling=type_filling;return(true);}//--- wrong filling policy, set error code
result.retcode=TRADE_RETCODE_INVALID_FILL;return(false);case ORDER_FILLING_IOC://--- analyze orderif(request.action==TRADE_ACTION_PENDING){//--- in case of pending order//--- add the expiration mode to the requestif(!ExpirationCheck(symbol, request))
request.type_time=ORDER_TIME_DAY;//--- stop order?if(request.type==ORDER_TYPE_BUY_STOP || request.type==ORDER_TYPE_SELL_STOP ||
request.type==ORDER_TYPE_BUY_LIMIT || request.type==ORDER_TYPE_SELL_LIMIT){//--- in case of stop order//--- add the corresponding filling policy to the request
request.type_filling=ORDER_FILLING_RETURN;return(true);}}//--- in case of limit order or instant execution order//--- if the required filling policy is supported, add it to the requestif((filling&SYMBOL_FILLING_IOC)==SYMBOL_FILLING_IOC){
request.type_filling=type_filling;return(true);}//--- wrong filling policy, set error code
result.retcode=TRADE_RETCODE_INVALID_FILL;return(false);case ORDER_FILLING_RETURN://--- add filling policy to the request
request.type_filling=type_filling;return(true);}//--- unknown execution mode, set error code
result.retcode=TRADE_RETCODE_ERROR;return(false);}//+------------------------------------------------------------------+//| 检查止损和止盈的正确性 |//+------------------------------------------------------------------+boolCheckStopLoss_Takeprofit(ENUM_ORDER_TYPE type,double price,double SL,double TP, string symbol=NULL)export{if(symbol ==NULL) symbol = _Symbol;//--- get the SYMBOL_TRADE_STOPS_LEVEL levelint stops_level=(int)SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL);if(stops_level!=0){PrintFormat("SYMBOL_TRADE_STOPS_LEVEL=%d: StopLoss and TakeProfit must"+" not be nearer than %d points from the closing price",stops_level,stops_level);}//---bool SL_check=false,TP_check=false;double bid =::SymbolInfoDouble(symbol, SYMBOL_BID);double ask =::SymbolInfoDouble(symbol, SYMBOL_ASK);double point =::SymbolInfoDouble(symbol, SYMBOL_POINT);//--- check the order typeswitch(type){//--- Buy operationcase ORDER_TYPE_BUY:{//--- check the StopLossif(SL !=0)
SL_check=(bid-SL>stops_level*point);else
SL_check =true;if(!SL_check)PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+" (Bid=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),SL,bid-stops_level*point,bid,stops_level);//--- check the TakeProfitif(TP !=0)
TP_check =(TP-bid>stops_level*point);else
TP_check =true;if(!TP_check)PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+" (Bid=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),TP,bid+stops_level*point,bid,stops_level);//--- return the result of checkingreturn(SL_check&&TP_check);}//--- Sell operationcase ORDER_TYPE_SELL:{//--- check the StopLossif(SL !=0)
SL_check=(SL-SymbolInfoDouble(symbol,SYMBOL_ASK)>stops_level*point);else
SL_check =true;if(!SL_check)PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+" (Ask=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),SL,ask+stops_level*point,ask,stops_level);//--- check the TakeProfitif(TP !=0)
TP_check=(ask-TP>stops_level*point);else
TP_check =true;if(!TP_check)PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+" (Ask=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),TP,ask-stops_level*point,ask,stops_level);//--- return the result of checkingreturn(TP_check&&SL_check);}break;//--- BuyLimit pending ordercase ORDER_TYPE_BUY_LIMIT:{//--- check the StopLossif(SL !=0)
SL_check=((price-SL)>stops_level*point);else
SL_check =true;if(!SL_check)PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+" (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),SL,price-stops_level*point,(int)((price-SL)/point),stops_level);//--- check the TakeProfitif(TP !=0)
TP_check=((TP-price)>stops_level*point);else
TP_check =true;if(!TP_check)PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+" (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),TP,price+stops_level*point,(int)((TP-price)/point),stops_level);//--- return the result of checkingreturn(SL_check&&TP_check);}//--- SellLimit pending ordercase ORDER_TYPE_SELL_LIMIT:{//--- check the StopLossif(SL !=0)
SL_check=((SL-price)>stops_level*point);else
SL_check =true;if(!SL_check)PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+" (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),SL,price+stops_level*point,(int)((SL-price)/point),stops_level);//--- check the TakeProfitif(TP!=0)
TP_check=((price-TP)>stops_level*point);else
TP_check =true;if(!TP_check)PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+" (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),TP,price-stops_level*point,(int)((price-TP)/point),stops_level);//--- return the result of checkingreturn(TP_check&&SL_check);}break;//--- BuyStop pending ordercase ORDER_TYPE_BUY_STOP:{//--- check the StopLossif(SL !=0)
SL_check=((price-SL)>stops_level*point);else
SL_check =true;if(!SL_check)PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+" (Open-StopLoss=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),SL,price-stops_level*point,(int)((price-SL)/point),stops_level);//--- check the TakeProfitif(TP!=0)
TP_check=((TP-price)>stops_level*point);else
TP_check =true;if(!TP_check)PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+" (TakeProfit-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),TP,price-stops_level*point,(int)((TP-price)/point),stops_level);//--- return the result of checkingreturn(SL_check&&TP_check);}//--- SellStop pending ordercase ORDER_TYPE_SELL_STOP:{//--- check the StopLossif(SL !=0)
SL_check=((SL-price)>stops_level*point);else
SL_check =true;if(!SL_check)PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f"+" (StopLoss-Open=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),SL,price+stops_level*point,(int)((SL-price)/point),stops_level);//--- check the TakeProfitif(TP !=0)
TP_check=((price-TP)>stops_level*point);else
TP_check =true;if(!TP_check)PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f"+" (Open-TakeProfit=%d points ==> SYMBOL_TRADE_STOPS_LEVEL=%d points)",EnumToString(type),TP,price-stops_level*point,(int)((price-TP)/point),stops_level);//--- return the result of checkingreturn(TP_check&&SL_check);}break;}//---returnfalse;}//+------------------------------------------------------------------+//| 检查挂起订单的到期类型 |//+------------------------------------------------------------------+boolExpirationCheck(const string symbol, MqlTradeRequest &request)export{//--- check symbol
string symbol_name=(symbol==NULL)? _Symbol : symbol;//--- get flagslong tmp_long;int flags=0;if(SymbolInfoInteger(symbol_name,SYMBOL_EXPIRATION_MODE,tmp_long))
flags=(int)tmp_long;//--- check typeswitch(request.type_time){case ORDER_TIME_GTC:if((flags&SYMBOL_EXPIRATION_GTC)!=0)return(true);break;case ORDER_TIME_DAY:if((flags&SYMBOL_EXPIRATION_DAY)!=0)return(true);break;case ORDER_TIME_SPECIFIED:if((flags&SYMBOL_EXPIRATION_SPECIFIED)!=0)return(true);break;case ORDER_TIME_SPECIFIED_DAY:if((flags&SYMBOL_EXPIRATION_SPECIFIED_DAY)!=0)return(true);break;default:Print(__FUNCTION__+": Unknown expiration type");}//--- failedreturn(false);}