2

我在使用 MQL5 修改正在运行的交易的止损时遇到了麻烦。选择订单对我有用。但是如果我尝试访问变量(例如OrderTicket()& OrderOpenPrice()),它总是返回 0.00000:

2017.06.01 00:06:32.114 2016.04.08 00:00:00   failed modify  buy 0.00  sl: 0.00000, tp: 0.00000 -> sl: 1.41594, tp: 0.00000 [Invalid request]

这是我的止损修改无效:

void modifyStops() {

   int total = OrdersTotal();          // total number of placed pending orders
   Print( total + " Orders on the line!!!" );

   //--- Over all placed pending orders
   for ( int i = 0; i <  total; i++ )
   {     bool isOrderSelected = OrderSelect( i, SELECT_BY_POS, MODE_TRADES );
         if (  isOrderSelected )
         {  // TODO: Check the Trades to contain the correct Order Number

               Print( "Symbol & Magicnumber matching" );
               double newStopLoss;

            // Update the stop loss
               if (  OrderType() == OP_BUY )
               {
                     newStopLoss = addTolerance( SL );
               } 
               else if (  OrderType() == OP_SELL )
               {
                          newStopLoss = minusTolerance( SL );
               }       
               newStopLoss = NormalizeDouble( newStopLoss, Digits );
               Print( "NEW STOP LOSS::::=====> ", Symbol(), " at ", newStopLoss );

               if ( !OrderModify( OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, Green ) )
               {
                     Print( "OrderModify returned the error of ", GetLastError() );
               }  
     }
}

CTrade 课程对我来说不能正常工作。我试图实现您发布的代码 - 但是:它似乎仍然没有成功。

不幸的是,我在我的 EA 中实现了这一点,当交易进行时 OrderGetTicket(i) 返回零。所以我的 void 看起来像这样:

void modifyStops() {
for(int i=0; i<PositionsTotal();i++) 
    {
    ulong ticket;
    if((ticket=PositionGetTicket(i))>0) 
        { 
         //--- return order properties 
         double open_price    =PositionGetDouble(POSITION_PRICE_OPEN); 
         datetime time_open     =(datetime)PositionGetInteger(POSITION_TIME); 
         string symbol        =PositionGetString(POSITION_SYMBOL); 
         int order_magic   =PositionGetInteger(POSITION_MAGIC); 
         double volume        =PositionGetDouble(POSITION_VOLUME); 
         double stoploss      =PositionGetDouble(POSITION_SL); 
         double takeprofit    =PositionGetDouble(POSITION_TP); 
         ENUM_ORDER_TYPE type          =EnumToString(ENUM_ORDER_TYPE(PositionGetInteger(POSITION_TYPE))); 
         //--- prepare and show information about the order 
         printf("#ticket %d %s %G %s at %G, with sl: %G tp: %G was set up at %s", 
                ticket,                 // order ticket 
                type,                   // type 
                volume,                 // placed volume 
                symbol,                 // symbol 
                open_price,             // specified open price
                stoploss,               //
                takeprofit,             // 
                TimeToString(time_open) // time of order placing 
                ); 
        } 
    }
}

printf 函数什么也不返回:

2017.06.02 01:42:26.910 2016.04.07 00:00:00   #ticket 1 (non-string passed) 0  at 0, with sl: 0 tp: 0 was set up at 1970.01.01 00:00

我不敢相信在 MQL5 中简单地修改 SL 有那么难。这太可怕了。但是我需要通过它来测试我在几对上的策略......

你有别的想法吗?我使用以下代码设置交易:

void createPendingOrder(ENUM_ORDER_TYPE orderType, double lots, double stopLoss) {
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};

//--- parameters to place a pending order
   request.action   =TRADE_ACTION_PENDING;                             // type of trade operation
   request.symbol   =Symbol();                                         // symbol
   request.volume   =lots;                                             // volume of 0.1 lot
   //request.deviation=2;                                              // allowed deviation from the price
   request.magic    =224466      ;                                     // MagicNumber of the order
   //int offset = 3;                                                   // offset from the current price to place the order, in points
   double price;                                                       // order triggering price
   double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);                // value of point
   int digits=SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);                // number of decimal places (precision)
   //--- checking the type of operation
   if(orderType==ORDER_TYPE_BUY_STOP)
     {
      request.type         =ORDER_TYPE_BUY_STOP;                            // order type
      price                =entryPrice;   
      request.price        =NormalizeDouble(price,digits);                      // normalized opening price 
      request.sl           =stopLoss;
     }
   else if(orderType==ORDER_TYPE_SELL_STOP)
     {
      request.type         =ORDER_TYPE_SELL_STOP;                           // order type
      price                =entryPrice;           
      request.price        =NormalizeDouble(price,digits);                  // normalized opening price 
      request.sl           =stopLoss;
     }
   else Alert("This example is only for placing pending orders");   // if not pending order is selected
//--- send the request
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());                 // if unable to send the request, output the error code
//--- information about the operation
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
}

例如,是否可以将结果对象保存在数组中,然后通过该对象访问正在运行的交易?

4

1 回答 1

6

您的问题是您试图在 MQL5 中运行 MQL4 代码。

MQL5中没有OrderModify(), OrderOpenPrice(), !!!OrderTicket()

请参阅此处的文档,了解如何选择、查询值和修改交易。

您将需要使用OrderGetDouble(),OrderGetInteger()OrderGetString()查询开盘价、止损等。例如

if((ticket=OrderGetTicket(i))>0) 
    { 
     //--- return order properties 
     open_price    =OrderGetDouble(ORDER_PRICE_OPEN); 
     time_setup    =(datetime)OrderGetInteger(ORDER_TIME_SETUP); 
     symbol        =OrderGetString(ORDER_SYMBOL); 
     order_magic   =OrderGetInteger(ORDER_MAGIC); 
     positionID    =OrderGetInteger(ORDER_POSITION_ID); 
     initial_volume=OrderGetDouble(ORDER_VOLUME_INITIAL); 
     type          =EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE))); 
     //--- prepare and show information about the order 
     printf("#ticket %d %s %G %s at %G was set up at %s", 
            ticket,                 // order ticket 
            type,                   // type 
            initial_volume,         // placed volume 
            symbol,                 // symbol 
            open_price,             // specified open price 
            TimeToString(time_setup)// time of order placing 
            ); 
    } 

使用OrderSend()函数https://www.mql5.com/en/docs/trading/ordersend修改订单

更新

MQL5 使用更复杂的订单、头寸、交易和历史订单系统。一篇MQL5 社区文章试图解释它们是如何相互关联的。

  • 订单 = 挂单(买入止损、买入限价、卖出止损、卖出限价)
  • 头寸 = 未平仓交易(买入、卖出)
  • HistoryOrders = 关闭/删除的交易
  • 交易 = 构成订单/头寸的交易

循环并查看挂单:

for(int i=0; i<OrdersTotal();i++) 
    {
    if((ticket=OrderGetTicket(i))>0) 
        { 
         //--- return order properties 
         open_price    =OrderGetDouble(ORDER_PRICE_OPEN); 
         time_setup    =(datetime)OrderGetInteger(ORDER_TIME_SETUP); 
         symbol        =OrderGetString(ORDER_SYMBOL); 
         order_magic   =OrderGetInteger(ORDER_MAGIC); 
         positionID    =OrderGetInteger(ORDER_POSITION_ID); 
         initial_volume=OrderGetDouble(ORDER_VOLUME_INITIAL); 
         type          =EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE))); 
         //--- prepare and show information about the order 
         printf("#ticket %d %s %G %s at %G was set up at %s", 
                ticket,                 // order ticket 
                type,                   // type 
                initial_volume,         // placed volume 
                symbol,                 // symbol 
                open_price,             // specified open price 
                TimeToString(time_setup)// time of order placing 
                ); 
        } 
    }

循环并查看未平仓交易:

for(int i=0; i<PositionsTotal();i++) 
    {
    if((ticket= PositionGetTicket(i))>0) 
        { 
         //--- return order properties 
         open_price    =PositionGetDouble(POSITION_PRICE_OPEN); 
         time_open     =(datetime)PositionGetInteger(POSITION_TIME); 
         symbol        =PositionGetString(POSITION_SYMBOL); 
         order_magic   =PositionGetInteger(POSITION_MAGIC); 
         volume        =PositionGetDouble(POSITION_VOLUME); 
         stoploss      =PositionGetDouble(POSITION_SL); 
         takeprofit    =PositionGetDouble(POSITION_TP); 
         type          =EnumToString(ENUM_ORDER_TYPE(PositionGetInteger(POSITION_TYPE))); 
         //--- prepare and show information about the order 
         printf("#ticket %d %s %G %s at %G, with sl: %G tp: %G was set up at %s", 
                ticket,                 // order ticket 
                type,                   // type 
                volume,                 // placed volume 
                symbol,                 // symbol 
                open_price,             // specified open price
                stoploss,               //
                takeprofit,             // 
                TimeToString(time_open) // time of order placing 
                ); 
        } 
    }

希望其他人能够对订单、头寸、成交、历史订单提供更好的解释,因为它们仍然让我头疼。

为了简单起见,我通常只创建一个CTrade 类的实例

更新2

使用标准交易函数和 Ctrade 类购买头寸的 trailSL 的最小示例

在里面

Ctrade *m_trade;
CSymbolInfo *m_symbol;
Void OnInit()
{
    m_trade  = new Ctrade();
    m_trade.SetExpertMagicNumber(100);
    m_symbol = new CSymbolInfo();
    m_symbol.Name(Symbol());
}
void OnTick()
{
   m_symbol.RefreshRates();
}

具有标准功能的买入交易的追踪 SL

void modifysl()
  {
   ulong ticket;
   MqlTradeRequest request = {0};
   MqlTradeResult  result  = {0};
   double newsl;

   for(int i=0; i<PositionsTotal();i++)
     {
      ticket=PositionGetTicket(i);
      if(ticket>0)
        {
         request.action   = TRADE_ACTION_SLTP; // type of trade operation
         request.position = ticket;   // ticket of the position
         request.symbol   = PositionGetString(POSITION_SYMBOL);     // symbol 
         request.sl       = PositionGetDouble(POSITION_SL);                // Stop Loss of the position
         request.tp       = PositionGetDouble(POSITION_TP);                // Take Profit of the position
         request.magic    = 100;                                    // MagicNumber of the position

   
         newsl = NormalizeDouble(m_symbol.Bid()-100*m_symbol.Point(),
                                 m_symbol.Digits());
         if(newsl>request.sl)
           {
            request.sl = newsl;
            if(!OrderSend(request,result))
              {
               PrintFormat("OrderSend error %d",GetLastError());  // if unable to send the request, output the error code
              }
            //--- information about the operation   
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
           }
        }
     }
  }

使用 CTrade 追踪买入头寸止损

void modifyslCtrade()
  {
   ulong ticket;
   MqlTradeRequest request= {0};
   MqlTradeResult response ={0};
   double newsl;

   for(int i=0; i<PositionsTotal();i++)
     {
      ticket=PositionGetTicket(i);
      if(ticket>0)
        {
         newsl = NormalizeDouble(m_symbol.Bid()-100*m_symbol.Point(),
                                 m_symbol.Digits());
         if(newsl>PositionGetDouble(POSITION_SL))
           { 
            m_trade.PositionModify(ticket,
                                   newsl,
                                   PositionGetDouble(POSITION_TP));
           }
        }
     }
  }
于 2017-06-01T10:01:46.737 回答