Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1505

 
Mo Isiak #:

Здравствуйте. Спасибо за ваш ответ. Ниже приведен вставленный код в соответствии с запросом.

Я также пытаюсь реализовать процесс с помощью функции onTradeTransaction() из mql5. Программа компилируется нормально, но лимитные ордера на покупку не удаляются, когда нет сделки на покупку. Мне кажется, я неправильно понимаю логику. Пожалуйста, кто-нибудь должен меня поправить. Смотрите код ниже

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 #:

Здравствуйте. Спасибо за ответ. Ниже приведен вставленный код в соответствии с запросом.

Здравствуйте.

Похоже, что у вас в коде не хватает выбора позиции с индексом i в циклах поиска открытых позиций. Без нее не понятно, тип какой позиции возвращает PositionGetInteger(POSITION_TYPE).

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

Аналогично надо добавить выбор позиции и в код поиска позиций SELL.

Документация по 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; } }
Юрий Быков #:

Здравствуйте.

Похоже, что в вашем коде отсутствует выбор позиции с индексом i в цикле поиска открытых позиций. Без него непонятно, какой тип позиции возвращает PositionGetInteger(POSITION_TYPE).

Аналогично следует добавить выбор позиции в код поиска позиций SELL.

Спасибо Юрию Быкову. Все отлично работает. Спасибо

 
Yuriy Bykov #:

Ой, я извиняюсь, невнимательно прочитал первое предложение.

По поводу ошибки: размер массивов high и low у вас устанавливается внутри функции iGetArray() и CopyRates(). Но там размер, по идее, должен устанавливаться значению переменной count, которая равна 300. А дальше в цикле вы хотите получить доступ к 1000 элементов. Мне кажется, вызов iGetArray() и CopyRates() вам не нужен. Достаточно вызвать

Спасибо все заработало.

 

Есть старая проблема, может подскажите почему так происходит.

Тема такая, натягиваем сетку фибо, берем время верхнего бара и время нижнего.

С помощью полученных индексов получаем кол-во баров между верхней и нежней линией фибо.

Но, если тоже самое проделать через цикл, всегда выходит на один бар меньше.

Как сделать что бы было одинаково ?

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



Как видно на скрине, верхний индекс   линии фибо = 19...  нижний  29, получается 10 баров, по факту их 11, метод bars посчитал правильно, а цикл нет.. как быть

 
Konstantin Seredkin #:

Есть старая проблема, может подскажите почему так происходит.

Тема такая, натягиваем сетку фибо, берем время верхнего бара и время нижнего.

С помощью полученных индексов получаем кол-во баров между верхней и нежней линией фибо.

Но, если тоже самое проделать через цикл, всегда выходит на один бар меньше.

Как сделать что бы было одинаково ?



Как видно на скрине, верхний индекс   линии фибо = 19...  нижний  29, получается 10 баров, по факту их 11, метод bars посчитал правильно, а цикл нет.. как быть

Видимо, "проблема заборного столба", https://ru.wikipedia.org/wiki/Ошибка_на_единицу

 

Здравствуйте, я еще совсем новичок впрограммировании наMQL5 и застрял на написании кода для советника по сетке. В принципе, я хочу, чтобы советник делал следующее:

Шаг 1. Если нет открытых позиций и отложенных ордеров, советник должен вызвать функцию OpenNewTrade()

Шаг 2. Если есть открытые позиции или отложенные ордера, советник должен закрыть все остальные позиции на продажу и удалить все лимитные ордера на покупку, когда позиция на продажу достигнет тейк-профита. Также он должен закрывать все остальные позиции на покупку и удалять все лимитные ордера на продажу, когда позиция на покупку достигает тейк-профита.

Шаг 3. Если шаг 2 выполнен правильно, то открытых позиций и отложенных ордеров больше не будет, поэтому шаг 1 вызывается снова в цикле.


ПРОБЛЕМА

==========

Все функции работают нормально, за исключением того, что функция закрытия позиций, как в шаге 2 выше, не работает должным образом, поэтому я не знаю, есть ли ошибка в логике кода. Например, всякий раз, когда позиция на продажу достигает тейк-профита, лимитные ордера на покупку удаляются корректно, но другая позиция (позиции) на продажу удаляется вместе с позицией (позициями) на покупку. Так не должно быть, поскольку я хочу, чтобы советник работал строго в соответствии с шагом 2. Ниже приведен код советника:

#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);
    }
   }
Также я не знаю, как сделать так, чтобы советник задавал свое имя в качестве торговых комментариев. Было бы здорово, если бы вы помогли мне с этим, так как я хочу, чтобы сделки этого советника отличались от сделок других советников. Спасибо.
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.
 

Подскажите начинающему. Не могу додуматься как можно преобразовать строку.

Как заменить символы в "var_1" подстроки от заданного индекса, на символы "var_2'' ?

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

Позиция на продажу, закрывается сделкой на покупку.

Этот код у вас проверяет закрытие позиции Sell.

m_deal.DealType() == DEAL_TYPE_BUY

Попробуйте так.

//+------------------------------------------------------------------+
//| 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;
                      }
                  }
              }            
          }
     }
  }

К тому же у вас флаг удаления позиций и ордеров, после первого удаления всегда true, так как нигде в коде вы его после удаления позиций и ордеров не делаете false.

Вроде по логике, должно быть так.

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();
     }
  }
 
Aleksandr Slavskii #:

К тому же у вас флаг удаления позиций и ордеров, после первого удаления всегда true, так как нигде в коде вы его после удаления позиций и ордеров не делаете false.

Вроде по логике, должно быть так.

Александр, а то, что эти флаги инициализированы false на глобальном уровне, разве это в счёт не идёт?

С уважением, Владимир.

Причина обращения: