【MT5】获取当日内(按服务器时间)的盈亏额

 
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      ""
#property version   "1.00"

datetime  Today0S;
//+------------------------------------------------------------------+
int OnInit()
  {
   Today0S=iTime(_Symbol,PERIOD_D1,0);


//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
void OnTick()
  {
   if(iTime(_Symbol,PERIOD_D1,0)!=Today0S)  { Today0S=iTime(_Symbol,PERIOD_D1,0); Sleep(200); }

   int     cnt,m,n,r=0,k=0,j=0;
   ulong   ticket;
   string  PiT[50]={""};   // 此时持仓品种  【 此时持仓不超过  50个单哟 】
   string  PiH[250]={""};  // 今日平仓品种  【 当日平仓不超过 250个单哟 】
   string  PTH[300]={""};  // 合并平、持品种
   string  Pin[300]={""};  // 整理后的今日平、持的交易品种
   double  DayYK=0;        // 今日盈亏
   for(cnt=PositionsTotal()-1;cnt>=0;cnt--)
     {
      if(PositionGetSymbol(cnt)!="")
        {
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL || PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
         PiT[r]=PositionGetString(POSITION_SYMBOL); r++;
        }
     }
   for(cnt=HistoryDealsTotal()-1;cnt>=0;cnt--)
     {
      if((ticket=HistoryDealGetTicket(cnt))>0)
        {
         if(HistoryDealGetInteger(ticket,DEAL_TIME)>=Today0S && (HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_SELL || HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_BUY))
           {
            PiH[k]=HistoryDealGetString(ticket,DEAL_SYMBOL); k++;
           }
        }
     }

   // 合并到临时新数组,并修改重复的元素值为空 
   if(r>0)  ArrayCopy(PTH,PiT,0,0,r);
   if(k>0)  ArrayCopy(PTH,PiH,r,0,k);
   for(m=0;m<r+k;m++)
     {
      for(n=r+k-1;n>m;n--)              // 对后面每个元素比较
        {
         if(PTH[n]==PTH[m])  PTH[n]=""; // 发现重复元素 修改赋值为空
        }
     }
   // 存放到 今日平、持的交易品种数组
   for(cnt=0;cnt<r+k;cnt++)
     {
      if(PTH[cnt]!="")                  // 若不为空值
        {
         Pin[j]=PTH[cnt];j++;           // 存放且计数
        }
     }
   // 使用品种数组求相关累值
   for(cnt=0;cnt<j;cnt++)  DayYK=DayYK+TodayYK(Pin[cnt]);



//---
  }





//============================================================================================================================= 
// 获取该品当日内(按服务器时间)自零点至此时的盈亏额   [ 注:此值非准确精度数值 ]
double TodayYK(string pm)
  {
   string   nam=pm;  if(pm=="") nam=Symbol();
   int      i,Spr=0;
   double   Chi_YK=0, PingYK=0, today_YK=0, Cpr=iClose(nam,PERIOD_D1,1);
   double   Poi=SymbolInfoDouble(nam,SYMBOL_POINT),YDE=SymbolInfoDouble(nam,SYMBOL_TRADE_TICK_VALUE);
   // 收盘价为当时的Bid,属于多单的平仓价。假若空单在收盘时平仓,则空单的平仓价应为: 收盘价+点差Spr*点值 ( 下列计算中,若无持仓了,则忽略,即按0计算 )

   // 第一部分   此时持仓
   double ykc=0,cSwap=0,Bykc=0,Sykc=0;
   for(i=PositionsTotal()-1;i>=0;i--)  // 注: MT5中未平仓的单不显示计算手续费(佣金)
     {
      if(PositionGetSymbol(i)==nam)    // ( 现价单或挂单激活时会新生一个订单号将该笔交易的佣金的一半计入历史数据中,在下列"日内平仓"中佣金累加时会包含此额 )
        {
         ykc=ykc+PositionGetDouble(POSITION_PROFIT);   // 持仓总浮盈(负即浮亏)

         if(PositionGetInteger(POSITION_TIME)<Today0S) // 今日之前下的单
           {
             // 粗略估算隔夜利息于当日的发生额
            int n1=Bars(nam,PERIOD_D1,PositionGetInteger(POSITION_TIME),TimeCurrent());
            if(n1!=0) cSwap=cSwap+PositionGetDouble(POSITION_SWAP)/n1;
             // 粗略估算多单凌晨前的浮盈(亏)额
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
            Bykc=Bykc+(Cpr-PositionGetDouble(POSITION_PRICE_OPEN))/Poi*PositionGetDouble(POSITION_VOLUME)*YDE;
             // 粗略估算空单凌晨前的浮盈(亏)额
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
              {
               Spr=(int)SymbolInfoInteger(nam,SYMBOL_SPREAD);
               Sykc=Sykc+(PositionGetDouble(POSITION_PRICE_OPEN)-(Cpr+Spr*Poi))/Poi*PositionGetDouble(POSITION_VOLUME)*YDE;
              }
           }
        }
     }
   Chi_YK=ykc+cSwap-Bykc-Sykc;

   // 第二部分   日内平仓
   HistorySelect(0,TimeCurrent());
   int      r, x=0;
   double   ykz=0,Yong=0,zSwap=0,Bykz=0,Sykz=0;
   ulong    ticket, Type_D[300]={-1}, Get_ID[300]={0};
   double   Swap_D[300]={0},Lots_D[300]={0};
   for(i=HistoryDealsTotal()-1;i>=0;i--)
     {
      if((ticket=HistoryDealGetTicket(i))>0)
        {
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)==nam &&  HistoryDealGetInteger(ticket,DEAL_TIME)>=Today0S)
           {
            ykz=ykz+HistoryDealGetDouble(ticket,DEAL_PROFIT);       // 浮盈(负即浮亏)

            Yong=Yong+HistoryDealGetDouble(ticket,DEAL_COMMISSION); // 佣金

            //+---------------------------------------------------------------------------------------------------+
            //| MT5历史数据之成交列表中: in为交易开始,与原ORDER订单多空方向一致; out为交易结束即平仓,与原ORDER  |
            //| 订单的多空方向相反。in与out订单号互不一样,但持仓号(原始订单号)一致,即:DEAL_POSITION_ID是一致的。|
            //| 因此,要从DEAR成交列表中准确查询原订单交易开始的时间和盈亏,务必通过DEAL_POSITION_ID来衔接倒推。  |
            //+---------------------------------------------------------------------------------------------------+

            if(HistoryDealGetDouble(ticket,DEAL_SWAP)>0) // 隔夜费大于0则属于非今日新开的单子 ( 隔夜费只列于out型的单的目录下 )
              {
               Get_ID[x]=HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
               Type_D[x]=HistoryDealGetInteger(ticket,DEAL_TYPE);
               Lots_D[x]=HistoryDealGetDouble(ticket,DEAL_VOLUME);
               Swap_D[x]=HistoryDealGetDouble(ticket,DEAL_SWAP);
               x++;
              }
           }
        }
     }
   for(r=0;r<x;r++)
     {
      for(i=HistoryDealsTotal()-1;i>=0;i--)
        {
         if((ticket=HistoryDealGetTicket(i))>0)
           {
            if((HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_IN || HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_INOUT) &&  /* 属in类型 */
                HistoryDealGetInteger(ticket,DEAL_POSITION_ID)==Get_ID[r] )                                                 /* 持仓号即原始订单号 相同 */
              {
               int n2=Bars(nam,PERIOD_D1,HistoryDealGetInteger(ticket,DEAL_TIME),TimeCurrent());
               if(n2!=0) zSwap=zSwap+Swap_D[r]/n2;                      // 分摊隔夜费并循环累加

               if(Type_D[r]==DEAL_TYPE_SELL)//此空则属原多单平仓        // 若属多单 计算并累加上个交易日收盘时的浮盈(亏)额
               Bykz=Bykz+(Cpr-HistoryDealGetDouble(ticket,DEAL_PRICE))/Poi*Lots_D[r]*YDE;

               if(Type_D[r]==DEAL_TYPE_BUY) //此多则属原空单平仓        // 若属空单 计算并累加上个交易日收盘时的浮盈(亏)额
               Sykz=Sykz+(HistoryDealGetDouble(ticket,DEAL_PRICE)-(Cpr+Spr*Poi))/Poi*Lots_D[r]*YDE;
              }
           }
        }
     }
   PingYK=ykz+Yong+zSwap-Bykz-Sykz;

   today_YK=Chi_YK + PingYK;
   return(today_YK);
  }
//============================================================================================================================= 
通过MQL5社区和服务探索MetaTrader 5的新机遇
通过MQL5社区和服务探索MetaTrader 5的新机遇
  • www.mql5.com
A script for opening a grid of orders If you need to quickly open several pending orders (Buy Limit, Sell Limit, Buy Stop, Sell Stop) on a certain distance from the current price, this script will do all the routine for you! Allow AutoTrading before running the script. Usage: Run the script on a chart. Input Parameters: Language of messages...
 

Forum on trading, automated trading systems and testing trading strategies

When you post code please use the CODE button (Alt-S)!

Use the CODE button


 
HistorySelect(Today0S,TimeCurrent());    这样直接获取今天的deals
 
xiaoqiang Wang:

这种超长的代码,基本没耐心看下去;(

原因: