multicharts

Author: Copyright 2012, MetaQuotes Software Corp.
Price Data Components
Miscellaneous
Uses files from the file systemIt reads information from a file
0 Views
0 Downloads
0 Favorites
multicharts
//+------------------------------------------------------------------+
//|                                                  MultiCharts.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//--- include the ChartObjectSubChart library
#include <ChartObjects\ChartObjectSubChart.mqh>
//--- size of OBJ_Chart
#define chart_width  318
#define chart_height 288
//--- start point for charts table drawing
#define start_x      0
#define start_y      0
#property script_show_inputs
//--- input parameters
input datetime start=D'2012.11.26 00:00:00';
input datetime stop=D'2012.12.01 00:00:00';
//+------------------------------------------------------------------+
//| Class for short and long lines levels                            |
//+------------------------------------------------------------------+
class CLines
  {
public:
   string            m_name;  // name of currency pair
   double            m_short; // level value for the "short" line
   double            m_long;  // level value for the "long" line
   //--- constructor, destructor
                     CLines(void) { };
                    ~CLines(void) { };
  };
//+------------------------------------------------------------------+
//| Class for draw a chart with rectangul area                       |
//| and short & long lines                                           |
//+------------------------------------------------------------------+
class CSubChartExtended: public CChartObjectSubChart
  {
private:
   long              m_subchartID;   // subchart ID
   static bool       m_lines_loaded; // flag of lines loading
   static CLines     m_linesData[];  // array for the lines

public:
                     CSubChartExtended(void);
                    ~CSubChartExtended(void);
   //--- subchart create
   bool              CreateSubChart(const long chart_id,const string name,const int window,
                                    const int X,const int Y,const int sizeX,const int sizeY);
   //--- changing of  display settings   
   void              ChangeSettings(void);
   void              SubChartNavigate(void);
   //--- drawing of graphical objects
   void              DrawRectangle(void);
   void              DrawLines(void);
   //--- redraw
   void              ReDraw(void);
   //--- loading lines data
   bool              LoadLines(const string path);
   virtual bool      Load(const int file_handle);
   //--- calculate the location of the point relative to the interval
   void              SetChartMaxMin(const double short_value,const double long_value);
   int               InRange(const double top,const double bottom,const double pos,const double indent);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSubChartExtended::CSubChartExtended(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CSubChartExtended::~CSubChartExtended(void)
  {
  }
//+------------------------------------------------------------------+
//| Subchart create                                                  |
//+------------------------------------------------------------------+
bool CSubChartExtended::CreateSubChart(const long chart_id,const string name,
                                       const int window,const int X,const int Y,
                                       const int sizeX,const int sizeY)
  {
//--- creating of chart object
   if(!Create(0,name,0,X,Y,sizeX,sizeY))
      return(false);
//--- get subchart ID
   m_subchartID=ObjectGetInteger(0,name,OBJPROP_CHART_ID);
//--- successful creating
   return(true);
  }
//+------------------------------------------------------------------+
//| Changing of  display settings                                    |
//+------------------------------------------------------------------+
void CSubChartExtended::ChangeSettings(void)
  {
//--- disable chart autoscroll
   ChartSetInteger(m_subchartID,CHART_AUTOSCROLL,false);
//--- set the background color
   if(!ChartSetInteger(m_subchartID,CHART_COLOR_BACKGROUND,C'245,255,250'))
      Print("Failed to set the background color for the chart. Code ",GetLastError());
   ResetLastError();
//--- color of axes, scale and OHLC line
   ChartSetInteger(m_subchartID,CHART_COLOR_FOREGROUND,clrBlack);
//--- disable Ask, Bid and Last lines
   ChartSetInteger(m_subchartID,CHART_SHOW_BID_LINE,false);
   ChartSetInteger(m_subchartID,CHART_SHOW_BID_LINE,false);
   ChartSetInteger(m_subchartID,CHART_SHOW_BID_LINE,false);
//--- disable OHLC
   ChartSetInteger(m_subchartID,CHART_SHOW_OHLC,false);
//--- use candles
   ChartSetInteger(m_subchartID,CHART_MODE,CHART_CANDLES);
//--- bullish candle color
   ChartSetInteger(m_subchartID,CHART_COLOR_CANDLE_BULL,clrWhite);
//--- bullish bur color
   ChartSetInteger(m_subchartID,CHART_COLOR_CHART_UP,clrBlack);
//--- bearish candle color
   ChartSetInteger(m_subchartID,CHART_COLOR_CANDLE_BEAR,clrBlack);
//--- bearish bar color
   ChartSetInteger(m_subchartID,CHART_COLOR_CHART_DOWN,clrBlack);
//--- line color
   ChartSetInteger(m_subchartID,CHART_COLOR_CHART_LINE,clrBlack);
//--- disable the grid
   if(!ChartSetInteger(m_subchartID,CHART_SHOW_GRID,0))
      Print("Failed to set property \"Grid \"\ for the chart. Code ",GetLastError());
   ResetLastError();
//--- disable the shift of the right edge of the chart
   ChartSetInteger(m_subchartID,CHART_SHIFT,0);
//--- set the shift equal to 30% of the chart width
   ChartSetDouble(m_subchartID,CHART_SHIFT_SIZE,10);
//--- disable the trade levels display
   if(!ChartSetInteger(m_subchartID,CHART_SHOW_TRADE_LEVELS,0))
      Print("Failed to set property \"Grid \"\ for the chart. Code ",GetLastError());
   ResetLastError();
  }
//+------------------------------------------------------------------+
//| Chart shift to the left to the desired dates                     |
//+------------------------------------------------------------------+
void CSubChartExtended::SubChartNavigate(void)
  {
//--- chart shift
   ChartNavigate(m_subchartID,CHART_END,GetShift(Name(),PERIOD_H4,m_subchartID));
  }
//+------------------------------------------------------------------+
//| Draw a rectangle on the subchart                                 |
//+------------------------------------------------------------------+
void CSubChartExtended::DrawRectangle(void)
  {
//--- create rectangle by start-stop dates
   if(ObjectCreate(m_subchartID,"rect",OBJ_RECTANGLE,0,start,200,stop,0.01))
     {
      //--- fill rectangle
      ObjectSetInteger(m_subchartID,"rect",OBJPROP_FILL,true);
      //--- rectangle color
      ObjectSetInteger(m_subchartID,"rect",OBJPROP_COLOR,White);
     }
   else
     {
      //--- error
      PrintFormat("Failed to create a rectangle, error code %d",GetLastError());
      ResetLastError();
     }
  }
//+------------------------------------------------------------------+
//| Draw short and long lines on the subchart                        |
//+------------------------------------------------------------------+
void CSubChartExtended::DrawLines(void)
  {
//--- check the flag of data loading
   if(m_lines_loaded)
     {
      //--- create variables
      double short_value=0;
      double long_value=0;
      int size=ArraySize(m_linesData);
      //--- find lines data by name of currency pair
      for(int j=0;j<size;j++)
         if(Name()==m_linesData[j].m_name)
           {
            short_value=m_linesData[j].m_short;
            long_value=m_linesData[j].m_long;
           }
      //--- create the short line on the chart
      if(ObjectCreate(m_subchartID,"short",OBJ_HLINE,0,start,short_value))
        {
         //--- line color
         ObjectSetInteger(m_subchartID,"short",OBJPROP_COLOR,Red);
        }
      else
        {
         //--- error
         PrintFormat("Failed to create a line, error code %d",GetLastError());
         ResetLastError();
        }
      //--- create the long line on the chart
      if(ObjectCreate(m_subchartID,"long",OBJ_HLINE,0,start,long_value))
        {
         //--- line color
         ObjectSetInteger(m_subchartID,"long",OBJPROP_COLOR,Blue);
        }
      else
        {
         //--- error
         PrintFormat("Failed to create a line, error code %d",GetLastError());
         ResetLastError();
        }
      //--- find and set the top and bottom boundaries, that the lines will be entered on the chart mapping area
      SetChartMaxMin(short_value,long_value);
     }
  }
//+------------------------------------------------------------------+
//| Subchart redraw                                                  |
//+------------------------------------------------------------------+
void CSubChartExtended::ReDraw(void)
  {
//--- A standard method of redrawing
   ChartRedraw(m_subchartID);
  }
//+------------------------------------------------------------------+
//| Getting handle for loading the lines from file                   |
//+------------------------------------------------------------------+
bool CSubChartExtended::LoadLines(const string path)
  {
//--- reset error
   ResetLastError();
//--- opening the file
   int file_handle=FileOpen(path,FILE_READ|FILE_TXT|FILE_ANSI);
//--- check
   if(file_handle==INVALID_HANDLE)
      return(false);
//--- loading the data
   Load(file_handle);
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Lines loading                                                    |
//+------------------------------------------------------------------+
bool CSubChartExtended::Load(const int file_handle)
  {
//--- variable to read a strings from the file
   string str=" ";
//--- buffer to split the string
   string buf[3];
//--- allocation
   ArrayResize(m_linesData,50);
//--- counter of rows
   int i=0;
//--- read until the end of file
   while(!FileIsEnding(file_handle))
     {
      //--- read the current string
      str=FileReadString(file_handle);
      //--- split it into 3 parts
      StringSplit(str,StringGetCharacter(" ",0),buf);
      //--- replace commas to points
      StringReplace(buf[1],",",".");
      StringReplace(buf[2],",",".");
      //--- store data
      m_linesData[i].m_name=buf[0];
      m_linesData[i].m_short=StringToDouble(buf[1]);
      m_linesData[i].m_long=StringToDouble(buf[2]);
      //--- increase the counter
      i++;
     }
//--- close file
   FileClose(file_handle);
   m_lines_loaded=true;
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Change the maximal and minimal chart boundaries                  |
//+------------------------------------------------------------------+
void CSubChartExtended::SetChartMaxMin(const double short_value,const double long_value)
  {
//--- current values of boundaries
   double chart_fixed_max=ChartGetDouble(m_subchartID,CHART_FIXED_MAX);
   double chart_fixed_min=ChartGetDouble(m_subchartID,CHART_FIXED_MIN);
//--- indent
   double indent=(chart_fixed_max-chart_fixed_min)*40/chart_height;
//--- calculate the values location relative to the interval
   int ind_short=InRange(chart_fixed_max,chart_fixed_min,short_value,indent);
   int ind_long=InRange(chart_fixed_max,chart_fixed_min,long_value,indent);
//--- If the both lines are inside the boundaries should not be changed
   if(ind_short==0 && ind_long==0)
      return;
//--- otherwise, you need to change the boundaries.
   ChartSetInteger(m_subchartID,CHART_SCALEFIX,true);
//--- both above
   if(ind_short==1 && ind_long==1)
      ChartSetDouble(m_subchartID,CHART_FIXED_MAX,MathMax(short_value,long_value)+indent);
//--- short above, long inside
   if(ind_short==1 && ind_long==0)
      ChartSetDouble(m_subchartID,CHART_FIXED_MAX,short_value+indent);
//--- short above, long below
   if(ind_short==1 && ind_long==-1)
     {
      ChartSetDouble(m_subchartID,CHART_FIXED_MAX,short_value+indent);
      ChartSetDouble(m_subchartID,CHART_FIXED_MIN,long_value-indent);
     }
//--- short inside, long above
   if(ind_short==0 && ind_long==1)
      ChartSetDouble(m_subchartID,CHART_FIXED_MAX,long_value+indent);
//--- short inside, long below
   if(ind_short==0 && ind_long==-1)
      ChartSetDouble(m_subchartID,CHART_FIXED_MIN,long_value-indent);
//--- short below, long above
   if(ind_short==-1 && ind_long==1)
     {
      ChartSetDouble(m_subchartID,CHART_FIXED_MAX,long_value+indent);
      ChartSetDouble(m_subchartID,CHART_FIXED_MIN,short_value-indent);
     }
//--- short below, long inside
   if(ind_short==-1 && ind_long==0)
      ChartSetDouble(m_subchartID,CHART_FIXED_MIN,short_value-indent);
//--- both below
   if(ind_short==-1 && ind_long==-1)
      ChartSetDouble(m_subchartID,CHART_FIXED_MIN,MathMin(short_value,long_value)-indent);
  }
//+------------------------------------------------------------------+
//| "pos" location relative to interval (bottom,top)                 |
//+------------------------------------------------------------------+
int CSubChartExtended::InRange(const double top,const double bottom,
                               const double pos,const double indent)
  {
//--- if above, return 1
   if(pos>=top-indent)
      return(1);
//--- if below, return -1
   if(pos<=bottom+indent)
      return(-1);
//--- inside
   return(0);
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- number of currency pairs
   int               symbols;
//--- name of currency pairs
   string            name;
//--- variables of row and column numbers for the chart drawing
   int               col;
   int               row;
//--- get the number of currency pairs
   symbols=SymbolsTotal(true);
//--- subchart object
   CSubChartExtended SubChart[];
   ArrayResize(SubChart,symbols);
//--- loading lines data
   if(SubChart[0].LoadLines("linesdata.txt")) Print("Data successfully loaded");
   else                                       Print("Failed to load data: ",GetLastError());
//--- loop over all pairs
   for(int i=0;i<symbols;i++)
     {
      //--- get the name of currency pair
      name=SymbolName(i,true);
      //--- get the position for the current chart
      GetPosition(2,i,row,col);
      //--- create a new subchart
      if(SubChart[i].CreateSubChart(0,name,0,start_x+col*chart_width,start_x+row*chart_height,chart_width,chart_height))
        {
         //--- set the symbol
         SubChart[i].Symbol(name);
         //--- time frame
         SubChart[i].Period(PERIOD_H4);
         //--- scale
         SubChart[i].Scale(3);
         //--- change the display properties
         SubChart[i].ChangeSettings();
         //--- redraw
         SubChart[i].ReDraw();
        }
      else
        {
         Print("Failed to create a chart, the error: ",GetLastError());
         ResetLastError();
        }
     }
//--- loop over all pairs again
   for(int i=0;i<symbols;i++)
     {
      //--- shift the visible area of ??the chart
      SubChart[i].SubChartNavigate();
      SubChart[i].ReDraw();
      //--- delay
      Sleep(1000);
      //--- draw a white rectangle
      SubChart[i].DrawRectangle();
      //--- redraw
      SubChart[i].ReDraw();
      //--- draw the short and long lines
      SubChart[i].DrawLines();
      //--- redraw
      SubChart[i].ReDraw();
     }
   Sleep(100000);
  }
//+------------------------------------------------------------------+
//|  Returns the row and column position in the table by number      |
//+------------------------------------------------------------------+
void GetPosition(const int cols,int abs_pos,int &row_pos,int &col_pos)
  {
//--- get the row and column numbers
   col_pos=abs_pos%cols;
   row_pos=abs_pos/cols;
  }
//+------------------------------------------------------------------+
//|  Returns the shift                                               |
//+------------------------------------------------------------------+
int GetShift(string name,ENUM_TIMEFRAMES timeframe,long chartID)
  {
//--- number of visible bars on the chart
   int visible_bars=32;
//--- variable for the shift
   int shift=0;
//--- array of dates
   datetime DATA_TIME[];
//--- determine the total number of dates for the currency pair
   int bars=Bars(name,timeframe);
//--- get the number of the retrieved dates
   int count=CopyTime(name,timeframe,0,bars,DATA_TIME);
//--- check if there is a data in array
   if(count!=-1)
     {
      //--- find the index number for the "start" date
      int index=0;
      for(int j=count-1;j>=0;j--)
         if(DATA_TIME[j]==start)
            index=j;
      //--- get the shift, 2 - indent for the rectangle
      shift=-count+index+visible_bars-2;
     }
//--- return shift
   return(shift);
  }
//+------------------------------------------------------------------+

Comments