Leer el macd de todos los simbolos dentro de la marketwatch

 

Buenas, 


Tengo una duda existencial en la creación de un indicador.

Estoy intentando crear un screener o buscador dentro de la  MarketWatch y necesito saber el macd de la posición 0 de todas acciones dentro de dicha ventana.

Para saber el macd necesito llamar a la funcion imacd pero esta la tengo que introducir fuera de Oninit para que me vaya leyendo el macd de las diferentes acciones

y a lo mejor por eso no funciona pero no veo otra opción.


Como veréis dentro de la función iMacd esta el string name que en teoría va cambiando a medida que varia el symbolo pero no se pq es como si no cambiara.


Que creéis que se puede modificar para que lea todos los valores de todos los simbolos?


este es mi código:


int p;

bool selected=true;
string name;
double macd[];

int MacdDefinition;


  int OnInit()
  {


//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---

 if(IsNewbar()==true){
 
Print("/////////////////////////////");


   
   ArraySetAsSeries(macd,true);    
   
    
 for(p=0;p<SymbolsTotal(selected);p++){
  
  name=SymbolName(p,selected);

  Print(name); 
          
  
MacdDefinition=iMACD(
name ,0,12,26,9,PRICE_CLOSE);
  
  
  CopyBuffer(MacdDefinition,0,0,5,macd);  
      

float macdvalue=macd[0];

Print("macd ",macdvalue);


     }
  
   }
   
 
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 

Correcto, parte del problema es ese, que esta  dando valor al "Manejador"  del iMACD en el OnTick, y por ello no tiene data para Calcular sobre cada nuevo Simbolo.
La solucion entonces puede ser:
1. Saber todos los sombolos con los que trabajara y crear un manejador por cada simbolo, y le asocia su valor a cada uno, en el OnInit. por ejemplo.

MacdDefinitionEURUSD = iMacd("EURUSD",x,x,x,x)
MacdDefinitionGBPUSD = iMacd("GBPUSD",x,x,x,x)

2.  permitir hacer el llamado en cada tick (y no una vez por vela). Con esto, garantizas que en algun momento, cuando llegue un nuevo tick a cada par, y a su vez, en el par donde esta el indicador,  pues tendra la data necesaria para calcularlo.
Esta segunda opcion la puedes filtrar con un cambio de precio, por ejemplo. pero entonces, tendra conflicto si se muestra o se oculta un nuevo par en el marketwatch, ademas de que consumirás muchos recursos.

Este "tema" te ayudara https://www.mql5.com/en/forum/322393

Saludos!!!

Error 4806 Requested data not found when CopyBuffer
Error 4806 Requested data not found when CopyBuffer
  • 2019.09.16
  • www.mql5.com
Hi Traders/Devs, I am trying to create quite a complex indicator that pulls data from the 28 major pairs and I keep getting error 4806 when I try t...
 

Muchas gracias por la ayuda Miguel Antonio,


Lo que ocurre es que tengo muchísimas acciones en el marketwatch y seria muy complicado hacerlo como en la solución 1 y en cuanto a la solución 2 consumiría demasiados recursos

y el ordenador fallaría.


Lo que me extraña es que con MQL4 funciona correctamente y de forma mucho más sencilla. no se supone que la versión MQL5 se realizó para mejorar la antigua versión?

Quiero creer que si con MQL4 se puede con MQL5 también no?


Te paso el código en MQL4:


 if (IsNewbar()==true){



for(i=0;i<SymbolsTotal(selected);i++){

 
 name=SymbolName(i,selected);   


 double macd=iMACD(name,PERIOD_H1,fastEMA,slowEMA,signalSMA,PRICE_CLOSE,MODE_MAIN,0); 

        

  Print(name+ " " + macd);

   }

  }
 
 
 //--- return value of prev_calculated for next call
   return(rates_total);
  }
 
jlvazquez:

Muchas gracias por la ayuda Miguel Antonio,


Lo que ocurre es que tengo muchísimas acciones en el marketwatch y seria muy complicado hacerlo como en la solución 1 y en cuanto a la solución 2 consumiría demasiados recursos

y el ordenador fallaría.


Lo que me extraña es que con MQL4 funciona correctamente y de forma mucho más sencilla. no se supone que la versión MQL5 se realizó para mejorar la antigua versión?

Quiero creer que si con MQL4 se puede con MQL5 también no?


Te paso el código en MQL4:


Pues es verdad, y aun asi, MQL5 es mejor que MQl4, 
Solo que no permite hacer mas sencillo todo.
Esto ocurre porque, de ser lo contrario, de necesitar solo uno, en MQL5, es mas sencillo, y mas "Ahorrador", tener un manejador desde el inicio, y no estar "llamandolo y/o creandolo" cada tick. (que de hecho tambien lo puedes hacer con varios, pero sabiendo la cantidad  previamente)

Pero tu necesidad es puntual y no se me ocurre mas que, usar una funcion en OnInit para crear un array de manejadores, 
y en la funcion OnTick() filtrar cuales de esos simbolos han cambiado en cada nueva vela para extraer el dato del indicador, lo marco como "ya recogi el dato en esta nueva vela, asi que lo omito por los proximos ticks HASTA una nueva vela"


esta opcion es viable, pero fallaria si  oculto o muestro un nuevo simbolo en el observador de mercado. Aunque  tambien puedo pensar en que poco sucedera y en caso de ello, buscar la forma de observar "ese cambio" para reiniciar todo.

Espero que le encuentres la vuelta
Saludos!!

 

Entonces entiendo que lo que debería hacer es poner un array de manejadores para todo los símbolos dentro de la función Oninit y después en la función Ontick recoger los datos que me interesen en cada vela nueva no?


Como lo hago para no tener que escribir un manejador para cada símbolo si tengo 500 por ejemplo?


Saludoooos!!

 
jlvazquez:

Entonces entiendo que lo que debería hacer es poner un array de manejadores para todo los símbolos dentro de la función Oninit y después en la función Ontick recoger los datos que me interesen en cada vela nueva no?


Como lo hago para no tener que escribir un manejador para cada símbolo si tengo 500 por ejemplo?


Saludoooos!!

declaras un array de  tipo INT, vacio,
Corres un ciclo for por todos los pares de la marketWatch,
cambias el tamaño del Array, 
Agregas a esa posicion del array, el manejador de ese par o simbolo en especifico.

la idea es que tanto el for de la creacion del manejador, como el for de la consulta, deben ser iguales, para que siempre esten considerando la misma posicion y el mismo par.

Recuerda que esto fallaria si ocultas o muestras un nuevo par en la ventana, pero lo puedes controlar y "reiniciar"

Espero que con esto puedas avanzar

Saludos!!!!


 

Buenas Miguel Antonio, 


Me he leído un montón de veces tu respuesta y he probado diferentes formas de codificarlo y todavía no he entendido exactamente como hacerlo.


Me podrías enviar un ejemplo sencillo ?


Saludooos !!

 
jlvazquez:

Buenas, 


Tengo una duda existencial en la creación de un indicador.

Estoy intentando crear un screener o buscador dentro de la  MarketWatch y necesito saber el macd de la posición 0 de todas acciones dentro de dicha ventana.

Para saber el macd necesito llamar a la funcion imacd pero esta la tengo que introducir fuera de Oninit para que me vaya leyendo el macd de las diferentes acciones

y a lo mejor por eso no funciona pero no veo otra opción.


Como veréis dentro de la función iMacd esta el string name que en teoría va cambiando a medida que varia el symbolo pero no se pq es como si no cambiara.


Que creéis que se puede modificar para que lea todos los valores de todos los simbolos?


este es mi código:


Hola jlvazquez, 

Prueba esto a ver si te funciona. Es para MQL5.

#include <Indicators\Oscilators.mqh>
CiMACD MiMACD;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Funcion()
  {
   int CantDeSimbolos = SymbolsTotal(true);
   for(int i = 0; i < CantDeSimbolos; i++)
     {
      string SimboloSeleccionado = SymbolName(i, true);
      MiMACD.Create(SimboloSeleccionado, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE);
      MiMACD.Refresh();
      if(SymbolIsSynchronized(SimboloSeleccionado))
        {
         Print("Main line: ", MiMACD.Main(0), "   ", "Signal line: ", MiMACD.Signal(0));
        }
     }
  }

Saludos...

 

Buenas,

ahora veo tu respuesta ya que no esperaba que me respondiese el Miguel Antonio y no entré más.

Al final he optado por crearme la formula del indicador por mi mismo y incluirlo dentro del Oninit y funciona perfectamente,

lo único que es un poco laborioso pq tienes que programar el indicador.

He probado con lo que me has enviado y me salen varios resultados extraños para cada símbolo (imagen adjunta).

En todo caso muchas gracias por haber contestado.

Saludoooos.

Archivos adjuntos:
macd_mt5.png  31 kb
 
jlvazquez:

Buenas,

ahora veo tu respuesta ya que no esperaba que me respondiese el Miguel Antonio y no entré más.

Al final he optado por crearme la formula del indicador por mi mismo y incluirlo dentro del Oninit y funciona perfectamente,

lo único que es un poco laborioso pq tienes que programar el indicador.

He probado con lo que me has enviado y me salen varios resultados extraños para cada símbolo (imagen adjunta).

En todo caso muchas gracias por haber contestado.

Saludoooos.

Los resultados que te muestra son los valores del MACD (el main y la señal). Al código me faltó agregarle de qué símbolo es la señal. También redondeé los número a dos decimales para mayor claridad. Te comparto el código. 

void Funcion()
  {
   int CantDeSimbolos = SymbolsTotal(true);
   for(int i = 0; i < CantDeSimbolos; i++)
     {
      string SimboloSeleccionado = SymbolName(i, true);
      MiMACD.Create(SimboloSeleccionado, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE);
      MiMACD.Refresh();
      if(SymbolIsSynchronized(SimboloSeleccionado))
        {
         Print("Simbolo: ", SimboloSeleccionado, "  ",
               " Main line: ", NormalizeDouble(MiMACD.Main(0), 2), "   ",
               "Signal line: ", NormalizeDouble(MiMACD.Signal(0), 2));
        }
     }
  }

Saludos

 

Ahora si lee todos los símbolos de mi marketwatch,

pero me da unos resultados como que no lee el valor de forma correcta y no se pq ocurre, 

adjunto imagen.

No podría dar mejor el dato real de solo el macd en vez de las dos medias?

Saludoooos!!

Archivos adjuntos:
Razón de la queja: