2

我正在尝试在我的公开市场订单中添加止损,MetaTrader 4当头寸获得 100 点“好”,这等于订单开盘价;

OrderStopLoss() == OrderOpenPrice()

但这并没有发生。

我添加了Print()&GetLastError()函数,但日志中没有任何内容,所以它一定是我的编码中的东西 - 但看不出有什么问题。

好的,这就是我目前所拥有的,一个用于购买的循环,一个用于销售的循环。我还按照我的建议对“双打”进行了规范化,并且还在顶部声明了 BuyMod 和 SellMod 为“真”。这应该确保默认值不会诉诸 false。我还认为如果我告诉你我有 MetaEditor 版本 5 build 1241 可能会有所帮助:)

我拥有的以下代码如下;

/*Breakeven Order Modification*/
bool BuyMod               =  true;
bool SellMod              =  true;
                for(int b = OrdersTotal()-1;b>=0;b--)
                {
                if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
                   {
                   double   aBidPrice   =  MarketInfo(Symbol(),MODE_BID);
                   double   anOpenPrice =  OrderOpenPrice();
                   double   aNewTpPrice =  OrderTakeProfit();
                   double   aCurrentSL  =  OrderStopLoss();
                   double   aNewSLPrice =  anOpenPrice;
                   double   pnlPoints   =  (aBidPrice - anOpenPrice)/_Point;
                   double   stopPoints  =  (aBidPrice - aNewSLPrice)/_Point;
                   int      stopLevel   =  int(MarketInfo(Symbol(),MODE_STOPLEVEL));
                   int      aTicket     =  OrderTicket();
                   if(OrderType() == OP_BUY)
                   if(stopPoints >= stopLevel)
                   if(aTicket > 0)
                   if(pnlPoints >= breakeven)
                   if(aNewSLPrice != aCurrentSL)
                      {
                      BuyMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,buycolor);
                      SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
                      }
                   }
                }
                for(int s = OrdersTotal()-1; s>=0; s--)
                {
                if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
                   {
                   double   anAskPrice  =  MarketInfo(Symbol(),MODE_ASK);
                   double   anOpenPrice =  OrderOpenPrice();
                   double   aNewTpPrice =  OrderTakeProfit();
                   double   aCurrentSL  =  OrderStopLoss();
                   double   aNewSLPrice =  anOpenPrice;
                   double   pnlPoints   =  (anOpenPrice - anAskPrice)/_Point;
                   double   stopPoints  =  (aNewSLPrice - anAskPrice)/_Point;
                   int      stopLevel   =  int(MarketInfo(Symbol(),MODE_STOPLEVEL));
                   int      aTicket     =  OrderTicket();
                   if(OrderType()== OP_SELL)
                   if(stopPoints >= stopLevel)
                   if(pnlPoints >= breakeven)
                   if(aNewSLPrice != aCurrentSL)
                   if(aTicket > 0)
                      {
                      SellMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,sellcolor);
                      SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
                      }
                   }
                }

交易算法交易 mql4 metatrader4

共享编辑删除标志

刚刚编辑

2天前问

托德吉尔贝264

您可能想知道,StackOverflow 不提倡重复问题。(见

4

3 回答 3

1

除了满足MQL4语法规则外,
还有更多条件:


第一个隐患是数字舍入问题。

MetaQuotes, Inc. 建议尽可能将浮动值标准化为适当的价格表示。

因此,
无论价格进入服务器端指令的任何地方,{ OrderSend(), OrderModify(), ... }都应始终通过调用来准备这样的aPriceDOMAIN值,在标准化价格到达任何服务器端指令调用之前。
NormalizeDouble( ... , _Digits )

听起来可能很幼稚,但这可以避免服务器端拒绝的问题。

定期将调用添加NormalizeDouble()到您的代码中,作为您的救生背心。


第二个,再好的隐患在 STOP_ZONE-s和FREEZE_ZONE-s

虽然不直接可见,但任何经纪人都在其各自的条款和条件中设置了这些参数。

在实践中,
这意味着,如果您指示{ OrderSend() | OrderModify() }设置/移动水平 aPriceDOMAIN设置得太接近当前实际Ask/ Bid(违反经纪人禁止STOP_ZONE

删除/修改aPriceDOMAIN已经设置且现在的 TP 或 SL 水平,在与实际/的经纪商禁止FREEZE_ZONE距离内,该指令将不会被成功接受和执行。AskBid

因此,除了调用NormalizeDouble(),总是等待更长的时间,因为价格移动“足够远”,并定期检查不违反禁止STOP_+FREEZE_区域,然后再对您的 algotrading 项目的订单管理部分进行任何修改。

无论如何,欢迎来到野生世界MQL4

Update:虽然 StackOverflow 不是一个 Do-a-Homework 网站,但让我提出一些解决方案的方向:

for ( int b = OrdersTotal() - 1; b >= 0; b-- ) // ________________________ // I AM NOT A FAN OF db.Pool-looping, but will keep original approach for context purposes
{     if (  ( OrderSelect( b, SELECT_BY_POS, MODE_TRADES ) ) == true )
      {    // YES, HAVE TO OPEN A CODE-BLOCK FOR if()-POSITIVE CASE:
           // ------------------------------------------------------
              double aBidPRICE   = MarketInfo( Symbol(), MODE_BID );       // .UPD
              double anOpenPRICE     = OrderOpenPrice();                   // .SET FROM a db.Pool Current Record
              double aNewTpPRICE     = OrderTakeProfit();                  // .SET FROM a db.Pool Current Record
              double aCurrentSlPRICE = OrderStopLoss();                    // .SET FROM a db.Pool Current Record
              double aNewSlPRICE     = anOpenPRICE;                        // .SET
              double  pnlPOINTs      = ( aBidPRICE - anOpenPRICE )/_Point; // .SET
              double stopPOINTs      = ( aBidPRICE - aNewSlPRICE )/_Point; // .SET
           // ------------------------------------------------------------ // .TEST
              if (                        OP_BUY    == OrderType()        )
                   if (                   Period()  == OrderMagicNumber() )
                        if (             stopPOINTa >  stopLevel          )
                             if (         pnlPOINTs >= breakeven          )
                                  if (  aNewSlPRICE != aCurrentSlPRICE    )
                                  {  // YES, HAVE TO OPEN A BLOCK {...}-CODE-BLOCK FOR THE if()if()if()if()-chain's-POSITIVE CASE:
                                     // -------------------------------------------------------------------------------------------
                                        int aBuyMOD = OrderModify( OrderTicket(),
                                                                   OrderOpenPrice(),
                                                                   NormalizeDouble( aNewSlPRICE, Digits ),
                                                                   NormalizeDouble( aNewTpPRICE, Digits ),
                                                                   0,
                                                                   buycolor
                                                                   );
                                        switch( aBuyMOD )
                                        {   case ( NULL  ): { ...; break; } // FAIL ( ANALYSE ERROR )
                                            default:        { ...; break; } // PASS OrderModify()
                                        }
      }
}
于 2016-04-18T23:32:05.500 回答
0

问题在于您对内置OrderModify()函数的调用。

OrderStopLoss() == OrderModify()将评估 as falsewhich 反过来将评估为 0 因为==是比较运算符。

AnOrderStopLoss()是对另一个内置函数(不是变量)的调用,您无法向其中保存任何内容,因此OrderStopLoss() = 4也无法正常工作。

MQL4文档中:

bool  OrderModify( int        ticket,      // ticket 
                   double     price,       // price 
                   double     stoploss,    // stop loss 
                   double     takeprofit,  // take profit 
                   datetime   expiration,  // expiration 
                   color      arrow_color  // color 
                   );

在您的情况下,假设ModBuy已经在代码中的某处定义:

ModBuy = OrderModify(  OrderTicket(),      // <-ticket from record OrderSelect()'d
                       OrderOpenPrice(),   // <-price  from current record
                       OrderOpenPrice(),   // <-price  from current record
                       OrderTakeProfit(),  // <-TP     from current record
                       0,                  // ( cannot set P/O expiration for M/O )
                       buycolor            // ( set a color for a GUI marker )
                       );

或者您可以使用任何其他有效值而不是第二个值OrderOpenPrice()来设置新的止损。

于 2016-04-17T21:52:27.180 回答
0

真的很抱歉,我是 Stackoverflow 的新手,这是我现在根据大家的评论和推荐修改的代码如下

 **Local Declarations**
  pnlPoints            =  0;
  point                =  MarketInfo(Symbol(),MODE_POINT);
  stopLevel            =  int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo (Symbol(),MODE_SPREAD));
  sl                   =  NormalizeDouble(OrderStopLoss(),Digits);
  tp                   =  OrderTakeProfit();
  cmd                  =  OrderType();
  breakeven            =  100;

  **Global Variables**
  double   pnlPoints;
  double   price,sl,tp;
  double   point;
  int      stopLevel;
  int      cmd;
  int      breakeven;
  double   newSL;
                for(int b = OrdersTotal()-1; b>=0; b--)
                {
                if((OrderSelect(b,SELECT_BY_POS,MODE_TRADES))==true)
                price = MarketInfo(Symbol(),MODE_BID);
                newSL = NormalizeDouble(OrderOpenPrice(),Digits);
                pnlPoints = (price - OrderOpenPrice())/point;
                   {
                   if(OrderType()==OP_BUY)
                      if(OrderMagicNumber() == Period())
                         if((price-newSL)/point>=stopLevel)
                            if(pnlPoints>=breakeven)
                               if(sl!=newSL)
                                  ModBuy = OrderModify(OrderTicket(),OrderOpenPrice(),newSL,tp,buycolor);
                                   else if(ModBuy == false)
                                   {
                                   Print("OrderModify failed with error #",GetLastError());
                                   }
                   }              
                }
于 2016-04-20T15:55:45.923 回答