Issue with ObjectGetValueByShift()

 
void OnTick()
  {
   long ID = ChartFirst();
   while(ID != -1)
     {
      string Symb = ChartSymbol(ID);
      string TF = ChartPeriod(ID);
      string TrendlLine = StringConcatenate("Line ", Symb, " ", TF);
      double Value = ObjectGetValueByShift(TrendlLine, 1);
      Print("The value: ", Value);
      ID = ChartNext(ID);
     }
  }
Hello all! How can I get the value of ObjectGetValueByShift from a non current chart? The function ObjectGetValueByShift() does not include chart ID as parameter. Thus when I try to ObjectGetValueByShift of an object (say trendline) that is located on a non current chart the value is zero (0).
Documentation on MQL5: Chart Operations / ChartID
Documentation on MQL5: Chart Operations / ChartID
  • www.mql5.com
ChartID - Chart Operations - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

Instead of using ObjectGetValueByShift which does not work in the Strategy Tester, use the "y = mx + c" calculation method instead. Using graphic objects will not function during optimisations.

By using simple maths — namely the equation "y = m * x + c", you can calculate the trend-line price value at the bar's shift.

Forum on trading, automated trading systems and testing trading strategies

Experts: Safe Trend Scalp

Fernando Carreiro, 2022.04.24 12:00

y = m * x + c

Let y = price
Let x = bar index

[price] = m * [index] + c

Given:

Price at Index 9 is 105 (10th bar)
Price at Index 1 is 100 (2nd bar)

Therefore:

m = Δy / Δx = (105 - 100) / ( 9 - 1 ) = 5 / 8 = 0.625

c = y - m * x = 105 - m * 9 = 100 - m * 1 = 99.375

Equation:

y = 0.625 * x + 99.375

[price] = 0.625 * [index] + 99.375

Example:

What is trend-line price at bar index 5?

[price @ 5] = 0.625 * 5 + 99.375 = 102.5

Forum on trading, automated trading systems and testing trading strategies

Experts: Safe Trend Scalp

Fernando Carreiro, 2022.04.24 12:31

Yes, obviously! It does not matter the slope as long as you clearly define the values for First and Last point.

Here is an example:

Given:

Price at Index 11 is 100 (12th bar)
Price at Index 1 is 105 (2nd bar)

Therefore:

m = Δy / Δx = (100 - 105) / ( 11 - 1 ) = -5 / 10 = -0.5

c = y - m * x = 100 - m * 11 = 105 - m * 1 = 105.5

Equation:

y = -0.5 * x + 105.5

[price] = -0.5 * [index] + 105.5

Example:

What is trend-line price at bar index 5?

[price @ 5] = -0.5 * 5 + 105.5 = 103

Forum on trading, automated trading systems and testing trading strategies

Experts: Safe Trend Scalp

Fernando Carreiro, 2022.04.25 01:13

No! Do you even understand what the ObjectGetValueByShif() does?

The function, does exactly the same thing as the "y=mx+c" equation. It calculates the price for the bars either inside or outside of the two connecting points of the trend-line.

Here is an example code of a Script, to demonstrate the two methods, that has been fully tested with log results:

#property strict
#property script_show_inputs

// Script input parameters
   input uint
      nStartPointBarShift  = 5,     // Bar shift of starting point of trend-line
      nEndPointBarShift    = 15,    // Bar shift of ending   point of trend-line
      nQueryPointBarShift  = 10;    // Bar shift of query    point of trend-line

// Script start event handler
   void OnStart()
   {
      // Check if parameters are acceptable
         if( nStartPointBarShift == nEndPointBarShift )
         {
            Print( "Invalid Parameters!" );
            return;
         };

      // Calculate values
         int
            nDeltaBarShift    = (int) nEndPointBarShift - (int) nStartPointBarShift;   // Change in bar shift

         datetime
            dtStartPointTime  = iTime( _Symbol, _Period, nStartPointBarShift ),        // Time at starting point
            dtEndPointTime    = iTime( _Symbol, _Period, nEndPointBarShift   );        // Time at ending point

         double
            dbStartPointPrice = iClose( _Symbol, _Period, nStartPointBarShift ),       // Price at starting point
            dbEndPointPrice   = iClose( _Symbol, _Period, nEndPointBarShift   ),       // Price at ending point
            dbDeltaPrice      = dbEndPointPrice - dbStartPointPrice,                   // Change in price
            dbLineSlope       = dbDeltaPrice / nDeltaBarShift,                         // Slope  is the value of "m"
            dbOffset          = dbEndPointPrice - dbLineSlope * nEndPointBarShift;     // Offset is the value of "c"

      // Draw trend-line object
         string sObjectName = "Test-Trendline";
         if( ObjectCreate( sObjectName, OBJ_TREND, 0, // Create trend-line object
               dtStartPointTime, dbStartPointPrice,   // Starting point of trend-line
               dtEndPointTime,   dbEndPointPrice ) )  // Ending   point of trend-line
         {
            // Get price by both methods
               double
                  dbValueByShift = ObjectGetValueByShift( sObjectName, nQueryPointBarShift ),
                  dbPriceByShift = dbLineSlope * nQueryPointBarShift + dbOffset;

            // Print out the values to the log
               PrintFormat( "Starting Point: %s @ %d",                            DoubleToString( dbStartPointPrice, _Digits ), nStartPointBarShift );
               PrintFormat( "Ending   Point: %s @ %d",                            DoubleToString( dbEndPointPrice,   _Digits ), nEndPointBarShift   );
               PrintFormat( "Query    Point: %s @ %d (by ObjectGetValueByShift)", DoubleToString( dbValueByShift,    _Digits ), nQueryPointBarShift );
               PrintFormat( "Query    Point: %s @ %d (by y=mx+c calculation)",    DoubleToString( dbPriceByShift,    _Digits ), nQueryPointBarShift );

            // Delete Object
               ObjectDelete( sObjectName );  // Delete trend-line object
         };
   };
