Indicator for Kagi Charting MQL5 Articles

Post on: 6 Апрель, 2015 No Comment

Indicator for Kagi Charting MQL5 Articles

Introduction

The article Indicator for Point and Figure Charting has described one of the programming ways of creating Point and figure chart. This chart is known since the 19th century. However, this is not the only chart from the remote past. Another notable representative of the early types of the financial market representation is Kagi chart. This chart will be discussed in the present article.

The stock exchange – financial institution unfamiliar to the 19th-century Japan – has been established in May 1878. It is known as Tokyo Stock Exchange nowadays. This event played a vital role in creating and subsequent development of Kagi charts. Europe and USA came to know Kagi charts after the publication of Steve Nison’s Beyond Candlesticks: New Japanese Charting Techniques Revealed in 1994.

The Japanese words Kagi means an L-shaped key that was in use at the time of the chart development. Also, there is a modified version of the name – key chart. In Steve Nison’s Beyond Candlesticks, you can also find alternative names of the chart: price range chart, hook chart, delta or chain chart.

What is so special about this chart? Its main feature is that it ignores the time scale leaving only the price one (unlike Japanese candlesticks, bars and lines). Thus, the chart hides inconsiderable price fluctuations leaving only the most significant ones.

The chart represents a set of thick Yang and thin Yin lines replacing each other depending on the market situation. In case the market moves in the same direction, the line is extended reaching a new price range. However, if the market turns back and reaches a predefined amount, the Kagi line is drawn in the opposite direction in the new column. The predefined amount is set either in points (usually used for currency pairs), or in percentage value of the current price (usually used for stocks). The line thickness varies depending on the closest High or Low breakthrough.

1. Charting example

Let’s use history data on EURUSD, H1 from October 8 to 11.

An example of standard imaging with a reverse threshold of 15 points is displayed in Fig. 1:

Fig. 1. Kagi chart, EURUSD H1

As we can see, the price started falling at 17:00. The downward movement continued till 21:00. At 22:00, the price moves upwards from 1.3566 and is closed at 1.3574. In other words, the price passes 11 points. This is not enough for a reversal, but the new Low has not been reached either. The next two hours the price goes flat and finally, at 01:00 (October 9), we see a strong upward movement, which is closed at 1.3591 comprising 25 points (1.3591-1.3566). This means that the price reversed up.

The uptrend continues the following hour. The price reaches 1.3599 reinforcing the thick Yang line. At 03:00, the price falls sharply closing at 1.3578, which is 21 points from the previous High (1.3599-1.3578). This is more than enough for the reversal. The line moves down but retains its form (thick Yang line).

Up to 16:00, the price moves down and finally it breaks through the nearest minimum and changes from thick Yang to thin Yin line. The previously mentioned Low value of 1.3566 had served as a breakthrough price here. The price continues moving as a Yin line and is changed to Yang at 14:00 on October 10 breaking through the nearest High of 1.3524 formed at 23:00 (October 9). This little example shows how Kagi chart is formed.

2. Kagi Indicator Charting Principle

In order to make the indicator independent from the current timeframe, it was decided to copy the data of the timeframe, at which the indicator was supposed to be formed, separately and then create the indicator using the obtained data.

This allows examining several timeframes simultaneously on a single chart expanding the boundaries of the technical analysis on Kagi charts. The indicator itself is located in a separate window, but it is also possible to display data on the main chart. In other words, basic formation (standard or modified look) is performed in the indicator window. The indicator is copied to the main chart, also price and time marks (depending on the settings) are drawn.

As mentioned earlier, the indicator draws the chart both in standard and modified version. The standard one has been described above. Now, let’s consider the modified version.

I don’t know if it is a new idea, but I have not heard of such version. The idea of the additional filter is that not only reverse points but each move of the chart is filtered now. In other words, the price should move some specified distance in order for the new High or Low (not to be confused with shoulder/waist) to be formed. Generally, wherever the price moves, it should first cover a specified distance. After that, it is defined if it was a trend continuation or a reversal.

Fig. 2 shows how the principle works. The modified chart look is shown in blue, while the standard one – in red. As we can see, the modified look responds to price movement changes more slowly filtering most of the minor signals.

Fig. 2. Modified (blue line) and standard (red line) versions of creating Kagi chart

Apart from Kagi chart, the indicator provides some additional elements both in the indicator window and in the main chart.

Depending on the settings, the marks can be set in the indicator window. These marks provide data on reversal prices. The same function is implemented using price levels, which (depending on the settings) can distribute evenly along the window at the entire price range used for forming the indicator or at each chart reversal. The colors can be set in three versions: according to the reversal type (up — down), line type (Yin — Yang) or no color change.

Reversal price marks, including temporary ones, are provided on the main chart. These marks (depending on the settings) may be of a single color or change the color in accordance with Yin or Yang line colors.

The entire indicator code is implemented using the functions communicating with each other through global variables.

The code can be divided into three main functions and eleven additional ones. The main burden of calculations and buffer fillings of basic graphical constructions and additional buffer arrays rests on the function of Kagi chart formation in the indicator window. The other two functions are responsible for providing the data: the first one copies the time data, while the other one — data on the prices of each bar of the selected timeframe.

The remaining auxiliary functions are responsible for performing all the constructions, deleting the objects, unloading the indicator accompanied by deletion of all indicator objects, reversal parameter calculation, drawing marks on the main chart and indicator window, creating graphical objects of Trend line type, drawing Kagi on the main chart, as well as defining the arrival of the new bar to launch the indicator formation.

3. Indicator Code and Algorithm

Now, let’s examine the indicator code and the algorithm of its formation in details. The code is quite large and it may be difficult enough for novice programmers to understand it. The functions communicating with each other via the global variables make the code quite confusing. In this part of the article, I will explain each function and part of the code separately. First, I will describe the indicator settings and then there will be clarifications concerning data copying initial functions, reversal parameter calculation, main function of the Kagi chart formation and calculation and other auxiliary functions.

3.1. Indicator Input Parameters

The code starts with the declaration of the indicator in a separate window, as well as of 12 buffers and 8 indicator graphical constructions. First of all, let’s define why 8 graphical constructions, including two histograms and six lines. have been used. Each histogram builds its own vertical line. One of the lines is responsible for Yin line, while the other one is for Yang line.

The case is somewhat more complicated with the lines, as there are three of them for each line. This is done due to the fact that the line is drawn if there is another point being drawn near the first one. In other words, we need only two line -type graphical constructions to be rotated to draw two lines adjacent to each other. However, if we need these lines to skip necessary points, we need the third construction to be rotated with other two ones.

This is explained in Figure 3, where you can see what happens if only two line-type graphical constructions are used:

Fig. 3. Example of using two and three graphical line-type constructions to display shoulder and waist lines

Then, the settings menu is created. There are five enumerations here (let’s examine them in the input parameters).

The first input parameter “period” is a period, at which construction is performed, it is followed by period_to_redraw — chart construction update period and the last time parameter is “start_data” — the time construction starts from.

These parameters are followed by chart construction and additional labeling ones:

  • kagi_type – chart construction type defined by user, standard or modified;
  • price_type – type of the price used for construction: Close, Open, High and Low;
  • type_doorstep – used reversal type: point and percentage;
  • doorstep – reversal value (specified in points or percentage value depending on the parameter above);
  • color_yin – Yin line color in the indicator window;
  • color_yang – Yang line color in the indicator window;
  • width_yin – Yin line width in the indicator window;
  • width_yang – Yang line width in the indicator window;
  • levels_on_off – whether price levels should be drawn in the indicator window;
  • levels_type – types of price levels in the indicator window. There are two values to choose from: at each reversal or evenly throughout the price range;
  • levels_number – number of price levels in the indicator window;
  • levels_change_color – allows changing the color of price level lines; the options are upper and lower reversals, Yin and Yang lines or no changes;
  • levels_first_color – the first color of a price level;
  • levels_second_color – the second color of a price level;
  • label_1 – drawing chart reversal price labels in the indicator window;
  • label_1_number – number of displayed labels in the indicator window;
  • label_1_color – color of price labels in the indicator window;
  • label_2 – drawing price labels on the main chart;
  • label_2_color – label color on the main chart;
  • time_line_draw – drawing reversal time lines on the main chart;
  • time_separate_windows – drawing continuation of reversal time lines from the main chart;
  • time_line_change_color – change the color of the time line depending on the reversal label at Yin or Yang line;
  • time_first_color – the first color of the time line on the main chart;
  • time_second_color – the second color of the time line on the main chart;
  • kagi_main_chart – whether Kagi should be drawn on the main chart;
  • color_yin_main – Yin line color on the main chart;
  • color_yang_main – Yang line color on the main chart;
  • width_yin_main – Yin line width on the main chart;
  • width_yang_main – Yang line width on the main chart;
  • magic_numb – magic number used for building objects and their deletion, as well as in the indicator name in order to launch several indicators on a single chart.

These parameters are in their turn followed by declarations of the indicator buffers, auxiliary buffers for storing price and time values, auxiliary variables (stop_data, bars_copied, bars_copied_time, copy_history, copy_time), arrays for storing data on what Yin or Yang line the change in the chart movement occurred, the time and price of that change, central price (if Yin is replaced by Yang on the bar or vice versa). Finally, one of the most used global variables containing data on the number of а chart movement changes is declared.

3.2. Indicator Initialization Function

The next one is the indicator initialization function. Indicator buffers and their indexing (mainly as time series; as Kagi chart is shorter than the main one, it is better to draw it backwards) are specified there. Also, the values that are not to be displayed on the screen are set (EMPTY_VALUE=-1).

Now, we assign the indicator name and display accuracy. As mentioned earlier, the magic number is added to the name. This is done to provide correct operation of ChartWindowFind() function. Otherwise, the graphical object drawn in the indicator window is displayed only at the first launched indicator (if several indicators on a single chart are used).

Next, we assign names to construction lines, prohibit display of the current numerical values in the indicator window, set the color and width of Yin and Yang lines, set the number of the price levels displayed in the indicator window.

3.3. Data Copying Function

Now, let’s examine data copying functions.

There are two of them here. The first one is for copying the prices, while the second one is for copying each bar’s open time. Both functions retain their values in the previously declared indicator’s calculation buffers.

First of all, let’s consider the prices copying function. Function input parameters: array for storing data, data copying start and finish time (current time). The body of the function contains the variables for responding to the function, the number of data (bars) copied to the intermediate array, the intermediate dynamic array itself and the number of bars that should be copied to the intermediate array. The number of bars is calculated based on the total number of bars in the given time period and the number of bars (global variable) copied at the previous function call.

If it is not the first time the data has been copied, the data on the last copied bar should be updated. To do this, we reduce the number of copied bars by one and increase the number of newly copied bars by one. We also change the size of the intermediate array preparing it for copying the bars.

Depending on the settings, we copy the prices to the intermediate array. If copying is successful, the data is copied from the intermediate array to the end of the buffer array (function response array), assign the positive answer to the function and update the global variable storing the data on the number of copied bars. This type of copying allows copying only a few last bars reducing the copying time.

The next function is the one for copying the time data. It is different from the previous one in that it deals with another variable type — datetime (which is converted to double when copied to Time buffer array – function answer array). Another difference is that switch() statement is not used, as there is no need in selecting the copied data.

3.4. Reversal Parameter Calculation Function

Since the reversal parameter can be a point or a percentage one, we need the function that will calculate the reversal parameter depending on the indicator settings. The function has only one parameter – price for calculating the percentage reversal. The variable for the answer is first initialized by double type and after the calculations, it is indirectly converted to int type for response.

This is done because floating point numbers are used in the calculations, while the answer should be presented as integers. Selection is implemented in the function by if-else conditional statement. The comparison is performed directly with external input variable (indicator parameters). Calculation of points is performed by using a simple equation. First, the total number of points the price has passed is defined. Then, the specified percentage is calculated based on this number and assigned to the returned variable.

3.5. The Main Function — Drawing Kagi Chart

We have already examined all the functions that are necessary for the operation of the main function — drawing Kagi chart in the indicator window (i.e. filling the indicator buffers). The function’s input parameters consist of data arrays. Two of them are the calculation buffers described above (previously copied Price and Time), all the rest are the arrays of the indicator graphical construction buffers.

Variables necessary for storing the data on the chart construction are declared inside the function. Since the chart is constructed using for loop statement, we should have the data on the stage the previous pass ended at. This can be achieved by six variables: line_move — where the price moved at the previous pass, line_gauge — line caliber (line width) — Yin or Yang, price_1 and price_2 — previous and current price being considered, price_down and price_up — previous price of a shoulder and waist. As we can see, price_1 is immediately equated to the first element of the array of copied prices due to the fact that this variable is involved in calculations before comparison from the very beginning of the loop.

Since buffer arrays of the indicator graphical construction have AS_SERIES indexing flag, they should be filled in reverse order. To achieve this, time arrays having the appropriate size are implemented. Global variables for storing the data on time, line types, shoulder and waist, as well as reversal prices are then converted the same way.

Then, all arrays should be filled with empty values (-1). This is done using two small loops. It is possible to join everything in a single loop. But using two ones makes all performed actions much clearer, while execution time is not changed much. In other words, graphical buffers and calculation time arrays are filled separately.

Now, all variables are declared, converted and filled, so that the main loop can be launched. It is pretty large (though calculation is performed fast enough) and includes scanning all previously copied bars.

The loop passes through all copied bars and fills necessary previously declared arrays to work with them further. First of all, let’s define all arrays used in the loop:

Indicator for Kagi Charting MQL5 Articles
  • yin_int_1 — primary value of vertical Yin line price (if vertical Yin line is drawn and the chart moves downwards, this is the upper value of the price; if the chart moves upwards, we have the opposite case);
  • yin_int_2 — secondary value of vertical Yin line price (if the upward line is drawn, this is the upper value; if the line is downward, we have the opposite case);
  • yang_int_1 — primary value of vertical Yang line price;
  • yang_int_2 — secondary value of vertical Yang line price;
  • lin_yin — horizontal Yin line value (price of reversal at Yin line);
  • lin_yang — horizontal Yang line value (price of reversal at Yang line);
  • time_change — time of the chart reversal (construction of a shoulder or a waist);
  • time_line — the line during the reversal Yin = 0 or Yang = 1;
  • time_central_price — the value of the central price, the price at the moment when Yin line turns into Yang or vice versa;
  • time_change_price — the value of reversal (shoulder or waist) price, the variable is a common one not depending on Yin or Yang line types.

The value of the current analyzed price from Price buffer is assigned to price_2 variable before each loop pass for further comparison in if-else conditional statements. After that, the buffer array of the copied data is analyzed step by step and the arrays mentioned above are filled. Each if-else conditional statement performs certain actions depending on the conditions: previous direction of chart lines (up or down) and previous look of the lines (Yin or Yang). Then the movement conditions (whether the price has passed a certain number of points) are checked depending on construction type (standard or modified).

If all is well, new variables (array elements) are reassigned or defined. The line type (Yin or Yang) is defined at the very beginning. Depending on the movement and previous actions, the further distribution is performed.

There are two possible price movements:

  1. Price moves up;
  2. Price moves down.

There also four types of previous actions in each direction:

  1. The previous line was Yin and it moved up;
  2. The previous line was Yang and it moved up;
  3. The previous line was Yin and it moved down;
  4. The previous line was Yang and it moved down.

Thus, we have eight cases apart from the first two definitions of the chart’s initial movement (first line appearance).

After that, the main loop is over. Reassignment (reversal) and filling of the buffers are performed to build the chart in a smaller loop consisting of the number of Kagi chart reversals previously defined in the main loop and written in “a” variable. As for distribution of upper and lower price values and vertical lines, it is all quite simple: a simple reversal is performed. In other words, the previously obtained primary values (arrays having indices 0,1,2,3. ) are assigned to the buffers’ end values (element with “а” index, i.e. а,а-1,а-2,а-3. is used as an end value). To prevent reversal (horizontal) lines from sticking together, rotation using switch statement is performed as mentioned above.

At that, the work of the main function of Kagi chart construction is complete.

3.6. Function for Creating Trend Line Graphical Object

Now, let’s examine the function for creating trend line graphical object. This function is needed in order to draw Kagi on the main chart.

The function is very simple. It contains the input parameters necessary for creating trend line graphical object: object name, first and second price and time points, as well as line width and color. The function body contains the graphical object creation function and six functions of changing the graphical object’s properties.

3.7. Drawing Kagi on the Main Chart

The next function that applies to the previous one multiple times is the function of Kagi construction on the main chart. The global variables filled in the previously examined main function of Kagi chart construction are used as input variables: the array of reversal prices (shoulders and waists), the array of change and central prices (the price, at which Yin line turns into Yang or vice versa), reversal time array (located in real time, [z-1] array index is used to mark the reversal start), the array of the type of the line, at which the reversal occurred (it is also one element forward, like the time array).

The function body consists of a loop. The loop is divided into two parts: drawing vertical and horizontal lines. The first one is also divided into two: drawing the verticals considering the line change (change central price) and the absence of change. Note the transferred parameters of the trend line object creation function.

Naming is performed repeatedly. The object name starts with a magic number (needed for deleting objects of a certain indicator), then its type is fixed and finally the index is assigned. The index is updated at each pass of the loop.

3.8. Implementing Additional Labels

As I have already mentioned above, the indicator implements additional labels. Let’s examine the function providing these labels on the main chart. There are only two label types here: reversal price and reversal time labels shown via price label and vertical label. The following parameters are passed as input ones: attribute of the reversal price label drawing and the label’s color, attributes of the reversal time label drawing and of the label’s color change, the first and second colors of the reversal time.

The entire function is divided into two parts: the first part is responsible for time labels, while the second one – for price labels. Both parts of the function consist of the loops limited by the number of charts reversals (“a” variable). if-else conditional statement is set before the loop. The statement checks the necessity of their drawing according to the indicator settings.

The first loop creates time labels, the object name definition is performed at the beginning of the loop (name generation principle has been described above). Then, the color is selected depending on the line from the globally declared line type array (if the parameter is set) and other parameters are applied to the line.

The second loop is responsible for creating reversal price labels. First, the object name is generated. Then, time array index selection is set depending on whether Kagi is to be constructed on the main chart or not. if this is not done, the labels will be located in the air and it will not be clear enough from what place the reversal has occurred. Then, the price label type object is created and configured.

Now, let’s see how we can set the labels in the indicator window.

All labels in the indicator window are mostly price ones, and there are only two types of them: reversal price labels and price levels. There are two types of drawing the price levels: on the chart reversals and at an equal distance of the entire chart price range. The first type can change the color of the levels in two ways: depending on the line type (Yin or Yang) and according to reversal (up or down).

Thus, the function itself is divided into two loops: the first one is responsible for creating reversal price labels, the second one deals with designation of the price levels. The latter is further divided into two types: label at each reversal or labels all over the price range on an equal level.

This function is different from the previous one in that it has limitations on the number of price labels and levels due to the fact that in great numbers they overload the chart complicating its understanding.

Because of this feature, both loops are limited by the number of passes specified in the indicator settings (number of price labels and levels). Such an approach is dangerous as the number of reversals may turn out to be much smaller than the number of set price labels in the settings. Due to this reason, reversal presence during each loop pass is checked for drawing a price label or level.

The only exception is drawing price levels along the entire price range on an equal distance. Generation of Price label type graphical objects is performed in the coordinates in reverse order, i.e. the labels are placed from the current date to the past. The same applies to price levels: the current price levels are generated first followed by earlier ones. The exceptions are price levels not dependent on the chart reversals.

Price level color changes are performed by using if-else conditional statements according to the settings.

3.9. Deleting Previously Created Graphical Objects

We know already that this indicator is rich in graphical objects. It is time to think how we can delete them quickly and efficiently.

This task is executed by the function for deleting the graphical objects. The initial name and the number of objects are used as the function parameters. Like during creation, the object name should contain the magic number and the name of an object type. The function call in the program is limited by the number of objects exceeding their possible existence. However, this does not affect the indicator’s functionality.

3.10. Function for Launching the Chart Construction

Now, after we have examined all functions for calculation and construction of Kagi chart, as well as for creating and deleting objects, we should consider another small function for checking the new bar’s arrival. The function is quite simple and has one input parameter — analyzed period. The function’s answer is also very simple. It has bool type and contains the answer on whether a new bar is present or not. The basis of the function body is switch statement which passes control to its different statements depending on the period.

In the example, the function covers the entire period range, though only one period can also be used.

The function algorithm has been taken from IsNewBar code: the time of the last bar opening is compared with the previously defined time value. If the values are different, there is a new bar. The new value is assigned as previously defined one and the function’s response is considered positive. If the last bar opening time coincides with the previously determined time value, then the new bar has not appeared yet and the function’s response is negative.

3.11. OnCalculate() and OnChartEvent() Functions

All the functions described above are consolidated in the function bearing the same name – Func Consolidation. This function is launched each time a new bar appears in OnCalculate() function and when R key is pressed from OnChartEvent() function.

Before the chart is generated or updated, the function for deleting all graphical objects is called in the consolidation function (Func Consolidation). Since there are quite a lot of objects and they are divided into main chart ‘s and indicator window’s price labels, vertical lines indicating reversal time, as well as Yin and Yang vertical and horizontal trend lines, the general number of function calls is 7.

Then, the history data is copied by price and time. The main function for building Kagi chart is launched afterwards. After that, the function for placing all price labels on the main chart and the indicator window is called. Finally, Kagi is generated on the main chart and the function for redrawing the objects is launched.

3.12. OnDeinit() Function

Deletion of all objects is performed in the indicator deinitialization function.

Now, let’s pass to using the indicator in practice.

4. Using Kagi Chart in Practice

There are many trading strategies based on Kagi chart. We will examine some of them.

Let’s start with the most popular strategy: sell when Yang changes to Yin and buy in the opposite case. This is shown in Fig. 4:

Fig. 4. Selling when Yang changes to Yin and buying in the opposite case

As can be seen in Fig. 4 (EURUSD M30, 5 points), this strategy shows good results. The figure displays 8 points for 4 signals, the first one (1) shows that the long position should be opened at 1.3518, which seems to be correct as the price then reaches about 1.3560 comprising 42 points per day. This is a good result.

The next point (2) recommends selling at 1.3519. As we can see, the price actually moves down crossing the level of 1.3485 (and covering 34 points) approximately for two hours.

Let’s move to point (3). The long position is opened at 1.3538 and the price moves up reaching 1.3695. Thus, the profit comprises 157 points already for one day and a half. Of course, these are the highest possible profits but the result is still good enough.

The next trading strategy is rolling back from the trend line shown in Fig. 5 (EURUSD M30, 5 points), October 7-18:

Fig. 5. Rolling back from the trend line

We can move further and trade following the channels. An example of searching for a channel can be examined on Fig. 6 (EURUSD H1, 5 points), roughly the same period:

Fig. 6. Trading by channels

The less popular strategy based on the fact that after 7-10 successively increasing shoulders or decreasing waists, there will certainly be a reversal (fall ot rise).

This is displayed in Figure 7 (GBPUSD H4, 25 points), July 10 — October 18:

Fig. 7. 7-10 successively increasing shoulders or decreasing waists

As can be seen in the image, seven ascending shoulders are followed by quite a considerable fall roughly equal to the half of the previous rise (about 300 points).

Let’s examine Trading through a price label strategy to show the necessity of using additional indicator parameters. The idea is to enter the market when the price exceeds (buy) or moves below (sell) the previous price label.

The strategy is shown in Fig. 8 (GBPUSD H4, 30 points, modified construction):

Fig. 8. Trading through a price label

Red arrows on Fig. 8 display when to buy or to sell. The arrows are moving from the previous price label displaying the locations the previous price labels were broken through.

Time labels serve mainly as trend direction pointers. Since the color of time labels can be changed relative to the line type, and Yin or Yang line type shows trend direction or reversal, the color may help us define the current market mood.

For example, let’s take #IBM stock chart (H4, 1%, standard construction) shown in Fig. 9:

Fig. 9. Defining trend direction using time labels

The chart shows that blue lines are mainly located on the chart’s tops, while red ones — at the bottoms.

Conclusion

The Kagi chart can be successfully used for market trading as a strategy basis or as an auxiliary tool for more precise analysis.

In this article, I have examined the code itself and some specificities of constructing the indicator. The main objective has been creation of the multi-functional indicator containing all necessary elements with some extra features that can be disabled.

I will be glad to consider new ideas and improvements for the indicator and, perhaps, implement them in the future. Also, please provide me with your feedback. I will be happy to answer your questions concerning the indicator.

This article continues the series devoted to developing indicators for constructing the charts from the past. The previous article can be found here. The series is to be continued and I hope to meet you again soon. Thank you for your interest! I wish you successful trading, as well as optimized and stable codes.

Translated from Russian by MetaQuotes Software Corp.

Categories
Stocks  
Tags
Here your chance to leave a comment!