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

 
Artyom Trishkin:
Pues bien, yo lo plasmaría todo en una función, y la llamaría cuando la necesite -incluso en cada tick (si es razonable y necesario), o en la apertura de una nueva vela- por ejemplo, una vez por hora, si trabajamos en H1.

Con la función, por supuesto, es práctico. Ya tengo el código resuelto. Ahora está claro. Voy a pensar, cómo llevarlo a esos fines que quiero y entender, cuándo y en qué momento tomar los datos necesarios.

 
Koldun Zloy:

Si fuera directamente "el colmo de la imprudencia", estaría prohibido.

WinAPI amplía enormemente las capacidades de MQL. Y puedes hacer una estupidez incluso sin dll.

Y aquí hay un ejemplo de paso de cadenas al portapapeles:

Bien hecho, y además con comentarios.

Gracias.

Aquí hay otra pregunta.

¿Sería posible emular un clic del ratón en unas coordenadas determinadas?

 
mila.com:

Genial, y además con comentarios.

Gracias.

Una pregunta más.

¿Es posible hacer una emulación de un clic de ratón en las coordenadas dadas?

Si no tienes que hacerlo desde MQL, mira en AutoIT, puedes hacer cualquier cosa allí. El producto es gratuito, sólo necesitas una DLL para interactuar con MQL.
 
mila.com:

Genial, y además con comentarios.

Gracias.

Una pregunta más.

¿Es posible emular un clic del ratón en unas coordenadas determinadas?

Sí, podemos.

#define  MK_LBUTTON     0x0001
#define  WM_LBUTTONDOWN 0x0201
#define  WM_LBUTTONUP   0x0202

struct POINT
{
   int x;
   int y;
};

#import "User32.dll"
   uint WindowFromPoint( int x, int y );
   uint PostMessageW( uint hWnd, uint Msg, uint wParam, uint lParam );
   int ScreenToClient( uint hWnd, POINT& lpPoint );
#import

int x = 1000;  // Экранные координаты
int y = 350;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   uint hwnd = WindowFromPoint( x, y ); // Получаем дескриптор окна в нужном месте
   
   if( hwnd ){
      POINT point;
      point.x = x;
      point.y = y;
      ScreenToClient( hwnd, point );  // Преобразуем экранные координаты в координаты рабочей области окна
      
      uint lParam = (point.y * 65536) + (point.x & 0xFFFF);  // Упаковываем координаты в 32-разрядное целое
      
      PostMessageW( hwnd, WM_LBUTTONDOWN, MK_LBUTTON, lParam ); // Посылаем сообщения от "мыши"
      PostMessageW( hwnd, WM_LBUTTONUP, MK_LBUTTON, lParam );
   }
}
 
Artyom Trishkin:
Pues bien, yo lo formaría todo en una función y la llamaría cuando lo necesitara - en cada tick (si es necesario y razonable) o en la apertura de una nueva vela - por ejemplo, una vez por hora, si trabajamos con H1.

Artem, entiendo correctamente, que si tenemos un bucle:for(int i=0; i<copy_bars; i++) y hay un bucle for(int j=0; j<copy_bars; j++) donde if(j==i) continue; ,

significará que el conteo es paralelo y si tenemos aproximadamente 5 velas, la comparación continuará:

1 con 1 - descarte.

1 con 2, 1 con 3, 1 con 4, 1 con 5.

Entonces se iniciará un ciclo donde estará:

2 con 1, 2 con 3, 2 con 4, 2 con 5.

y así sucesivamente.

¿Es así como va a ser?

 
Andrey Koldorkin:

Artem, he entendido bien, si tenemos un bucle:for(int i=0; i<copy_bars; i++) y hay un bucle for(int j=0; j<copy_bars; j++) donde if(j==i) continue; ,

significará que el conteo es paralelo y si tenemos aproximadamente 5 velas, la comparación continuará:

1 con 1 - descarte.

1 con 2, 1 con 3, 1 con 4, 1 con 5.

Entonces se iniciará un ciclo donde estará:

2 con 1, 2 con 3, 2 con 4, 2 con 5.

y así sucesivamente.

¿Será lo mismo?

Sí.
 
Artyom Trishkin:
Sí.

Otra pregunta: Si no necesitamos comparar la vela actual, ¿no tenemos que empezar la cuenta desde 1 y no desde cero?

¿O debemos entender que aquí el 0 es la vela 1, el 1 es la vela 2, etc.?

 
Andrey Koldorkin:

Otra pregunta: Si no necesitamos comparar la vela actual, ¿no tenemos que empezar la cuenta desde 1 y no desde cero?

¿o debemos entender que aquí 0 es la vela 1, 1 es la vela 2, etc.?

Aquí el cero es el principio de la matriz. Y en el array escribimos las velas desde la primera hasta ..., no "hasta", sino en el número que necesitemos:

int copied=CopyRates(Symbol(),PERIOD_CURRENT,1,copy_bars,array);

1 es el número de velas a copiar, y copy_bars es el número de velas a copiar.

Por lo tanto, array[] contiene la vela necesaria en la celda con índice 0 - ya sea 1 o 1+copy_bars-1. Dependiendo de la dirección de indexación de array[] (ArraySetAsSeries() establece la dirección de indexación, que se puede comprobar utilizando ArrayGetAsSeries(), ArrayIsSeries())

 
Artyom Trishkin:

Aquí el cero es el principio de la matriz. Y en el array escribimos velas desde la primera hasta ..., no "hasta", sino en número de velas que necesitamos:

1 es el número de velas a copiar, y copy_bars es el número de velas a copiar.

Por lo tanto, array[] contiene la vela requerida en la celda con índice 0 - ya sea 1 o 1+copy_bars-1. Dependiendo de la dirección de indexación de array[] (ArraySetAsSeries() establece la dirección de indexación, que se puede comprobar con ArrayGetAsSeries(), ArrayIsSeries())

Esta programación. Cuanto más se adentre en el bosque....

Primero he comprobado lo que muestra a través de la Alerta. Parece que es al revés, es decir, la vela más cercana a la actual tiene el número máximo.

Entonces lo comprobé vía:

bool series=ArrayIsSeries(dataCandle);

Alerta (serie);

y el script muestra "falso".

Según mi lógica, si false está en el extremo equivocado, entonces true estará en el extremo correcto.

Yo receté:

ArraySetAsSeries (dataCandle, true); //cambiar la dirección

bool series=ArrayIsSeries(dataCandle); //comprobar de nuevo

Alert (series); //escribir el resultado en la pantalla.

Pero sigo recibiendo "falso" después de eso.

¿Cuál es mi problema?

 
Andrey Koldorkin:

Oh, esta programación. Cuanto más se adentre en el bosque....

Primero comprobé sólo a través de Alerta lo que estaba dando. Resulta ser lo contrario, es decir, la vela más cercana a la vela actual tiene el número máximo.

Entonces lo comprobé vía:

bool series=ArrayIsSeries(dataCandle);

Alerta (serie);

y el script muestra "falso".

Según mi lógica, si false está en el extremo equivocado, entonces true estará en el extremo correcto.

Yo receté:

ArraySetAsSeries (dataCandle, true); //cambiar la dirección

bool series=ArrayIsSeries(dataCandle); //comprobar de nuevo

Alert (series); //escribir el resultado en la pantalla.

Pero sigo recibiendo "falso" después de eso.

¿Cuál es mi problema?

El dataCandles es una estructura. El array donde escribimos las velas del historial - array[]. Y tenemos que hacerlo como una serie de tiempo para que su indexación coincida con la indexación de las velas en el gráfico. Es decir, la celda cero del array[] corresponderá a las velas más cercanas a la fecha actual.

Es decir, 1. copiar las velas en la matriz array[], 2. convertirla en una serie temporal, y luego leer los valores de la misma en la estructura.

Se puede prescindir de array[] - simplemente escribir los datos directamente desde el gráfico en la estructura, pero sugerí esto por compatibilidad con Five - permite copiar directamente sólo en el indicador usando high[i], low[i] y otros datos, pero en el script o Asesor Experto, tenemos que copiar primero el intervalo de historia necesario en el array, lo cual hice.

Razón de la queja: