如何修改活跃交易的止损?

时间:2017-05-31 22:14:24

标签: algorithmic-trading mql5 metatrader5

我无法使用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 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);
}

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

1 个答案:

答案 0 :(得分:2)

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

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

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

您需要使用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使用更复杂的Orders,Positions,Deals和historyOrders系统。 MQL5 community article试图解释它们之间的关系。

  • 订单=待定交易(买入止损,买入限价,卖出止损,卖出限价)
  • 职位=开放交易(买入,卖出)
  • 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 Class

的实例

UPDATE2

使用标准交易功能和Ctrade类

的买入头寸的最小跟踪示例

初始化

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));
           }
        }
     }
  }