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

 
Добрый день. По мотивам урока " Использование структур для повышения эффективности разработки программ" воодушевился применением функции внутри структуры и создал вот такую простейшую конструкцию в МТ5.
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Expert\Money\MoneyFixedMargin.mqh>

CPositionInfo      m_position;// object of CPositionInfo class
COrderInfo         m_order;   // object of COrderInfo class
CTrade             m_trade;   // object of CTrade class
CSymbolInfo        m_symbol;  // object of CSymbolInfo class
CAccountInfo       m_account; // object of CAccountInfo class
CDealInfo          m_deal;    // object of CDealInfo class
CMoneyFixedMargin *m_money;   // object of CMoneyFixedMargin class
//+------------------------------------------------------------------+
//| Structure Positions                                              |
//+------------------------------------------------------------------+
struct STRUCT_POSITION
  {
   ENUM_POSITION_TYPE type;       // тип позиции
   ulong              ticket;     // тикет позиции
   long               identifier; // идентификатор
   long               magic;      // магический номер
   double             volume;     // объем позиции
   double             open_price; // цена открытия
   datetime           open_time;  // время открытия
   double             profit;     // профит позиции
   double             comission;  // комиссия
   double             swap;       // своп
   string             comment;    // комментарий
   
   void               GetCurrentPositionProperty();
  };
  STRUCT_POSITION StrPositionArray[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   STRUCT_POSITION.GetCurrentPositionProperty();
  }
//+------------------------------------------------------------------+
//---Заполнение массива свойств позиций                              +
//+------------------------------------------------------------------+
void STRUCT_POSITION::GetCurrentPositionProperty(void)
{   
   ZeroMemory(this);
   int pos_total = PositionsTotal();
   ArrayResize(StrPositionArray,pos_total,1000);
   for(int i=0; i<pos_total; i++)
      {
         if(m_position.SelectByIndex(i))
            {
               StrPositionArray[i].ticket     = m_position.Ticket();                  // тикет позиции
               StrPositionArray[i].identifier = m_position.Identifier();              // идентификатор
               StrPositionArray[i].magic      = m_position.Magic();                   // магический номер
               StrPositionArray[i].comment    = m_position.Comment();                 // комментарий
               StrPositionArray[i].type       =(ENUM_POSITION_TYPE)m_position.PositionType();// тип позиции
               StrPositionArray[i].volume     = m_position.Volume();                  // объем позиции
               StrPositionArray[i].open_price = m_position.PriceOpen();               // цена открытия
               StrPositionArray[i].open_time  = m_position.Time();                    // время открытия
               StrPositionArray[i].profit     = m_position.Profit();                  // профит позиции
               StrPositionArray[i].comission  = m_position.Commission();              // комиссия
               StrPositionArray[i].swap       = m_position.Swap();                    // своп
            }
      } 
} 
//+------------------------------------------------------------------+

В структуре

STRUCT_POSITION

присутствует метод 

GetCurrentPositionProperty(void)

который рассчитывает и присваивает значения элементам структуры. Определяем тело метода вне структуры. Для этого используем операцию разрешения контекста (::).

В OnTick() вызываем фунцию:

 

void OnTick() { //--- STRUCT_POSITION.GetCurrentPositionProperty(); }

И получаем ошибку:

'.' - name expected    eSower_and_Gather_5.mq5    69    19
Где накосячено не понимаю, помогите плиз.

 
Sergey Voytsekhovsky:

'.' - name expected    eSower_and_Gather_5.mq5    69    19

Что за строка 69 19? Опубликуйте строку кода 69 и укажите где 19 позиция. Сразу станет ясно где ошибка.

 
Vladimir Karputov:

Что за строка 69 19? Опубликуйте строку кода 69 и укажите где 19 позиция. Сразу станет ясно где ошибка.

STRUCT_POSITION.GetCurrentPositionProperty();

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

 
Vladimir Karputov:

Что за строка 69 19? Опубликуйте строку кода 69 и укажите где 19 позиция. Сразу станет ясно где ошибка.

Это точка, которая должна давать доступ к функции, которая в свою очередь использует контекст структурыю Это то что я понял из учебников. Но почему это не работает понять не могу.

 
Sergey Voytsekhovsky:

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

'STRUCT_POSITION' - это ТИП ДАННЫХ. Вам нужно создать переменную с этим типом и потом вызывать ПЕРЕМЕННАЯ.GetCurrentPositionProperty();

Документация по MQL5: Основы языка / Типы данных
Документация по MQL5: Основы языка / Типы данных
  • www.mql5.com
Любая программа оперирует данными. Данные могут быть различных типов в зависимости от назначения. Например, для доступа к элементам массива используются данные целочисленного типа. Ценовые данные имеют тип двойной точности с плавающей точкой. Это связано с тем, что в языке MQL5 не предусмотрено специального типа для ценовых данных. Данные...
 
Sergey Voytsekhovsky:

Это точка, которая должна давать доступ к функции, которая в свою очередь использует контекст структурыю Это то что я понял из учебников. Но почему это не работает понять не могу.

Код: (просто вызывается функция - функция советника, а не метод структуры - так понятнее)

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Expert\Money\MoneyFixedMargin.mqh>
//---
CPositionInfo      m_position;// object of CPositionInfo class
COrderInfo         m_order;   // object of COrderInfo class
CTrade             m_trade;   // object of CTrade class
CSymbolInfo        m_symbol;  // object of CSymbolInfo class
CAccountInfo       m_account; // object of CAccountInfo class
CDealInfo          m_deal;    // object of CDealInfo class
CMoneyFixedMargin *m_money;   // object of CMoneyFixedMargin class
//+------------------------------------------------------------------+
//| Structure Positions                                              |
//+------------------------------------------------------------------+
struct STRUCT_POSITION
  {
   ENUM_POSITION_TYPE type;       // тип позиции
   ulong              ticket;     // тикет позиции
   long               identifier; // идентификатор
   long               magic;      // магический номер
   double             volume;     // объем позиции
   double             open_price; // цена открытия
   datetime           open_time;  // время открытия
   double             profit;     // профит позиции
   double             comission;  // комиссия
   double             swap;       // своп
   string             comment;    // комментарий

   void               GetCurrentPositionProperty();
  };
STRUCT_POSITION StrPositionArray[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   GetCurrentPositionProperty();
  }
//+------------------------------------------------------------------+
//| Заполнение массива свойств позиций                               |
//+------------------------------------------------------------------+
void GetCurrentPositionProperty(void)
  {
   int pos_total = PositionsTotal();
   ArrayResize(StrPositionArray,pos_total,1000);
   for(int i=0; i<pos_total; i++)
     {
      if(m_position.SelectByIndex(i))
        {
         StrPositionArray[i].ticket     = m_position.Ticket();                  // тикет позиции
         StrPositionArray[i].identifier = m_position.Identifier();              // идентификатор
         StrPositionArray[i].magic      = m_position.Magic();                   // магический номер
         StrPositionArray[i].comment    = m_position.Comment();                 // комментарий
         StrPositionArray[i].type       =(ENUM_POSITION_TYPE)m_position.PositionType();// тип позиции
         StrPositionArray[i].volume     = m_position.Volume();                  // объем позиции
         StrPositionArray[i].open_price = m_position.PriceOpen();               // цена открытия
         StrPositionArray[i].open_time  = m_position.Time();                    // время открытия
         StrPositionArray[i].profit     = m_position.Profit();                  // профит позиции
         StrPositionArray[i].comission  = m_position.Commission();              // комиссия
         StrPositionArray[i].swap       = m_position.Swap();                    // своп
        }
     }
  }
//+------------------------------------------------------------------+
 
Vladimir Karputov:

'STRUCT_POSITION' - это ТИП ДАННЫХ. Вам нужно создать объект с этим типом и потом вызывать ОБЬЕКТ.GetCurrentPositionProperty();

Пробовал. Такой обЪект создан, объявлен сразу после объявления структуры

StrPositionArray[]

Если прописать в ОнТике

void OnTick()
  {
//---
   StrPositionArray[].GetCurrentPositionProperty();
  }

получаем ошибку:

']' - expression expected eSower_and_Gather_5.mq5 69 21

это та-же строка, только вторая скобка, та что прямо перед точкой.
 
Vladimir Karputov:

Код: (просто вызывается функция - функция советника, а не метод структуры - так понятнее)

Тоесть использовать :: было пустой затеей? 

Тогда зачем прописывать функцию 

GetCurrentPositionProperty()

внутри структуры??? Она ведь и без прописывания внутри структиуры отлично будет заполнять ее. Проясните плиз, что-то вообще запутался, может это уже устаревшая фишка, про которую нужно забыть ???

 
Sergey Voytsekhovsky:

Тоесть использовать :: было пустой затеей? 

Тогда зачем прописывать функцию 

внутри структуры??? Она ведь и без прописывания внутри структиуры отлично будет заполнять ее. Проясните плиз, что-то вообще запутался, может это уже устаревшая фишка, про которую нужно забыть ???

Копипаст. Осталась строка после копипаста.

Нужно так (внутри структуру нет никаких методов)

//+------------------------------------------------------------------+
//| Structure Positions                                              |
//+------------------------------------------------------------------+
struct STRUCT_POSITION
  {
   ENUM_POSITION_TYPE type;       // тип позиции
   ulong              ticket;     // тикет позиции
   long               identifier; // идентификатор
   long               magic;      // магический номер
   double             volume;     // объем позиции
   double             open_price; // цена открытия
   datetime           open_time;  // время открытия
   double             profit;     // профит позиции
   double             comission;  // комиссия
   double             swap;       // своп
   string             comment;    // комментарий
  };
STRUCT_POSITION StrPositionArray[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
 
Vladimir Karputov:

Копипаст. Осталась строка после копипаста.

Нужно так (внутри структуру нет никаких методов)

Ну вот, а я столько времени потратил на урок. Правда он был для МТ4, там это преподнесено как фишка, вот выдержка из текста:

1
2
3
4
5
6
7
8
9
10
11
12
struct state
   {
    int                buy_count;         // количество ордеров buy
    int                sell_count;        // количество ордеров sell
    double             buy_bottom_price;  // цена открытия самого нижнего ордера buy
    double             sell_top_price;    // цена открытия самого верхнего ордера sell
    double             profit;            // прибыль всех ордеров
 
    // метод для сбора информации о состоянии счёта
    // и обновления элементов структуры
    void               Refresh();
   } State;

В структуре присутствует метод  Refresh(), который рассчитывает и присваивает значения элементам структуры. Определим тело метода вне структуры. Для этого используем операцию разрешения контекста (::). Контекст – это дескриптор (имя) структуры:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//+------------------------------------------------------------------+
//| Метод собирает информацию о текущем состоянии счёта              |
//| и обновляет соответствующие поля структуры                       |
//+------------------------------------------------------------------+
void state::Refresh( void )
   {
// обнуляем числовые поля структуры
    ZeroMemory( this );
 
    for ( int i=OrdersTotal()-1; i>=0; i--)
       if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
          if (OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
            {
             double OpenPrice=OrderOpenPrice();
             profit+=OrderProfit()+OrderCommission()+OrderSwap();
             switch (OrderType())
               {
                case OP_BUY:
                   buy_count++;
                   if (OpenPrice<buy_bottom_price || buy_bottom_price==0)
                      buy_bottom_price=OpenPrice;
                   break ;
                case OP_SELL:
                   sell_count++;
                   if (OpenPrice>sell_top_price || sell_top_price==0)
                      sell_top_price=OpenPrice;
                   break ;
               }
            }
 
   }

Обратите внимание, что в теле метода мы обращаемся к элементам структуры, не используя точку, так как мы использовали операцию разрешения контекста. Числовые поля перед их обновлением в самом начале тела метода обнуляются функцией  ZeroMemory() с ключевым словом  this, таким образом, структура передаёт ссылку на саму себя.

Основной код советника внутри обработчика  OnTick() теперь будет выглядеть так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
   {
    for ( int i=0; i<2000; i++)
    {
     double b=MathSqrt(i);
    }
// открываем новые ордера и фиксируем прибыль только на открытии нового бара
    if (IsNewBar())
      {
       // получаем новый сигнал
       int Signal=GetSignal();
       // сразу выходим из функции, если на закрытом баре не был сформирован сигнал
       if (Signal<0)
          return ;
 
       // обновляем структуру
       State.Refresh(); // (!!!)
Причина обращения: