1

I have tried many things but can't get it to work with the code below.

I've tried variations of the logic of the code below but have failed and am not sure where to implement it:

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

The OrderSelect() has been an issue for me, so any help will be greatly appreciated.

Below is the EA I'm trying to add it to, but just knowing how and where to put it will help.

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 );
}
user229044
  • 232,980
  • 40
  • 330
  • 338
Rob
  • 69
  • 5

1 Answers1

0

... open WHEN ... is the key part of the goal

OrderSelect() is not of much help for you to solve the "Open WHEN" puzzle. It just crawls accross a db.POOL of records, that MetaTrader Terminal 4 localhost internal DBMS takes care of, which is slow and very, very inefficient way to handle event the order-management tasks, so try to avoid any arbitrary scans thereof in a production-grade system. Here, you even will not get any cardinal piece of information you need for your task from such devastating db.POOL scans, so let's focus on the goal first.


... WHAT ... is the idea behind the goal?

The EA is a scholastically trivial variation on a slow-200 / fast-30 simple moving average cross.

There I guess you would like to add your additional idea of opening additional trades on condition the underlying SMA-cross-originated trade has reached it's { SL | TP }-termination respectively, right?

For such case, Brokers with a MetaTrader Server 4 typically allow you to place a so called pending order, which instructs a Broker, to maintain a record about your will to enter market, supposing a price reaches a pre-defined level -- ( guess what, these would be the { SL | TP } as you requested in the title -- and such record is waiting ( with some more configurable options ), until a such price movement happens or not, during which such position is waiting in an inactive state, called a pending order ...

For Terms & Conditions, kindly check your Broker's contract and/or ask their Customer Care representative. Some special limitations may apply ( better to know a-priori ).


... WHERE ... to put the code?

Without re-designing the provided code ( some minor errors/inefficiencies there ) the code shall go here:

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

The spread-adjustment is not absolute, as during instable periods of time, the market is exposed to spurious spread volatilities. Again, Brokers' Terms & Conditions apply here, so be carefull.

user3666197
  • 1
  • 6
  • 50
  • 92
  • Good answer... But not exactly answering the question "when order hits a TP/SL". The provided method is more like a workaround. – gies0r Jan 22 '17 at 17:48