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

 
Подскажите плз, как проще и быстрее всего получить результат последней сделки по текущему символу? А то из документации все сложно как то. Для получения результата надо найти сначала тикет нужной сделки, что б найти тикет нужно найти сделку в итории по ее индексу, индекс надо искать в истории, не говоря о том, что еще надо по символу отфильтровать. появляется чувство, что я слишком усложняю задачу
 
WinZip:
Подскажите плз, как проще и быстрее всего получить результат последней сделки по текущему символу? А то из документации все сложно как то. Для получения результата надо найти сначала тикет нужной сделки, что б найти тикет нужно найти сделку в итории по ее индексу, индекс надо искать в истории, не говоря о том, что еще надо по символу отфильтровать. появляется чувство, что я слишком усложняю задачу

Чтобы не лезть в торговую историю каждый раз - просто отлавливайте в OnTradeTransaction сделку с типом 

TRADE_TRANSACTION_DEAL_ADD – добавление сделки в историю


//+------------------------------------------------------------------+
//| 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)
     {
      long     deal_ticket       =0;
      long     deal_order        =0;
      long     deal_time         =0;
      long     deal_time_msc     =0;
      long     deal_type         =-1;
      long     deal_entry        =-1;
      long     deal_magic        =0;
      long     deal_reason       =-1;
      long     deal_position_id  =0;
      double   deal_volume       =0.0;
      double   deal_price        =0.0;
      double   deal_commission   =0.0;
      double   deal_swap         =0.0;
      double   deal_profit       =0.0;
      string   deal_symbol       ="";
      string   deal_comment      ="";
      string   deal_external_id  ="";
      if(HistoryDealSelect(trans.deal))
        {
         deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
         deal_order        =HistoryDealGetInteger(trans.deal,DEAL_ORDER);
         deal_time         =HistoryDealGetInteger(trans.deal,DEAL_TIME);
         deal_time_msc     =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);
         deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_reason       =HistoryDealGetInteger(trans.deal,DEAL_REASON);
         deal_position_id  =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);

         deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_price        =HistoryDealGetDouble(trans.deal,DEAL_PRICE);
         deal_commission   =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);
         deal_swap         =HistoryDealGetDouble(trans.deal,DEAL_SWAP);
         deal_profit       =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);

         deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);
         deal_external_id  =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);
        }
      else
         return;
      ENUM_DEAL_ENTRY enum_deal_entry=(ENUM_DEAL_ENTRY)deal_entry;
      if(deal_symbol==m_symbol.Name() && deal_magic==InpMagic)
        {
         if(deal_type==DEAL_TYPE_BUY || deal_type==DEAL_TYPE_SELL)
           {
            
...
           }
        }
     }
  }

m_symbol.Name() - текущий символ, InpMagic - уникальный идентификатор эксперта

 
Здравствуйте  я зарегистрировался через  сайт и с фейсбук почты и немогу зайти через мета трейдер 5-4 помогите и пополтил счет 
 
Igor Makanu:

далеко не факт, вот проверял что быстрее _Symbol или Symbol() https://www.mql5.com/ru/forum/160683/page933#comment_12780905

т.е. время доступа один в один, оптимизация кода в MQL очень круто работает, поэтому, что удобнее то и используйте

по моим тестам время доступа к переменной может отличаться, смотря где описана переменная и с какими модификаторами, но там 2-5% скорости, что в принципе можно списать на реализацию в конкретном билде, от номера билда точно это зависит

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

Так же погугли за ключевые слова

__inline 
__forceinline
Как ни странно, они есть в mql как не документированные.
 
Roman:

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

не надо ничего продумывать, для этих вещей служат мануалы, а мануала по распределению памяти в MQL никогда не было, только сообщения разработчиков, причем часто с уточнением, что реализация может измениться

ладно, разговор сводится кто какую книжку по программированию читал, я со школы и до сих пор читаю и так последние 30 лет

 
Igor Makanu:

не надо ничего продумывать, для этих вещей служат мануалы, а мануала по распределению памяти в MQL никогда не было, только сообщения разработчиков, причем часто с уточнением, что реализация может измениться

ладно, разговор сводится кто какую книжку по программированию читал, я со школы и до сих пор читаю и так последние 30 лет

Конечно не надо продумывать, а зачем... компилятор сам всё сделает. ))
C# не С

А по __inline смотри видос.
Там как раз объясняется как работают функции в памяти, для тех кому нет ни какой разницы.

[Удален]  
Vladimir Karputov:

Картинку сначала нарисуйте и укажите что для Вас "нулевой бар" для индикатора с параметром shift.

Нарисовал. Нулевой бар выделен вертикальной линией.


 
RickD:

Нарисовал. Нулевой бар выделен вертикальной линией.


Пример кода:

//+------------------------------------------------------------------+
//|                                        iMA Values on a Chart.mq5 |
//|                              Copyright © 2019, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- input parameters
input int                  Inp_MA_ma_period     = 12;          // MA: averaging period
input int                  Inp_MA_ma_shift      = 5;           // MA: horizontal shift
input ENUM_MA_METHOD       Inp_MA_ma_method     = MODE_SMA;    // MA: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_applied_price = PRICE_CLOSE; // MA: type of price
//---
int    handle_iMA;                           // variable for storing the handle of the iMA indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iMA
   handle_iMA=iMA(Symbol(),Period(),Inp_MA_ma_period,Inp_MA_ma_shift,
                  Inp_MA_ma_method,Inp_MA_applied_price);
//--- if the handle is not created
   if(handle_iMA==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double array_ma[];
   ArraySetAsSeries(array_ma,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iMA,0,start_pos,count,array_ma))
      return;

   string text="";
   for(int i=0; i<count; i++)
      text=text+IntegerToString(i)+": "+DoubleToString(array_ma[i],Digits()+1)+"\n";

   Comment(text);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+

Результат:


Как видите спокойно копируется, без танцев с бубном.

Файлы:
[Удален]  
Vladimir Karputov:

Пример кода:

Результат:


Как видите спокойно копируется, без танцев с бубном.

Пример кода. На основе индикатора. Индикатор занимается распледелением памяти буфера.

#property copyright "Copyright 2019"
#property link      ""
#property version   "1.00"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   0

//---

input int                  MA_period = 12;
input int                  MA_shift = 5;
input ENUM_MA_METHOD       MA_method = MODE_SMA;
input ENUM_APPLIED_PRICE   MA_applied_price = PRICE_CLOSE;

int start_pos = 0;

//---

double MA_Calc_Buf[];

int hMA = INVALID_HANDLE;


int OnInit()
{
  SetIndexBuffer(0, MA_Calc_Buf, INDICATOR_CALCULATIONS); 
  ArraySetAsSeries(MA_Calc_Buf, true);
 
  hMA = iMA(NULL, 0, MA_period, MA_shift, MA_method, MA_applied_price);   
  if (hMA == INVALID_HANDLE)
  {
    int LErr = GetLastError();
    PrintFormat("iMA create failed (%d)", LErr);
    return (INIT_FAILED);
  }
 
  return (INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
  if (hMA != INVALID_HANDLE)
  {
    IndicatorRelease(hMA);
    hMA = INVALID_HANDLE;
  }
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{ 
  int copied;
  copied = CopyBuffer(hMA, 0, start_pos, rates_total, MA_Calc_Buf);
  if (copied == -1)
  {
    int LErr = GetLastError();
    PrintFormat("CopyBuffer(hMA) failed (%d)", LErr);
    return (prev_calculated);
  }
 
  if (copied == 0)
  {
    PrintFormat("CopyBuffer(hMA) copied 0 bars");
    return (prev_calculated);
  } 
 
  string text = "";
  for (int i=0; i<15; i++)
    text = text + IntegerToString(i) + ": " + DoubleToString(MA_Calc_Buf[i], Digits()+1) + "\n";
 
  Comment(text);

  return (rates_total);
}

Когда start_pos = 0, то значение, соответствующее 0-му бару чарта, мы видим на 5-й позиции. 1.017041 В вашем эксперте оно на нулевой позиции. Ok.


Но мне нужно получить это значение на нулевой позиции.

Я задаю start_pos = 5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -10. И только сейчас получаю нужный результат.


 
RickD:

Пример кода. На основе индикатора. Индикатор занимается распледелением памяти буфера.

Когда start_pos = 0, то значение, соответствующее 0-му бару чарта, мы видим на 5-й позиции. 1.017041 В вашем эксперте оно на нулевой позиции. Ok.


Но мне нужно получить это значение на нулевой позиции.

Я задаю start_pos = 5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -10. И только сейчас получаю нужный результат.


Нужно понимать разницу при работе ИЗ советника и ИЗ индикатора. Для работы из индикатора пользуйтесь примером из справки (iMA).

Документация по MQL5: Технические индикаторы / iMA
Документация по MQL5: Технические индикаторы / iMA
  • www.mql5.com
//|                                                     Demo_iMA.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iMA;                ...