Different colors for DRAW_ZIGZAG in MT4. - page 3

 

As a follow-up, the following posts can be of use to understanding how to use the equation "y = mx + c" for the ZigZag lines.

Even though the posts below are for calculating a Trend-Line, it is the same principle to using DRAW_LINE buffer to draw a line for the ZigZag lines. In other words, it word be the simulating of a TrendLine using DRAW_LINE buffer.

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

 
Fernando Carreiro #:

Yes, it does work, but you have to create the intermediate points as well and not just the start and end points. That is why I wrote that you need to apply the equation "y = mx + c" (equation for a line).

And please don't use trend-line graphical objects. That is inefficient.

This method can work, but it has two drawbacks.
1- It is very complex in terms of coding. I feel like the complexity does not worth the outcome.
2- In this Zigzag indicator sometimes I need to connect high of a candle to its low of the same candle, when we use DRAW_LINE each buffer will connect to its own values, that is buffer 1 cannot be connected to buffer 2, therefore I cannot connect high of a candle to its low. The only way for that is using DRAW_ZIGZAG. 

 
Fatemeh Ameri #:

This method can work, but it has two drawbacks.
1- It is very complex in terms of coding. I feel like the complexity does not worth the outcome.
2- In this Zigzag indicator sometimes I need to connect high of a candle to its low of the same candle, when we use DRAW_LINE each buffer will connect to its own values, that is buffer 1 cannot be connected to buffer 2, therefore I cannot connect high of a candle to its low. The only way for that is using DRAW_ZIGZAG. 

  1. If the objective is draw a colour ZigZag in MQL4 that does not support it natively, then I don't believe the extra steps could be considered "not worth it", but that is a matter of subjective opinion.
  2. That is true, and a partial solution would be to mix both the DRAW_ZIGZAG and the DRAW_LINE method for one of the directions, but it is not foolproof.
 
Fernando Carreiro #:
  1. If the objective is draw a colour ZigZag in MQL4 that does not support it natively, then I don't believe the extra steps could be considered "not worth it", but that is a matter of subjective opinion.
  2. That is true, and a partial solution would be to mix both the DRAW_ZIGZAG and the DRAW_LINE method for one of the directions, but it is not foolproof.

Thank you man for all your help, always the best.