2022.04.25 00:07:12.139 Compiling '(Test)\TestTrendlineValue'
2022.04.25 00:07:53.150 Script (Test)\TestTrendlineValue EURUSD,H1: loaded successfully
2022.04.25 00:07:56.080 TestTrendlineValue EURUSD,H1 inputs: nStartPointBarShift=5; nEndPointBarShift=15; nQueryPointBarShift=10; 
2022.04.25 00:07:56.111 TestTrendlineValue EURUSD,H1: initialized
2022.04.25 00:07:56.111 TestTrendlineValue EURUSD,H1: Starting Point: 1.07855 @ 5
2022.04.25 00:07:56.111 TestTrendlineValue EURUSD,H1: Ending   Point: 1.07973 @ 15
2022.04.25 00:07:56.111 TestTrendlineValue EURUSD,H1: Query    Point: 1.07914 @ 10 (by ObjectGetValueByShift)
2022.04.25 00:07:56.111 TestTrendlineValue EURUSD,H1: Query    Point: 1.07914 @ 10 (by y=mx+c calculation)
2022.04.25 00:07:56.111 TestTrendlineValue EURUSD,H1: uninit reason 0
2022.04.25 00:07:56.111 Script TestTrendlineValue EURUSD,H1: removed
ObjectGetValueByShift - Object Functions - MQL4 Reference
ObjectGetValueByShift - Object Functions - MQL4 Reference
  • docs.mql4.com
ObjectGetValueByShift - Object Functions - MQL4 Reference
 
Fernando Carreiro #:

Instead of using ObjectGetValueByShift which does not work in the Strategy Tester, use the "y = mx + c" calculation method instead. Using graphic objects will not function during optimisations.

By using simple maths — namely the equation "y = m * x + c", you can calculate the trend-line price value at the bar's shift.

Your method is great. Your method is a way of solving two equations simultaneousely (the eqaution of the trendline and that of a vertical line). But I don't intend using the ObjectGetValueByShift in a Strategy Tester or for Optimization of any Sort, in case that is the only place it does not work. If it can work on a normal EA function, then I think I will prefer ObjectGetValueByShift.
 
Fernando Carreiro #:

Instead of using ObjectGetValueByShift which does not work in the Strategy Tester, use the "y = mx + c" calculation method instead. Using graphic objects will not function during optimisations.

By using simple maths — namely the equation "y = m * x + c", you can calculate the trend-line price value at the bar's shift.

But I think your code does not answer the question asked. Your code is an equation alternative to the ObjectGetValueByShift method on a current chart for Optimisation and Strategy tester. My question is how to get the value of a trendline of a NON CURRENT chart which the equation method may or may not be able to obtain as well, because the two end points in question will have to be obtained from the non current chart.

 
macpee #: But I think your code does not answer the question asked. Your code compares the equation method and the ObjectGetValueByShift method on a current chart for Optimisation and Strategy tester. My question is how to get the value of a trendline of a NON CURRENT chart which the equation method may or may not be able to obtain as well, because the two end points in question will have to be obtained from the non current chart.

You are limiting your scope of understanding. The "y = mx + c" will work for ANY data, irrespective of the source, be it a trend-line on the current chart, or any chart or even an virtual one.

So if your trend-line is on another chart, simply read the start and end points of that object (on the other chart) and apply the maths. To get the start and end points, simply use the other graphical object functions that do support the chart id.

If however, you do not wish to use this method, then consider using ObjectGetValueByTime instead (which supports chart id, and is also available in MQL5). Simply convert the shift into a time by using iTime for example.

double  ObjectGetValueByTime(
   long       chart_id,      // chart ID
   string     object_name,   // object name
   datetime   time,          // time
   int        line_id=0      // line ID
   );
ObjectGetValueByTime - Object Functions - MQL4 Reference
ObjectGetValueByTime - Object Functions - MQL4 Reference
  • docs.mql4.com
ObjectGetValueByTime - Object Functions - MQL4 Reference
 
Fernando Carreiro #:

You are limiting your scope of understanding. The "y = mx + c" will work for ANY data, irrespective of the source, be it a trend-line on the current chart, or any chart or even an virtual one.

So if your trend-line is on another chart, simply read the start and end points of that object (on the other chart) and apply the maths. To get the start and en points, simply use the other graphical object functions that do support the chart id.

If however, you do not wish to use this method, then consider using ObjectGetValueByTime instead (which supports chart id). Simply convert the shift into a time by using iTime for example.

This is great. Lets explore then so as to increase my understanding. Thanks
Reason: