How to change user input values with OnChartEvent and a button in an indicator.

 

How to change input values with OnChartEvent and a button in an indicator.


I want my indicator  to change one of it's user input with a button, then to recalculate everything in OnInit and redo all the loops in OnCalculate, so I create a button, then I change the values of the input in the OnChartEvent, but this value is never passed to the OnInit and OnCalculate. So this code doesnt work

the output is
     #BUTTON XLMUSD,Daily: FROM OnChartEvent_99_0.5778444999999999
    #BUTTON XLMUSD,Daily: FROM OnChartEvent_99_0.5778444999999999
     #BUTTON XLMUSD,Daily: FROM OnCalculate_20_0.5778444999999999

so the Average is never recomputed.

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2018, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+

#property strict
#property indicator_chart_window

bool Init=false;
extern int LOOKBACK=20;
double Average=0;


int XShift = 1;     // Horizontal shift
int YShift = 222;     // Vertical shift

// ---


// +------------------------------------------------------------------+
// | Custom indicator initialization function                         |
// +------------------------------------------------------------------+
int OnInit()
{
 if(_Period<PERIOD_H1)
 {
  LOOKBACK=40;
  Average=234;
 }
 Print("FROM OnInit", "_", LOOKBACK,"_",Average);
 ButtonCreate(0, "NAME_BUTTON", 0, 444 + XShift, YShift, 55, 55, CORNER_LEFT_LOWER, "M15", "Arial", 15, Green, Black, Pink, false, false, false, false, 0);
 ObjectSetString(0, "NAME_BUTTON", OBJPROP_TOOLTIP, "CHANGE LOOKBACK");
 return(INIT_SUCCEEDED);
}

// +------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int Reason)
{
 ObjectsDeleteAll(0, "NAME_BUTTON");
}
// +------------------------------------------------------------------+
// | 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[])
{
// --- return value of prev_calculated for next call
 if(Init) return(rates_total);
 Init  = true;
 for(int i=LOOKBACK; i<LOOKBACK+44; i++)
 {
  Average=Average+(Open[i])/LOOKBACK;
 }
 Print("FROM OnCalculate", "_", LOOKBACK,"_",Average);
 return(rates_total);
}
// +------------------------------------------------------------------+
// | ChartEvent function                                              |
// +------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
 if(!Init) return;
 if (id==CHARTEVENT_OBJECT_CLICK)
 {
  if (sparam=="NAME_BUTTON")
  {
   LOOKBACK=99;
 Print("FROM OnChartEvent", "_", LOOKBACK,"_",Average);
   ChartRedraw(0);
   // ObjectSetInteger(0,"NAME_BUTTON",OBJPROP_COLOR,clrBlack);
   // ObjectSetInteger(0,"NAME_BUTTON",OBJPROP_BGCOLOR,clrWhite);
   // ObjectSetInteger(0,"NAME_BUTTON",OBJPROP_BORDER_COLOR,clrBlack);
   ObjectSetInteger(0, "NAME_BUTTON", OBJPROP_STATE, false);
   return;
  }
 }
}
// +------------------------------------------------------------------+
// |                                                                  |
// +------------------------------------------------------------------+
bool ButtonCreate(const long chart_ID            = 0,               // chart's ID
                  const string name              = "Button",        // button name
                  const int sub_window           = 0,               // subwindow index
                  const int xx                   = 0,                // X coordinate
                  const int yy                   = 0,                // Y coordinate
                  const int width                = 50,              // button width
                  const int height               = 18,              // button height
                  const ENUM_BASE_CORNER cornerr = CORNER_LEFT_UPPER,   // chart corner for anchoring
                  const string text              = "Button",        // text
                  const string font              = "Arial",         // font
                  const int font_size            = 10,              // font size
                  const color clr                = clrBlack,        // text color
                  const color back_clr           = C'236,233,216', // background color
                  const color border_clr         = clrNONE,         // border color
                  const bool state               = false,           // pressed/released
                  const bool back                = false,           // in the background
                  const bool selection           = false,           // highlight to move
                  const bool hidden              = true,            // hidden in the object list
                  const long z_order             = 0)              // priority for mouse click
{
// --- reset the error value
 ResetLastError();
// --- create the button
 if (ObjectFind(chart_ID, name)<0)
 {
  if (!ObjectCreate(chart_ID, name, OBJ_BUTTON, sub_window, 0, 0))
  {
   Print(__FUNCTION__,
         ": failed to create the button! Error code = ", GetLastError());
   return(false);
  }
  // --- set button coordinates
  ObjectSetInteger(chart_ID, name, OBJPROP_XDISTANCE, (int)(xx * 1));
  ObjectSetInteger(chart_ID, name, OBJPROP_YDISTANCE, (int)(yy * 1));
  // --- set button size
  ObjectSetInteger(chart_ID, name, OBJPROP_XSIZE, (int)(width * 1));
  ObjectSetInteger(chart_ID, name, OBJPROP_YSIZE, (int)(height * 1));
  // --- set the chart's corner, relative to which point coordinates are defined
  ObjectSetInteger(chart_ID, name, OBJPROP_CORNER, cornerr);
  // --- set the text
  ObjectSetString(chart_ID, name, OBJPROP_TEXT, text);
  // --- set text font
  ObjectSetString(chart_ID, name, OBJPROP_FONT, font);
  // --- set font size
  ObjectSetInteger(chart_ID, name, OBJPROP_FONTSIZE, font_size);
  // --- set text color
  ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
  // --- set background color
  ObjectSetInteger(chart_ID, name, OBJPROP_BGCOLOR, back_clr);
  // --- set border color
  ObjectSetInteger(chart_ID, name, OBJPROP_BORDER_COLOR, border_clr);
  // --- display in the foreground (false) or background (true)
  ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back);
  // --- set button state
  ObjectSetInteger(chart_ID, name, OBJPROP_STATE, state);
  // --- enable (true) or disable (false) the mode of moving the button by mouse
  ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection);
  ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection);
  // --- hide (true) or display (false) graphical object name in the object list
  ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden);
  // --- set the priority for receiving the event of a mouse click in the chart
  ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order);
  // --- successful execution
 }
 return(true);
}
// +------------------------------------------------------------------+

// +------------------------------------------------------------------+
// | Get chart scale (from 0 to 5).                                   |
// +------------------------------------------------------------------+
int ChartScaleGet(const long chart_ID = 0)
{
// --- prepare the variable to get the property value
 long result = -1;
// --- reset the error value
 ResetLastError();
// --- receive the property value
 if (!ChartGetInteger(chart_ID, CHART_SCALE, 0, result))
 {
  // --- display the error message in Experts journal
  Print(__FUNCTION__ + ", Error Code = ", GetLastError());
 }
// --- return the value of the chart property
 return((int)result);
}

// +------------------------------------------------------------------+
// | Set chart scale (from 0 to 5).                                   |
// +------------------------------------------------------------------+
bool ChartScaleSet(const long value, const long chart_ID = 0)
{
// --- reset the error value
 ResetLastError();
// --- set property value
 if (!ChartSetInteger(chart_ID, CHART_SCALE, 0, value))
 {
  // --- display the error message in Experts journal
  Print(__FUNCTION__ + ", Error Code = ", GetLastError());
  return(false);
 }
// --- successful execution
 return(true);
}


//+--------------------------------------------------------------------------------+
//| The function receives the value of the chart maximum in the main window or a   |
//| subwindow.                                                                     |
//+--------------------------------------------------------------------------------+
double ChartPriceMax(const long chart_ID=0,const int sub_window=0)
{
//--- prepare the variable to get the result
 double result=EMPTY_VALUE;
//--- reset the error value
 ResetLastError();
//--- receive the property value
 if(!ChartGetDouble(chart_ID,CHART_PRICE_MAX,sub_window,result))
 {
  //--- display the error message in Experts journal
  Print(__FUNCTION__+", Error Code = ",GetLastError());
 }
//--- return the value of the chart property
 return(result);
}

//+---------------------------------------------------------------------------------+
//| The function receives the value of the chart minimum in the main window or a    |
//| subwindow.                                                                      |
//+---------------------------------------------------------------------------------+
double ChartPriceMin(const long chart_ID=0,const int sub_window=0)
{
//--- prepare the variable to get the result
 double result=EMPTY_VALUE;
//--- reset the error value
 ResetLastError();
//--- receive the property value
 if(!ChartGetDouble(chart_ID,CHART_PRICE_MIN,sub_window,result))
 {
  //--- display the error message in Experts journal
  Print(__FUNCTION__+", Error Code = ",GetLastError());
 }
//--- return the value of the chart property
 return(result);
}
//+------------------------------------------------------------------+
 
Enau:

How to change input values with OnChartEvent and a button in an indicator.

I don't think you can redo "OnInit" and "OnCalculate".

Why don't you just call the calculation part as a separate 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[])
{
// --- return value of prev_calculated for next call
   if(Init) return(rates_total);
   Init  = true;
   ReCalculate();
   
   Print("FROM OnCalculate", "_", LOOKBACK, "_", Average);
   return(rates_total);
}
// +------------------------------------------------------------------+
void ReCalculate()
{
   Average = 0.0;
        
   for(int i = LOOKBACK; i < LOOKBACK + 44; i++)
   {
      Average = Average + (Open[i]) / LOOKBACK;
   }
}
// +------------------------------------------------------------------+
// | ChartEvent function                                              |
// +------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   if(!Init) return;
   if (id == CHARTEVENT_OBJECT_CLICK)
   {
      if (sparam == "NAME_BUTTON")
      {
         if (LOOKBACK == 99)
            LOOKBACK = 20;
         else
            LOOKBACK = 99;
         ReCalculate();
         Print("FROM OnChartEvent", "_", LOOKBACK, "_", Average);
         ChartRedraw(0);
         // ObjectSetInteger(0,"NAME_BUTTON",OBJPROP_COLOR,clrBlack);
         // ObjectSetInteger(0,"NAME_BUTTON",OBJPROP_BGCOLOR,clrWhite);
         // ObjectSetInteger(0,"NAME_BUTTON",OBJPROP_BORDER_COLOR,clrBlack);
         ObjectSetInteger(0, "NAME_BUTTON", OBJPROP_STATE, false);
         return;
      }
   }
}

Reason: