2017/4/30
一.常用交易函数封装
1.6种挂单类型
1.1.limit是亏损方向
buy limit
sell limit
1.2.stop是盈利方向
buy stop
sell stop
1.3.buy stop limit 先突破盈利方向 在回调
sell stop limit
2.交易类实现
//+------------------------------------------------------------------+
//| Trade.mqh |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class Trade
{
private:
public:
//slPoint = stop loss point止损点,tpPoint = take profit Point止盈点
int buy(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
int buyPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
//买入挂单
int buyPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
int buyPendingOrderPlus(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
//买入stop limit
int buyPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
int buyPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
int sell(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
int sellPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
//卖出挂单
int sellPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
int sellPendingOrderPlus(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
//卖出stop limit
int sellPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
int sellPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
void closeAllBuy(string symbol,int magic=0);
void closeAllSell(string symbol,int magic=0);
void closeALLBuyAndSell(string symbol,int magic=0);
void mofiyStoplossAndTakeProfit(string symbol,ENUM_POSITION_TYPE type,double sl,double tp,int magic=0);
//修改挂单止盈止损
void modifyPendingOrderStoplossAndTakeProfit(string symbol,ENUM_ORDER_TYPE type,double pendingPrice,double limitPrice,double sl,double tp,int magic=0);
void deleteAllPendingOrders(string symbol,int magic);
//获取指定类型的持仓单数量
int getPositionNum(string symbol,ENUM_POSITION_TYPE type,int magic=0);
int getAllPositionNum(string symbol,int magic=0);
//获取指定类型订单累计盈利总额
double profit(string symbol,ENUM_POSITION_TYPE type,int magic=0);
//所有订单累计盈利总额
double profitall(string symbol,int magic=0);
//获取格式化单量(平台允许的最接近单量)
double formatLots(string symbol,double lots);
//下百分比的单量
double percentLots(ENUM_ORDER_TYPE action,string symbol,int percent);
//获取最新的持仓单单号
int getNewestPositionOrder(string symbol,ENUM_POSITION_TYPE type,double &openprice,datetime &opentime,double &openlots,double &opensl,double &opentp,int magic=0);
//盈亏平衡点(等于这个点位BEP,就刚好不赚不亏)
double breakEvenPointPrice(string symbol,ENUM_POSITION_TYPE type,int magic=0);
//移动止损(trailingPoint:移动点)
void trailingStop(int trailingPoint,string symbol,ENUM_POSITION_TYPE type,int magic=0);
//获取最近的交易类型历史订单
void getLastDealsHistory(string symbol,ENUM_DEAL_TYPE type,double &deal_price,datetime &deal_time,double &lots,int magic=0);
//当前货币对小数点位数
int digits(string symbol);
Trade();
~Trade();
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
Trade::Trade()
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
Trade::~Trade()
{
}
//+------------------------------------------------------------------+
//slPoint = stop loss point止损点,tpPoint = take profit Point止盈点
int Trade::buy(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
//市价单
request.action=TRADE_ACTION_DEAL;
request.magic=magic;
request.symbol=symbol;
request.volume=lots;
request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.sl=SymbolInfoDouble(symbol,SYMBOL_ASK)-slPoint*Point();
}
if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.tp=SymbolInfoDouble(symbol,SYMBOL_ASK)+tpPoint*Point();
}
//滑点
request.deviation=100;
//多单
request.type=ORDER_TYPE_BUY;
request.comment=comment;
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
return(result.order);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::buyPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
int a=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && PositionGetInteger(POSITION_MAGIC)==magic && PositionGetString(POSITION_COMMENT)==comment)
{
//不开单
a=1;
return(0);
}
}
}
if(a==0)
{
a=buy(symbol,lots,slPoint,tpPoint,comment,magic);
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::buyPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
pendingPrice=NormalizeDouble(pendingPrice,Digits());
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_PENDING;
request.magic=magic;
request.symbol=symbol;
request.volume=lots;
request.price=pendingPrice;
request.sl=pendingPrice-slPoint*Point();
request.tp=pendingPrice+tpPoint*Point();
request.deviation=100;
double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
if(pendingPrice>ask)
{
request.type=ORDER_TYPE_BUY_STOP;
}
if(pendingPrice<ask)
{
request.type=ORDER_TYPE_BUY_LIMIT;
}
request.comment=comment;
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
return(result.order);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::buyPendingOrderPlus(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
int a=0;
int t=OrdersTotal();
for(int i=t-1;i>=0;i--)
{
if(OrderGetTicket(i)>0)
{
if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT || OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
{
a=1;
return(0);
}
}
}
if(a==0)
{
a=buyPendingOrder(pendingPrice,symbol,lots,slPoint,tpPoint,comment,magic);
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::buyPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
stopPrice=NormalizeDouble(stopPrice,Digits());
limitPrice=NormalizeDouble(limitPrice,Digits());
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_PENDING;
request.type=ORDER_TYPE_BUY_STOP_LIMIT;
request.symbol=symbol;
double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
if(stopPrice<=ask)
{
Alert("stopPrice必须大于市价");
return(0);
}
if(limitPrice>=stopPrice)
{
Alert("limitprice必须小于stopprice");
return(0);
}
request.volume=lots;
request.deviation=100;
request.price=stopPrice;
request.stoplimit=limitPrice;
if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.sl=limitPrice-slPoint*Point();
}
if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.tp=limitPrice+tpPoint*Point();
}
request.comment=comment;
request.magic=magic;
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
return(result.order);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::buyPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
int a=0;
int t=OrdersTotal();
for(int i=t-1;i>=0;i--)
{
if(OrderGetTicket(i)>0)
{
if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP_LIMIT) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
{
//不开挂单
a=1;
return(0);
}
}
}
if(a==0)
{
a=buyPendingStoplimitOrder(stopPrice,limitPrice,symbol,lots,slPoint,tpPoint,comment,magic);
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::sell(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
//市价单
request.action=TRADE_ACTION_DEAL;
request.magic=magic;
request.symbol=symbol;
request.volume=lots;
request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.sl=SymbolInfoDouble(symbol,SYMBOL_BID)+slPoint*Point();
}
if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.tp=SymbolInfoDouble(symbol,SYMBOL_BID)-tpPoint*Point();
}
//滑点
request.deviation=100;
//空单
request.type=ORDER_TYPE_SELL;
request.comment=comment;
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
//--- 操作信息
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
return(result.order);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::sellPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
int a=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && PositionGetInteger(POSITION_MAGIC)==magic && PositionGetString(POSITION_COMMENT)==comment)
{
//不开单
a=1;
return(0);
}
}
}
if(a==0)
{
a=sell(symbol,lots,slPoint,tpPoint,comment,magic);
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::sellPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
pendingPrice=NormalizeDouble(pendingPrice,Digits());
MqlTradeRequest request={0};
MqlTradeResult result={0};
//市价单
request.action=TRADE_ACTION_PENDING;
request.magic=magic;
request.symbol=symbol;
request.volume=lots;
request.price=pendingPrice;
request.sl=pendingPrice+slPoint*Point();
request.tp=pendingPrice-tpPoint*Point();
//滑点
request.deviation=100;
//空单
double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
if(pendingPrice<bid)
{
request.type=ORDER_TYPE_SELL_STOP;
}
if(pendingPrice>bid)
{
request.type=ORDER_TYPE_SELL_LIMIT;
}
request.comment=comment;
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
return(result.order);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::sellPendingOrderPlus(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
int a=0;
int t=OrdersTotal();
for(int i=t-1;i>=0;i--)
{
if(OrderGetTicket(i)>0)
{
if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT || OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
{
//不开挂单
a=1;
return(0);
}
}
}
if(a==0)
{
a=sellPendingOrder(pendingPrice,symbol,lots,slPoint,tpPoint,comment,magic);
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::sellPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
stopPrice=NormalizeDouble(stopPrice,Digits());
limitPrice=NormalizeDouble(limitPrice,Digits());
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_PENDING;
request.type=ORDER_TYPE_SELL_STOP_LIMIT;
request.symbol=symbol;
double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
if(stopPrice>=bid)
{
Alert("stopPrice必须小于市价");
return(0);
}
if(limitPrice<=stopPrice)
{
Alert("limitprice必须大于stopprice");
return(0);
}
request.volume=lots;
//滑点
request.deviation=100;
request.price=stopPrice;
request.stoplimit=limitPrice;
if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.sl=limitPrice+slPoint*Point();
}
if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
{
request.tp=limitPrice-tpPoint*Point();
}
request.comment=comment;
request.magic=magic;
//--- 发送请求
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误代码
return(result.order);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Trade::sellPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
{
int a=0;
int t=OrdersTotal();
for(int i=t-1;i>=0;i--)
{
if(OrderGetTicket(i)>0)
{
if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP_LIMIT) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
{
//不开挂单
a=1;
return(0);
}
}
}
if(a==0)
{
a=sellPendingStoplimitOrder(stopPrice,limitPrice,symbol,lots,slPoint,tpPoint,comment,magic);
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trade::closeAllBuy(string symbol,int magic=0)
{
//持仓单遍历
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
//选择持仓单
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
bool needClose=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needClose=true;
}
if(needClose)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_DEAL; // 交易操作类型
request.symbol=symbol; // 交易品种
request.volume=PositionGetDouble(POSITION_VOLUME); //交易量
request.type=ORDER_TYPE_SELL; //订单类型
request.price=SymbolInfoDouble(symbol,SYMBOL_BID); // 持仓价格
request.deviation=100;//滑点
request.position=PositionGetTicket(i);//平仓最好都写下,不然和sell一样了。
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trade::closeAllSell(string symbol,int magic=0)
{
//持仓单遍历
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
//选择持仓单
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
bool needClose=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needClose=true;
}
if(needClose)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_DEAL; // 交易操作类型
request.symbol=symbol; // 交易品种
request.volume=PositionGetDouble(POSITION_VOLUME); // 交易量
request.type=ORDER_TYPE_BUY; // 订单类型
request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); // 持仓价格
request.deviation=100; //滑点
request.position =PositionGetTicket(i);
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trade::closeALLBuyAndSell(string symbol,int magic=0)
{
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
bool needClose=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needClose=true;
}
if(needClose)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_DEAL; // 交易操作类型
request.symbol=symbol; // 交易品种
request.volume=PositionGetDouble(POSITION_VOLUME); // 交易量
request.type=ORDER_TYPE_SELL; // 订单类型
request.price=SymbolInfoDouble(symbol,SYMBOL_BID); // 持仓价格
request.deviation=100; //滑点
request.position =PositionGetTicket(i);
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误
}
}
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
bool needClose=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needClose=true;
}
if(needClose)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_DEAL; // 交易操作类型
request.symbol=symbol; // 交易品种
request.volume=PositionGetDouble(POSITION_VOLUME); // 交易量
request.type=ORDER_TYPE_BUY; // 订单类型
request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); // 持仓价格
request.deviation=100; //滑点
request.position =PositionGetTicket(i);
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // 如果不能发送请求,输出错误
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//修改止盈止损
void Trade::mofiyStoplossAndTakeProfit(string symbol,ENUM_POSITION_TYPE type,double sl,double tp,int magic=0)
{
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol)
{
double old_sl=NormalizeDouble(PositionGetDouble(POSITION_SL),digits(symbol));
double old_tp=NormalizeDouble(PositionGetDouble(POSITION_TP),digits(symbol));
double new_sl=NormalizeDouble(sl,digits(symbol));
double new_tp=NormalizeDouble(sl,digits(symbol));
//PrintFormat("buysell:old_sl=%lf,old_tp=%lf,new_sl=%lf,new_tp=%lf",old_sl,old_tp,new_sl,new_tp);
if(type==POSITION_TYPE_BUY)
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
//Modify Stop Loss and Take Profit values of an opened position
request.action=TRADE_ACTION_SLTP;
// Position ticket
request.position=PositionGetTicket(i);
request.symbol=symbol;
if(sl>0 && new_sl!=old_sl) request.sl=new_sl;
if(tp>0 && new_tp!=old_tp) request.tp=new_tp;
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
}
}
if(type==POSITION_TYPE_SELL)
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_SLTP;
request.position=PositionGetTicket(i);
request.symbol=symbol;
if(sl>0 && new_sl!=old_sl) request.sl=new_sl;
if(tp>0 && new_tp!=old_tp) request.tp=new_tp;
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trade::modifyPendingOrderStoplossAndTakeProfit(string symbol,ENUM_ORDER_TYPE type,double pendingPrice,double limitPrice,double sl,double tp,int magic=0)
{
int t=OrdersTotal();
for(int i=t-1;i>=0;i--)
{
if(OrderGetTicket(i)>0)
{
if(OrderGetString(ORDER_SYMBOL)==symbol)
{
//1.stop 和 limit类型
if(type==ORDER_TYPE_BUY_LIMIT || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_SELL_LIMIT || type==ORDER_TYPE_SELL_STOP)
{
bool needAction=false;
if(magic==0 || OrderGetInteger(ORDER_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
//Modify Stop Loss and Take Profit values of an opened position
request.action=TRADE_ACTION_MODIFY;
request.type=type;
// Position ticket
request.order=OrderGetTicket(i);
request.symbol=symbol;
if(sl>0)request.sl=NormalizeDouble(sl,digits(symbol));
if(tp>0)request.tp=NormalizeDouble(tp,digits(symbol));
if(pendingPrice!=0)
{
request.price=NormalizeDouble(pendingPrice,Digits());
}
if(sl<0) request.sl=NormalizeDouble(OrderGetDouble(ORDER_SL),digits(symbol));
if(tp<0) request.tp=NormalizeDouble(OrderGetDouble(ORDER_TP),digits(symbol));
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
}
}
//2.stoplimit类型
if(type==ORDER_TYPE_BUY_STOP_LIMIT || type==ORDER_TYPE_SELL_STOP_LIMIT)
{
bool needAction=false;
if(magic==0 || OrderGetInteger(ORDER_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
//Modify Stop Loss and Take Profit values of an opened position
request.action=TRADE_ACTION_MODIFY;
request.type=type;
// Position ticket
request.order=OrderGetTicket(i);
request.symbol=symbol;
if(sl>0)request.sl=NormalizeDouble(sl,digits(symbol));
if(tp>0)request.tp=NormalizeDouble(tp,digits(symbol));
if(pendingPrice!=0)
{
request.price=NormalizeDouble(pendingPrice,Digits());
}
if(limitPrice!=0)
{
request.stoplimit=NormalizeDouble(limitPrice,Digits());
}
if(sl<0) request.sl=NormalizeDouble(OrderGetDouble(ORDER_SL),digits(symbol));
if(tp<0) request.tp=NormalizeDouble(OrderGetDouble(ORDER_TP),digits(symbol));
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
}
}
}
}
}
}
//删除所有挂单
void Trade::deleteAllPendingOrders(string symbol,int magic)
{
int t=OrdersTotal();
for(int i=t-1;i>=0;i--)
{
if(OrderGetTicket(i)>0)
{
if(OrderGetString(ORDER_SYMBOL)==symbol)
{
bool needAction=false;
if(magic==0 || OrderGetInteger(ORDER_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
//Delete the pending order placed previously
request.action=TRADE_ACTION_REMOVE;
request.order=OrderGetTicket(i);
request.symbol=symbol;
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
}
}
}
}
}
//+------------------------------------------------------------------+
int Trade::getPositionNum(string symbol,ENUM_POSITION_TYPE type,int magic=0)
{
int a=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
a++;
}
}
}
}
return(a);
}
//+------------------------------------------------------------------+
int Trade::getAllPositionNum(string symbol,int magic=0)
{
int a=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL))
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
a++;
}
}
}
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double Trade::profit(string symbol,ENUM_POSITION_TYPE type,int magic=0)
{
double a=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
a=a+PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
}
}
}
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double Trade::profitall(string symbol,int magic=0)
{
double a=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL))
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
a=a+PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
}
}
}
}
return(a);
}
//+------------------------------------------------------------------+
double Trade::formatLots(string symbol,double lots)
{
double a=0;
double miniLots=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
double stepLots=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
if(lots<miniLots) return(0);
else
{
//The function returns integer numeric value closest from below.
double a1=MathFloor(lots/miniLots)*miniLots;
a=a1+MathFloor((lots-a1)/stepLots)*stepLots;
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double Trade::percentLots(ENUM_ORDER_TYPE action,string symbol,int percent)
{
double marg=0;
OrderCalcMargin(action,symbol,1,SymbolInfoDouble(symbol,SYMBOL_BID),marg);
//a marg/总钱数*percent
double a=0;
return(formatLots(symbol,a));
}
//+------------------------------------------------------------------+
int Trade::getNewestPositionOrder(string symbol,ENUM_POSITION_TYPE type,double &openPrice,datetime &openTime,double &openLots,double &openStopLoss,double &openTakeProfit,int magic=0)
{
openPrice=0;
openTime=0;
openLots=0;
openStopLoss=0;
openTakeProfit=0;
int ticket=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
openPrice=PositionGetDouble(POSITION_PRICE_OPEN);
openTime=PositionGetInteger(POSITION_TIME);
openLots=PositionGetDouble(POSITION_VOLUME);
openStopLoss=PositionGetDouble(POSITION_SL);
openTakeProfit=PositionGetDouble(POSITION_TP);
ticket=PositionGetInteger(POSITION_TICKET);
break;
}
}
}
}
return(ticket);
}
//+------------------------------------------------------------------+
double Trade::breakEvenPointPrice(string symbol,ENUM_POSITION_TYPE type,int magic=0)
{
double a=0;
double totalLots=0;
double sum=0;
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
totalLots=totalLots+PositionGetDouble(POSITION_VOLUME);
sum=sum+PositionGetDouble(POSITION_VOLUME)*PositionGetDouble(POSITION_PRICE_OPEN);
}
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
totalLots=totalLots-PositionGetDouble(POSITION_VOLUME);
sum=sum-PositionGetDouble(POSITION_VOLUME)*PositionGetDouble(POSITION_PRICE_OPEN);
}
}
}
}
}
if((totalLots!=0) && (sum!=0))
{
a=NormalizeDouble(sum/totalLots,SymbolInfoInteger(symbol,SYMBOL_DIGITS));
}
else
{
a=0;
}
return(a);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trade::trailingStop(int trailingPoint,string symbol,ENUM_POSITION_TYPE type,int magic=0)
{
int t=PositionsTotal();
for(int i=t-1;i>=0;i--)
{
if(PositionGetTicket(i)>0)
{
if(PositionGetString(POSITION_SYMBOL)==symbol)
{
double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
double openPrice=PositionGetDouble(POSITION_PRICE_OPEN);
double sl=PositionGetDouble(POSITION_SL);
double tp=PositionGetDouble(POSITION_TP);
if(type==POSITION_TYPE_BUY)
{
if((bid-openPrice)>=point*trailingPoint && (sl<(bid-point*trailingPoint) || (sl==0)))
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_SLTP;
request.position=PositionGetTicket(i);
request.symbol=symbol;
request.sl=bid-point*trailingPoint;
request.tp=tp;
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
}
}
}
if(type==POSITION_TYPE_SELL)
{
if((openPrice-ask)>=point*trailingPoint && ((sl>(ask+point*trailingPoint)) || (sl==0)))
{
bool needAction=false;
if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
{
needAction=true;
}
if(needAction)
{
MqlTradeRequest request={0};
MqlTradeResult result={0};
request.action=TRADE_ACTION_SLTP;
request.position=PositionGetTicket(i);
request.symbol=symbol;
request.sl=ask+point*trailingPoint;
request.tp=tp;
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trade::getLastDealsHistory(string symbol,ENUM_DEAL_TYPE type,double &deal_price,datetime &deal_time,double &lots,int magic=0)
{
//1.一般都要写这个
HistorySelect(0,TimeCurrent());
int dealsTotal=HistoryDealsTotal();
for(int i=dealsTotal-1;i>=0;i--)
{
int deal_ticket=HistoryDealGetTicket(i);
if(deal_ticket>0)
{
if(HistoryDealGetInteger(deal_ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT && HistoryDealGetString(deal_ticket,DEAL_SYMBOL)==symbol && HistoryDealGetInteger(deal_ticket,DEAL_TYPE)==type)
{
if(magic==0)
{
deal_time=HistoryDealGetInteger(deal_ticket,DEAL_TIME);
lots=HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
deal_price=HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
break;
}
else
{
if(HistoryDealGetInteger(deal_ticket,DEAL_MAGIC)==magic)
{
deal_time=HistoryDealGetInteger(deal_ticket,DEAL_TIME);
lots=HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
deal_price=HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
break;
}
}
}
}
}
}
//+------------------------------------------------------------------+
int Trade::digits(string symbol)
{
return SymbolInfoInteger(symbol,SYMBOL_DIGITS);
}
//+------------------------------------------------------------------+
2.1.交易类使用
//+------------------------------------------------------------------+
//| commonUseScript.mq5 |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//显示确认框
#property script_show_confirm
#include <wz\Trade.mqh>
int magic=170430;
Trade td;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnStart()
{
//td.buy(Symbol(),0.1,200,200,"buy",magic);
//td.sell(Symbol(),0.1,200,200,"sell",magic);
//td.closeAllBuy(Symbol());
//td.closeAllSell(Symbol());
//td.closeALLBuyAndSell(Symbol());
//td.mofiyStoplossAndTakeProfit(Symbol(),POSITION_TYPE_BUY,1.00,1.19);
//td.deleteAllPendingOrders(Symbol());
//double lots=td.formatLots(Symbol(),1.23456);
double openPrice=0;
datetime openTime=0;
double openLots=0;
double openStopLoss=0;
double openTakeProfit=0;
int ticket=td.getNewestPositionOrder(Symbol(),POSITION_TYPE_SELL,openPrice,openTime,openLots,openStopLoss,openTakeProfit);
}
//+------------------------------------------------------------------+
如果您发现本文对你有所帮助,如果您认为其他人也可能受益,请把它分享出去。
网友评论