SpreadSymbol

Price Data Components
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
SpreadSymbol
ÿþ#property description "Original Filename: " + __FILE__

#property description "Compile Time: " + (string)__DATETIME__

#ifdef _RELEASE

  #property description "Compiler Version: " + (string)__MQLBUILD__ + " " + __CPU_ARCHITECTURE__ + " Release."

#else // #ifdef _RELEASE

  #property description "Compiler Version: " + (string)__MQLBUILD__ + " " + __CPU_ARCHITECTURE__ + " Debug."

#endif // #ifdef _RELEASE #else

#property link "https://www.mql5.com/ru/code/40669"



#include <fxsaber\SpreadSymbol\SpreadSymbol.mqh>



input datetime inFrom = D'2024.01.01'; // From where to calculate

input int inEMAPeriod = 5; // Average bar spread for how many days

input bool inOnlySymbol1 = false; // Output only the Symbol1

input double inCommission = 0; // Commission(%) per side



input group "Another Symbol1"

input string inServerName1 = ""; // ServerName of anoher symbol1

input int inShiftTime1 = 0; // How many hours to shift time1

input double inCommission1 = 0; // Commission(%) per side1



input group "Another Symbol2"

input string inServerName2 = ""; // ServerName of anoher symbol2

input int inShiftTime2 = 0; // How many hours to shift time2

input double inCommission2 = 0; // Commission(%) per side2



input group "Another Symbol3"

input string inServerName3 = ""; // ServerName of anoher symbol3

input int inShiftTime3 = 0; // How many hours to shift time3

input double inCommission3 = 0; // Commission(%) per side3



input group "Screenshots. 'A' - All symbols, 'F' - Current"

input bool inFullScreen = true; // FullScreen



#property indicator_separate_window



#property indicator_buffers 7 // You need to add here if you have increased the number of symbols.

#property indicator_plots indicator_buffers



#property indicator_label1  "Spread_High"

#property indicator_type1 DRAW_HISTOGRAM

#property indicator_style1 STYLE_SOLID

#property indicator_color1 clrBlue



#property indicator_label2  "Spread_Avg"

#property indicator_type2 DRAW_HISTOGRAM

#property indicator_style2 STYLE_SOLID

#property indicator_color2 clrLime



#property indicator_label3  "Spread_Low"

#property indicator_type3 DRAW_HISTOGRAM

#property indicator_style3 STYLE_SOLID

#property indicator_color3 clrRed



#property indicator_label4  "Spread_Avg_EMA"

#property indicator_type4 DRAW_LINE

#property indicator_style4 STYLE_SOLID

#property indicator_color4 clrYellow

#property indicator_width4 2



#property indicator_label5  "Spread1_Avg_EMA"

#property indicator_type5 DRAW_LINE

#property indicator_style5 STYLE_SOLID

#property indicator_color5 clrRed

#property indicator_width5 2



#property indicator_label6  "Spread2_Avg_EMA"

#property indicator_type6 DRAW_LINE

#property indicator_style6 STYLE_SOLID

#property indicator_color6 clrPink

#property indicator_width6 2



// You need to add here if you have increased the number of symbols.

#property indicator_label7  "Spread3_Avg_EMA"

#property indicator_type7 DRAW_LINE

#property indicator_style7 STYLE_SOLID

#property indicator_color7 clrBlue

#property indicator_width7 2



// You need to add here if you have increased the number of symbols.

double Buffer0[];

double Buffer1[];

double Buffer2[];

double Buffer3[];

double Buffer4[];

double Buffer5[];

double Buffer6[];



// You need to add here if you have increased the number of symbols.

SPREADSYMBOL SpreadSymbol(inEMAPeriod, NULL, inOnlySymbol1 ? inServerName1 : NULL);

SPREADSYMBOL SpreadSymbol1(inEMAPeriod, NULL, inOnlySymbol1 ? NULL : inServerName1);

SPREADSYMBOL SpreadSymbol2(inEMAPeriod, NULL, inOnlySymbol1 ? NULL : inServerName2);

SPREADSYMBOL SpreadSymbol3(inEMAPeriod, NULL, inOnlySymbol1 ? NULL : inServerName3);



// You need to add here if you have increased the number of symbols.

const string UniStr = _Symbol + (string)inFrom +

                      (string)inEMAPeriod + (string)inOnlySymbol1 +

                      inServerName1 + (string)inShiftTime1 +

                      inServerName2 + (string)inShiftTime2 +

                      inServerName3 + (string)inShiftTime3;



void SetScale() // https://www.mql5.com/ru/forum/96537/page4#comment_2866477

{

  const int Width = 1 << ((int)ChartGetInteger(0, CHART_SCALE) + 1);



  if (Width != PlotIndexGetInteger(0, PLOT_LINE_WIDTH))

  {

    PlotIndexSetInteger(0, PLOT_LINE_WIDTH, Width);

    PlotIndexSetInteger(1, PLOT_LINE_WIDTH, Width);

    PlotIndexSetInteger(2, PLOT_LINE_WIDTH, Width);



    ChartRedraw();

  }

}



void SetText( const string Str, const int Y, const color Color )

{

  const string Name = (string)Y + UniStr;



  if (Str == NULL)

    ObjectDelete(0, Name);

  else

  {

    ObjectCreate(0, Name, OBJ_LABEL, ChartWindowFind(), 0, 0);

    ObjectSetString(0, Name, OBJPROP_TEXT, Str);

    ObjectSetInteger(0, Name, OBJPROP_COLOR, Color);

    ObjectSetInteger(0, Name, OBJPROP_YDISTANCE, Y);

  }



  return;

}



void OnDeinit( const int )

{

  for (int Y = 20; Y <= 80; Y += 20) // You need to add here if you have increased the number of symbols.

    ObjectDelete(0, (string)Y + UniStr);

}



void OnInit()

{

  // You need to add here if you have increased the number of symbols.

  SetIndexBuffer(0, Buffer0);

  SetIndexBuffer(1, Buffer1);

  SetIndexBuffer(2, Buffer2);

  SetIndexBuffer(3, Buffer3);

  SetIndexBuffer(4, Buffer4);

  SetIndexBuffer(5, Buffer5);

  SetIndexBuffer(6, Buffer6);



  const double dCommission = inOnlySymbol1 ? inCommission1 : inCommission;



  // You need to add here if you have increased the number of symbols.

  const string sCommission = dCommission ? "_" + (string)dCommission + "%" : NULL;

  const string sCommission1 = inCommission1 ? "_" + (string)inCommission1 + "%" : NULL;

  const string sCommission2 = inCommission2 ? "_" + (string)inCommission2 + "%" : NULL;

  const string sCommission3 = inCommission3 ? "_" + (string)inCommission3 + "%" : NULL;



  PlotIndexSetString(0, PLOT_LABEL, SpreadSymbol.GetName(dCommission) + "_high" + sCommission);

  PlotIndexSetString(1, PLOT_LABEL, SpreadSymbol.GetName(dCommission) + "_avg" + sCommission);

  PlotIndexSetString(2, PLOT_LABEL, SpreadSymbol.GetName(dCommission) + "_low" + sCommission);

  PlotIndexSetString(3, PLOT_LABEL, SpreadSymbol.GetName(dCommission) + "_avg(" + (string)inEMAPeriod + ")" + sCommission);



  // You need to add here if you have increased the number of symbols.

  const bool IsReal1 = SpreadSymbol1.IsReal();

  const bool IsReal2 = SpreadSymbol2.IsReal();

  const bool IsReal3 = SpreadSymbol3.IsReal();



  // You need to add here if you have increased the number of symbols.

  SpreadSymbol1.ActualCustomData();

  SpreadSymbol2.ActualCustomData();

  SpreadSymbol3.ActualCustomData();



  // You need to add here if you have increased the number of symbols.

  PlotIndexSetString(4, PLOT_LABEL, IsReal1 ? "Unknown" : (SpreadSymbol1.GetName(inCommission1) + "_avg(" + (string)inEMAPeriod + ")" + sCommission1));

  PlotIndexSetString(5, PLOT_LABEL, IsReal2 ? "Unknown" : (SpreadSymbol2.GetName(inCommission2) + "_avg(" + (string)inEMAPeriod + ")" + sCommission2));

  PlotIndexSetString(6, PLOT_LABEL, IsReal3 ? "Unknown" : (SpreadSymbol3.GetName(inCommission2) + "_avg(" + (string)inEMAPeriod + ")" + sCommission3));



//  for (int i = 3; i <= 6; i++)

//    PlotIndexSetDouble(i, PLOT_EMPTY_VALUE, 0);



  // You need to add here if you have increased the number of symbols.

  const ENUM_DRAW_TYPE DrawType = (IsReal1 && IsReal2 && IsReal3) ? DRAW_HISTOGRAM : DRAW_NONE;



  PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DrawType);

  PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DrawType);

  PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DrawType);



  // You need to add here if you have increased the number of symbols.

  SetText(SpreadSymbol.GetName() + "_avg(" + (string)inEMAPeriod + ")" + sCommission, 20, PlotIndexGetInteger(3, PLOT_LINE_COLOR));

  SetText(!IsReal1 ? SpreadSymbol1.GetName() + "_avg(" + (string)inEMAPeriod + ")" + sCommission1 : NULL, 40, PlotIndexGetInteger(4, PLOT_LINE_COLOR));

  SetText(!IsReal2 ? SpreadSymbol2.GetName() + "_avg(" + (string)inEMAPeriod + ")" + sCommission2 : NULL, 60, PlotIndexGetInteger(5, PLOT_LINE_COLOR));

  SetText(!IsReal3 ? SpreadSymbol3.GetName() + "_avg(" + (string)inEMAPeriod + ")" + sCommission3 : NULL, 80, PlotIndexGetInteger(6, PLOT_LINE_COLOR));



  IndicatorSetInteger(INDICATOR_DIGITS, 8);

  IndicatorSetDouble(INDICATOR_MINIMUM, 0);

/*

  // https://www.mql5.com/ru/forum/1111/page3246#comment_42061024

  ResetLastError();

  IndicatorSetString(INDICATOR_SHORTNAME, NULL);

  Print(_LastError);

*/

  SpreadSymbol.SetFrom(inFrom);

  SpreadSymbol.Refresh();

}



void ToEmpty( const int Pos )

{

  // You need to add here if you have increased the number of symbols.

  Buffer0[Pos] = EMPTY_VALUE;

  Buffer1[Pos] = EMPTY_VALUE;

  Buffer2[Pos] = EMPTY_VALUE;

  Buffer3[Pos] = EMPTY_VALUE;

  Buffer4[Pos] = EMPTY_VALUE;

  Buffer5[Pos] = EMPTY_VALUE;

  Buffer6[Pos] = EMPTY_VALUE;



  return;

}



#define MACROS(A, B)                                                                       \

  if (IsReal##A)                                                                           \

    Buffer##B[Prev] = EMPTY_VALUE;                                                         \

  else                                                                                     \

  {                                                                                        \

    while ((i##A < Size##A) && (Rates##A[i##A].time < time[Prev] + inShiftTime##A * 3600)) \

      i##A++;                                                                              \

                                                                                           \

    if ((i##A < Size##A) && (Rates##A[i##A].time == time[Prev] + inShiftTime##A * 3600))   \

      Buffer##B[Prev] = Rates##A[i##A++].close;                                            \

  }



int Calculate( const int prev_calculated, const int rates_total, const datetime &time[] )

{

  static const bool IsM1 = (Period() == PERIOD_M1);



  // You need to add here if you have increased the number of symbols.

  static const bool IsReal1 = SpreadSymbol1.IsReal();

  static const bool IsReal2 = SpreadSymbol2.IsReal();

  static const bool IsReal3 = SpreadSymbol3.IsReal();



  static const int ShiftTime = inOnlySymbol1 ? inShiftTime1 : 0;



  // You need to add here if you have increased the number of symbols.

  static double dCommission = (inOnlySymbol1 ? inCommission1 : inCommission) / 100;

  static double dCommission1 = inCommission1 / 100;

  static double dCommission2 = inCommission2 / 100;

  static double dCommission3 = inCommission3 / 100;



  int Prev = prev_calculated;

  int NewPrev = Prev;



  if ((prev_calculated < rates_total - IsM1) && (rates_total == ArraySize(time)))

  {

    ArrayFill(Buffer0, prev_calculated, rates_total - prev_calculated, EMPTY_VALUE);

    ArrayFill(Buffer1, prev_calculated, rates_total - prev_calculated, EMPTY_VALUE);

    ArrayFill(Buffer2, prev_calculated, rates_total - prev_calculated, EMPTY_VALUE);

    ArrayFill(Buffer3, prev_calculated, rates_total - prev_calculated, EMPTY_VALUE);

    ArrayFill(Buffer4, prev_calculated, rates_total - prev_calculated, EMPTY_VALUE);

    ArrayFill(Buffer5, prev_calculated, rates_total - prev_calculated, EMPTY_VALUE);

    ArrayFill(Buffer6, prev_calculated, rates_total - prev_calculated, EMPTY_VALUE);



    SpreadSymbol.Refresh();



    MqlRates Rates[];

    const int Size = SpreadSymbol.GetData(Rates, time[prev_calculated] - ShiftTime * 3600, !prev_calculated, PERIOD_CURRENT, dCommission);



    MqlRates Rates1[];

    const int Size1 = IsReal1 ? 0 : SpreadSymbol1.GetData(Rates1, time[prev_calculated] - inShiftTime1 * 3600, !prev_calculated, PERIOD_CURRENT, dCommission1);



    MqlRates Rates2[];

    const int Size2 = IsReal2 ? 0 : SpreadSymbol2.GetData(Rates2, time[prev_calculated] - inShiftTime2 * 3600, !prev_calculated, PERIOD_CURRENT, dCommission2);



    // You need to add here if you have increased the number of symbols.

    MqlRates Rates3[];

    const int Size3 = IsReal3 ? 0 : SpreadSymbol3.GetData(Rates3, time[prev_calculated] - inShiftTime3 * 3600, !prev_calculated, PERIOD_CURRENT, dCommission3);



    for (int i = 0, i1 = 0, i2 = 0, i3 = 0; i < Size; i++) // You need to add here if you have increased the number of symbols.

      while (Prev < rates_total)

        if (Rates[i].time <= time[Prev] + ShiftTime * 3600)

        {

          // You need to add here if you have increased the number of symbols.

          MACROS(1, 4)

          MACROS(2, 5)

          MACROS(3, 6)



          if (Rates[i].time == time[Prev] + ShiftTime * 3600)

          {

            Buffer0[Prev] = Rates[i].high;

            Buffer1[Prev] = Rates[i].open;

            Buffer2[Prev] = Rates[i].low;

            Buffer3[Prev] = Rates[i].close;



            NewPrev = Prev++;



            if (IsM1)

              NewPrev++;

          }



          break;

        }

        else

          ToEmpty(Prev++);



    for (int i = Prev; i < rates_total; i++)

      ToEmpty(i);

  }



  return(NewPrev);

}



const string GlobalName = __FILE__ + (string)ChartID();



int GetMyPosition()

{

  int i = SymbolsTotal(true) - 1;



  while ((i >= 0) && (SymbolName(i--, true) != _Symbol))

    ;



  return(++i);

}



string GetNextSymbol( const bool First = false )

{

  string Res = NULL;

  int i = (First ? SymbolsTotal(true) : GetMyPosition()) - 1;



  while (i >= 0)

  {

    const string Symb = SymbolName(i--, true);



    if (!SymbolInfoInteger(Symb, SYMBOL_CUSTOM) && SymbolInfoInteger(Symb, SYMBOL_VISIBLE))

    {

      Res = Symb;



      break;

    }

  }



  return(Res);

}



union DOUBLE_LONG

{

  double d;

  datetime t;

};



void StartAll()

{

  static bool FirstRun = true;



  if (FirstRun)

  {

    DOUBLE_LONG Union;



    if (GlobalVariableCheck(GlobalName))

    {

      Union.d = GlobalVariableGet(GlobalName);

      Union.t = MathAbs(Union.t);

    }

    else

      Union.t = -GetBarTime((int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR));



    if (!(FirstRun = !GlobalVariableSet(GlobalName, Union.d)))

      ChartSetSymbolPeriod(0, GetNextSymbol(true), PERIOD_CURRENT);

  }

}



void f1( const datetime Time )

{

  ChartNavigate(0, CHART_CURRENT_POS, (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR) - iBarShift(_Symbol, PERIOD_CURRENT, Time));

}



void f2( const datetime Time )

{

  ChartNavigate(0, CHART_END, (int)((1 - (ChartGetInteger(0, CHART_SHIFT) ? ChartGetDouble(0, CHART_SHIFT_SIZE) : 0) / 100) *

                                    ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (1 << ChartGetInteger(0, CHART_SCALE))) -

                                    iBarShift(_Symbol, PERIOD_CURRENT, Time) + ((int)(ChartGetInteger(0, CHART_SHIFT) << 1) - 1));

}



void f3( const datetime Time )

{

  ChartNavigate(0, CHART_BEGIN, Bars(_Symbol, _Period) - iBarShift(_Symbol, PERIOD_CURRENT, Time) - 1);

}



bool ChartToTime( const datetime Time )

{

  bool Res = (GetBarTime((int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR)) == Time);



  if (!Res)

  {

    ChartSetInteger(0, CHART_AUTOSCROLL, true);

    ChartSetInteger(0, CHART_AUTOSCROLL, false);



    f2(Time);



    const color ColorStopLevel = (color)::ChartGetInteger(0, CHART_COLOR_STOP_LEVEL);



    ::ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, ColorStopLevel + 1);

    ChartRedraw();



    ::ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, ColorStopLevel);

    ChartRedraw();



    Res = (GetBarTime((int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR)) == Time);

  }



  return(Res);

}



void NextSymbol()

{

  static bool FirstRun = true;



  if (FirstRun && GlobalVariableCheck(GlobalName))

  {

    const string Symb = GetNextSymbol();



    DOUBLE_LONG Union;



    Union.d = GlobalVariableGet(GlobalName);

    ChartToTime(MathAbs(Union.t));



    if (Symb != NULL)

    {

      if (Union.t <= 0)

        Alert(IntegerToString(GetMyPosition(), 3, '0') + "_" + _Symbol + ": data preparation.");

      else

        SaveScreen(inFullScreen);



      ChartSetSymbolPeriod(0, Symb, PERIOD_CURRENT);

    }

    else if (Union.t > 0)

    {

      SaveScreen(inFullScreen);



      GlobalVariableDel(GlobalName);

    }

    else

    {

      Alert(IntegerToString(GetMyPosition(), 3, '0') + "_" + _Symbol + ": data preparation.");



      StartAll();

    }



    FirstRun = false;

  }

}



datetime time2[];

int prev_calculated2 = 0;

int rates_total2 = 0;



bool IsFull( const datetime &time[] )

{

  static const int Seconds = PeriodSeconds();

  static bool PrevRes = false;



  const int Size = ArraySize(time);



  if (!PrevRes && (PrevRes = (!prev_calculated2 || ((prev_calculated2 >= rates_total2 - 2) &&

                                                    (!Size || ((rates_total2 == Size) &&

                                                               (time[rates_total2 - 1] + Seconds >= (datetime)SymbolInfoInteger(_Symbol, SYMBOL_TIME))))))))

  {

    ArrayFree(time2);



    EventKillTimer();



    IndicatorSetString(INDICATOR_SHORTNAME, "SpreadSymbol");

  }



  return(PrevRes);

}



#define KEY_A 65

#define KEY_F 70



int GetChartSum( const ENUM_CHART_PROPERTY_INTEGER Property, const long Chart = 0 )

{

  int Sum = 0;



  for (int i = (int)ChartGetInteger(Chart, CHART_WINDOWS_TOTAL) - 1; i >= 0; i--)

    if (ChartGetInteger(Chart, CHART_WINDOW_IS_VISIBLE, i))

      Sum += (int)ChartGetInteger(Chart, Property, i);



  return(Sum);

}



string StringBetween( string &Str, const string StrBegin, const string StrEnd = NULL )

{

  string Res = NULL;

  int PosBegin = ::StringFind(Str, StrBegin);



  if ((PosBegin >= 0) || (StrBegin == NULL))

  {

    PosBegin = (PosBegin >= 0) ? PosBegin + ::StringLen(StrBegin) : 0;



    const int PosEnd = ::StringFind(Str, StrEnd, PosBegin);



    if (PosEnd != PosBegin)

      Res = ::StringSubstr(Str, PosBegin, (PosEnd >= 0) ? PosEnd - PosBegin : -1);



    Str = (PosEnd >= 0) ? ::StringSubstr(Str, PosEnd + ::StringLen(StrEnd)) : NULL;



    if (Str == "")

      Str = NULL;

  }



  return((Res == "") ? NULL : Res);

}



string GetServerName( const string Symb )

{

  string Str = SymbolInfoString(Symb, SYMBOL_DESCRIPTION);



  return(StringBetween(Str, "(", ")"));

}



string GetFolderName()

{

  string Str = "[" + GetServerName(SpreadSymbol.GetName()) + "]";



  // You need to add here if you have increased the number of symbols.

  if (!SpreadSymbol1.IsReal())

    Str += "_[" + GetServerName(SpreadSymbol1.GetName()) + "]";



  if (!SpreadSymbol2.IsReal())

    Str += "_[" + GetServerName(SpreadSymbol2.GetName()) + "]";



  if (!SpreadSymbol3.IsReal())

    Str += "_[" + GetServerName(SpreadSymbol3.GetName()) + "]";



  Str += "_avg(" + (string)inEMAPeriod + ")";



  return(Str);

}



datetime GetBarTime( const int Pos )

{

  datetime BarTime[1];



  CopyTime(_Symbol, PERIOD_CURRENT, Pos, 1, BarTime);



  return(BarTime[0]);

}



int GetPriceScaleWidth()

{

  int Res = 0;



  if (ChartGetInteger(0, CHART_SHOW_PRICE_SCALE))

  {

    Res = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);



    if (ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false))

    {

      Res = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) - Res;



      ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, true);

      ChartRedraw();

    }

  }



  return(Res);

}



#define BORDERS_WIDTH 7

#define CHART_DATE_SCALE_HEIGHT_IN_PIXELS 25



bool SaveScreen( const bool FullScreen = false )

{

  const int WidthPriceScale = GetPriceScaleWidth();

  const int Width = FullScreen ? TerminalInfoInteger(TERMINAL_SCREEN_WIDTH)

                               : ((int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) + WidthPriceScale + BORDERS_WIDTH);

  const int Height = FullScreen ? TerminalInfoInteger(TERMINAL_SCREEN_HEIGHT)

                               : GetChartSum(CHART_HEIGHT_IN_PIXELS) + (ChartGetInteger(0, CHART_SHOW_DATE_SCALE) ? CHART_DATE_SCALE_HEIGHT_IN_PIXELS : 0);



  const int Width2 = Width - WidthPriceScale - BORDERS_WIDTH;

  const int Scale = 1 << ChartGetInteger(0, CHART_SCALE);



  const int LeftBarPos = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR);

  const int RightBarPos = LeftBarPos - (Width2 / Scale);



  const datetime AddTime = (Width % Scale) * PeriodSeconds(PERIOD_CURRENT) / Scale;



  const datetime LeftBarTime = GetBarTime(LeftBarPos);

  const datetime RightBarTime = (RightBarPos > 0) ? GetBarTime(RightBarPos) + AddTime : GetBarTime(0);



  const int SubWindow = ChartWindowFind();



  ObjectDelete(0, "V_Left");

  ObjectDelete(0, "V_Right");



  ObjectCreate(0, "V_Left", OBJ_VLINE, SubWindow, LeftBarTime, 0);

  ObjectCreate(0, "V_Right", OBJ_VLINE, SubWindow, RightBarTime, 0);



  string FileName = "Spreads\\" + GetFolderName() + "\\" + _Symbol + "_" + StringSubstr(EnumToString(_Period), 7) +

                    "_" + TimeToString(LeftBarTime) + " - " + TimeToString(RightBarTime) + ".png";

  StringReplace(FileName, ":", "-");



  ResetLastError();

  const bool Res = ChartScreenShot(0, FileName, Width, Height, ALIGN_LEFT);



  Alert(IntegerToString(GetMyPosition(), 3, '0') + "_" + _Symbol + ": " + FileName + (Res ? " is saved" : "is not saved, error = " + (string)_LastError));



  ObjectDelete(0, "V_Left");

  ObjectDelete(0, "V_Right");



  ChartRedraw();



  return(Res);

}



void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam )

{

  if (id == CHARTEVENT_CHART_CHANGE)

    SetScale();

  else if ((id == CHARTEVENT_KEYDOWN) && !GlobalVariableCheck(GlobalName))

    switch ((int)lparam)

    {

    case KEY_A:

      StartAll();



      break;

    case KEY_F:

      SaveScreen(inFullScreen);



      break;

    }

}



void OnTimer()

{

  static int Count = 0;



  if (!(++Count % 10))

    IndicatorSetString(INDICATOR_SHORTNAME, "Waiting data... " + (string)Count);



  if (rates_total2 != Bars(_Symbol, _Period))

  {

    rates_total2 = CopyTime(_Symbol, PERIOD_CURRENT, 0, Bars(_Symbol, _Period), time2);



    prev_calculated2 = Calculate(prev_calculated2, rates_total2, time2);



    ChartRedraw();

  }



  if (rates_total2 == Bars(_Symbol, _Period))

  {

    static int i = 0;



    const bool Res = IsFull(time2);



    if (Res)

      i = 0;

    else if (!(++i % 100))

      Alert("Check that the last bars of " + _Symbol + " are formed correctly!");



    if (Res)

      NextSymbol();

    else

    {

      prev_calculated2 = Calculate(prev_calculated2, rates_total2, time2);



      ChartRedraw();

    }

  }

}



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[] )

{

  static bool FirstRun = EventSetMillisecondTimer(100);



  prev_calculated2 = Calculate(prev_calculated, rates_total, time);

  rates_total2 = rates_total;



  if (FirstRun && (FirstRun = !IsFull(time)))

    ArrayCopy(time2, time);

  else

    NextSymbol();



  return(prev_calculated2);

}

Comments