Questions from Beginners MQL5 MT5 MetaTrader 5 - page 1505

 
Konstantin Seredkin #:

It is clear, on mql5 I have everything and works, I wrote how to make this code work on mql4 highlighted in yellow what I wrote, but in places where it is highlighted in red error gives an error of exceeding the limits of the array

Oops, I apologise, I didn't read the first sentence carefully.

Regarding the error: the size of the high and low arrays is set inside the iGetArray() and CopyRates() functions. But there the size should be set to the value of the count variable, which is equal to 300. And further in the loop you want to get access to 1000 items. I think you don't need to call iGetArray() and CopyRates(). It is enough to call

ArrayResize(high, 1000);
ArrayResize(low, 1000);
 
Mo Isiak #:

Hello. Thank you for your response. Below is the inserted code as requeted.

I am also trying to implement the process using the onTradeTransaction() function of mql5. The prgram compiles fine still buy the buy limit orders are not deleted when there is no buy trade. I think I am getting the logic wrongly. Please someone should correct me. See code below

void OnTradeTransaction(
   const MqlTradeTransaction& trans,      //trade transaction structure
   const MqlTradeRequest& request,        //request structure
   const MqlTradeResult& result          // response structure
   ){
      if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
      {
      int totalPositions = PositionsTotal();
   
      // Check if there are no open buy positions
      for (int i = 0; i < totalPositions; i++)
         {
           if (PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY)
             {
                  for(int i = OrdersTotal()-1; i >= 0; i--)
                  {
                        ulong ticket = OrderGetTicket(i);
                        
                        if(OrderGetInteger(ORDER_MAGIC) == InpMagic)
                        {
                           trade.OrderDelete(ticket);
              
                        }
                   }
              }
         }

      }
   }
 
Mo Isiak #:

Hello. Thank you for your reply. Below is the pasted code as requested.

Hello.

It looks like your code is missing the selection of the position with index i in the loops of searching for open positions. Without it, it is not clear what type of position PositionGetInteger(POSITION_TYPE) returns.

for (int i = 0; i < totalPositions; i++)
   {
        ulong ticket = PositionGetTicket(i);
        if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
        {
            hasOpenBuyPosition = true;
            break;
        }
   }

Similarly, you should add position selection to the code of searching for SELL positions.

Документация по MQL5: Торговые функции / PositionGetTicket
Документация по MQL5: Торговые функции / PositionGetTicket
  • www.mql5.com
PositionGetTicket - Торговые функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Yuriy Bykov #:
for (int i = 0; i < totalPositions; i++)    {         ulong ticket = PositionGetTicket(i);         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)         {             hasOpenBuyPosition = true;             break;         }    }
Yuriy Bykov #:

Hello.

It looks like your code is missing the selection of the position with index i in the loops of searching for open positions. Without it, it is not clear what type of position PositionGetInteger(POSITION_TYPE) returns.

Similarly, you should add position selection to the code of searching for SELL positions.

Thank you Yuriy Bykov. This worked perfectly. Thank you

 
Yuriy Bykov #:

Oops, I apologise, didn't read the first sentence carefully.

Regarding the error: the size of the high and low arrays is set inside the iGetArray() and CopyRates() functions. But there the size should be set to the value of the count variable, which is equal to 300. And further in the loop you want to get access to 1000 items. I think you don't need to call iGetArray() and CopyRates(). It is enough to call

Thank you, everything worked.

 

There is an old problem, maybe you can tell me why this happens.

The theme is as follows: we stretch the fibo grid, take the time of the upper bar and the time of the lower bar.

With the help of the obtained indices we get the number of bars between the upper and tender fibo line.

But if we do the same thing through the cycle, we always get one bar less.

How to make it equal?

int z_bar  =0;
      z_bar = Bars(_Symbol,0,fibo_time_end,fibo_time_start);                                                              // получаем количество баров в границах фибо
      for(int i=iBarShift(_Symbol,0,fibo_time_start); i<iBarShift(_Symbol,0,fibo_time_end); i++)            // перебираем циклом
      {
      Comment(fibo_time_start,"   ",iBarShift(_Symbol,0,fibo_time_start),"    -   ",fibo_time_end,"   ",iBarShift(_Symbol,0,fibo_time_end),"   ",z_bar/*,"   ",l_bars*/,"\n",
              price_start,"\n",
              price_end,"\n");
      }



As you can see on the screen, the upper index of the fibo line = 19... the lower one is 29, it turns out 10 bars, in fact they are 11, the bars method calculated correctly, but the cycle does not... how to be

 
Konstantin Seredkin #:

There is an old problem, maybe you can tell me why this is happening.

The theme is as follows: we pull the fibo grid, take the time of the upper bar and the time of the lower bar.

With the help of the obtained indices we get the number of bars between the upper and tender fibo line.

But if we do the same thing through the cycle, we always get one bar less.

How to make it equal?



As you can see on the screen, the upper index of the fibo line = 19... lower 29, it turns out 10 bars, in fact they are 11, the bars method calculated correctly, but the cycle is not... how to be

Apparently, "fence post problem", https://ru.wikipedia.org/wiki/Ошибка_на_единицу

 

Hi, I am still quite new to MQL5 programming and I am stuck writing the code for a grid EA. Basically, I want the EA to do the following:

Step 1. If there are no open positions and pending orders, the EA should call the OpenNewTrade() function

Step 2. While there are open positions or pending orders, the EA should close all other sell positions and delete all buy limit orders whenever a sell position hits take profit. Also, it should close all other buy positions and delete all sell limit orders whenever a buy position hits take profit.

Step 3. If step 2 above is properly executed, there will be no more open positions and pending orders, therefore, step 1 gets called again in a loop.


PROBLEM

==========

All functions work fine except that the function to close positions as in step 2 above isn't working properly so I don't know if there is an error in the logic of the code. For instance, whenever a sell position hits take profit, the buy limit orders are deleted correctly but the other sell position(s) gets deleted along with buy position(s). this is not supposed to be so as I want the EA to function strictly according to step 2. Below is the code for the EA:

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Expert\Money\MoneyFixedMargin.mqh>
//-------
CPositionInfo  m_position;
CTrade         trade;
CSymbolInfo    m_symbol;
CAccountInfo   m_account;
CDealInfo      m_deal;
COrderInfo     m_order;
CMoneyFixedMargin *m_money;
//--------
bool     m_need_close_all_buy             = false;
bool     m_need_close_all_sell            = false; 
bool     m_need_delete_all_buy            = false;
bool     m_need_delete_all_sell           = false;
//--------
input double FirstLot = 0.01;           
input int TakeProfitPoints = 20;
input int GridLevelBuy = 3;
input int GridLevelSell = 3;   
input int GridDistancePoints = 20;   
input int InpMagic = 123456;
//-------
void OnInit()
{
   trade.SetExpertMagicNumber(InpMagic);
}
//-------
void OnDeinit(const int reason)
{
   
}
//-------
void OnTick()
   {
           if(m_need_close_all_buy)
           {
            CloseAllBuyPositions();
           }
         //----
         if(m_need_close_all_sell)
           {
             CloseAllSellPositions();
           }
         //---
         if(m_need_delete_all_buy)
           {
              DeleteAllPendingBuyOrders();
           }
         //---
         if(m_need_delete_all_sell)
           {
              DeleteAllPendingSellOrders();
           }
         //---
         if(PositionsTotal() == 0 && OrdersTotal() == 0)
            {
               OpenNewTrades();
            } 
   }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
          if(HistoryDealSelect(trans.deal))
          {
              m_deal.Ticket(trans.deal);
              
              if(m_deal.DealType() == DEAL_TYPE_SELL && 
                 (m_deal.Entry() == DEAL_ENTRY_OUT || m_deal.Entry() == DEAL_ENTRY_INOUT))
              {
                  long deal_reason = -1;
                  if(m_deal.InfoInteger(DEAL_REASON, deal_reason))
                  {
                      if((ENUM_DEAL_REASON)deal_reason == DEAL_REASON_TP)
                      {
                          // Close all sell positions
                          m_need_close_all_sell=true;//---------------------------------------------This is the line of code that wont execute properly
                          // Delete all pending buy orders
                          m_need_delete_all_buy=true;
                      }
                  }
              }
              if(m_deal.DealType() == DEAL_TYPE_BUY && 
                 (m_deal.Entry() == DEAL_ENTRY_OUT || m_deal.Entry() == DEAL_ENTRY_INOUT))
              {
                  long deal_reason = -1;
                  if(m_deal.InfoInteger(DEAL_REASON, deal_reason))
                  {
                      if((ENUM_DEAL_REASON)deal_reason == DEAL_REASON_TP)
                      {
                          // Close all buy positions
                          m_need_close_all_buy=true;//---------------------------------------------This is the line of code that wont execute properly
                          // Delete all pending sell orders
                          m_need_delete_all_sell=true;
                      }
                  }
              }            
          }
     }
  }
//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void CloseAllBuyPositions(void)
  {
   int totalPositions = PositionsTotal();
       for(int i = PositionsTotal()-1; i >= 0; i--)
            {
               ulong ticket = PositionGetTicket(i);
               string symbol = PositionGetString(POSITION_SYMBOL);
               if(PositionGetInteger(POSITION_MAGIC) == InpMagic && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && symbol == _Symbol)
               {
                  trade.PositionClose(ticket);
               }
            }
  }
void CloseAllSellPositions(void)
  {
   int totalPositions = PositionsTotal();
       for(int i = PositionsTotal()-1; i >= 0; i--)
            {
               ulong ticket = PositionGetTicket(i);
               string symbol = PositionGetString(POSITION_SYMBOL);
               if(PositionGetInteger(POSITION_MAGIC) == InpMagic && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && symbol == _Symbol)
               {
                  trade.PositionClose(ticket);
               }
            }
  }
//+------------------------------------------------------------------+
//| Delete all pending orders                                        |
//+------------------------------------------------------------------+
void DeleteAllPendingBuyOrders(void)
  {
       int totalOrders = OrdersTotal();
       for(int i = OrdersTotal()-1; i >= 0; i--)
            {
               ulong ticket = OrderGetTicket(i);
               string symbol = OrderGetString(ORDER_SYMBOL);
               if(OrderGetInteger(ORDER_MAGIC) == InpMagic && OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT && symbol == _Symbol)
               {
                  trade.OrderDelete(ticket);
               }
            }
  }
void DeleteAllPendingSellOrders(void)
  {
       int totalOrders = OrdersTotal();
       for(int i = OrdersTotal()-1; i >= 0; i--)
            {
               ulong ticket = OrderGetTicket(i);
               string symbol = OrderGetString(ORDER_SYMBOL);
               if(OrderGetInteger(ORDER_MAGIC) == InpMagic && OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT && symbol == _Symbol)
               {
                  trade.OrderDelete(ticket);
               }
            }
  }
//+------------------------------------------------------------------+
void OpenNewTrades()
   {
    double bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
    double ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
    double tpBuy, tpSell, buyLimitPrice, sellLimitPrice;

    // Calculate take profit for initial buy and sell positions
    tpBuy = ask + TakeProfitPoints * _Point;
    tpSell = bid - TakeProfitPoints * _Point;

    // Place initial buy position with take profit
    trade.Buy(FirstLot, _Symbol, ask, 0, tpBuy);
    
    // Place initial sell position with take profit
    trade.Sell(FirstLot, _Symbol, bid, 0, tpSell);

    // Place buy limit orders
    for(int i = 0; i < GridLevelBuy; i++)
    {
        buyLimitPrice = ask - (GridDistancePoints * (i + 1)) * _Point;
        tpBuy = buyLimitPrice + TakeProfitPoints * _Point;
        trade.BuyLimit(FirstLot * MathPow(2, i), buyLimitPrice, _Symbol, 0, tpBuy);
    }

    // Place sell limit orders
    for(int i = 0; i < GridLevelSell; i++)
    {
        sellLimitPrice = bid + (GridDistancePoints * (i + 1)) * _Point;
        tpSell = sellLimitPrice - TakeProfitPoints * _Point;
        trade.SellLimit(FirstLot * MathPow(2, i), sellLimitPrice, _Symbol, 0, tpSell);
    }
   }
Also I don't know how to have the EA set its name as trade comments. It will be nice if you could help me with it as I will like the trades from this EA differentiated from trades placed by other EAs. Thank you.
How to Order a Trading Robot in MQL5 and MQL4
How to Order a Trading Robot in MQL5 and MQL4
  • www.mql5.com
"Freelance" is the largest freelance service for ordering MQL4/MQL5 trading robots and technical indicators. Hundreds of professional developers are ready to develop a custom trading application for the MetaTrader 4/5 terminal.
 

Help for a beginner. I can't figure out how to convert a string.

How to replace the characters in "var_1" substring from the given index, with the characters "var_2'' ?

   string var_1  = "100000000";
   string var_2  = " млн."
   Print(); // 100 млн   
 

A Sell position is closed with a Buy transaction.

This code checks if the Sell position is closed.

m_deal.DealType() == DEAL_TYPE_BUY

Try it like this.

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
          if(HistoryDealSelect(trans.deal))
          {
              m_deal.Ticket(trans.deal);
              
              if(m_deal.DealType() == DEAL_TYPE_BUY && 
                 (m_deal.Entry() == DEAL_ENTRY_OUT || m_deal.Entry() == DEAL_ENTRY_INOUT))
              {
                  long deal_reason = -1;
                  if(m_deal.InfoInteger(DEAL_REASON, deal_reason))
                  {
                      if((ENUM_DEAL_REASON)deal_reason == DEAL_REASON_TP)
                      {
                          // Close all sell positions
                          m_need_close_all_sell=true;//---------------------------------------------This is the line of code that wont execute properly
                          // Delete all pending buy orders
                          m_need_delete_all_buy=true;
                      }
                  }
              }
              if(m_deal.DealType() == DEAL_TYPE_SELL&& 
                 (m_deal.Entry() == DEAL_ENTRY_OUT || m_deal.Entry() == DEAL_ENTRY_INOUT))
              {
                  long deal_reason = -1;
                  if(m_deal.InfoInteger(DEAL_REASON, deal_reason))
                  {
                      if((ENUM_DEAL_REASON)deal_reason == DEAL_REASON_TP)
                      {
                          // Close all buy positions
                          m_need_close_all_buy=true;//---------------------------------------------This is the line of code that wont execute properly
                          // Delete all pending sell orders
                          m_need_delete_all_sell=true;
                      }
                  }
              }            
          }
     }
  }

In addition, you have the flag of deleting positions and orders, after the first deletion is always true, because nowhere in the code you do not make it false after deleting positions and orders.

Logically, it should be like this.

void OnTick()
  {
   if(m_need_close_all_buy)
     {
      CloseAllBuyPositions();
      m_need_close_all_buy = false;
     }
//----
   if(m_need_close_all_sell)
     {
      CloseAllSellPositions();
      m_need_close_all_sell = false;
     }
//---
   if(m_need_delete_all_buy)
     {
      DeleteAllPendingBuyOrders();
      m_need_delete_all_buy = false;
     }
//---
   if(m_need_delete_all_sell)
     {
      DeleteAllPendingSellOrders();
      m_need_delete_all_sell = false;
     }
//---
   if(PositionsTotal() == 0 && OrdersTotal() == 0)
     {
      OpenNewTrades();
     }
  }
Reason: