Preguntas de los principiantes MQL5 MT5 MetaTrader 5 - página 1264

 
Hola.Me inspiréen la lección " Uso de estructuras para el desarrollo eficaz de programas"y creé una estructura sencilla como ésta en MT5.
#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();                    // своп
            }
      } 
} 
//+------------------------------------------------------------------+

En la estructura

ESTRUCTURA_POSICIÓN

La estructura contiene el método

GetCurrentPositionProperty(void)

que calcula y asigna valores a los elementos de la estructura. Definir el cuerpo del método fuera de la estructura. Para ello, utilice la operación de resolución de contexto (::).

En OnTick() llamamos a la función:

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

Y aquí obtenemos un error:

'.' - nombre esperado eSower_and_Gather_5.mq5 69 19
No sé dónde ha ido mal, por favor, ayuda.

 
Sergey Voytsekhovsky:

'.' - nombre esperado eSower_and_Gather_5.mq5 69 19

¿Qué es la línea 69 19? Por favor, publique la línea de código 69 y especifique dónde está la posición 19. Inmediatamente se verá dónde está el error.

 
Vladimir Karputov:

¿Qué es la línea 69 19? Contabilice la línea 69 y especifique dónde está la posición 19. Inmediatamente se verá dónde está el error.

STRUCT_POSITION.GetCurrentPositionProperty();

Está resaltado en rojo en el post anterior. Gracias por su pronta respuesta.

 
Vladimir Karputov:

¿Qué es la línea 69 19? Contabilice la línea 69 y especifique dónde está la posición 19. Inmediatamente se verá dónde está el error.

Este es un punto que debe dar acceso a una función que a su vez utiliza el contexto de la estructura. Pero no puedo entender por qué no funciona.

 
Sergey Voytsekhovsky:

está resaltado en rojo en el post anterior. Gracias por su pronta respuesta.

STRUCT_POSITION' es un TIPO DE DATOS. Es necesario crear una variable con este tipo y luego llamar a VARIABLE.GetCurrentPositionProperty();

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

Este es el punto que debe dar acceso a la función, que a su vez utiliza el contexto de la estructura.Esto es lo que he entendido de los libros de texto. Pero no puedo entender por qué no funciona.

Código: (sólo llamar a una función - función EA, no un método de estructura - que tiene más sentido)

//+------------------------------------------------------------------+
//|                                                      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' es un TIPO DE DATOS. Es necesario crear un objeto con este tipo y luego llamar a OBJECT.GetCurrentPositionProperty();

Lo he probado. Dicho objeto se crea, se declara justo después de la declaración del

StrPositionArray[].

Si lo pones en OnTick

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

obtenemos un error:

']' - expresión esperada eSower_and_Gather_5.mq5 69 21

Esta es la misma línea, sólo el segundo paréntesis, el que está justo antes del punto.
 
Vladimir Karputov:

Código: (sólo llamar a una función - función EA, no un método de estructura - que tiene más sentido)

¿Así que usar :: fue una idea inútil?

Entonces, ¿por qué escribió la función

GetCurrentPositionProperty()

dentro de la estructura? Llenaría la estructura sin ningún relleno en su interior, ¿no es así? Por favor, aclárense, estoy confundido, ¿tal vez sea una función obsoleta, debería olvidarme de ella?

 
Sergey Voytsekhovsky:

¿Así que usar :: fue una pérdida de tiempo?

Entonces, ¿por qué escribir una función

dentro de la estructura??? Es decir, llenará la estructura perfectamente incluso sin ella. Por favor, aclárense, estoy confundido, tal vez sea una idea obsoleta que debería olvidarse.

Copiar y pegar. Queda una línea después del copypaste.

Debería ser así (no hay métodos dentro de la estructura)

//+------------------------------------------------------------------+
//| 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:

Copiar y pegar. Queda una línea después del copypaste.

Debería ser así (no hay métodos dentro de la estructura)

Bueno, he pasado mucho tiempo en la lección. Aunque era para MT4, allí se presentaba como un truco, así que aquí hay un extracto del texto:

1
2
3
4
5
6
7
8
9
10
11
12
struct state
{
int buy_count; // número de órdenes de compra
int sell_count; // número de órdenes de venta
double buy_bottom_price; //precio de apertura de la orden de compra más baja
double sell_top_price; //precio de apertura de la orden de venta más alta
double profit; // beneficio de todos los pedidos
// método para recoger información sobre el estado de la cuenta
// y refrescar los elementos de la estructura
void Refresh() ;
} Estado;

La estructura tiene un método Refresh() que calcula y asigna valores a los elementos de la estructura. Vamos a definir el cuerpo del método fuera de la estructura. Para ello, utilice la operación de resolución de contexto (::). El contexto es un descriptor (nombre) de la estructura:

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
//+------------------------------------------------------------------+
//| El método recoge información sobre el estado actual de la cuenta ||
//| y actualiza los campos relevantes de la estructura ||
//+------------------------------------------------------------------+
void state::Refresh( void )
{
//cero los campos numéricos de la estructura
ZeroMemory( this );
for ( int i=TotalPedidos()-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())
{
caso OP_BUY:
buy_count++;
si (Precio_abierto<precio_inferior_de_compra || precio_inferior_de_compra==0)
buy_bottom_price=Precio Abierto;
romper ;
caso OP_SELL:
vender_cuentas++;
si (Precio_abierto>precio_de_venta ||precio_de_venta==0)
sell_top_price=Precio Abierto;
romper ;
}
}
}

Nótese que en el cuerpo del método nos referimos a los elementos de la estructura sin utilizar un punto, ya que utilizamos la operación de resolución de contexto. Los campos numéricos se ponen a cero mediante ZeroMemory() con la palabra clave this antes de actualizarlos al principio del cuerpo del método, por lo que la estructura pasa una referencia a sí misma.

El código principal de EA dentro del manejador OnTick() ahora se verá así

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
//+------------------------------------------------------------------+
//| Función de tic experto|
//+------------------------------------------------------------------+
void OnTick()
{
for ( int i=0; i<2000; i++)
{
doble b=MathSqrt(i);
}
// abrir nuevas órdenes y tomar beneficios sólo en la apertura de una nueva barra
si (IsNewBar())
{
// obtener una nueva señal
int Señal=GetSignal();
// salir inmediatamente de la función si la señal no se ha generado en la barra cerrada.
si (Señal<0)
volver ;
//actualizar la estructura
State.Refresh(); // (!!! )