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

标签 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]

这是我的止损 modyfing void:

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

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

最佳答案

您的问题是您正试图在 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 使用一个复杂得多的订单、头寸、交易和历史订单系统。一个MQL5 community article试图解释它们是如何相互关联的。

  • 订单 = 待定交易(Buy Stop、Buy Limit、Sell Stop、Sell Limit)
  • 头寸 = 未平仓交易(买入、卖出)
  • HistoryOrders = 关闭/删除的交易
  • Deals = 构成订单/头寸的交易

循环查看挂单:

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 的实例。

更新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();
}

使用标准函数的买入交易跟踪止损

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

关于algorithmic-trading - 如何修改活跃交易的止损?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44295495/

相关文章:

algorithmic-trading - 如何在多个时间范围内搜索烛台形态

python - 实时算法交易专家的逻辑

plugins - Metatrader 插件 : what is it?

algorithm - 在哪里可以找到有关交易算法的免费教程

r - 根据信号在特定日期对股票投资组合进行等权重新分配

javascript - 使用 javascript 将参数发送到 java 应用程序

mql4 - 如何在 Expert Advisor (EA) 中包含斐波那契水平?

Python TA-Lib抽象API使用

c++ - 嵌套 opencl 的内核函数