Unable to execute OrderClose() function to all open positions

 

Hi

I am a newbie into mql4 coding and i am trying do my first ever code for mt4. In my strategy I might have hedged positions, which I close all of them when it reaches break-even point. But unfortunately orderclose doesn't execute at all. In the backtesting orders are being opened but orders aren't closed. Can somebody help?


I am attaching the code here. Please advise.



#define     NL    "\n"

#property copyright "Prajwal Shetty"
#property version   "1.00"
//

// Define the parameters for the trading strategy
extern double stop_loss = 110;
extern double ProfitTarget = 160;
extern double initial_lot = 0.01;
double lot_multiplier = 2;
extern int max_orders = 7;
int order_count = 0;
double current_lot = initial_lot * MathPow(lot_multiplier, order_count);
extern bool   CloseAllNow      = false;          // closes all orders now
extern bool   CloseProfitableTradesOnly = false; // closes only profitable trades
extern double ProftableTradeAmount      = 1;     // Only trades above this amount close out
extern bool   ClosePendingOnly = false;          // closes pending orders only
extern bool   UseAlerts        = false;


datetime gBarTime;


// Function to check if there is an open buy position
bool isBuyPositionOpen()
{
    for (int i = 0; i < OrdersTotal(); i++)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if (OrderType() == OP_BUY)
                return true;
        }
    }
    return false;
}

// Function to check if there is an open sell position
bool isSellPositionOpen()
{
    for (int i = 0; i < OrdersTotal(); i++)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if (OrderType() == OP_SELL)
                return true;
        }
    }
    return false;
}

// Function to check if previous candle is green
bool isPreviousCandleGreen()
{
    double previous_close = iClose(Symbol(), PERIOD_CURRENT, 1);
    double previous_open = iOpen(Symbol(), PERIOD_CURRENT, 1);
    if (previous_close > previous_open)
        return true;
    else
        return false;
}

// Function to check if previous candle is red
bool isPreviousCandleRed()
{
    double previous_close = iClose(Symbol(), PERIOD_CURRENT, 1);
    double previous_open = iOpen(Symbol(), PERIOD_CURRENT, 1);
    if (previous_close < previous_open)
        return true;
    else
        return false;
}

// Function to check for losing trades
void check_for_losses()
{
    for (int i = 0; i < OrdersTotal(); i++)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            double profit = OrderProfit();
            if (profit < 0)
            {
                order_count = 0;
                break;
            }
        }
    }
}




//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
// Main function to run the trading strategy
void OnTick()
{

//---
      // new local variable to hold the current open time of the furthest right bar
      datetime rightBarTime = iTime(_Symbol,_Period,0);
      
      // check if furthest right bar has the same open time as our global varible
      if(rightBarTime != gBarTime)
      {
         // set the global variable to be the time of the new bar
         gBarTime = rightBarTime;
         // call out on bar function
         OnBar();
      }
  
}



void OnBar()
{
    if (!isBuyPositionOpen() && isPreviousCandleGreen()) // Buy Position
    {
        int buy_result = OrderSend(Symbol(), OP_BUY, current_lot, Ask, 3, NULL, NULL, "Buy Order", 16384, 0, Green);
        if (buy_result < 0)
            Print("Error opening buy order: ");
        else
            order_count++;
        
    }

    if (!isSellPositionOpen() && isPreviousCandleRed()) //Sell Position
    {
        int sell_result = OrderSend(Symbol(), OP_SELL, current_lot, Bid, 3, NULL, NULL, "Sell Order", 16384, 0, Red);
        if (sell_result < 0)
            Print("Error opening sell order: ");
        else
            order_count++;
        
    }

    if (isBuyPositionOpen() && isPreviousCandleRed()) //SellStop Position
    {
        int sellstop_result = OrderSend(Symbol(), OP_SELLSTOP, current_lot, Bid - (stop_loss * Point), 3, NULL, NULL, "SellStop Order", 16384, 0, Red);
        if (sellstop_result < 0)
            Print("Error opening sellstop order: ");
        else
            order_count++;
        
   }

    if (isSellPositionOpen() && isPreviousCandleGreen()) //BuyStop Position
    {
        int buystop_result = OrderSend(Symbol(), OP_BUYSTOP, current_lot, Ask + (stop_loss * Point), 3, NULL, NULL, "BuyStop Order", 16384, 0, Green);
        if (buystop_result < 0)
            Print("Error opening buystop order: ");
        else
            order_count++;
        
    }
}



//+------------------------------------------------------------------------+
//| Closes everything
//+------------------------------------------------------------------------+
void CloseAll()
{
   int i;
   bool result = false;

   while(OrdersTotal()>0)
   {
      // Close open positions first to lock in profit/loss
      for(i=OrdersTotal()-1;i>=0;i--)
      {
         if(OrderSelect(i, SELECT_BY_POS)==false) continue;

         result = false;



         if ( OrderType() == OP_BUY)  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 15, Red );
         if ( OrderType() == OP_SELL)  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 15, Red );
         if (UseAlerts) PlaySound("alert.wav");
      }
      for(i=OrdersTotal()-1;i>=0;i--)
      {
         if(OrderSelect(i, SELECT_BY_POS)==false) continue;

         result = false;
         if ( OrderType()== OP_BUYSTOP)  result = OrderDelete( OrderTicket() );
         if ( OrderType()== OP_SELLSTOP)  result = OrderDelete( OrderTicket() );
         if ( OrderType()== OP_BUYLIMIT)  result = OrderDelete( OrderTicket() );
         if ( OrderType()== OP_SELLLIMIT)  result = OrderDelete( OrderTicket() );
         if (UseAlerts) PlaySound("alert.wav");
      }
      Sleep(1000);
   }
}

//+------------------------------------------------------------------------+
//| cancels all orders that are in profit
//+------------------------------------------------------------------------+
void CloseAllinProfit()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
 {
    if(OrderSelect(i, SELECT_BY_POS)==false) continue;
    bool result = false;
        if ( OrderType() == OP_BUY && OrderProfit()+OrderSwap()>ProftableTradeAmount)  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
        if ( OrderType() == OP_SELL && OrderProfit()+OrderSwap()>ProftableTradeAmount)  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
        if (UseAlerts) PlaySound("alert.wav");
 }
  return; 
}

//+------------------------------------------------------------------------+
//| cancels all pending orders 
//+------------------------------------------------------------------------+
void ClosePendingOrdersOnly()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
 {
    if(OrderSelect(i, SELECT_BY_POS)==false) continue;
    bool result = false;
        if ( OrderType()== OP_BUYSTOP)   result = OrderDelete( OrderTicket() );
        if ( OrderType()== OP_SELLSTOP)  result = OrderDelete( OrderTicket() );
  }
  return; 
  }

//+-----------+
//| Main      |
//+-----------+
int OnStart()
  {
   int      OrdersBUY;
   int      OrdersSELL;
   double   BuyLots, SellLots, BuyProfit, SellProfit;

//+------------------------------------------------------------------+
//  Determine last order price                                       |
//-------------------------------------------------------------------+
      for(int i=0;i<OrdersTotal();i++)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
         if(OrderType()==OP_BUY)  
         {
            OrdersBUY++;
            BuyLots += OrderLots();
            BuyProfit += OrderProfit() + OrderCommission() + OrderSwap();
         }
         if(OrderType()==OP_SELL) 
         {
            OrdersSELL++;
            SellLots += OrderLots();
            SellProfit += OrderProfit() + OrderCommission() + OrderSwap();
         }
      }               
   
    if(CloseAllNow) CloseAll();
    
    if(CloseProfitableTradesOnly) CloseAllinProfit();
    
    if(BuyProfit+SellProfit >= ProfitTarget) CloseAll(); 

    if(ClosePendingOnly) ClosePendingOrdersOnly();
       
   
   Comment("                            Comments Last Update 12-12-2006 10:00pm", NL,
           "                            Buys    ", OrdersBUY, NL,
           "                            BuyLots        ", BuyLots, NL,
           "                            Sells    ", OrdersSELL, NL,
           "                            SellLots        ", SellLots, NL,
           "                            Balance ", AccountBalance(), NL,
           "                            Equity        ", AccountEquity(), NL,
           "                            Margin              ", AccountMargin(), NL,
           "                            MarginPercent        ", MathRound((AccountEquity()/AccountMargin())*100), NL,
           "                            Current Time is  ",TimeHour(CurTime()),":",TimeMinute(CurTime()),".",TimeSeconds(CurTime()));
 
   return(0);
 }
 
anybody on this please?
 
N R Prajwal Shetty #:

Topics concerning MT4 and MQL4 have their own section.

In future please post in the correct section.

I have moved your topic to the MQL4 and Metatrader 4 section.

 
  1. //+------------------------------------------------------------------+
    // Main function to run the trading strategy
    void OnTick()
    ⋮
    //+-----------+
    //| Main      |
    //+-----------+
    int OnStart()
     ⋮

    OnTick is for EAs. OnStart is for scripts. You can't have both. Program Running - MQL4 programs - MQL4 Reference

  2. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
              Code debugging - Developing programs - MetaEditor Help
              Error Handling and Logging in MQL5 - MQL5 Articles (2015)
              Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
              Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)

  3.    while(OrdersTotal()>0)
    Magic number only allows an EA to identify its trades from all others. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number/symbol filtering on your OrderSelect / Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)

              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum (2013)
              PositionClose is not working - MQL5 programming forum (2020)
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles (2006)
              Orders, Positions and Deals in MetaTrader 5 - MQL5 Articles (2011)
              Limit one open buy/sell position at a time - General - MQL5 programming forum (2022)

    You need one Magic Number for each symbol/timeframe/strategy. Trade current timeframe, one strategy, and filter by symbol requires one MN.

 

Simple answer – don’t; use OnStart and OnTick in the same code. Just copy your code from OnStart into OnTick function and it should work.

 
N R Prajwal Shetty #:
anybody on this please?
Is this your code? 
 
Marzena Maria Szmit #:

Simple answer – don’t; use OnStart and OnTick in the same code. Just copy your code from OnStart into OnTick function and it should work.

Hi thank you for answer. i modified it that way.... but still i cant get the orders to close. i get an orderclose error 4051.

void OnTick()
{

//---
      // new local variable to hold the current open time of the furthest right bar
      datetime rightBarTime = iTime(_Symbol,_Period,0);
      
      // check if furthest right bar has the same open time as our global varible
      if(rightBarTime != gBarTime)
      {
         // set the global variable to be the time of the new bar
         gBarTime = rightBarTime;
         // call out on bar function
         OnBar();
      }
}

void OnBar()
{
    double current_lot = initial_lot * MathPow(lot_multiplier, order_count);
    double   BuyLots=0.0, SellLots=0.0, BuyProfit=0.0, SellProfit=0.0;
    int gBuyTicket = 0;
    int gSellTicket = 0;
    int gBuyStopTicket = 0;
    int gSellStopTicket = 0;
    if (!isBuyPositionOpen() && !isSellPositionOpen() && isPreviousCandleGreen() && order_count < max_orders) // Buy Position
    {
        gBuyTicket = OrderSend(Symbol(), OP_BUY, current_lot, Ask, 3, 0, 0, "Buy Order", 16384, 0, Green);
        if (gBuyTicket < 0)
            Print("Error opening buy order: ");
        else
            order_count++;
            BuyProfit += OrderProfit() + OrderCommission() + OrderSwap();
        
    
    }

    if (!isSellPositionOpen() && !isBuyPositionOpen() && isPreviousCandleRed() && order_count < max_orders) //Sell Position
    {
        gSellTicket = OrderSend(Symbol(), OP_SELL, current_lot, Bid, 3, 0, 0, "Sell Order", 16384, 0, Red);
        if (gSellTicket < 0)
            Print("Error opening sell order: ");
        else
            order_count++;
            SellProfit += OrderProfit() + OrderCommission() + OrderSwap();
        
    
    }

    if (isBuyPositionOpen() && isPreviousCandleRed() && isSecondPreviousCandleGreen() && order_count < max_orders) //SellStop Position
    {
        gSellStopTicket = OrderSend(Symbol(), OP_SELLSTOP, current_lot, Bid - (stop_loss * Point), 3, 0, 0, "SellStop Order", 16384, 0, Red);
        if (gSellStopTicket < 0)
            Print("Error opening sellstop order: ");
        else
            order_count++;
            SellProfit += OrderProfit() + OrderCommission() + OrderSwap();
        
        
   }

    if (isSellPositionOpen() && isPreviousCandleGreen() && isSecondPreviousCandleRed() && order_count < max_orders) //BuyStop Position
    {
        gBuyStopTicket = OrderSend(Symbol(), OP_BUYSTOP, current_lot, Ask + (stop_loss * Point), 3, 0, 0, "BuyStop Order", 16384, 0, Green);
        if (gBuyStopTicket < 0)
            Print("Error opening buystop order: ");
        else
            order_count++;
            BuyProfit += OrderProfit() + OrderCommission() + OrderSwap();
    }
   
        
    
    if (BuyProfit+SellProfit >= ProfitTarget) if (!DoNotCloseOrders)
    {
      closeAllPositions(gBuyTicket && gSellTicket && gBuyStopTicket && gSellStopTicket);
      
    }

   string sprofit=AccountCurrency()+" total Profit (current: "+DoubleToStr(BuyProfit+SellProfit,2)+" "+AccountCurrency()+")";
   
   Comment("           Comments Last Update 13-12-2013", NL,//Comments Last Update 12-12-2006 10:00pm", NL,
           "           Close Mode: at ",DoubleToStr(ProfitTarget,2)," "+sprofit, NL,
           "              Buys            ", OrdersBUY, NL,
           "              BuyLots         ", BuyLots, NL,
           "              Sells           ", OrdersSELL, NL,
           "              SellLots        ", DoubleToStr(SellLots,2), NL, NL,
           "              Balance         ", DoubleToStr(AccountBalance(),2)," ",AccountCurrency(), NL,
           "              Equity          ", DoubleToStr(AccountEquity(),2)," ",AccountCurrency(), NL,
           "              Margin          ", DoubleToStr(AccountMargin(),2)," ",AccountCurrency(), NL,
           "              Free Margin     ", DoubleToStr(AccountFreeMargin(),2)," ",AccountCurrency(), NL,
           "              Current Time is ",TimeHour(CurTime()),":",TimeMinute(CurTime()),".",TimeSeconds(CurTime()));
 
}

// Function to close all open positions
void closeAllPositions(int pTicket)
{
   while(IsTradeContextBusy())
   {
      Sleep(50);
   }
    
   if (OrderSelect(pTicket, SELECT_BY_POS, MODE_TRADES))
   {
      Alert("Order Exists: ", pTicket);
      double lots = OrderLots();
      double price = 0;
      if(OrderType() == OP_BUY) price = Bid;
      else if(OrderType() == OP_SELL) price = Ask;
      else if(OrderType() == OP_SELLSTOP) price = Ask;
      else if(OrderType() == OP_BUYSTOP) price = Bid;
      bool closed = OrderClose(pTicket, lots, price, 15, Red);
      if(closed)
      {
         order_count = 0;
         //break;
      }
      if(!closed) Alert("Trade not closed: ", pTicket);
   }
   else
   {
      Alert("Order not selected");
   }
}    
 
William Roeder #:
  1. OnTick is for EAs. OnStart is for scripts. You can't have both. Program Running - MQL4 programs - MQL4 Reference

  2. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
              Code debugging - Developing programs - MetaEditor Help
              Error Handling and Logging in MQL5 - MQL5 Articles (2015)
              Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
              Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)

  3. Magic number only allows an EA to identify its trades from all others. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number/symbol filtering on your OrderSelect / Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)

              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum (2013)
              PositionClose is not working - MQL5 programming forum (2020)
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles (2006)
              Orders, Positions and Deals in MetaTrader 5 - MQL5 Articles (2011)
              Limit one open buy/sell position at a time - General - MQL5 programming forum (2022)

    You need one Magic Number for each symbol/timeframe/strategy. Trade current timeframe, one strategy, and filter by symbol requires one MN.

Thank you for the response and sorry for expecting too much from this. I thot if somebody could help me it would be great. I am like a 2 year kid when it comes to coding. and i am trying to learn my way up.

thanks a lot for the help

 
N R Prajwal Shetty #:

Thank you for the response and sorry for expecting too much from this. I thot if somebody could help me it would be great. I am like a 2 year kid when it comes to coding. and i am trying to learn my way up.

thanks a lot for the help

Try this 

https://docs.mql4.com/trading/ordercloseprice  ..

OrderClosePrice - Trade Functions - MQL4 Reference
OrderClosePrice - Trade Functions - MQL4 Reference
  • docs.mql4.com
OrderClosePrice - Trade Functions - MQL4 Reference
Reason: