How to get the pixel values from a chart.

 

Hello.

I am trying to get the pixel values from a chart to use in a convolutional neural network but I don't know where to begin. How do I get the pixel values?

 
Michael Mureithi Mbugua:

Hello.

I am trying to get the pixel values from a chart to use in a convolutional neural network but I don't know where to begin. How do I get the pixel values?

use ChartGetInteger

https://www.mql5.com/en/docs/chart_operations/chartgetinteger

https://www.mql5.com/en/docs/constants/chartconstants/enum_chart_property#enum_chart_property_integer

Documentation on MQL5: Chart Operations / ChartGetInteger
Documentation on MQL5: Chart Operations / ChartGetInteger
  • www.mql5.com
ChartGetInteger - Chart Operations - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

Thank you for replying.

I have looked into the links you have provided but I still don't know which  ENUM_CHART_PROPERTY_INTEGER to use.

The only ones that I think have anything to do with pixels is the  CHART_WIDTH_IN_PIXELS and  CHART_HEIGHT_IN_PIXELS. Those can get me the coordinates of the pixels but I am trying to get the value of the pixels.


Thanks again.

Documentation on MQL5: Constants, Enumerations and Structures / Chart Constants / Examples of Working with the Chart
Documentation on MQL5: Constants, Enumerations and Structures / Chart Constants / Examples of Working with the Chart
  • www.mql5.com
Examples of Working with the Chart - Chart Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
You mean something like the dpi? Terminal Screen DPI
Client Terminal Properties - Environment State - Constants, Enumerations and Structures - MQL4 Reference
Client Terminal Properties - Environment State - Constants, Enumerations and Structures - MQL4 Reference
  • docs.mql4.com
Client Terminal Properties - Environment State - Constants, Enumerations and Structures - MQL4 Reference
 
Nope. Not that. Thanks though.
 
You need to get a screenshot.

Use this: ChartScreenShot()

I never tried to store the screenshot as a resource, but you will get a bmp file which in turn you can read again.



 
Michael Mureithi Mbugua #:

Thank you for replying.

I have looked into the links you have provided but I still don't know which  ENUM_CHART_PROPERTY_INTEGER to use

Then you need to say more clearly what it is you are after but, beyond the dpi value and chart pixel info already detailed you won’t find it in mql 
 
Dominik Egert #:
You need to get a screenshot.

Use this: ChartScreenShot()

I never tried to store the screenshot as a resource, but you will get a bmp file which in turn you can read again.




Having the X/Y coordinates of a pixel via ChartTimePriceToXY, how can I get the (color) value of this pixel?

 

I bet the best option here is to use the WinAPI function GetPixel. You would have to get a handle to the dc of the chart window and then call the function on it. Just can't say if this is really viable (that's how you would do on a normal WinAPI application) and remember that GetPixel is really slow. If you want speed, there're other options using more complex winapi functions

 

Can you explain more about the more complex winapi functions concerning GetPixel?

 
tquestlog #:

Can you explain more about the more complex winapi functions concerning GetPixel?

It's been a while since I have worked with these functions, so there may be something incorrect among the explanation. Also, I'm not fully sure if this works exactly the same with MT5, as it uses MDI to display each chart. But it would work like this:


1 - Get the chart window handle (HWND). That can be done by calling ChartGetInteger and passing the CHART_WINDOW_HANDLE argument.

2 - From that window handle, get the handle to the window device context (HDC). That can be done by calling the WinAPI function GetDC and pass as argument the return value from the step 1.

3 - Create a compatible dc of that device context by calling the WinAPI function CreateCompatibleDC.

4 - Also create a compatible bitmap from the device context obtained in the step 2 by calling the WinAPI function CreateCompatibleBitmap. You also need to pass the bitmap dimensions (you can get the chart dimensions using MQL5 functions or WinAPI functions, like GetClientRect);

5 - Select the compatible bitmap into the created compatible device context by calling the WinAPI function SelectObject;

6 - Call the WinAPI function BitBlt to copy the data form the source device context to the created compatible device context (target DC).

7 - Call the WinAPI function GetDIBits to copy the pixels to an array. Probably a uchar array could do it, but remember to resize the array to how many pixels there're on the screen (width * height * 4 -> if we're dealing with an ARGB pixel type). Take a look into the documentation of the function, because you need to pass a BITMAPINFO structure as a parameter - check how its parameters could be filled. If I recall correctly, one important thing to notice is that the BITMAPINFO structure contains the dimensions of the bitmap. If the height is positive, GetDIBits will copy the data from the bottom left to the top right of the screen; if it is negative, GetDIBits copies the data from the top left to the bottom right.

8 - Your array is now filled with the pixels of the screen. After that, call DeleteObject to delete the created compatible bitmap and DeleteDC to delete the created compatible device context. If you don't do this, you'll have a memory leak and your memory consumption will increase to infinite.


This piece of code was written in C++. This function was part of a class, but I think you can start from it:


Color Canvas::getPixel(float x, float y)
{
        BITMAPINFO bmi{};
        HDC comp_dc = NULL;
        HBITMAP comp_bmp = NULL;
        HBITMAP old_bmp = NULL;
        uchar* pixels = nullptr;

        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi.bmiHeader.biWidth = m_width;
        bmi.bmiHeader.biHeight = m_height;
        bmi.bmiHeader.biBitCount = 32;
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biCompression = BI_RGB;

        comp_dc = CreateCompatibleDC(m_hdc);
        comp_bmp = CreateCompatibleBitmap(m_hdc, m_width, m_height);
        old_bmp = (HBITMAP)SelectObject(comp_dc, comp_bmp);

        BitBlt(comp_dc, 0, 0, m_width, m_height, m_hdc, 0, 0, SRCCOPY);

        pixels = new uchar[((ulong)m_width*(ulong)m_height)*4];

        int ret = GetDIBits(m_hdc, comp_bmp, 0, m_height, (void*)pixels, &bmi, DIB_RGB_COLORS);

        if (ret == 0)
        {
                DeleteDC(comp_dc);
		DeleteObject(comp_bmp);
                delete[] pixels;
                return 0;
        }

        int index = (x*4) + ((m_height-(y+1)) * m_width * 4); // gets the pixel at the position x,y
        Color clr(pixels[index+2], pixels[index+1], pixels[index+0]);

        DeleteObject(comp_bmp);
        DeleteDC(comp_dc);

        delete[] pixels;

        return clr;
}