price compare condition

 
hi

i have performance problem with the function i coded to compare the current buy stop orders prices and the current market ask price also the current sell stops orders prices and the current and current market bid prices 
if the current ask lower than buy order , delete and place new one 
if the current bid higher than sell order , delete and place new one 

if possible please help debug the problem 
thanks 
void Newposition5()
{
  int ordertotal = OrdersTotal();
  int positiontotal = PositionsTotal();

  if (ordertotal == 1 && positiontotal == 1  )
    {
       for(int i = 0; i < ordertotal  ; i++)
      { 
         if (OrderSelect(OrderGetTicket(i)) )
          {
            ENUM_ORDER_TYPE ordertype = OrderGetInteger(ORDER_TYPE);
            ENUM_POSITION_TYPE positionType = PositionGetInteger(POSITION_TYPE);
            double bidPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
            double askPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
            double buyPrice = NormalizeDouble(askPrice + (pricedistancee * SymbolInfoDouble(Symbol(), SYMBOL_POINT)), SymbolInfoInteger(Symbol(), SYMBOL_DIGITS));
            double sellPrice = NormalizeDouble(bidPrice - (pricedistancee * SymbolInfoDouble(Symbol(), SYMBOL_POINT)), SymbolInfoInteger(Symbol(), SYMBOL_DIGITS));
            if ( ordertype == ORDER_TYPE_SELL_STOP)
            {
                if (OrderGetDouble(ORDER_PRICE_CURRENT)  > buyPrice )
                {
                   trade.OrderDelete(OrderGetTicket(i));
                   placesellorder();
                }

            }
             if ( ordertype == ORDER_TYPE_BUY_STOP) 
            {
                if (sellPrice > OrderGetDouble( ORDER_PRICE_CURRENT))
                {
                   trade.OrderDelete(OrderGetTicket(i));
                   placesellorder();
                }
            }
            
          }
        }
     }
      
}
 
amin meeh:
if the current ask lower than buy order , delete and place new one 
if the current bid higher than sell order , delete and place new one 

Nonsense.

  1. You can not create a buy order at any price other than the Ask.

  2. If the Ask is lower than the buy limit price, the order has already opened at that Ask. You can't delete an open order.

  3. There is no need to create pending orders in code.

    1. The pending has the slight advantage, A) you are closer to the top of the queue (filled quicker), B) there's no round trip network delay (filled quicker.)

      Don't worry about it unless you're scalping M1 or trading news.

    2. Humans can't watch the screen 24/7, so they use pending orders; EAs can, so no need for pending orders, have it wait until the market reaches the trigger price and just open an order.

 
William Roeder #:

Nonsense.

  1. You can not create a buy order at any price other than the Ask.

  2. If the Ask is lower than the buy limit price, the order has already opened at that Ask. You can't delete an open order.

  3. There is no need to create pending orders in code.

    1. The pending has the slight advantage, A) you are closer to the top of the queue (filled quicker), B) there's no round trip network delay (filled quicker.)

      Don't worry about it unless you're scalping M1 or trading news.

    2. Humans can't watch the screen 24/7, so they use pending orders; EAs can, so no need for pending orders, have it wait until the market reaches the trigger price and just open an order.

Dear  William Roeder,
thanks for respond 

1,2: my order is buy stop limit and sell stop limit
which means i can set an buy stop limit at ask or higher than ask price
my buy stop limit are always sets at 10 point more than ask price 
and my sell limit are always set at 10 point less than bid price which orders don't open at the same time 
in my code i compare the ask + 10 point distance by the current buy stop price 

for example :

A= ask + 10 point (1.110)
B= current buy stop limit (1.110)
next A price = ask price + 10 point (1.100)
if A goes down , then delete B and replace with new buy stop order 

and the same for sell stop order 

3.1:

yes you are right . is for scalping 1 min




 

1st - You check if there's one order pending and if there's one position opened. Do not enter a loop; if you're sure there's only one order and you're always gonna work with it, you can assume it is indexed at 0. The same is valid for positions. 

2nd - You call SymbolInfoDouble(Symbol(), SYMBOL_POINT) every time you call this function Newposition5. The symbol point never changes. Call it in the OnInit function, store it to a global variable and work with it.

Also, prices move on a minimum tick, not point. Point and Tick may be different. I would suggest you to call SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE) instead.

3rd - You may be calling SymbolInfoDouble more than once to get bid/ask data. If this is the case, it reduces the performance of your EA. Try calling it only once per OnTick execution, store it in a global variable and work with it. Bid/ask data is not gonna change on the same OnTick call.

4th - Function calls are expensive to the cpu. One single call may not result in a significative performance downgrade, but imagine millions or dozens of millions. Although there's an optimizer, we cannot make sure it changes the function call for a variable (probably it does). Make sure you optimize your code at max without depending on the optimizer. Both of the calls for SymbolInfoInteger(Symbol(), SYMBOL_DIGITS) can be changed to the _Digits variable.

5th - You call ENUM_POSITION_TYPE positionType = PositionGetInteger(POSITION_TYPE) but never uses this variable. Again, although the optimizer may erase this line when compiling, optimize it yourself and remove this line if it is not used.

6th - Consider all those tips above and avoid repeating yourself. See that you call those functions a lot and also calls OrderGetTicket twice. Store it in a variable and call it once.

7th - Per the documentation, when you call OrderGetTicket, the function automatically selects the order for further working with it. There's no need to call OrderSelect.

8th - buyPrice is only used if ordertype == ORDER_TYPE_SELL_STOP and sellPrice is only used if ordertype == ORDER_TYPE_BUY_STOP. Calculate them inside the respective if statementes to avoid useless calculation.

9th - use an else if statemente to compare ordertype variable. Avoid checking the condition twice. The ordertype can only be one of these two values, so you only check it once.

10th - Run the profiler (MetaEditor → Menu → Debug →  Start Profiling on history data) and check which function calls are slowing your code, since we cannot see other parts of it.


Finally, your code could be written like this:


void Newposition5()
{
    int ordertotal = OrdersTotal();
    int positiontotal = PositionsTotal();

    if (ordertotal == 1 && positiontotal == 1  )
    {
        ulong ticket=OrderGetTicket(0);
        if(ticket!=0)
        {
            ENUM_ORDER_TYPE ordertype = OrderGetInteger(ORDER_TYPE);
            if (ordertype == ORDER_TYPE_SELL_STOP)
            {
                double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); // leave them if you call it only here; if not, call it on OnTick and store it to a global variable
                double buyPrice = NormalizeDouble(askPrice + (pricedistancee * SymbolInfoDouble(Symbol(), SYMBOL_POINT)), _Digits);
                if (OrderGetDouble(ORDER_PRICE_CURRENT)  > buyPrice )
                {
                    trade.OrderDelete(ticket);
                    placesellorder();
                }
            }
            else if (ordertype == ORDER_TYPE_BUY_STOP)
            {
                double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); // leave them if you call it only here; if not, call it on OnTick and store it to a global variable
                double sellPrice = NormalizeDouble(bidPrice - (pricedistancee * SymbolInfoDouble(Symbol(), SYMBOL_POINT)), _Digits);
                
                if (sellPrice > OrderGetDouble(ORDER_PRICE_CURRENT))
                {
                    trade.OrderDelete(ticket);
                    placesellorder();
                }
            }
        }
    }
}
 
Emanuel Cavalcante Amorim Filho #:

1st - You check if there's one order pending and if there's one position opened. Do not enter a loop; if you're sure there's only one order and you're always gonna work with it, you can assume it is indexed at 0. The same is valid for positions. 

2nd - You call SymbolInfoDouble(Symbol(), SYMBOL_POINT) every time you call this function Newposition5. The symbol point never changes. Call it in the OnInit function, store it to a global variable and work with it.

Also, prices move on a minimum tick, not point. Point and Tick may be different. I would suggest you to call SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE) instead.



hi dear  Emanuel Cavalcante Amorim Filho,

thanks for your respond .
i used all the suggestions and made all the changes 
used also the final code and optimized the function code 
but still doesn't work ( i mean the price of the orders doesn't change with the market prices )

can you please test the code and tell me what is the problem , even with final code you send me 

thanks 

 

Oh, I thought you meant a performance problem (speed/slow EA execution), not something with the order not being placed/executed. With the code you provided there's little information to help you about it, since we don't know exactly which errors are showing up or the contents of your placesellorder function, for example. Note that this placesellorder, as the name implies, only places a sell order. This may be causing a bug, because you call it to place a buy order aswell.


Also, you use OrderGetDouble(ORDER_PRICE_CURRENT). This returns the current symbol price.

Let's say the following:


Market price is at U$ 10.00. You place an BUY_STOP_LIMIT order with stop_limit at U$ 11.00 and the limit price at U$ 9.00 (the stop_limit/trigger price should always be above the ask price for a BUY_STOP; on the other hand, the limit/entry price should always be below the ask price). If the market price moves U$ 1.00 below the limit price (in this case, if the price reaches U$ 9.00), you may want to reduce both the stop_limit and limit by U$ 1.00, for example (or any value you want, respecting the limits said above). In this case, you need to compare the value from OrderGetDouble(ORDER_PRICE_OPEN), which returns the limit price of your order.

You may also want to check if the price moves a certain distance from the stop price. In this case, check the return of OrderGetDouble(ORDER_PRICE_STOPLIMIT).

Do the same thing for sell orders.


Please note that the order type you are using (STOP_LIMIT) has two different prices: limit and stop_limit. When you say "(...) current ask lower than buy order"  you may be referring to either of them both. Specify one of them; check them according to the example and adapt the code.

 
Emanuel Cavalcante Amorim Filho #:

Oh, I thought you meant a performance problem (speed/slow EA execution), not something with the order not being placed/executed. With the code you provided there's little information to help you about it, since we don't know exactly which errors are showing up or the contents of your placesellorder function, for example. Note that this placesellorder, as the name implies, only places a sell order. This may be causing a bug, because you call it to place a buy order aswell.


Also, you use OrderGetDouble(ORDER_PRICE_CURRENT). This returns the current symbol price.

Let's say the following:


Market price is at U$ 10.00. You place an BUY_STOP_LIMIT order with stop_limit at U$ 11.00 and the limit price at U$ 9.00 (the stop_limit/trigger price should always be above the ask price for a BUY_STOP; on the other hand, the limit/entry price should always be below the ask price). If the market price moves U$ 1.00 below the limit price (in this case, if the price reaches U$ 9.00), you may want to reduce both the stop_limit and limit by U$ 1.00, for example (or any value you want, respecting the limits said above). In this case, you need to compare the value from OrderGetDouble(ORDER_PRICE_OPEN), which returns the limit price of your order.

You may also want to check if the price moves a certain distance from the stop price. In this case, check the return of OrderGetDouble(ORDER_PRICE_STOPLIMIT).

Do the same thing for sell orders.


Please note that the order type you are using (STOP_LIMIT) has two different prices: limit and stop_limit. When you say "(...) current ask lower than buy order"  you may be referring to either of them both. Specify one of them; check them according to the example and adapt the code.

THANKS AGAIN for your respond
i used before OrderGetDouble(ORDER_PRICE_STOPLIMIT) to track order stop limit price and compare to the ask and bid prices 
the result is :
sell stop limit price : changes with bid price and if goes up stop limit goes up and if bid goes down , stop limit goes down with bid which is incorrect result by result we wish to be .  it has to move up if want to move 
buy stop limit price : it doesn't even move and change the price of the order .

 

THANKS FOR ALL FIO YOUR RESPONDS .
I FIXED THE PROBLEM AND NOW WORK CORRECTLY BY POTIMIZE THE CODE SPEED PERFROMANCE