Как открыть Buy, когда Buy-ордер достигает T/P, Sell, если Buy-ордер достигает S/L; a Продать, если ордер на продажу достигает T/P, и открыть покупку, если Sell достигнет S/L?

Я пробовал много вещей, но не могу заставить его работать с кодом ниже.

Я пробовал варианты логики кода ниже, но потерпел неудачу и не знаю, где ее реализовать:

if (  OrderSelect( OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY ) )
{
      if (  OrderType() == OP_BUY )
      {
            if (  OrderClosePrice() >  OrderStopLoss() )      Print( "Hit TP" );
            else                                              Print( "Hit SL" );
      }
      else if (  OrderType() == OP_SELL )
           {
                 if (  OrderClosePrice() <  OrderStopLoss() ) Print( "Hit TP" );
                 else                                         Print( "Hit SL" );
           }
}  

or

Orderselect...

if (  MathAbs( OrderClosePrice()
             - OrderTakeProfit()
               ) > MathAbs( OrderClosePrice()
                          - OrderStopLoss()
                            )
      ) Print( "StopLoss" );

if (  MathAbs( OrderClosePrice()
             - OrderTakeProfit()
               ) < MathAbs( OrderClosePrice()
                          - OrderStopLoss()
                            )
      ) Print( "TakeProfit" );

У меня возникла проблема с OrderSelect(), поэтому буду очень признательна за любую помощь.

Ниже приведен советник, в который я пытаюсь его добавить, но просто знание того, как и где его разместить, поможет.

extern int      MagicNumber     = 10001;
extern double   Lots            =     0.01;
extern double   StopLoss        =     1;
extern double   TakeProfit      =     1;
extern int      TrailingStop    =     0;
extern int      Slippage        =     3;
//+------------------------------------------------------------------+
//    expert start function
//+------------------------------------------------------------------+
int start() // New-MQL4.56789 #strict uses another constructor:         int OnTick(){...}
{
  double MyPoint = Point;
  if (  Digits == 3
     || Digits == 5
     )  MyPoint = Point*10;

  double TheStopLoss    = 0;
  double TheTakeProfit  = 0;

  if ( TotalOrdersCount() == 0 )
  {
     int result = 0;
     if (  ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) <  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
        && ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) >  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
        ) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open BUY rule
     {
        result = OrderSend( Symbol(),
                            OP_BUY,
                            Lots,
                            Ask,
                            Slippage,
                            0,
                            0,
                            "Buy",
                            MagicNumber,
                            0,
                            Blue
                            );
        if (  result >  0 )
        {
              TheStopLoss   = 0;
              TheTakeProfit = 0;

              if (  TakeProfit >  0 ) TheTakeProfit = Ask + TakeProfit * MyPoint;
              if (  StopLoss   >  0 ) TheStopLoss   = Ask - StopLoss   * MyPoint;

              OrderSelect( result, SELECT_BY_TICKET );
              OrderModify( OrderTicket(),
                           OrderOpenPrice(),
                           NormalizeDouble( TheStopLoss,   Digits ),
                           NormalizeDouble( TheTakeProfit, Digits ),
                           0,
                           Green
                           );
        }
        return(0);
     }
     if (  ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) >  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
        && ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) <  iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
        ) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open SELL rule
     {
        result = OrderSend( Symbol(),
                            OP_SELL,
                            Lots,
                            Bid,
                            Slippage,
                            0,
                            0,
                            "Sell",
                            MagicNumber,
                            0,
                            Red
                            );
        if (  result >  0 )
        {     
              TheStopLoss   = 0;
              TheTakeProfit = 0;

              if (  TakeProfit >  0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
              if (  StopLoss   >  0 ) TheStopLoss   = Bid + StopLoss   * MyPoint;

              OrderSelect( result, SELECT_BY_TICKET );
              OrderModify( OrderTicket(),
                           OrderOpenPrice(),
                           NormalizeDouble( TheStopLoss,   Digits ),
                           NormalizeDouble( TheTakeProfit, Digits ),
                           0,
                           Green
                           );
        }
        return(0);
     }
  }

  for ( int cnt = 0; cnt <  OrdersTotal(); cnt++ )
  {     
        OrderSelect( cnt, SELECT_BY_POS, MODE_TRADES );

        if (  OrderType()        <= OP_SELL
           && OrderSymbol()      == Symbol()
           && OrderMagicNumber() == MagicNumber
           )  
        {     
              if (  OrderType() == OP_BUY )
              {     
                    if (  TrailingStop >  0 )
                    {     
                          if (  Bid - OrderOpenPrice() >  MyPoint * TrailingStop )
                          {     
                                if (  OrderStopLoss()  <  Bid - MyPoint * TrailingStop )
                                {     
                                      OrderModify( OrderTicket(),
                                                   OrderOpenPrice(),
                                                   Bid - TrailingStop * MyPoint,
                                                   OrderTakeProfit(),
                                                   0,
                                                   Green
                                                   );
                                      return(0);
                                }
                          }
                    }
              }
              else 
              {     
                    if (  TrailingStop >  0 )
                    {     
                          if (  ( OrderOpenPrice() - Ask ) >  ( MyPoint * TrailingStop ) )
                          {     
                                if (  ( OrderStopLoss() >  ( Ask + MyPoint * TrailingStop ) )
                                   || ( OrderStopLoss() == 0 )
                                   )
                                {     
                                      OrderModify( OrderTicket(),
                                                   OrderOpenPrice(),
                                                   Ask + MyPoint * TrailingStop,
                                                   OrderTakeProfit(),
                                                   0,
                                                   Red
                                                   );
                                      return(0);
                                }
                          }
                    }
              }
        }
  }
  return(0);
}

int    TotalOrdersCount()
{      
       int result = 0;
       for (  int i = 0; i <  OrdersTotal(); i++ )
       {
           OrderSelect( i, SELECT_BY_POS, MODE_TRADES );

           if (  OrderMagicNumber() == MagicNumber ) result++;

       }
       return( result );
}

person Rob    schedule 15.05.2016    source источник


Ответы (1)


... открыть КОГДА... является ключевой частью цели

OrderSelect() не очень поможет вам решить головоломку "Открыть КОГДА". Он просто просматривает db.POOL записей, о которых заботится внутренняя СУБД MetaTrader Terminal 4 localhost, что является медленным и очень, очень неэффективным способом обработки событий, связанных с управлением ордерами. задач, поэтому старайтесь избегать их произвольного сканирования в системе производственного уровня. Здесь вы даже не получите никакой кардинальной информации, необходимой для вашей задачи, от таких разрушительных db.POOL сканирований, поэтому давайте сначала сосредоточимся на цели.


... ЧТО... стоит за целью?

EA — это схоластически тривиальная вариация на пересечении простой скользящей средней медленной-200/быстрой-30.

Здесь, я думаю, вы хотели бы добавить свою дополнительную идею открытия дополнительных сделок при условии, что базовая сделка, основанная на SMA, достигла своего { SL | TP }-завершения соответственно, верно?

В таком случае Брокеры с MetaTrader Server 4 обычно позволяют вам размещать так называемый отложенный ордер, который указывает Брокеру вести запись о вашем желании выйти на рынок. , предположим, что цена достигает заранее определенного уровня -- (угадайте, это будут { SL | TP }, как вы просили в заголовке -- и такая запись ожидает (с некоторыми дополнительными настраиваемыми параметрами), пока такое движение цены не произойдет или нет , в течение которого такая позиция находится в неактивном состоянии, называемом отложенным ордером ...

Чтобы ознакомиться с Условиями и положениями, ознакомьтесь с договором вашего Брокера и/или обратитесь к его представителю по обслуживанию клиентов. Могут применяться некоторые специальные ограничения (лучше знать априори).


...ГДЕ... ставить код?

Без перепроектирования предоставленного кода (некоторые незначительные ошибки/неэффективность) код должен быть здесь:

    result = OrderSend( Symbol(),
                        OP_SELL,  // PRIMARY SELL <<<AT-MARKET>>>
                        Lots,
                        Bid,
                        Slippage,
                        0,
                        0,
                        "Sell",
                        MagicNumber,
                        0,
                        Red
                        );
    if (  result >  0 )
    {     
          TheStopLoss   = 0;
          TheTakeProfit = 0;

          if (  TakeProfit >  0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
          if (  StopLoss   >  0 ) TheStopLoss   = Bid + StopLoss   * MyPoint;

          OrderSelect( result, SELECT_BY_TICKET );

          OrderModify( OrderTicket(),
                       OrderOpenPrice(),
                       NormalizeDouble( TheStopLoss,   Digits ),
                       NormalizeDouble( TheTakeProfit, Digits ),
                       0,
                       Green
                       );
       // ---------------------------------------------------- HERE ADD
          OrderSend(   Symbol(),
                       OP_SELLSTOP,    // SELL-STOP PENDING ORDER ON SELL.TP
                       Lots,
                       NormalizeDouble( TheTakeProfit
                                      - MarketInfo( _Symbol, MODE_SPREAD ),
                                        Digits
                                        ),
                       Slippage,
                       0,              // SL: T.B.D.
                       0,              // TP: T.B.D.
                       "Sell on Sell.TP",
                       sTpMagicNumber, // avoid collisions with other logic
                       0,              // never expires
                       Red
                       );

          OrderSend(   Symbol(),
                       OP_BUYSTOP,    // BUY-STOP PENDING ORDER ON SELL.SL
                       Lots,
                       NormalizeDouble( TheStopLoss
                                      - MarketInfo( _Symbol, MODE_SPREAD ),
                                        Digits
                                        ),
                       Slippage,
                       0,              // SL: T.B.D.
                       0,              // TP: T.B.D.
                       "Buy on Sell.SL",
                       bSlMagicNumber, // avoid collisions with other logic
                       0,              // never expires
                       Red
                       );
    }

Корректировка спреда не является абсолютной, так как в нестабильные периоды времени рынок подвержен ложной волатильности спреда. Опять же, здесь применяются Правила и условия брокеров, так что будьте осторожны.

person user3666197    schedule 16.05.2016
comment
Хороший ответ... Но не совсем отвечающий на вопрос ‹b›когда ордер достигает TP/SL‹/b›. Предоставленный метод больше похож на обходной путь. - person gies0r; 22.01.2017