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

 
Alexey Belyakov:

Добрый день! Уважаемые программисты. Вопрос по MQL5

Как сделать контроль позиций в эксперте?. Чтобы на одном баре была, только одна  открытая позиция.  То есть закрытие позиции неважно где - на каком баре, но вот открытие должно быть только на одном баре.

этот код полностью игнорируется в чём ошибка, не пойму.



Ошибка: Вы смешали в кучу мух и котлеты - Вы смешали ОТЛОЖЕННЫЕ ОРДЕРА и ПОЗИЦИИ.

Чтобы не путаться, пожалуйста ознакомьтесь со справкой: Общие принципы


Выше предложили простой способ - при открытии позиции запоминаете время открытия текущего бара. Дальше, если Вы хотите открыть новую позицию, Вы сверяете сохранённое время и время открытия текущего бара.

Запоминать время открытия позиции удобно в OnTradeTransaction:

//+------------------------------------------------------------------+
//| 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);
      else
         return;
      if(m_deal.Symbol()==m_symbol.Name() && m_deal.Magic()==InpMagic)
        {
         if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL)
           {
            if(m_deal.Entry()==DEAL_ENTRY_IN || m_deal.Entry()==DEAL_ENTRY_INOUT)
               m_last_deal_in=iTime(m_symbol.Name(),InpTimeFrame,0);
            int size_need_position=ArraySize(SPosition);
            if(size_need_position>0)
              {
               for(int i=0; i<size_need_position; i++)
                 {
                  if(SPosition[i].waiting_transaction)
                     if(SPosition[i].waiting_order_ticket==m_deal.Order())
                       {
                        Print(__FUNCTION__," Transaction confirmed");
                        SPosition[i].transaction_confirmed=true;
                        break;
                       }
                 }
              }
           }
        }
     }
  }

и при возникновении сигнала сверять время:

//+------------------------------------------------------------------+
//| Search trading signals                                           |
//+------------------------------------------------------------------+
bool SearchTradingSignals(void)
  {
   if(m_prev_bars==m_last_deal_in) // on one bar - only one deal
      return(true);


Пример взят из кода OHLC Check 2

Общие принципы - Торговые операции - Справка по MetaTrader 5
Общие принципы - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит и...
 

Сложнова-то....как-то. На первом этапе проблем никаких " запоминаете время открытия текущего бара"

Вот запомнил: 

if (PositionsTotal()==1)  // Здесь проверяю, что открыта одна позиция
{
datetime Cu=iTime(NULL,_Period,0);        // Здесь в переменную - время открытия бара при открытой позиции

Но  здесь " Вы сверяете сохранённое время и время открытия текущего бара." проблемы.

Я вот примерно тоже самое доработал.Вот посмотрите: 

if (PositionsTotal()==1)  // Здесь проверяю, что открыта одна позиция (или была открыта, неважно, любое торговое действие)
{
datetime Cu=iTime(NULL,_Period,0);        // Здесь в переменную - время открытия бара при открытой позиции
int hd=+iBarShift(Symbol(),_Period,Cu)+1;    // Здесь в переменную - бар на котором произошло открытие позиции 
if (hd>=1)                                //Здесь проверяем - если этих баров, больше чем один, то.......   
{
return; //....то зацикливанием программу, НО проблема только в return
}
}

Здесь  мне только всего лишь нужно зациклить прогу типа "return(-1)" Но из-за void присваивать выражение ретурну нельзя.  Как обойти этот момент.? Как зациклить но не return?

Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Тикет позиции. Уникальное число, которое присваивается каждой вновь открытой позиции. Как правило, соответствует тикету ордера, в результате которого она была открыта, за исключением случаев изменения тикета в результате служебных операций на сервере. Например, начисления свопов переоткрытием позиции. Для нахождения ордера, которым была открыта...
 
datetime PR=iTime(NULL,_Period,0);  // проверяю время открытие бара
if (PositionsTotal()==1)  
{
datetime TK=iTime(NULL,_Period,0);  // время открытия бара при открытой позиции                        
if (PR==TK)                         // сравниваю
{
return(true);  // НЕ катит true - ошибка 
}
}


Такой вариант тоже не прокатил.

 
Alexey Belyakov:

Сложнова-то....как-то. На первом этапе проблем никаких " запоминаете время открытия текущего бара"

Вот запомнил: 

Но  здесь " Вы сверяете сохранённое время и время открытия текущего бара." проблемы.

Я вот примерно тоже самое доработал.Вот посмотрите: 

Здесь  мне только всего лишь нужно зациклить прогу типа "return(-1)" Но из-за void присваивать выражение ретурну нельзя.  Как обойти этот момент.? Как зациклить но не return?

За зацикливание программ применяется лечение: рубание рук по самую шею. Чтобы впредь не повадно было.


Вот, что Вам нужно - полное тело программы, Вам только нужно оформить получение сигнала:

//+------------------------------------------------------------------+
//|                              Example One position on one bar.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\DealInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
CDealInfo      m_deal;                       // object of CDealInfo class
//--- input parameters
input ulong    InpMagic             = 200;      // Magic number
//---
datetime m_prev_bars                = 0;        // "0" -> D'1970.01.01 00:00';
datetime m_last_deal_in             = 0;        // "0" -> D'1970.01.01 00:00';
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
   RefreshRates();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(m_symbol.Name(),Period(),0);
   if(time_0==m_prev_bars)
      return;
   m_prev_bars=time_0;
   if(!RefreshRates())
     {
      m_prev_bars=0;
      return;
     }
//--- search for trading signals
   if(!SearchTradingSignals())
     {
      m_prev_bars=0;
      return;
     }
  }
//+------------------------------------------------------------------+
//| 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);
      else
         return;
      if(m_deal.Symbol()==m_symbol.Name() && m_deal.Magic()==InpMagic)
        {
         if(m_deal.DealType()==DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL)
           {
            if(m_deal.Entry()==DEAL_ENTRY_IN || m_deal.Entry()==DEAL_ENTRY_INOUT)
               m_last_deal_in=iTime(m_symbol.Name(),Period(),0);
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Search trading signals                                           |
//+------------------------------------------------------------------+
bool SearchTradingSignals(void)
  {
   if(m_prev_bars==m_last_deal_in) // on one bar - only one deal
      return(true);
//--- signal
//---
   return(false);
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
      return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+


переменная 'm_prev_bars' хранит время открытия текущего бара, а переменная 'm_last_deal_in' - время открытия бара, на котором была открыта позиция.

Сравнение этих двух переменных производится в блоке получения сигналов 'SearchTradingSignals'.

 
Alexey Belyakov:


Такой вариант тоже не прокатил.

До чего-же барабашка любит километровые коды…

Ваша проблема решается в ШЕСТЬ строк кода, с учётом объявления переменных.

/************************Expert tick function************************/
void OnTick()
 {
  bool signal = true;
  datetime timeBar = iTime(_Symbol, PERIOD_CURRENT, 0);// период можно поставить по своему усмотрению
  datetime static timeOpen = 0;
  if(timeBar > timeOpen)
   {
    if(signal)
     {
      // открыть позицию
      timeOpen = timeBar;
     }
   }
 }/******************************************************************/

Надеюсь с переменной signal разберётесь.

 

О! Заработало! Спасибо, товарищи за идеи!

Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)

Вот так внедрил:

datetime timeBar = iTime(_Symbol,PERIOD_CURRENT, 0);// период можно поставить по своему усмотрению
datetime static timeOpen = 0;

if((PositionsTotal()==0)&&(c0>h1)&&(rGENUP>0.30)&&(timeBar > timeOpen))    // Условие для открытия позиции.
     {
      MqlTradeRequest request;
      MqlTradeResult  result;
      request.action   =TRADE_ACTION_DEAL;                         // тип торговой операции
      request.symbol   =Symbol();                                 // символ
      request.volume   =1;                                       // объем в 1 лот
      request.type     =ORDER_TYPE_BUY;                         // тип ордера
      request.price    =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // цена для открытия
      request.deviation=3;
      request.sl    = NormalizeDouble(Ask-50*_Point,_Digits);
      request.tp    = NormalizeDouble(Ask+50*_Point,_Digits);    

      if(!OrderSend(request,result))
         PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
      //--- информация об операции
      PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
      // допустимое отклонение от цены
timeOpen = timeBar;
}
Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?


Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 
Alexey Belyakov:

О! Заработало! Спасибо, товарищи за идеи!

Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)

Вот так внедрил:

Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?


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

Пример:

//+------------------------------------------------------------------+
//|                                            Only_one_purchase.mq5 |
//+------------------------------------------------------------------+
#property version   "1.003"
#property script_show_inputs
#include <Trade\Trade.mqh>
CTrade         m_trade;          // trading object
//--- input parameters
input ENUM_POSITION_TYPE   InpPositionType   = POSITION_TYPE_BUY; // Position Type
input double               InpVolume         = 0.0;               // Volume
input ulong                m_magic           = 15489;             // magic number
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   m_trade.SetExpertMagicNumber(m_magic);
//--- open a position
   if(InpPositionType==POSITION_TYPE_BUY)
      m_trade.Buy(InpVolume);
   else
      m_trade.Sell(InpVolume);
  }
//+------------------------------------------------------------------+
 
Alexey Belyakov:

О! Заработало! Спасибо, товарищи за идеи!

Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)

Вот так внедрил:

Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?


Так если у вас в условии есть

if((PositionsTotal()==0)&&

то зачем ещё проверки на новый бар? Или есть вариант, что позиция закроется на этом-же баре и надо запретить второе открытие?

 
Alexey Belyakov:

О! Заработало! Спасибо, товарищи за идеи!

Правда пришлось подшаманить чуть-чуть. Ещё проще даже получилось, без (true). Правда объяснить не смогу эту хитро-запутанную логику MQL.)

Вот так внедрил:

Я вот офигеваю, почему такой большой код в MQL5 для открытия позиции. В отличие от MQL4. В 4-ке одна строчка всего лишь. Тут же...Можно ли сократить? Например убрать обработчик ошибок?


Знаете, когда-то давно, когда был MQL4, люди с возмущением говорили, что не дают им более низкоуровневого доступа - чтобы можно было что-то по-своему делать.

Ну вот, дали - теперь к составляющим OrderSend() в MQL4 дали доступ - так сказать развернули в MQL его логику - делайте что просили. Так нет - теперь возмущения, что слишком сложно.

Сложно? Не вопрос - нате вам торговые классы в СБ - практически то же самое, что и в MQL4 стандартные торговые функции.
Считайте, что в MQL4 такие классы - это и есть торговые функции. А в MQL5 - всё с открытым доступом.

Пользуйтесь.

 
Artyom Trishkin:

Знаете, когда-то давно, когда был MQL4, люди с возмущением говорили, что не дают им более низкоуровневого доступа - чтобы можно было что-то по-своему делать.

Ну вот, дали - теперь к составляющим OrderSend() в MQL4 дали доступ - так сказать развернули в MQL его логику - делайте что просили. Так нет - теперь возмущения, что слишком сложно.

Сложно? Не вопрос - нате вам торговые классы в СБ - практически то же самое, что и в MQL4 стандартные торговые функции.
Считайте, что в MQL4 такие классы - это и есть торговые функции. А в MQL5 - всё с открытым доступом.

Пользуйтесь.

Доцент, а Доцент. Ты почему такой злой (сегодня) ©