MQL5为什么同样的交易函数在模拟盘可以,在实盘中却实行错误?

 

我有一个代码块,功能是实行开仓并返回此单的deal ticket

在模拟盘可以正确的返回 deal ticket, 但在实盘中返回的是0,这是为什么?

试过很多方法,都行不通,希望懂的高手,请帮我分析分析,谢谢!

//+------------------------------------------------------------------+
//|                                                        Test1.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>
CTrade    m_trade;
CDealInfo m_deal;
//+------------------------------------------------------------------+
//| EA交易初始化函数                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   EventSetMillisecondTimer(1);
   OpenPosition(ORDER_TYPE_BUY, 0.01, 123456);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| EA报价函数                                                        |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ulong OpenPosition(const ENUM_ORDER_TYPE type,
                   const double lot,
                   const long magic)
  {
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   m_trade.SetExpertMagicNumber(magic);
   if(m_trade.PositionOpen(_Symbol, type, lot, (type == ORDER_TYPE_BUY) ? ask : bid, 0, 0))
     {
      ulong deal_ticket = m_trade.ResultDeal();
      if(HistoryDealSelect(deal_ticket))
         m_deal.Ticket(deal_ticket);
      string flag = (m_deal.DealType() == DEAL_TYPE_BUY) ? "buy" : "sell";
      printf(StringFormat("open deal ticket= #%%d order ticket= #%%d %%s %%.2f %%s at %%.%df", _Digits),
             deal_ticket, m_deal.Order(), flag, m_deal.Volume(), _Symbol, m_deal.Price());
      return(deal_ticket);
     }
   return(0);
  }
 
ulong OpenPosition(const ENUM_ORDER_TYPE type,
                   const double volume,
                   const long magic,
                   const bool record_time = false)
  {
   ulong deal_ticket = 0;
   double sl = 0;
   double tp = 0;
   m_trade.SetExpertMagicNumber(magic);
   RefreshRates();
   double ask = m_symbol.Ask();
   double bid = m_symbol.Bid();
   switch(type)
     {
      case ORDER_TYPE_BUY:
         if(TakeProfit > 0)
            tp = m_symbol.NormalizePrice(ask + TakeProfit * m_point);
         if(StopLoss > 0)
            sl = m_symbol.NormalizePrice(bid - StopLoss * m_point);
         break;
      case ORDER_TYPE_SELL:
         if(TakeProfit > 0)
            tp = m_symbol.NormalizePrice(bid - TakeProfit * m_point);
         if(StopLoss > 0)
            sl = m_symbol.NormalizePrice(ask + StopLoss * m_point);
         break;
     }
   ulong time = GetTickCount64();
   if(m_trade.PositionOpen(m_symbol.Name(), type, volume, (type == ORDER_TYPE_BUY) ? ask : bid, sl, tp, PositionComment))
     {
      open_execution = GetTickCount64() - time;
      bool condtion = true;
      do
        {
         ulong order_ticket = m_trade.ResultOrder();
         HistorySelect(iTime(m_symbol.Name(), PERIOD_D1, 0), TimeTradeServer());
         int total = HistoryDealsTotal();
         for(int i = total - 1; i >= 0; i--)
           {
            if(!m_deal.SelectByIndex(i))
               continue;
            if(m_deal.Symbol() != m_symbol.Name())
               continue;
            if(m_deal.Entry() != DEAL_ENTRY_IN)
               continue;
            if(m_deal.Order() != order_ticket)
               continue;
            printf(StringFormat("open  #%%I64u %%s %%.2f %%s at %%.%df done in %%I64u ms", m_symbol.Digits()),
                   m_deal.Order(), (type == ORDER_TYPE_BUY) ? "buy" : "sell", m_deal.Volume(), m_deal.Symbol(), m_deal.Price(), open_execution);
            if(record_time)
               last_open_time = m_deal.Time();
            deal_ticket = m_deal.Ticket();
            condtion = false;
           }
        }
      while(condtion);
     }
   return(deal_ticket);
  }
 

应该是订单没有交易成功,才返回0

我直接复制你的代码过去就是实盘成功返回ticket的

话说怎么都爱系统自带类,我就见太麻烦,跳来跳去,还不如自己写
 
Mage He #:

应该是订单没有交易成功,才返回0

我直接复制你的代码过去就是实盘成功返回ticket的

话说怎么都爱系统自带类,我就见太麻烦,跳来跳去,还不如自己写

楼主已经说了很清楚了,在模拟帐户能返回正确的deal ticket, 在实盘只会返回0值 , 这是由于MT5服务器不同于MT4服务器的订单机制
所以要获取deal ticket, 只能按照我以上的代码来获取,而楼主的代码只适用模拟帐户,在真实帐户中由于需要等待服务器返回真实的deal ticket,


在这等待的过程中, 代码已经实行了, 所以只会一直返回0值,不过我又完善了一下此代码

另外说一下, 系统的自带类的好处是可以省掉很多代码量

//+------------------------------------------------------------------+
//|                                                        Test1.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
CTrade        m_trade;
CDealInfo     m_deal;
CSymbolInfo   m_symbol;
CPositionInfo m_pos;
input double TakeProfit = 0;
input double StopLoss   = 0;
input string PositionComment = "";
double m_point;
//+------------------------------------------------------------------+
//| EA交易初始化函数                                                |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   EventSetMillisecondTimer(1);
   if(!m_symbol.Name(_Symbol)) // sets symbol name
      return(INIT_FAILED);
   RefreshRates();
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
   m_trade.SetDeviationInPoints(INT_MAX);
   int adjust = (m_symbol.Digits() == 3 || m_symbol.Digits() == 5) ? 10 : 1;
   m_point = m_symbol.Point() * adjust;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   EventKillTimer();
   Comment("");
  }
//+------------------------------------------------------------------+
//| EA报价函数                                                       |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Comment(TimeGMT());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool RefreshRates(void)
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print("RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask() == 0 || m_symbol.Bid() == 0)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ulong OpenPosition(const ENUM_ORDER_TYPE type,
                   const double volume,
                   const long magic)
  {
   RefreshRates();
   double ask = m_symbol.Ask();
   double bid = m_symbol.Bid();
   ulong deal_ticket = 0;
   double sl = 0;
   double tp = 0;
   switch(type)
     {
      case ORDER_TYPE_BUY:
         if(TakeProfit > 0)
            tp = m_symbol.NormalizePrice(ask + TakeProfit * m_point);
         if(StopLoss > 0)
            sl = m_symbol.NormalizePrice(bid - StopLoss * m_point);
         break;
      case ORDER_TYPE_SELL:
         if(TakeProfit > 0)
            tp = m_symbol.NormalizePrice(bid - TakeProfit * m_point);
         if(StopLoss > 0)
            sl = m_symbol.NormalizePrice(ask + StopLoss * m_point);
         break;
     }
   m_trade.SetExpertMagicNumber(magic);
   ulong time = GetTickCount64();
   if(m_trade.PositionOpen(m_symbol.Name(), type, volume, (type == ORDER_TYPE_BUY) ? ask : bid, sl, tp, PositionComment))
     {
      ulong open_execution = GetTickCount64() - time;
      datetime from_date = TimeTradeServer() - 30;
      do
        {
         ulong order_ticket = m_trade.ResultOrder();
         HistorySelect(from_date, TimeTradeServer());
         int total = HistoryDealsTotal();
         for(int i = total - 1; i >= 0; i--)
           {
            if(!m_deal.SelectByIndex(i))
               continue;
            if(m_deal.Symbol() != m_symbol.Name())
               continue;
            if(m_deal.Entry() != DEAL_ENTRY_IN)
               continue;
            if(m_deal.Order() != order_ticket)
               continue;
            printf(StringFormat("open  #%%I64u %%s %%.2f %%s at %%.%df done in %%I64u ms", m_symbol.Digits()),
                   m_deal.Order(), (type == ORDER_TYPE_BUY) ? "buy" : "sell", m_deal.Volume(), m_deal.Symbol(), m_deal.Price(), open_execution);
            deal_ticket = m_deal.Ticket();
            break;
           }
        }
      while(deal_ticket == 0);
     }
   return(deal_ticket);
  }
原因: