Trying to close a "frame" when the "frame" is in profit

 

Hi,

I am writing a new EA which restricts trading to spans of currency-price which I refer to as "frames." These frames have upper limits, lower limits, a datatime value of when the frame was opened, and a datetime value of when the frame was closed (0 if it is still open).

ex:

--------------------------------------  upper limit = 1.3800

 T R A D E   H E R E  T R A D E   H E R E  TR A D E   H E R E 

 T R A D E   H E R E  T R A D E   H E R E  TR A D E   H E R E 

 T R A D E   H E R E  T R A D E   H E R E  TR A D E   H E R E 

 T R A D E   H E R E  T R A D E   H E R E  TR A D E   H E R E 

-------------------------------------- lower limit = 1.3500

When the price leaves the frame, if I made money within the frame overall I want to close every order within the frame.

Since I only want to close the frame when I have profited inside it, my balance should never drop below the balance when the frame opened. However, there seems to be some bug that is eluding me because the balance DOES in fact drop below the previous value. Can anyone figure this out? I am stumped :(

I got most of this stuff working; please skip to my last post.

I have a couple arrays that I use to keep track of the frame, they are:

double upperHistoryLimit[]; //contains all of the upper limits every opened/open now
double lowerHistoryLimit[]; //contains all of the lower limits every opened/open now
datetime setFrameTime[];    //contains the time the frame was open
datetime closeFrameTime[];  //contains the time the next frame was opened

And here is my code for the relevant portion:

void SetFrame() { //This is how I create the "frame" and how I memorize its variables
      
   int _arraySize = ArraySize(upperHistoryLimit);

   ArrayResize(upperHistoryLimit, _arraySize +1);
   ArrayResize(lowerHistoryLimit, _arraySize +1);
   ArrayResize(freezeOrderNum, _arraySize +1);
   ArrayResize(setFrameTime, _arraySize +1);
   ArrayResize(closeFrameTime, _arraySize +1);
 
   
   if (upperHistoryLimit[_arraySize]!=0) Print ("upperHistoryLimit[_arraySize] = ",upperHistoryLimit[_arraySize]);
   upperHistoryLimit[_arraySize]= Bid * ((100+FrameSize)/100);
   lowerHistoryLimit[_arraySize] = Ask * ((100-FrameSize)/100);
   setFrameTime[_arraySize] = TimeCurrent();
         

   if (firstTime == true) 
   {
      ObjectCreate("upperLimit", OBJ_HLINE, 0, Time[0], upperHistoryLimit[_arraySize] , 0, 0);
      ObjectCreate("lowerLimit", OBJ_HLINE, 0, Time[0], lowerHistoryLimit[_arraySize], 0, 0);
   } 
   else
   {   
      ObjectSet("upperLimit", OBJ_HLINE,  upperHistoryLimit[_arraySize]);
      ObjectSet("lowerLimit", OBJ_HLINE,  lowerHistoryLimit[_arraySize]);
      closeFrameTime[_arraySize-1] = TimeCurrent();
   }
}
//This is in the Start Function:


RefreshRates();
withinFrame_BuyTP = CheckWithinFrame((Ask-Spread*Point)+TakeProfit*Point); //Check if future buy limit's TP is within the frame
withinFrame_SellTP = CheckWithinFrame((Bid+Spread*Point)-TakeProfit*Point); //Check if future sell limit's TP is within the frame 
     
withinFrame_Ask = CheckWithinFrame(Ask); //Check if current Ask price is within the frame
withinFrame_Bid = CheckWithinFrame(Bid); //Check if current Bid price is within the frame    


if ((withinFrame_Ask == false) || (withinFrame_Bid == false))  //if either current price is not in the current frame
      {
     
        if ((withinFrame_BuyTP == false) && (withinFrame_SellTP == false)) //if both future orders' TP is not within the current frame
         {
              
           
            if ((justClosed == false) && getFrameProfit(ArraySize(upperHistoryLimit)-1) >0) //getFrameProfit should return the profit of the most recent frame in the array.
            {
                
              closeOpenOrdersFrame(-1,ArraySize(upperHistoryLimit)-1); //closeOpenOrdersFrame should close every order of the most recent frame in the array.
              justClosed = true;
            }
            
         }
bool CheckWithinFrame(double currentPrice) //returns true if the passed variable is between upperLimit and lowerLimit; else = false
{
   int size = ArraySize(upperHistoryLimit);
   
   if ((currentPrice < upperHistoryLimit[size-1]) && (currentPrice > lowerHistoryLimit[size-1]))
   {
     
      return (true);
   }
   else
   {
   
      return (false);
   }
   
}
   double getFrameProfit(int _index){ //Should return the total profit within the frame (could be positive or negative)
   int cnt;
   double profit = 0;
   int total=OrdersTotal();
   if (total == 0) return (0);
   for(cnt=total;cnt>=0;cnt--){
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if ((OrderOpenPrice() < upperHistoryLimit[_index]) && (OrderOpenPrice() > lowerHistoryLimit[_index]))
      {
         if (OrderOpenTime() < closeFrameTime[_index] || closeFrameTime[_index] == 0)
         {
             if (OrderOpenTime() > setFrameTime[_index])
             {
               profit += OrderProfit();
             }
         }  
     }     
   }
   
   profit = 0;
   total=OrdersHistoryTotal();
   for(cnt=total;cnt>=0;cnt--){
      OrderSelect(cnt, SELECT_BY_POS, MODE_HISTORY);
      if ((OrderOpenPrice() < upperHistoryLimit[_index]) && (OrderOpenPrice() > lowerHistoryLimit[_index]))
      {
         if (OrderOpenTime() < closeFrameTime[_index] || closeFrameTime[_index] == 0)
         {
             if (OrderOpenTime() > setFrameTime[_index])
             {
               profit += OrderProfit();
             }
         }  
     }     
   }
   
   return (profit);
}
void closeOpenOrdersFrame(int magic, int _index){ //This function should close all open orders inside the frame.
   int total, cnt,type;
   double price;
   color clr;
   
   Print ("closeOpenOrdersFrame(" + type + "," + magic + ")");
   while (getNumOpenOrdersInFrame(magic,_index) > 0){
      while (IsTradeContextBusy()){
         Print("closeOpenOrders(): waiting for trade context.");
         Sleep(MathRand()/10);
      }
      
      total=OrdersTotal();
      

      
      for(cnt=0; cnt<total; cnt++){
         RefreshRates();
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         type = OrderType();
         
         if (type == OP_BUY){
            price = Bid;
            clr = CLR_SELL_ARROW;
         }else{
            price = Ask;
            clr = CLR_BUY_ARROW;
         }
                  
         if ((OrderOpenPrice() < upperHistoryLimit[_index]) && (OrderOpenPrice() > lowerHistoryLimit[_index]))
         {
            if (OrderOpenTime() < closeFrameTime[_index] || closeFrameTime[_index] == 0)
            {
               if (OrderOpenTime() > setFrameTime[_index])
               {
                  if((type == -1 || OrderType() == type) && (magic == -1 || OrderMagicNumber() == magic))
                  {
                     if(IsTradeContextBusy())
                     {
                        break; // something else is trading too, back to the while loop.
                     }
                     if (type == OP_BUYSTOP || type == OP_SELLSTOP || type == OP_BUYLIMIT || type == OP_SELLLIMIT)
                     {
                        orderDeleteReliable(OrderTicket());
                     }
                     else
                     {
                        orderCloseReliable(OrderTicket(), OrderLots(), price, 0, clr);
                     }
                     break; // restart the loop from 0 (hello FIFO!)
                  }
               } 
            }
        }
      }
   }
}
int getNumOpenOrders(int type, int magic){ //This should return the number of currently open orders (limits included)
   int cnt;
   int num = 0;
   int total=OrdersTotal();
   for(cnt=total;cnt>=0;cnt--){
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if((magic == -1 || OrderMagicNumber() == magic) && (type == -1 || OrderType() == type)){
         num++;
      }
   }
   return (num);
}
 

mfurlender wrote >>

...there seems to be some bug that is eluding me because the balance DOES in fact drop below the previous value.

I did not go over all your code, but since this has to do with profit I just read the getFrameProfit() function -> It calculates total profit for open orders in that frame and then zeros the result before calculating closed orders profit...?

 
 int total=OrdersTotal();
   if (total == 0) return (0);
   for(cnt=total;cnt>=0;cnt--){
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);  //  << first OrderSelect is invalid, you should start counting from ( OrdersTotal()-1 )
 

When closing or deleteing orders you MUST count down.

Always check orderSelect return code

refreshData after the orderSelect only if you are actually closing (modifying or sending.)

for(int index = OrdersTotal() - 1; index >= 0; index--) if (
    OrderSelect(index, SELECT_BY_POS)     // Only my orders w/
&&  OrderMagicNumber()  == MagicNumber    // my magic number
&&  OrderSymbol()       == Symbol() ) {   // and period and symbol
 

Ok; the function that finds the frame's profit works correctly, thanks to you guys, and my closeOpenOrdersFrame function launches. However it does not close any orders! If someone could help me out with this I would really appreciate it. This is the second day that I'm stuck with this bug and it is getting really frustrating :( :(

Here are the functions involved:

//This is from my Start Function
if ((withinFrame_Ask == false) || (withinFrame_Bid == false))  //if either current price is not in the current frame
      {

         if ((withinFrame_BuyTP == false) && (withinFrame_SellTP == false)) //if both future orders' TP is not within the current frame
         {
     
            double profit = getFrameProfit(ArraySize(upperHistoryLimit)-1); //get the frame's profit
            string _string;
            
            if ((OrdersTotal() != 0))
            {
               _string = (StringConcatenate("Profit = ",profit));
               print (_string);
               
               if (profit > 0)
               {
                  Print ("profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0");
                  
                  closeOpenOrdersFrame(-1,ArraySize(upperHistoryLimit)-1); //close every order in that frame (THIS IS WHAT IS NOT WORKING)
                  //CloseFrame(ArraySize(upperHistoryLimit)-1);
                 
               }   
            }
            if (profit < 0 && (OrdersTotal() != 0) && (justFrozen==false)) //and if there are open orders OR pending limits
            {
               _string = (StringConcatenate("Profit = ",profit));
               print (_string);
              // FreezeOrder(ArraySize(upperHistoryLimit)-1);
   
               Sleep(5000); //wait
  
 
            }
         }
         

Here is the main problem function:

void closeOpenOrdersFrame(int magic, int _index){ //This is supposed to close every order in the frame but it never even gets to the nested If statements!
   int total, cnt,type;
   double price;
   color clr;
   
   Print ("closeOpenOrdersFrame(" + type + "," + magic + ")");

      total=OrdersTotal();

      
      
      double profit_total = 0;

      
      Print ("Ding 0"); 
      for(cnt=total-1;cnt>=0;cnt--){
      Print ("Ding 0.25"); 
         if (!OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) Print ("closeOpenOrdersFrame: Error Selecting Order: ",GetLastError()); continue;
         RefreshRates();
         type = OrderType();
         
         if (type == OP_BUY){
            price = Bid;
            clr = CLR_SELL_ARROW;
         }else{
            price = Ask;
            clr = CLR_BUY_ARROW;
         }
         Print ("Ding 0.5");         
         if ((OrderOpenPrice() < upperHistoryLimit[_index]) && (OrderOpenPrice() > lowerHistoryLimit[_index]))
         {
            Print ("Ding 1");
            if (OrderOpenTime() < closeFrameTime[_index] || closeFrameTime[_index] == 0)
            {  Print ("Ding 2");
               if (OrderOpenTime() > setFrameTime[_index])
               {  Print ("Ding 3");
                  if((type == -1 || OrderType() == type) && (magic == -1 || OrderMagicNumber() == magic))
                  {
                     Print ("Ding 4");
                     if(IsTradeContextBusy())
                     {
                        Print ("IsTradeContextBusy");
                        break; // something else is trading too, back to the while loop.
                     }
                     if (type == OP_BUYSTOP || type == OP_SELLSTOP || type == OP_BUYLIMIT || type == OP_SELLLIMIT)
                     {
                        orderDeleteReliable(OrderTicket());
                     }
                     else
                     {
                        Print ("Ding 5!!!!");
                        profit_total+=OrderProfit();
                        Print ("profit_total = ",profit_total);
                        orderCloseReliable(OrderTicket(), OrderLots(), price, 0, clr);
                        Print ("Order Closed!");
                        
                     }
                     
                  }
               } 
            }
        }
      
   }
      string _string = StringConcatenate("Closed Order Profit:  ",profit_total);
      print (_string);
   
   
   return;
}

Here is the output:

2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: closeOpenOrdersFrame(0,-1)
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: Ding 0.25
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: Ding 0
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: closeOpenOrdersFrame(0,-1)
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: Ding 0.25
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: Ding 0
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: closeOpenOrdersFrame(0,-1)
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0profit > 0
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: Ding 0.25
2010.05.11 00:56:03     2009.06.12 04:14  Frame_0.3 EURUSD,M15: Ding 0

Plz help!

 

You forgot a pair of braces:

 if (!OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) { Print ("closeOpenOrdersFrame: Error Selecting Order: ",GetLastError()); continue; }

(I haven't checked the rest of the code... But this would definitely never let u get passed that 'continue' statement).

 

That did it, thanks a lot!

It works now, woo!

I'll definitely be back with more problems though ;)

Reason: