
Kagi Grafik Göstergesi
Giriş
"Nokta ve Şekil Grafik Oluşturma Göstergesi" makalesi, Nokta ve şekil grafiğioluşturmanın programlama yollarından biri açıklamaktadır. Bu grafik 19. yüzyıldan beri bilinmektedir. Ancak, uzak geçmişten gelen tek grafik bu değildir. Finansal piyasa temsilinin ilk türlerinin bir başka kayda değer temsilcisi Kagi grafiğidir. Bu grafik bu makalede tartışılacaktır.
Menkul kıymetler borsası - 19. yüzyıl Japonya'sına aşina olmayan finans kurumu - Mayıs 1878'de kurulmuştur. Günümüzde Tokyo Menkul Kıymetler Borsası olarak bilinmektedir. Bu olay, Kagi grafiklerinin oluşturulmasında ve daha sonra geliştirilmesinde hayati bir rol oynamıştır. Avrupa ve ABD, 1994'te Steve Nison'ın aşağıdaki yayınının ardından Kagi grafiklerini öğrenmeye başlamıştır: "Beyond Candlesticks: New Japanese Charting Techniques Revealed".
Japonca "Kagi" kelimesi, grafik geliştirildiği sırada kullanılan L şeklinde bir anahtar anlamına gelir. Ayrıca, adın değiştirilmiş bir versiyonu var: "anahtar grafik". Steve Nison'ın "Beyond Candlesticks" isimli makalesinde, grafiğin alternatif adlarını da bulabilirsiniz: fiyat aralığı grafiği, kanca grafiği, delta veya zincir grafiği.
Bu grafikte bu kadar özel olan nedir? Başlıca özelliği, zaman ölçeğini yok sayarak yalnızca fiyatınkini bırakmasıdır (Japon mumlar, çubuklar ve çizgilerin aksine). Böylece, grafik, yalnızca en önemlilerini bırakarak önemsiz fiyat dalgalanmalarını gizler.
Grafik, piyasa durumuna göre birbirinin yerini alan bir dizi kalın Yang ve ince Yin çizgisini temsil eder. Piyasanın aynı yönde hareket etmesi durumunda çizgi genişletilerek yeni bir fiyat aralığına ulaşılır. Ancak piyasa geri döner ve önceden belirlenmiş bir miktara ulaşırsa, yeni sütunda Kagi çizgisi ters yönde çizilir. Önceden tanımlanmış miktar, nokta olarak (genellikle döviz çiftleri için kullanılır) veya mevcut fiyatın yüzde değeri olarak (genellikle hisse senetleri için kullanılır) belirlenir. Çizgi kalınlığı, en yakın Yüksek veya Düşük fiyat rekorlarına göre değişir.
1. Grafik oluşturma örneği
8 ila 11 Ekim tarihleri arasında EURUSD, H1'e dair geçmiş verilerini kullanalım.
15 noktalık bir ters eşiği olan standart bir görüntüleme örneği Şekil 1'de gösterilmektedir:
Şekil 1. Kagi grafiği, EURUSD H1
Gördüğümüz gibi fiyat 17:00'da düşmeye başladı. Aşağı yönlü hareket 21:00'a kadar devam etti. Saat 22:00'de fiyat 1,3566'dan yukarı doğru hareket ediyor ve 1,3574'te kapanıyor. Yani fiyat 11 noktadan geçiyor. Bu bir geri dönüş için yeterli değil, ancak yeni Düşük değerine de ulaşılamamış. Sonraki iki saat fiyat yatay seyrediyor ve son olarak 01:00'da (9 Ekim), 25 nokta (1,3591-1,3566) içeren 1,3591'de kapanan güçlü bir yukarı yönlü hareket görüyoruz. Bu, fiyatın yukarı ters çevrildiği anlamına gelir.
Yükseliş trendi takip eden saatte de devam ediyor. Fiyat, kalın Yang çizgisini güçlendirerek 1,3599'a ulaşıyor. Saat 03:00'da fiyat, önceki Yüksek Değerden (1,3599-1,3578) itibaren 21 nokta olan 1,3578'de keskin bir şekilde kapanıyor. Bu geri dönüş için fazlasıyla yeterli. Çizgi aşağı doğru hareket ediyor, ancak biçimini (kalın Yang çizgisi) koruyor.
Saat 16:00'ya kadar fiyat aşağı doğru hareket ediyor ve sonunda en yakın minimum değerini kırıyor ve kalın Yang'dan ince Yin çizgisine dönüyor. Daha önce bahsedilen 1,3566'lık Düşük değer burada bir rekor fiyat görevi görmüştür. Fiyat bir Yin çizgisi olarak hareket etmeye devam ediyor ve 23:00'da (9 Ekim) oluşan en yakın Yüksek değer 1,3524'ü kırarak 10 Ekim saat 14:00'da Yang olarak değişiyor. Bu küçük örnek, Kagi grafiğinin nasıl oluşturulduğunu gösterir.
2. Kagi Gösterge Grafik Oluşturma İlkesi
Göstergenin mevcut zaman aralığından bağımsız hale getirilmesi için göstergenin oluşturulması gereken zaman aralığına ait verilerin ayrı ayrı kopyalanması ve ardından elde edilen veriler kullanılarak göstergenin oluşturulmasına karar verilmiştir.
Bu, Kagi grafiklerinde teknik analizin sınırlarını genişleten tek bir grafik üzerinde aynı anda birkaç zaman aralığının incelenmesine olanak sağlar. Göstergenin kendisi ayrı bir pencerede bulunur, ancak verileri ana grafikte görüntülemek de mümkündür. Diğer bir deyişle, temel oluşum (standart veya değiştirilmiş görünüm) gösterge penceresinde gerçekleştirilir. Gösterge ana grafiğe kopyalanır, ayrıca fiyat ve zaman işaretleri (ayarlara bağlı olarak) çizilir.
Daha önce de belirtildiği gibi, gösterge, grafiği hem standart hem de değiştirilmiş versiyonda çizer. Standart olanı yukarıda açıklanmıştır. Şimdi, değiştirilmiş versiyonu ele alalım.
Yeni bir fikir mi bilmiyorum, ama böyle bir versiyonunu duymadım. Ek filtre fikri, yalnızca noktaların ters çevrilmesi değil, aynı zamanda grafiğin her hareketinin filtrelenmesidir. Diğer bir deyişle, yeni Yüksek veya Düşük değerlerin (omuz/bel ile karıştırılmamalıdır) oluşması için fiyatın belirli bir mesafe boyunca hareket etmesi gerekir. Genel olarak, fiyat nereye giderse gitsin, önce belirli bir mesafeyi kat etmelidir. Bundan sonra, bunun, trendin devamı mı yoksa tersi mi olduğu belirlenir.
Şekil 2, ilkenin nasıl çalıştığını göstermektedir. Değiştirilmiş grafik görünümü mavi, standart görünüm ise kırmızı renkte gösterilir. Gördüğümüz gibi, değiştirilmiş görünüm, küçük sinyallerin çoğunu filtreleyerek fiyat hareketi değişikliklerine daha yavaş yanıt veriyor.
Şekil 2. Kagi grafiği oluşturmanın değiştirilmiş (mavi çizgi) ve standart (kırmızı çizgi) versiyonları
Kagi grafiği dışında, gösterge hem gösterge penceresinde hem de ana grafikte bazı ek öğeler sağlar.
Ayarlara bağlı olarak, işaretler gösterge penceresinde ayarlanabilir. Bu işaretler ters fiyatlar hakkında veri sağlar. Aynı fonksiyon, (ayarlara bağlı olarak) göstergeyi oluşturmak için kullanılan tüm fiyat aralığında veya her bir grafiğin tersinde pencere boyunca eşit olarak dağıtılabilen fiyat seviyeleri kullanılarak uygulanır. Renkler üç versiyonda ayarlanabilir: ters çevirme türüne (yukarı - aşağı), çizgi türüne (Yin - Yang) göre veya renk değişikliği yokluğuna göre.
Geçici olanlar dahil olmak üzere ters fiyat işaretleri ana grafikte verilmiştir. Bu işaretler (ayarlara bağlı olarak) tek renk olabilir veya Yin veya Yang çizgi renklerine göre renk değiştirebilir.
Gösterge kodunun tamamı, global değişkenler aracılığıyla birbirleriyle iletişim kuran fonksiyonlar kullanılarak uygulanır.
Kod, üç ana fonksiyona ve on bir ek fonksiyona ayrılabilir. Temel grafik yapıların ve ek tampon dizilerinin hesaplamaları ve tampon doldurmalarının ana yükü, gösterge penceresindeki Kagi grafiği oluşturma fonksiyonuna dayanmaktadır. Diğer iki fonksiyon verilerin sağlanmasından sorumludur: İlki, zaman verilerini kopyalarken, diğeri seçilen zaman aralığındaki her bir çubuğun fiyatlarına ilişkin verileri kopyalar.
Geri kalan yardımcı fonksiyonlar, tüm oluşumların gerçekleştirilmesi, nesnelerin silinmesi, tüm gösterge nesnelerinin silinmesi ile birlikte göstergenin boşaltılması, ters çevirme parametre hesaplaması, ana grafik ve gösterge penceresine işaretlerin çizilmesi, "Trend çizgisi" türünde grafik nesnelerinin oluşturulması, ana grafik üzerine Kagi çizilmesi ve gösterge oluşumunu başlatmak için yeni çubuğun varışının tanımlanmasından sorumludur.
3. Gösterge Kodu ve Algoritma
Şimdi gösterge kodunu ve oluşumunun algoritmasını detaylı olarak inceleyelim. Kod oldukça büyüktür ve acemi programcıların bunu anlaması epey zor olabilir. Global değişkenler aracılığıyla birbirleriyle iletişim kuran fonksiyonlar, kodu oldukça kafa karıştırıcı hale getirir. Makalenin bu bölümünde, her bir fonksiyonu ve kodun bir bölümünü ayrı ayrı açıklayacağım. İlk olarak gösterge ayarlarını anlatacağım, ardından veri kopyalama başlangıç fonksiyonları, ters çevirme parametre hesaplama, Kagi grafiği oluşturma ve hesaplama ana fonksiyonu ve diğer yardımcı fonksiyonlar hakkında açıklamalar yapacağım.
3.1. Gösterge Giriş Parametreleri
Kod, 12 tampon ve 8 gösterge grafik yapısının yanı sıra ayrı bir pencerede göstergenin bildirilmesi ile başlar. İlk olarak, iki "histogram" ve altı "çizgi" dahil olmak üzere 8 grafik yapısının neden kullanıldığını açıklayalım. Her "histogram" kendi dikey çizgisini oluşturur. Çizgilerden biri Yin çizgisinden, diğeri Yang çizgisinden sorumludur.
Her çizgi için üç tane olduğundan, durum "çizgiler" ile biraz daha karmaşıktır. Bunun yapılma nedeni, birincinin yakınında çizilen başka bir nokta varsa çizginin çizilmesidir. Diğer bir deyişle, birbirine bitişik iki çizgi çizmek için döndürülecek sadece iki "çizgi" türünde grafik yapısına ihtiyacımız var. Ancak, bu çizgilerin gerekli noktaları atlamasına ihtiyacımız varsa, üçüncü yapının diğer ikisiyle birlikte döndürülmesi gerekir.
Bu, yalnızca iki "çizgi" türünde grafik yapısı kullanıldığında ne olduğunu görebileceğiniz Şekil 3'te açıklanmıştır:
Şekil 3. Omuz ve bel çizgilerini görüntülemek için iki ve üç grafik "çizgi" türünde yapının kullanıldığı örnek
Ardından ayarlar menüsü oluşturulur. Burada beş numaralandırma vardır (bunları giriş parametrelerinde inceleyelim).
İlk giriş parametresi "dönem", oluşumun gerçekleştirildiği dönemdir; bunu "period_to_redraw" grafik oluşumun güncelleme periyodu takip eder; ve son zaman parametresi "start_data" oluşumun başladığı zamandır.
Bu parametreleri, grafik oluşumu ve ek etiketleme parametreleri takip eder:
- kagi_type – kullanıcı tarafından tanımlanan, standart veya değiştirilmiş grafik oluşumu türü;
- price_type – oluşum için kullanılan fiyat türü: Close, Open, High ve Low;
- type_doorstep – kullanılan ters çevirme türü: nokta ve yüzde;
- doorstep – ters çevirme değeri (yukarıdaki parametreye göre nokta veya yüzde değeri olarak belirtilir);
- color_yin – gösterge penceresindeki Yin çizgi rengi;
- color_yang – gösterge penceresindeki Yang çizgi rengi;
- width_yin – gösterge penceresindeki Yin çizgi genişliği;
- width_yang – gösterge penceresindeki Yang çizgi genişliği;
- level_on_off – gösterge penceresinde fiyat seviyelerinin çizilmesi gerekip gerekmediği;
- level_type – gösterge penceresindeki fiyat seviyeleri türleri. Aralarından seçebileceğiniz iki değer vardır: her bir ters çevirmede veya fiyat aralığı boyunca eşit olarak;
- level_number – gösterge penceresindeki fiyat seviyelerinin sayısı;
- level_change_color – fiyat seviyesi çizgilerinin renginin değiştirilmesine olanak sağlar; seçenekler yukarı ve aşağı ters çevirmeler, Yin ve Yang çizgileri veya değişiklik yok;
- level_first_color – bir fiyat seviyesinin ilk rengi;
- level_second_color – bir fiyat seviyesinin ikinci rengi;
- label_1 - gösterge penceresine grafik ters fiyat etiketleri çizme;
- label_1_number – gösterge penceresinde görüntülenen etiket sayısı;
- label_1_color - gösterge penceresindeki fiyat etiketlerinin rengi;
- label_2 - ana grafiğe fiyat etiketleri çizme;
- label_2_color – ana grafikteki etiket rengi;
- time_line_draw – ana grafiğe ters zaman çizgileri çizme;
- time_separate_windows – ana grafikten ters zaman çizgilerinin devamını çizme;
- time_line_change_color – Yin veya Yang çizgisindeki ters etikete göre zaman çizgisinin rengini değiştirme;
- time_first_color – ana grafikteki zaman çizgisinin ilk rengi;
- time_second_color – ana grafikteki zaman çizgisinin ikinci rengi;
- kagi_main_chart – Kagi'nin ana grafikte çizilmesi gerekip gerekmediği;
- color_yin_main – ana grafikteki Yin çizgi rengi;
- color_yang_main – ana grafikteki Yang çizgi rengi;
- width_yin_main – ana grafikteki Yin çizgi genişliği;
- width_yang_main – ana grafikteki Yang çizgi genişliği;
- magic_numb - nesneleri oluşturmak ve silmek için kullanılan ve ayrıca tek bir grafikte birkaç gösterge başlatmak için gösterge adında sihirli sayı.
Bu parametreleri sırasıyla, gösterge tamponlarının bildirimleri, fiyat ve zaman değerlerini saklamak için yardımcı tamponlar, yardımcı değişkenler (stop_data, bars_copied, bars_copied_time, copy_history, copy_time), grafik hareketi değişikliğinin hangi Yin veya Yang çizgisinde meydana geldiğine dair verilerin saklanması için diziler, bu değişikliğin zamanı ve fiyatı, merkezi fiyat (çubukta Yin Yang ile değiştirilmişse veya tam tersi olmuşsa) izler. Son olarak, "а" grafiği hareket değişikliklerinin sayısı hakkında veri içeren en çok kullanılan global değişkenlerden biri bildirilir.
//+------------------------------------------------------------------+ //| BKCV.mq5 | //| Azotskiy Aktiniy ICQ:695710750 | //| https://www.mql5.com/ru/users/Aktiniy | //+------------------------------------------------------------------+ //--- Build Kagi Chart Variable #property copyright "Azotskiy Aktiniy ICQ:695710750" #property link "https://www.mql5.com/en/users/Aktiniy" #property version "1.00" #property description "Build Kagi Chart Variable" #property description " " #property description "This indicator makes drawing a chart Kagi as a matter of indicator window, and in the main chart window" #property indicator_separate_window #property indicator_buffers 12 #property indicator_plots 8 //--- plot Yin #property indicator_label1 "Yin" #property indicator_type1 DRAW_HISTOGRAM2 #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Yin1 #property indicator_label2 "Yin1" #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot Yin2 #property indicator_label3 "Yin2" #property indicator_type3 DRAW_LINE #property indicator_color3 clrRed #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot Yin3 #property indicator_label4 "Yin3" #property indicator_type4 DRAW_LINE #property indicator_color4 clrRed #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- plot Yang #property indicator_label5 "Yang" #property indicator_type5 DRAW_HISTOGRAM2 #property indicator_color5 clrRed #property indicator_style5 STYLE_SOLID #property indicator_width5 2 //--- plot Yang1 #property indicator_label6 "Yang1" #property indicator_type6 DRAW_LINE #property indicator_color6 clrRed #property indicator_style6 STYLE_SOLID #property indicator_width6 2 //--- plot Yang2 #property indicator_label7 "Yang2" #property indicator_type7 DRAW_LINE #property indicator_color7 clrRed #property indicator_style7 STYLE_SOLID #property indicator_width7 2 //--- plot Yang3 #property indicator_label8 "Yang3" #property indicator_type8 DRAW_LINE #property indicator_color8 clrRed #property indicator_style8 STYLE_SOLID #property indicator_width8 2 //--- Enumerations as input data (for more attractive setting) //--- Kagi charting type enum kagi_type_enum { classic=0, // Classic modified=1, // Modified }; //--- Type of the price used for construction enum price_type_enum { c=0, // Close o=1, // Open h=2, // High l=3, // Low }; //--- Type of the used reversal enum type_doorstep_enum { point=0, // Point procent=1, // Percent }; //--- Type of levels location enum levels_type_enum { cor=0, // Cornering equ=1, // Equal distance }; //--- Level colors change type (works when "Type of levels location"="Cornering") enum levels_change_color_enum { up_down=0, // Up & Down yin_yang=1, // Yin & Yang no=2, // Don't change }; //--- input parameters input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // Calculation period to build the chart input ENUM_TIMEFRAMES period_to_redraw=PERIOD_M1; // Refresh period chart input datetime start_data=D'2013.07.10 00:00:00'; // Start time to build the chart input kagi_type_enum kagi_type=classic; // The type to build Kagi chart input price_type_enum price_type=c; // Price used to build chart input type_doorstep_enum type_doorstep=point; // Type calculate doorstep input double doorstep=25; // Doorstep reversal input color color_yin=clrRed; // Color Yin line (indicator window) input color color_yang=clrRed; // Color Yang line (indicator window) input char width_yin=1; // Width Yin line (indicator window) input char width_yang=2; // Width Yang line (indicator window) input bool levels_on_off=false; // Draw level (indicator window) input levels_type_enum levels_type=cor; // Type of drawing levels (indicator window) input uint levels_number=6; // Number of levels (indicator window) input levels_change_color_enum levels_change_color=up_down; // Type change color of levels (indicator window) input color levels_first_color=clrBeige; // The first color of level (indicator window) input color levels_second_color=clrCoral; // The second color of level (indicator window) input bool label_1=true; // Draw price label on (indicator window) input uint label_1_number=10; // The number of labels (indicator window) input color label_1_color=clrGreenYellow; // The color of labels (indicator window) input bool label_2=true; // Draw price label on (main chart) input color label_2_color=clrGreenYellow; // The color of labels (main chart) input bool time_line_draw=true; // Draw a timeline reversal (main chart) input bool time_separate_windows=false; // Draw a timeline reversal on indicator window input bool time_line_change_color=true; // Different color timeline on the Yin and Yang lines (main chart) input color time_first_color=clrRed; // The first color of timeline (main chart) input color time_second_color=clrGreenYellow; // The second color of timeline (main chart) input bool kagi_main_chart=true; // Draw Kagi on main chart (main chart) input color color_yin_main=clrRed; // Color Yin line (main chart) input color color_yang_main=clrRed; // Color Yang line (main chart) input char width_yin_main=1; // Width Yin line (main chart) input char width_yang_main=2; // Width Yang line (main chart) input long magic_numb=65758473787389; // The magic number for drawing objects //--- indicator buffers double YinBuffer1[]; double YinBuffer2[]; double Yin1Buffer[]; double Yin2Buffer[]; double Yin3Buffer[]; double YangBuffer1[]; double YangBuffer2[]; double Yang1Buffer[]; double Yang2Buffer[]; double Yang3Buffer[]; //--- additional variables double Price[]; // Buffer for storing the copied price data double Time[]; // Buffer for storing the copied time data //--- datetime stop_data; // Current time int bars_copied=0; // Number of the already copied bars from the initial date int bars_copied_time; // Number of the already copied bars having the initial date bool copy_history=false; // Price history copying result bool copy_time=false; // Time history copying result //--- datetime time_change[]; // Array for writing the time when the chart movement started changing (up or down) char time_line[]; // Array for storing the data on what line (Yin=0 or Yang=1) direction has changed double time_change_price[]; // Array for writing the chart movement change price double time_central_price[]; // Array for writing the average price during the chart movement change uint a=0; // Variable for building the chart, number of chart reversals is fixed
3.2. Gösterge Başlatma Fonksiyonu
Bir sonraki gösterge başlatma fonksiyonudur. Gösterge tamponları ve bunların indislenmesi (esas olarak zaman serisi olarak; Kagi grafiği ana grafikten daha kısa olduğu için bunu geriye doğru çizmek daha iyidir) burada belirtilir. Ayrıca ekranda görüntülenmeyecek değerler de ayarlanır (EMPTY_VALUE=-1).
Şimdi, gösterge adını ve ekran doğruluğunu atıyoruz. Daha önce de belirtildiği gibi, sihirli sayı ada eklenir. Bu, ChartWindowFind() fonksiyonunun doğru çalışmasını sağlamak için yapılır. Aksi takdirde, gösterge penceresine çizilen grafik nesnesi yalnızca ilk başlatılan göstergede görüntülenir (tek bir grafik üzerinde birden fazla gösterge kullanılıyorsa).
Daha sonra, yapı çizgilerine adlar atarız, gösterge penceresinde mevcut sayısal değerlerin gösterilmesini engelleriz, Yin ve Yang çizgilerinin rengini ve genişliğini belirleriz, gösterge penceresinde görüntülenen fiyat seviyelerinin sayısını belirleriz.
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,YinBuffer1,INDICATOR_DATA); ArraySetAsSeries(YinBuffer1,true); SetIndexBuffer(1,YinBuffer2,INDICATOR_DATA); ArraySetAsSeries(YinBuffer2,true); SetIndexBuffer(2,Yin1Buffer,INDICATOR_DATA); ArraySetAsSeries(Yin1Buffer,true); SetIndexBuffer(3,Yin2Buffer,INDICATOR_DATA); ArraySetAsSeries(Yin2Buffer,true); SetIndexBuffer(4,Yin3Buffer,INDICATOR_DATA); ArraySetAsSeries(Yin3Buffer,true); //--- SetIndexBuffer(5,YangBuffer1,INDICATOR_DATA); ArraySetAsSeries(YangBuffer1,true); SetIndexBuffer(6,YangBuffer2,INDICATOR_DATA); ArraySetAsSeries(YangBuffer2,true); SetIndexBuffer(7,Yang1Buffer,INDICATOR_DATA); ArraySetAsSeries(Yang1Buffer,true); SetIndexBuffer(8,Yang2Buffer,INDICATOR_DATA); ArraySetAsSeries(Yang2Buffer,true); SetIndexBuffer(9,Yang3Buffer,INDICATOR_DATA); ArraySetAsSeries(Yang3Buffer,true); //--- add the buffer for copying data on prices for calculation SetIndexBuffer(10,Price,INDICATOR_CALCULATIONS); //--- add the buffer for copying data on bar open time for construction SetIndexBuffer(11,Time,INDICATOR_CALCULATIONS); //--- set what values are not to be drawn for(char x=0; x<8; x++) { PlotIndexSetDouble(x,PLOT_EMPTY_VALUE,-1); } //--- set the indicator's look IndicatorSetString(INDICATOR_SHORTNAME,"BKCV "+IntegerToString(magic_numb)); // Indicator name IndicatorSetInteger(INDICATOR_DIGITS,_Digits); // Display accuracy //--- assign names to graphical constructions PlotIndexSetString(0,PLOT_LABEL,"Yin"); PlotIndexSetString(1,PLOT_LABEL,"Yin"); PlotIndexSetString(2,PLOT_LABEL,"Yin"); PlotIndexSetString(3,PLOT_LABEL,"Yin"); PlotIndexSetString(4,PLOT_LABEL,"Yang"); PlotIndexSetString(5,PLOT_LABEL,"Yang"); PlotIndexSetString(6,PLOT_LABEL,"Yang"); PlotIndexSetString(7,PLOT_LABEL,"Yang"); //--- prohibit display of the results of the current values for graphical constructions PlotIndexSetInteger(0,PLOT_SHOW_DATA,false); PlotIndexSetInteger(1,PLOT_SHOW_DATA,false); PlotIndexSetInteger(2,PLOT_SHOW_DATA,false); PlotIndexSetInteger(3,PLOT_SHOW_DATA,false); PlotIndexSetInteger(4,PLOT_SHOW_DATA,false); PlotIndexSetInteger(5,PLOT_SHOW_DATA,false); PlotIndexSetInteger(6,PLOT_SHOW_DATA,false); PlotIndexSetInteger(7,PLOT_SHOW_DATA,false); //--- set color for Yin line PlotIndexSetInteger(0,PLOT_LINE_COLOR,color_yin); PlotIndexSetInteger(1,PLOT_LINE_COLOR,color_yin); PlotIndexSetInteger(2,PLOT_LINE_COLOR,color_yin); PlotIndexSetInteger(3,PLOT_LINE_COLOR,color_yin); //--- set color for Yang line PlotIndexSetInteger(4,PLOT_LINE_COLOR,color_yang); PlotIndexSetInteger(5,PLOT_LINE_COLOR,color_yang); PlotIndexSetInteger(6,PLOT_LINE_COLOR,color_yang); PlotIndexSetInteger(7,PLOT_LINE_COLOR,color_yang); //--- set Yin line width PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width_yin); PlotIndexSetInteger(1,PLOT_LINE_WIDTH,width_yin); PlotIndexSetInteger(2,PLOT_LINE_WIDTH,width_yin); PlotIndexSetInteger(3,PLOT_LINE_WIDTH,width_yin); //--- set Yang line width PlotIndexSetInteger(4,PLOT_LINE_WIDTH,width_yang); PlotIndexSetInteger(5,PLOT_LINE_WIDTH,width_yang); PlotIndexSetInteger(6,PLOT_LINE_WIDTH,width_yang); PlotIndexSetInteger(7,PLOT_LINE_WIDTH,width_yang); //--- set the number of levels in the indicator window IndicatorSetInteger(INDICATOR_LEVELS,levels_number); //--- return(INIT_SUCCEEDED); }
3.3. Veri Kopyalama Fonksiyonu
Şimdi veri kopyalama fonksiyonlarını inceleyelim.
İki tane vardır. Birincisi fiyatları kopyalamak içindir, ikincisi ise her bir çubuğun açık zamanını kopyalamak içindir. Her iki fonksiyon da değerlerini önceden bildirilen göstergenin hesaplama tamponlarında tutar.
İlk olarak, fiyatları kopyalama fonksiyonunu ele alalım. Fonksiyon giriş parametreleri: veri saklama dizisi, veri kopyalama başlangıç ve bitiş zamanı (mevcut zaman). Fonksiyonun gövdesi, fonksiyona cevap verecek değişkenleri, ara diziye kopyalanan veri (çubuk) sayısını, ara dinamik dizinin kendisini ve ara diziye kopyalanması gereken çubuk sayısını içerir. Çubuk sayısı, verilen zaman aralığındaki toplam çubuk sayısı ve önceki fonksiyon çağrısında kopyalanan çubuk sayısı (genel değişken) temel alınarak hesaplanır.
Veriler ilk kez kopyalanmıyorsa, son kopyalanan çubuktaki veriler güncellenmelidir. Bunu yapmak için kopyalanan çubukların sayısını bir sayı azaltıp yeni kopyalanan çubukların sayısını bir sayı artırırız. Ayrıca, çubukları kopyalamak için bunu hazırlayan ara dizinin boyutunu da değiştiririz.
Ayarlara bağlı olarak fiyatları ara diziye kopyalarız. Kopyalama başarılı olursa, veriler ara diziden tampon dizisinin (fonksiyon yanıt dizisi) sonuna kopyalanır, fonksiyona olumlu yanıt atanır ve kopyalanan çubukların sayısına dair verileri saklayan global değişken güncellenir. Böyle bir kopyalama, yalnızca son birkaç çubuğun kopyalanmasına olanak sağlayarak kopyalama süresini azaltır.
//+------------------------------------------------------------------+ //| Func Copy History | //+------------------------------------------------------------------+ bool func_copy_history(double &result_array[], datetime data_start, datetime data_stop) { //--- int x=false; // Variable for answer int result_copy=-1; // Number of copied data static double price_interim[]; // Temporary dynamic array for storing copied data static int bars_to_copy; // Number of bars for copying bars_to_copy=Bars(_Symbol,period,data_start,data_stop); // Find out the current number of bars on the time interval bars_to_copy-=bars_copied; // Calculate the number of bars to be copied if(bars_copied!=0) // If it is not the first time the data has been copied { bars_copied--; bars_to_copy++; } ArrayResize(price_interim,bars_to_copy); // Change the size of the receiving array switch(price_type) { case 0: result_copy=CopyClose(_Symbol,period,0,bars_to_copy,price_interim); break; case 1: result_copy=CopyOpen(_Symbol,period,0,bars_to_copy,price_interim); break; case 2: result_copy=CopyHigh(_Symbol,period,0,bars_to_copy,price_interim); break; case 3: result_copy=CopyLow(_Symbol,period,0,bars_to_copy,price_interim); break; } if(result_copy!=-1) // If copying to the intermediate array is successful { ArrayCopy(result_array,price_interim,bars_copied,0,WHOLE_ARRAY); // Copy the data from the temporary array to the main one x=true; // assign the positive answer to the function bars_copied+=result_copy; // Increase the value of the processed data } //--- return(x); }
Bir sonraki fonksiyon, zaman verilerini kopyalamak içindir. Bir öncekinden farklıdır, çünkü başka bir değişken türüyle ilgilidir - datetime (bu, Zaman tamponu dizisine - fonksiyon yanıt dizisine - kopyalandığında double olarak dönüştürülür). Diğer bir fark ise, kopyalanan verilerin seçilmesine gerek olmadığı için switch() ifadesinin kullanılmamasıdır.
//+------------------------------------------------------------------+ //| Func Copy Time | //+------------------------------------------------------------------+ bool func_copy_time(double &result_array[], datetime data_start, datetime data_stop) { //--- int x=false; // Variable for answer int result_copy=-1; // Number of copied data static datetime time_interim[]; // Temporary dynamic array for storing copied data static int bars_to_copy_time; // Number of bars for copying bars_to_copy_time=Bars(_Symbol,period,data_start,data_stop); // Find out the current number of bars on the time interval bars_to_copy_time-=bars_copied_time; // Calculate the number of bars to be copied if(bars_copied_time!=0) // If it is not the first time the data has been copied { bars_copied_time--; bars_to_copy_time++; } ArrayResize(time_interim,bars_to_copy_time); // Change the size of the receiving array result_copy=CopyTime(_Symbol,period,0,bars_to_copy_time,time_interim); if(result_copy!=-1) // If copying to the intermediate array is successful { ArrayCopy(result_array,time_interim,bars_copied_time,0,WHOLE_ARRAY); // Copy the data from the temporary array to the main one x=true; // assign the positive answer to the function bars_copied_time+=result_copy; // Increase the value of the processed data } //--- return(x); }
3.4. Ters Çevirme Parametre Hesaplama Fonksiyonu
Ters çevirme parametresi bir nokta veya yüzde olabileceğinden, gösterge ayarlarına bağlı olarak ters çevirme parametresini hesaplayacak fonksiyona ihtiyacımız vardır. Fonksiyonun yalnızca bir parametresi vardır – yüzde ters çevirmeyi hesaplamak için fiyat. Cevap için değişken ilk olarak double türü ile başlatılır ve hesaplamalardan sonra cevap için dolaylı olarak int türüne dönüştürülür.
Bunun nedeni, hesaplamalarda floating (kayan) nokta sayılarının kullanılması ve cevabın tamsayı olarak sunulmasının gerekmesidir. Seçim, fonksiyonda if-else koşullu ifadesi ile uygulanır. Karşılaştırma doğrudan harici giriş değişkeni (gösterge parametreleri) ile yapılır. Noktaların hesaplanması basit bir denklem kullanılarak yapılır. İlk olarak, fiyatın geçtiği toplam nokta sayısı tanımlanır. Daha sonra bu sayıya göre belirlenen yüzde hesaplanır ve döndürülen değişkene atanır.
//+------------------------------------------------------------------+ //| Func Calculate Doorstep | //+------------------------------------------------------------------+ int func_calc_dorstep(double price) { double x=0; // Variable for answer if(type_doorstep==0) // If the calculation is to be performed in points { x=doorstep; } if(type_doorstep==1) // If the calculation is to be performed in percentage { x=price/_Point*doorstep/100; } return((int)x); }
3.5. Ana Fonksiyon - Kagi Grafiği Çizme
Ana fonksiyonun - gösterge penceresinde Kagi grafiği çizme (yani gösterge tamponlarını doldurma) - çalışması için gerekli olan tüm fonksiyonları zaten inceledik. Fonksiyonun giriş parametreleri veri dizilerinden oluşur. Bunlardan ikisi yukarıda açıklanan hesaplama tamponlarıdır (önceden kopyalanan Fiyat ve Zaman), geri kalanı gösterge grafik oluşum tamponlarının dizileridir.
Verileri grafik oluşumunda saklamak için gerekli olan değişkenler fonksiyonun içinde bildirilir. Grafik for döngü ifadesi kullanılarak oluşturulduğundan, önceki geçişin bittiği aşamadaki verilere sahip olmalıyız. Bu ise, altı değişken ile gerçekleştirilebilir: line_move - fiyatın önceki geçişte hareket ettiği yer; line_gauge - çizgi ölçüsü (çizgi genişliği) - Yin veya Yang, price_1 ve price_2 - dikkate alınan önceki ve mevcut fiyat, price_down ve price_up - bir omuz ve belin önceki fiyatı. Gördüğümüz gibi, price_1, bu değişkenin döngünün en başından karşılaştırmadan önce hesaplamalarda yer alması nedeniyle, kopyalanan fiyatlar dizisinin hemen ilk öğesine eşitlenir.
Gösterge grafik oluşumunun tampon dizileri AS_SERIES indisleme bayrağına sahip olduğundan, ters sırada doldurulmaları gerekir. Bunu başarmak için uygun boyuta sahip zaman dizileri uygulanır. Verileri zaman, çizgi türleri, "omuz" ve "bel" olarak saklamak için global değişkenler ve ayrıca ters fiyatlar daha sonra aynı şekilde dönüştürülür.
Ardından, tüm diziler "boş" değerler (-1) ile doldurulmalıdır. Bu, iki küçük döngü kullanılarak yapılır. Her şeyi tek bir döngüde birleştirmek mümkündür. Ancak ikisini kullanmak, gerçekleştirilen tüm eylemleri çok daha net hale getirirken, yürütme süresi çok fazla değişmez. Diğer bir deyişle, grafik tamponları ve hesaplama zamanı dizileri ayrı ayrı doldurulur.
Artık tüm değişkenler bildirilir, dönüştürülür ve doldurulur, böylece ana döngü başlatılabilir. Bu oldukça büyüktür (hesaplama yeterince hızlı yapılsa da) ve önceden kopyalanmış tüm çubukların taranmasını içerir.
Döngü, kopyalanan tüm çubuklardan geçer ve bunlarla daha fazla çalışmak için önceden bildirilmiş gerekli dizileri doldurur. İlk olarak döngüde kullanılan tüm dizileri tanımlayalım:
- yin_int_1 - dikey Yin çizgisi fiyatının birincil değeri (dikey Yin çizgisi çizilirse ve grafik aşağı doğru hareket ederse bu, fiyatın üst değeridir; grafik yukarı doğru hareket ederse, bunun tersi olur);
- yin_int_2 - dikey Yin çizgisi fiyatının ikincil değeri (yukarı yönlü çizgi çizilirse bu, üst değerdir; çizgi aşağı yönlü ise, tersi durumumuz olur);
- yang_int_1 - dikey Yang çizgisi fiyatının birincil değeri;
- yang_int_2 - dikey Yang çizgisi fiyatının ikincil değeri;
- lin_yin - yatay Yin çizgisi değeri (Yin çizgisinde ters çevirme fiyatı);
- lin_yang - yatay Yang çizgisi değeri (Yang çizgisinde ters çevirme fiyatı);
- time_change - grafiğin ters çevrilme zamanı (omuz veya bel oluşumu);
- time_line - ters çevirme Yin = 0 veya Yang = 1 sırasındaki çizgi;
- time_central_price - merkezi fiyatın değeri, Yin çizgisinin Yang çizgisine dönüştüğü andaki fiyat veya bunun tam tersi;
- time_change_price - ters çevirme (omuz veya bel) fiyatının değeri, değişken Yin veya Yang çizgi türlerine bağlı olmayan yaygın bir değişkendir.
Fiyat tamponundan mevcut analiz edilen fiyatın değeri, if-else koşullu ifadelerde daha fazla karşılaştırma için her döngü geçişinden önce price_2 değişkenine atanır. Daha sonra kopyalanan verinin tampon dizisi adım adım analiz edilir ve yukarıda bahsedilen diziler doldurulur. Her if-else koşullu ifadesi, belirli eylemleri koşullara göre gerçekleştirir: grafik çizgilerinin önceki yönü (yukarı veya aşağı) ve çizgilerin önceki görünümü (Yin veya Yang). Daha sonra oluşum türüne (standart veya değiştirilmiş) göre hareket koşulları (fiyatın belirli bir noktayı geçip geçmediği) kontrol edilir.
Her şey yolundaysa, yeni değişkenler (dizi öğeleri) yeniden atanır veya tanımlanır. Çizgi türü (Yin veya Yang) en başta tanımlanır. Harekete ve önceki eylemlere göre, daha fazla dağıtım gerçekleştirilir.
İki olası fiyat hareketi vardır:
- Fiyat yukarı hareket eder;
- Fiyat aşağı hareket eder.
Ayrıca her yönde önceki eylemlerin dört türü vardır:
- Önceki çizgi Yin'dir ve yukarı hareket etmiştir;
- Önceki çizgi Yang'dır ve yukarı hareket etmiştir;
- Önceki çizgi Yin'dir ve aşağı hareket etmiştir;
- Önceki çizgi Yang'dır ve aşağı hareket etmiştir.
Böylece, grafiğin ilk hareketinin (ilk çizgi görünümü) ilk iki tanımı dışında sekiz durumumuz vardır.
Bundan sonra, ana döngü tamamlanmıştır. Tamponların yeniden atanması (ters çevrilmesi) ve doldurulması, grafiği, daha önce ana döngüde tanımlanan ve "a" değişkeninde yazılan Kagi grafiği ters çevrilme sayısından oluşan daha küçük bir döngüde oluşturmak için gerçekleştirilir. Alt ve üst fiyat değerlerinin ve dikey çizgilerin dağılımına gelince, her şey oldukça basittir: Basit bir tersine çevirme gerçekleştirilir. Diğer bir deyişle, önceden elde edilen birincil değerler (0,1,2,3... indislerine sahip diziler) tamponların son değerlerine ("а" indisli öğe, yani, а,а-1,а-2,a-3... bir son değer olarak kullanılır) atanır. Ters (yatay) çizgilerin birbirine yapışmasını önlemek için yukarıda belirtildiği gibi switch (değiştir) ifadesi kullanılarak döndürme yapılır.
Böylece, Kagi haritasının ana fonksiyonunun çalışması tamamlanmış olur.
//+------------------------------------------------------------------+ //| Func Draw Kagi | //+------------------------------------------------------------------+ void func_draw_kagi(double &array_input[], double &arr_yin_1[], double &arr_yin_2[], double &arr_yin_lin1[], double &arr_yin_lin2[], double &arr_yin_lin3[], double &arr_yang_1[], double &arr_yang_2[], double &arr_yang_lin1[], double &arr_yang_lin2[], double &arr_yang_lin3[], double &arr_time[]) { //--- a=0; // Variable for the chart construction fixing the number of chart reversals char line_move=0; // Previous price direction 1-up, -1-down char line_gauge=0; // Previous look of the line 1-thick yang, -1-thin yin double price_1=0,price_2=0; // Auxiliary variables for defining the price movement double price_down=-99999,price_up=99999; // Auxiliary variables for storing the reversal price values price_1=array_input[0]; //--- auxiliary arrays for the initial data storing before the reversal (transferring to the buffers) double yin_int_1[]; double yin_int_2[]; double lin_yin[]; double yang_int_1[]; double yang_int_2[]; double lin_yang[]; //--- change the sizes of dynamic arrays ArrayResize(yin_int_1,bars_copied); ArrayResize(yin_int_2,bars_copied); ArrayResize(yang_int_1,bars_copied); ArrayResize(yang_int_2,bars_copied); ArrayResize(lin_yin,bars_copied); ArrayResize(lin_yang,bars_copied); //--- time data storing arrays ArrayResize(time_change,bars_copied_time); ArrayResize(time_line,bars_copied_time); // Look of the line Yin = 0 or Yang = 1 ArrayResize(time_change_price,bars_copied_time); ArrayResize(time_central_price,bars_copied_time); //--- assign -1 (not displayed) value to the transferred buffers for(int z=0; z<bars_copied; z++) { arr_yin_1[z]=-1; arr_yin_2[z]=-1; arr_yin_lin1[z]=-1; arr_yin_lin2[z]=-1; arr_yin_lin3[z]=-1; arr_yang_1[z]=-1; arr_yang_2[z]=-1; arr_yang_lin1[z]=-1; arr_yang_lin2[z]=-1; arr_yang_lin3[z]=-1; } //--- equate -1 (not displayed) value to the arrays for(int z=0; z<bars_copied; z++) { yin_int_1[z]=-1; yin_int_2[z]=-1; lin_yin[z]=-1; yang_int_1[z]=-1; yang_int_2[z]=-1; lin_yang[z]=-1; time_change[z]=-1; time_line[z]=-1; time_change_price[z]=-1; time_central_price[z]=-1; } //--- function's main loop for(int z=0; z<bars_copied; z++) { price_2=array_input[z]; //--- first, let's define the initial market direction //--- first THIN DESCENDING line if(((price_1-price_2)/_Point>func_calc_dorstep(price_2)) && line_move==0) { yin_int_1[a]=price_1; yin_int_2[a]=price_2; line_move=-1; line_gauge=-1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=0; } //--- first THICK ASCENDING line if(((price_1-price_2)/_Point<-func_calc_dorstep(price_2)) && line_move==0) { yang_int_1[a]=price_1; yang_int_2[a]=price_2; line_move=1; line_gauge=1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=1; } //--- price moves DOWN //--- if the price moved DOWN before that, the line is THIN if(line_move==-1 && line_gauge==-1) { if(((price_1-price_2)/_Point>func_calc_dorstep(price_2)) || (kagi_type==0 && (price_1-price_2)/_Point>0)) { yin_int_2[a]=price_2; line_move=-1; line_gauge=-1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=0; } } //--- if the price moved DOWN before that, the line is THICK if(line_move==-1 && line_gauge==1) { if(((price_1-price_2)/_Point>func_calc_dorstep(price_2)) || (kagi_type==0 && (price_1-price_2)/_Point>0)) { if(price_2<price_down) // If the thick line crossed the lower shoulder when moving downwards { yin_int_1[a]=price_down; yin_int_2[a]=price_2; yang_int_2[a]=price_down; line_move=-1; line_gauge=-1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_central_price[a]=price_down; time_line[a]=0; } else //if(price_2>=price_down) // If the thick line has not crossed the lower shoulder when moving downwards { yang_int_2[a]=price_2; line_move=-1; line_gauge=1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=1; } } } //--- if the price has moved UPWARDS before that, the line is THIN if(line_move==1 && line_gauge==-1) { if((price_1-price_2)/_Point>func_calc_dorstep(price_2)) { a++; yin_int_1[a]=price_1; yin_int_2[a]=price_2; lin_yin[a]=price_1; line_move=-1; line_gauge=-1; price_up=price_1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=0; time_change_price[a]=lin_yin[a]; } } //--- if the price has moved UPWARDS before that, the line is THICK if(line_move==1 && line_gauge==1) { if((price_1-price_2)/_Point>func_calc_dorstep(price_2)) { a++; if(price_2<price_down) // If the thick line has crossed the lower shoulder when moving downwards { yin_int_1[a]=price_down; yin_int_2[a]=price_2; yang_int_1[a]=price_1; yang_int_2[a]=price_down; lin_yang[a]=price_1; line_move=-1; line_gauge=-1; price_up=price_1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=0; time_change_price[a]=lin_yang[a]; time_central_price[a]=price_down; } else//if(price_2>=price_down) // If the thick line has not crossed the lower shoulder when moving downwards { yang_int_1[a]=price_1; yang_int_2[a]=price_2; lin_yang[a]=price_1; line_move=-1; line_gauge=1; price_up=price_1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=1; time_change_price[a]=lin_yang[a]; } } } //--- the price moves UP //--- if the price has moved UPWARDS before that, the line is THICK if(line_move==1 && line_gauge==1) { if(((price_1-price_2)/_Point<-func_calc_dorstep(price_2)) || (kagi_type==0 && (price_1-price_2)/_Point<0)) { yang_int_2[a]=price_2; line_move=1; line_gauge=1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=1; } } //--- if the price has moved UPWARDS before that, the line is THIN if(line_move==1 && line_gauge==-1) { if(((price_1-price_2)/_Point<-func_calc_dorstep(price_2)) || (kagi_type==0 && (price_1-price_2)/_Point<0)) { if(price_2>price_up) // If the thin line has not crossed the upper shoulder when moving upwards { yin_int_2[a]=price_up; yang_int_1[a]=price_up; yang_int_2[a]=price_2; line_move=1; line_gauge=1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_central_price[a]=price_up; time_line[a]=1; } else//if(price_2<=price_up) // If the thin line has not crossed the upper shoulder when moving upwards { yin_int_2[a]=price_2; line_move=1; line_gauge=-1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=0; } } } //--- if the price has moved DOWNWARDS before that, the line is THICK if(line_move==-1 && line_gauge==1) { if((price_1-price_2)/_Point<-func_calc_dorstep(price_2)) { a++; yang_int_1[a]=price_1; yang_int_2[a]=price_2; lin_yang[a]=price_1; line_move=1; line_gauge=1; price_down=price_1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=1; time_change_price[a]=lin_yang[a]; } } //--- if the price has moved DOWNWARDS before that, the line is THIN if(line_move==-1 && line_gauge==-1) { if((price_1-price_2)/_Point<-func_calc_dorstep(price_2)) { a++; if(price_2>price_up) // If the thin line has crossed the upper shoulder when moving upwards { yin_int_1[a]=price_1; yin_int_2[a]=price_up; yang_int_1[a]=price_up; yang_int_2[a]=price_2; lin_yin[a]=price_1; line_move=1; line_gauge=1; price_down=price_1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=1; time_change_price[a]=lin_yin[a]; time_central_price[a]=price_up; } else //if(price_2<=price_up) // If the thin line has not crossed the upper shoulder when moving upwards { yin_int_1[a]=price_1; yin_int_2[a]=price_2; lin_yin[a]=price_1; line_move=1; line_gauge=-1; price_down=price_1; price_1=price_2; time_change[a]=(datetime)arr_time[z]; time_line[a]=0; time_change_price[a]=lin_yin[a]; } } } } //--- function's main loop //--- assign actual values to drawing buffers uint y=a; //--- auxiliary variables for storing data on filling the current buffer char yin=1; char yang=1; for(uint z=0; z<=a; z++) { arr_yin_1[z]=yin_int_1[y]; arr_yin_2[z]=yin_int_2[y]; switch(yin) { case 1: { arr_yin_lin1[z]=lin_yin[y]; arr_yin_lin1[z+1]=lin_yin[y]; yin++; } break; case 2: { arr_yin_lin2[z]=lin_yin[y]; arr_yin_lin2[z+1]=lin_yin[y]; yin++; } break; case 3: { arr_yin_lin3[z]=lin_yin[y]; arr_yin_lin3[z+1]=lin_yin[y]; yin=1; } break; } arr_yang_1[z]=yang_int_1[y]; arr_yang_2[z]=yang_int_2[y]; switch(yang) { case 1: { arr_yang_lin1[z]=lin_yang[y]; arr_yang_lin1[z+1]=lin_yang[y]; yang++; } break; case 2: { arr_yang_lin2[z]=lin_yang[y]; arr_yang_lin2[z+1]=lin_yang[y]; yang++; } break; case 3: { arr_yang_lin3[z]=lin_yang[y]; arr_yang_lin3[z+1]=lin_yang[y]; yang=1; } break; } y--; } //--- }
3.6. "Trend Çizgisi" Grafik Nesnesi Oluşturma Fonksiyonu
Şimdi, "trend çizgisi" grafik nesnesi oluşturma fonksiyonunu inceleyelim. Kagi'yi ana grafiğe çizmek için bu fonksiyona ihtiyaç vardır.
Fonksiyon çok basittir. "Trend çizgisi" grafik nesnesini oluşturmak için gerekli giriş parametrelerini içerir: nesne adı, birinci ve ikinci fiyat ve zaman noktalarının yanı sıra çizgi genişliği ve rengi. Fonksiyon gövdesi, grafik nesnesi oluşturma fonksiyonunu ve grafik nesnesinin özelliklerini değiştirmenin altı fonksiyonunu içerir.
//+------------------------------------------------------------------+ //| Func Object Create Trend Line | //+------------------------------------------------------------------+ void func_create_trend_line(string name, double price1, double price2, datetime time1, datetime time2, int width, color color_line) { ObjectCreate(0,name,OBJ_TREND,0,time1,price1,time2,price2); //--- set the line color ObjectSetInteger(0,name,OBJPROP_COLOR,color_line); //--- set the line display style ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); //--- set the line width ObjectSetInteger(0,name,OBJPROP_WIDTH,width); //--- display in the foreground (false) or background (true) ObjectSetInteger(0,name,OBJPROP_BACK,false); //--- enable (true) or disable (false) the mode of continuing the line display to the left ObjectSetInteger(0,name,OBJPROP_RAY_LEFT,false); //--- enable (true) or disable (false) the mode of continuing the line display to the right ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,false); }
3.7. Ana Grafiğe Kagi Çizme
Bir önceki için birden çok kez geçerli olan bir sonraki fonksiyon, Kagi oluşumunun ana grafikteki fonksiyonudur. Kagi grafik oluşumunun daha önce incelenen ana fonksiyonunda doldurulan global değişkenler giriş değişkenleri olarak kullanılır: ters fiyatların dizisi ("omuzlar" ve "beller"), değişim dizisi ve merkezi fiyatlar (Yin çizgisinin Yang'a dönüştüğü fiyat veya bunun tam tersi), ters çevirme zaman dizisi (gerçek zamanlı olarak bulunur, [z-1] dizi indisi ters çevirme başlangıcı işaretlemek için kullanılır), ters çevirmenin gerçekleştiği çizgi türünün dizisi (aynı zamanda zaman dizisi gibi ileriye dönük bir öğedir).
Fonksiyon gövdesi bir döngüden oluşur. Döngü iki bölüme ayrılır: dikey ve yatay çizgiler çizme. İlki de ikiye ayrılır: çizgi değişikliği (merkezi fiyatı değiştirir) göz önünde bulundurularak dikey çizgileri çizme ve değişiklik olmaması. "Trend çizgisi" nesne oluşturma fonksiyonunun aktarılan parametrelerine dikkat edin.
Adlandırma tekrarlı bir şekilde gerçekleştirilir. Nesne adı sihirli bir sayıyla başlar (belirli bir göstergenin nesnelerini silmek için gereklidir), sonra bunun türü sabitlenir ve son olarak indis atanır. İndis, döngünün her geçişinde güncellenir.
//+------------------------------------------------------------------+ //| Func Kagi Main Chart | //+------------------------------------------------------------------+ void func_kagi_main_chart(double &price[], // Shoulder prices array double ¢ral_price[], // Array of the prices of passing through the shoulders datetime &time[], // Current location time array ([-1] - start of shoulder) char &type_line_end[]) // Line type by the start of shoulder formation { //--- start of the loop for(uint z=1; z<=a; z++) { //--- check for the pass conditions (no pass) if(central_price[z]==-1) { if(type_line_end[z-1]==0 && price[z+1]!=-1) { func_create_trend_line(IntegerToString(magic_numb)+"_trend_yin_v"+IntegerToString(z), price[z],price[z+1],time[z],time[z],width_yin_main,color_yin_main); } if(type_line_end[z-1]==1 && price[z+1]!=-1) { func_create_trend_line(IntegerToString(magic_numb)+"_trend_yang_v"+IntegerToString(z), price[z],price[z+1],time[z],time[z],width_yang_main,color_yang_main); } } else //--- check for the pass conditions (pass is present) { if(type_line_end[z-1]==0 && price[z+1]!=-1) { func_create_trend_line(IntegerToString(magic_numb)+"_trend_yin_v"+IntegerToString(z), central_price[z],price[z],time[z],time[z],width_yin_main,color_yin_main); func_create_trend_line(IntegerToString(magic_numb)+"_trend_yang_v"+IntegerToString(z), central_price[z],price[z+1],time[z],time[z],width_yang_main,color_yang_main); } if(type_line_end[z-1]==1 && price[z+1]!=-1) { func_create_trend_line(IntegerToString(magic_numb)+"_trend_yin_v"+IntegerToString(z), central_price[z],price[z+1],time[z],time[z],width_yin_main,color_yin_main); func_create_trend_line(IntegerToString(magic_numb)+"_trend_yang_v"+IntegerToString(z), central_price[z],price[z],time[z],time[z],width_yang_main,color_yang_main); } } //--- check for the pass conditions (pass is present) //--- draw the horizontals if(type_line_end[z-1]==0) { func_create_trend_line(IntegerToString(magic_numb)+"_trend_h"+IntegerToString(z), price[z],price[z],time[z-1],time[z],width_yin_main,color_yin_main); } if(type_line_end[z-1]==1) { func_create_trend_line(IntegerToString(magic_numb)+"_trend_h"+IntegerToString(z), price[z],price[z],time[z-1],time[z],width_yang_main,color_yang_main); } //--- draw the horizontals } }
3.8. Ek Etiketler Uygulama
Yukarıda daha önce de belirttiğim gibi, gösterge ek etiketler uygular. Ana grafikte bu etiketleri sağlayan fonksiyonu inceleyelim. Burada iki etiket türü vardır: ters çevirme fiyatı ve "fiyat etiketi" ve "dikey etiket" aracılığıyla gösterilen ters çevirme zaman etiketleri. Aşağıdaki parametreler giriş parametreleri olarak aktarılır: ters fiyat etiketi çiziminin ve etiketin renginin öznitelikleri, ters çevirme zaman etiketi çiziminin ve etiketin renk değişiminin, ters çevirme süresinin birinci ve ikinci renklerinin öznitelikleri.
Tüm fonksiyon iki kısma ayrılmıştır: ilk kısım zaman etiketlerinden, ikincisi ise fiyat etiketlerinden sorumludur. Fonksiyonun her iki parçası da grafik ters çevirme sayısıyla ("a" değişkeni) sınırlandırılan döngülerden oluşur. if-else koşullu ifadesi döngüden önce ayarlanır. İfade, gösterge ayarlarına göre çizimlerinin gerekliliğini kontrol eder.
İlk döngü zaman etiketleri oluşturur, nesne adı tanımı döngünün başında gerçekleştirilir (ad oluşturma ilkesi yukarıda açıklanmıştır). Daha sonra, renk genel olarak bildirilen çizgi türü dizisindeki çizgiye göre seçilir (parametre ayarlanmışsa) ve diğer parametreler çizgiye uygulanır.
İkinci döngü ters fiyat etiketleri oluşturmaktan sorumludur. İlk olarak, nesne adı oluşturulur. Daha sonra, Kagi'nin ana grafik üzerinde oluşturulup oluşturulmayacağına göre zaman dizisi indis seçimi belirlenir. Bu yapılmazsa, etiketler "havada" yer alacak ve ters çevirmenin hangi yerden gerçekleştiği yeterince net olmayacaktır. Ardından, "fiyat etiketi" türü nesne oluşturulur ve yapılandırılır.
//+------------------------------------------------------------------+ //| Func Label Main Chart | //+------------------------------------------------------------------+ void func_label_main_chart(bool label_print, color label_color, bool time_change_print, bool time_change_color, color time_color_first, color time_color_second) { if(time_change_print==true) { for(uint z=1; z<=a; z++) { string name=IntegerToString(magic_numb)+"_time_2_"+IntegerToString(z); //--- create an object of a vertical line type ObjectCreate(0,name,OBJ_VLINE,0,time_change[z],0); //--- set the line color color color_line=clrBlack; if(time_change_color==true) { if(time_line[z]==0)color_line=time_color_first; if(time_line[z]==1)color_line=time_color_second; } else color_line=time_color_first; ObjectSetInteger(0,name,OBJPROP_COLOR,color_line); //--- set the line display style ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); //--- set the line width ObjectSetInteger(0,name,OBJPROP_WIDTH,1); //--- display on the foreground (false) or background (true) ObjectSetInteger(0,name,OBJPROP_BACK,false); //--- enable (true) or disable (false) the line display mode in the chart subwindows ObjectSetInteger(0,name,OBJPROP_RAY,time_separate_windows); } } if(label_print==true) { for(uint z=1; z<=a; z++) { string name=IntegerToString(magic_numb)+"_label_2_"+IntegerToString(z); uint numb_time; if(kagi_main_chart==true)numb_time=z; else numb_time=z-1; //--- create a label type object ObjectCreate(0,name,OBJ_ARROW_RIGHT_PRICE,0,time_change[numb_time],time_change_price[z]); //--- set the label color ObjectSetInteger(0,name,OBJPROP_COLOR,label_color); //--- set the edging line style ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); //--- set the label size ObjectSetInteger(0,name,OBJPROP_WIDTH,1); //--- display on the foreground (false) or background (true) ObjectSetInteger(0,name,OBJPROP_BACK,false); } } }
Şimdi, etiketleri gösterge penceresinde nasıl ayarlayabileceğimizi görelim.
Gösterge penceresindeki tüm etiketler çoğunlukla fiyattır ve bunların sadece iki türü vardır: ters çevirme fiyat etiketleri ve fiyat seviyeleri. Fiyat seviyelerini çizmenin iki türü vardır: grafik ters çevirmelerinde ve tüm grafik fiyat aralığının eşit bir mesafesinde. İlk tür seviyelerin rengini iki şekilde değiştirebilir: çizgi türüne (Yin veya Yang) göre ve ters çevirmeye (yukarı veya aşağı) göre.
Bu nedenle, fonksiyonun kendisi iki döngüye ayrılır: birincisi ters çevirme fiyat etiketlerini oluşturmaktan sorumludur, ikincisi ise fiyat seviyelerinin belirlenmesi ile ilgilidir. İkincisi iki türe daha ayrılır: her ters çevirmede etiket veya eşit seviyede fiyat aralığının her yerinde etiketler.
Bu fonksiyon, büyük sayılarda bunların grafiğin anlaşılmasını zorlaştıran şekilde aşırı yüklenmesi nedeniyle fiyat etiketlerinin ve seviyelerinin sayısında sınırlamalar olmasından dolayı öncekinden farklıdır.
Bu özellik nedeniyle, her iki döngü de gösterge ayarlarında belirtilen geçiş sayısıyla (fiyat etiketlerinin ve seviyelerinin sayısı) sınırlıdır. Böyle bir yaklaşım tehlikelidir, çünkü ters çevirme sayısı ayarlarda ayarlanan fiyat etiketlerinin sayısından çok daha küçük olabilir. Bu nedenle, her döngü geçişi sırasında ters çevirme varlığı bir fiyat etiketi veya seviyesi çizimi için kontrol edilir.
Tek istisna, tüm fiyat aralığı boyunca eşit mesafede fiyat seviyeleri çizilmesidir. "Fiyat etiketi" türü grafik nesnelerinin oluşturulması, koordinatlarda ters sırada gerçekleştirilir, yani etiketler mevcut tarihten geçmişe doğru yerleştirilir. Aynı şey fiyat seviyeleri için de geçerlidir: mevcut fiyat seviyeleri önce, daha öncekiler ise sonra oluşturulur. İstisnalar, grafik ters çevirmelerine bağlı olmayan fiyat seviyeleridir.
Fiyat seviyesi renk değişiklikleri ayarlara göre if-else koşullu ifadeleri kullanılarak yapılır.
//+------------------------------------------------------------------+ //| Func Label Indicator Window | //+------------------------------------------------------------------+ void func_label_indicator_window(bool label_print, // Draw price labels bool levels_print, // Draw levels char levels_type_draw, // Type of drawing the levels by reversals or at an equal distance of the entire price range char levels_color_change) // Change line color { uint number=a; if(label_print==true) { for(uint z=0; z<=label_1_number; z++) { if(z<number) { string name=IntegerToString(magic_numb)+"_label_1_"+IntegerToString(z); //--- create label type object ObjectCreate(0,name,OBJ_ARROW_RIGHT_PRICE,ChartWindowFind(),(datetime)Time[(bars_copied_time-z-2)],time_change_price[number-z]); //--- set the label color ObjectSetInteger(0,name,OBJPROP_COLOR,label_1_color); //--- set the style of the edging line ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); //--- set the label size ObjectSetInteger(0,name,OBJPROP_WIDTH,1); //--- display on the foreground (false) or background (true) ObjectSetInteger(0,name,OBJPROP_BACK,false); } } } if(levels_print==true) { if(levels_type_draw==0) { for(uint z=0; z<=levels_number; z++) { if(z<number) { IndicatorSetDouble(INDICATOR_LEVELVALUE,z,time_change_price[number-z]); if(levels_change_color==0) { double numb_even=z; if(MathMod(numb_even,2)==0) { IndicatorSetInteger(INDICATOR_LEVELCOLOR,z,levels_first_color); } if(MathMod(numb_even,2)!=0) { IndicatorSetInteger(INDICATOR_LEVELCOLOR,z,levels_second_color); } } if(levels_change_color==1) { if(time_line[number-z]==0)IndicatorSetInteger(INDICATOR_LEVELCOLOR,z,levels_first_color); if(time_line[number-z]==1)IndicatorSetInteger(INDICATOR_LEVELCOLOR,z,levels_second_color); } if(levels_change_color==2) { IndicatorSetInteger(INDICATOR_LEVELCOLOR,z,levels_first_color); } } } } if(levels_type_draw==1) { double max_price=Price[ArrayMaximum(Price)]; double min_price=Price[ArrayMinimum(Price,1,ArrayMinimum(Price)-1)]; double number_difference=(max_price-min_price)/levels_number; NormalizeDouble(number_difference,_Digits); for(uint z=0; z<=levels_number; z++) { IndicatorSetDouble(INDICATOR_LEVELVALUE,z,(min_price+(z*number_difference))); IndicatorSetInteger(INDICATOR_LEVELCOLOR,z,levels_first_color); } } } }
3.9. Önceden Oluşturulmuş Grafik Nesnelerini Silme
Bu göstergenin grafik nesneleri açısından zengin olduğunu zaten biliyoruz. Bunları hızlı ve verimli bir şekilde nasıl silebileceğimizi düşünmenin zamanı geldi.
Bu görev, grafik nesnelerini silme fonksiyonu tarafından yürütülür. Fonksiyon parametreleri olarak başlangıç adı ve nesne sayısı kullanılır. Oluşturma sırasında olduğu gibi, nesne adı sihirli sayıyı ve nesne türünün adını içermelidir. Programdaki fonksiyon çağrısı, bunların olası varlıklarını aşan nesne sayısı ile sınırlıdır. Ancak bu, göstergenin fonksiyonelliğini etkilemez.
//+------------------------------------------------------------------+ //| Func Delete Objects | //+------------------------------------------------------------------+ void func_delete_objects(string name, int number) { string name_del; for(int x=0; x<=number; x++) { name_del=name+IntegerToString(x); ObjectDelete(0,name_del); } }
3.10. Grafik Oluşumunu Başlatma Fonksiyonu
Şimdi, Kagi grafiğinin hesaplanması ve oluşumunun yanı sıra nesnelerin oluşturulması ve silinmesi için tüm fonksiyonları inceledikten sonra, yeni çubuğun varışını kontrol etmek için başka bir küçük fonksiyon düşünmeliyiz. Fonksiyon oldukça basittir ve bir giriş parametresine sahiptir: analiz edilen dönem. Fonksiyonun cevabı da çok basittir. Bu, bool türündedir ve yeni bir çubuğun bulunup bulunmadığının cevabını içerir. Fonksiyon gövdesinin temeli, kontrolü döneme bağlı olarak farklı ifadelerine geçiren switch ifadesidir.
Örnekte, fonksiyon tüm dönem aralığını kapsar, ancak yalnızca bir dönem de kullanılabilir.
Fonksiyon algoritması IsNewBar kodundan alınmıştır: son çubuğun açılma zamanı önceden tanımlanmış zaman değeri ile karşılaştırılır. Değerler farklıysa yeni bir çubuk vardır. Yeni değer daha önce tanımlanmış olarak atanır ve fonksiyonun cevabı pozitif olarak kabul edilir. Son çubuk açılış saati önceden belirlenmiş zaman değeriyle çakışıyorsa, yeni çubuk henüz görünmemiştir ve fonksiyonun cevabı negatiftir.
//+------------------------------------------------------------------+ //| Func New Bar | //+------------------------------------------------------------------+ bool func_new_bar(ENUM_TIMEFRAMES period_time) { //---- static datetime old_Times[22];// array for storing old values bool res=false; // analysis result variable int i=0; // old_Times[] array cell index datetime new_Time[1]; // new bar time switch(period_time) { case PERIOD_M1: i= 0; break; case PERIOD_M2: i= 1; break; case PERIOD_M3: i= 2; break; case PERIOD_M4: i= 3; break; case PERIOD_M5: i= 4; break; case PERIOD_M6: i= 5; break; case PERIOD_M10: i= 6; break; case PERIOD_M12: i= 7; break; case PERIOD_M15: i= 8; break; case PERIOD_M20: i= 9; break; case PERIOD_M30: i=10; break; case PERIOD_H1: i=11; break; case PERIOD_H2: i=12; break; case PERIOD_H3: i=13; break; case PERIOD_H4: i=14; break; case PERIOD_H6: i=15; break; case PERIOD_H8: i=16; break; case PERIOD_H12: i=17; break; case PERIOD_D1: i=18; break; case PERIOD_W1: i=19; break; case PERIOD_MN1: i=20; break; case PERIOD_CURRENT: i=21; break; } // copy the time of the last bar to new_Time[0] cell int copied=CopyTime(_Symbol,period_time,0,1,new_Time); if(copied>0) // all is well. Data has been copied { if(old_Times[i]!=new_Time[0]) // if the bar's old time is not equal to new one { if(old_Times[i]!=0) res=true; // if it is not the first launch, true = new bar old_Times[i]=new_Time[0]; // store the bar's time } } //---- return(res); }
3.11. OnCalculate() ve OnChartEvent() Fonksiyonları
Yukarıda açıklanan tüm fonksiyonlar aynı adı taşıyan fonksiyonda birleştirilir: Func (Fonksiyon) Birleştirme. Bu fonksiyon, OnCalculate() fonksiyonunda her yeni çubuk göründüğünde ve OnChartEvent() fonksiyonundan "R" tuşuna basıldığında başlatılır.
Grafik oluşturulmadan veya güncellenmeden önce, tüm grafik nesneleri silme fonksiyonu birleştirme fonksiyonunda (Fonksiyon Birleştirme) çağrılır. Oldukça fazla nesne olduğundan ve bunlar ana grafik ve gösterge penceresinin fiyat etiketlerine, ters çevirme zamanını gösteren dikey çizgilere ve Yin ve Yang dikey ve yatay trend çizgilerine ayrıldığından, fonksiyon çağrılarının genel sayısı 7'dir.
Daha sonra geçmiş verileri fiyat ve zamana göre kopyalanır. Kagi grafiği oluşturmak için ana fonksiyon daha sonra başlatılır. Bundan sonra, tüm fiyat etiketlerini ana grafiğe ve gösterge penceresine yerleştirme fonksiyonu çağrılır. Son olarak, Kagi ana grafikte oluşturulur ve nesneleri yeniden çizme fonksiyonu başlatılır.
//+------------------------------------------------------------------+ //| Func Consolidation | //+------------------------------------------------------------------+ void func_consolidation() { //--- date of construction end stop_data=TimeCurrent(); //--- deleting all graphical objects belonging to the indicator func_delete_objects(IntegerToString(magic_numb)+"_label_2_",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_label_1_",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_time_2_",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_yin_v",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_yang_v",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_h",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_h",ObjectsTotal(0,-1,-1)); //--- copy price data to the main buffer copy_history=func_copy_history(Price,start_data,stop_data); //--- display information about the error when copying price data if(copy_history==false)Alert("Error of copy history Price"); //--- copy time data to the main buffer copy_time=func_copy_time(Time,start_data,stop_data); //--- display a notification of the error occurred while copying time data if(copy_time==false)Alert("Error of copy history Time"); //--- construct Kagi chart in the indicator window func_draw_kagi(Price,YinBuffer1,YinBuffer2,Yin1Buffer,Yin2Buffer,Yin3Buffer, YangBuffer1,YangBuffer2,Yang1Buffer,Yang2Buffer,Yang3Buffer,Time); //--- draw labels on the main chart func_label_main_chart(label_2,label_2_color,time_line_draw,time_line_change_color,time_first_color,time_second_color); //--- draw labels on the indicator chart func_label_indicator_window(label_1,levels_on_off,levels_type,levels_change_color); //--- construct Kagi chart in the main window if(kagi_main_chart==true)func_kagi_main_chart(time_change_price,time_central_price,time_change,time_line); //--- redraw the chart ChartRedraw(0); //--- } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- if(func_new_bar(period_to_redraw)==true) { func_consolidation(); } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| OnChartEvent | //+------------------------------------------------------------------+ void OnChartEvent(const int id, // event ID const long& lparam, // long type event parameter const double& dparam, // double type event parameter const string& sparam) // string type event parameter { if(id==CHARTEVENT_KEYDOWN) // Keyboard button pressing event { if(lparam==82) // "R" key has been pressed { func_consolidation(); } } }
3.12. OnDeinit() Fonksiyonu
Tüm nesnelerin silinmesi gösterge sonlandırma fonksiyonunda gerçekleştirilir.
//+------------------------------------------------------------------+ //| OnDeinit | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- delete all graphical objects belonging to the indicator func_delete_objects(IntegerToString(magic_numb)+"_label_2_",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_label_1_",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_time_2_",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_yin_v",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_yang_v",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_h",ObjectsTotal(0,-1,-1)); func_delete_objects(IntegerToString(magic_numb)+"_trend_h",ObjectsTotal(0,-1,-1)); //--- redraw the chart ChartRedraw(0); }
Şimdi, göstergeyi pratikte kullanmaya geçelim.
4. Pratikte Kagi Grafiğini Kullanma
Kagi grafiğine dayalı birçok alım satım stratejisi vardır. Bazılarını inceleyeceğiz.
En popüler strateji ile başlayalım: Yang Yin'e dönüştüğünde sat ve tam tersi durumda satın al. Bu Şekil 4'te gösterilmektedir:
Şekil 4. Yang, Yin'e dönüştüğünde satmak ve tersi durumda satın almak
Şekil 4'te görüldüğü gibi (EURUSD M30, 5 nokta), bu strateji iyi sonuçlar göstermektedir. Şekil 4 sinyal için 8 nokta gösterir, ilki (1) uzun pozisyonun 1,3518'de açılması gerektiğini gösterir, bu da fiyat daha sonra günde 42 noktayı içine alarak yaklaşık 1,3560'a ulaştığı için doğru görünüyor. Bu iyi bir sonuç.
Bir sonraki nokta (2) 1,3519'dan satışı önerir. Gördüğümüz gibi, fiyat aslında yaklaşık iki saat boyunca 1,3485 seviyesini (ve 34 noktayı kapsayan) geçerek aşağı doğru hareket ediyor.
Noktaya (3) geçelim. Uzun pozisyon 1,3538'den açılır ve fiyat 1,3695'e kadar yükselir. Böylece, kâr zaten bir buçuk gün için 157 noktayı içerir. Tabii ki, bunlar mümkün olan en yüksek karlardır, ancak sonuç hala yeterince iyidir.
Bir sonraki alım satım stratejisi, Şekil 5'te (EURUSD M30, 5 puan), 7-18 Ekim'de gösterilen trend çizgisinden geri dönüyor:
Şekil 5. Trend çizgisinden geri dönüş
Daha da ilerleyebilir ve kanalları takip ederek alım satım yapabiliriz. Bir kanal arama örneği Şekil 6'da (EURUSD H1, 5 puan), kabaca aynı dönemde incelenebilir:
Şekil 6. Kanallar ile alım satım
7-10 ardışık olarak artan "omuzlar" veya azalan "beller" sonrasında, kesinlikle bir ters çevirme olacağı (düşüş veya yükseliş) gerçeğine dayanan daha az popüler strateji.
Bu, Şekil 7'de (GBPUSD H4, 25 nokta), 10 Temmuz - 18 Ekim'de gösterilir:
Şekil 7. 7-10 ardışık olarak artan "omuzlar" veya azalan "beller"
Görüntüde de görülebileceği gibi, yedi yükselen omuzu, kabaca önceki yükselişin yarısına (yaklaşık 300 nokta) eşit olarak oldukça önemli bir düşüş izler.
Ek gösterge parametrelerinin kullanılmasının gerekliliğini göstermek için "Fiyat etiketi üzerinden alım satım" stratejisini inceleyelim. Fikir, fiyat bir önceki fiyat etiketini aştığında (alış) veya altında hareket ettiğinde (satış) piyasaya girmektir.
Strateji Şekil 8'de gösterilmektedir (GBPUSD H4, 30 puan, değiştirilmiş yapı):
Şekil 8. Bir fiyat etiketi yoluyla alım satım
Şekil 8'deki kırmızı oklar ne zaman alış veya satış yapılacağını gösterir. Oklar, önceki fiyat etiketlerinin kırıldığı konumları görüntüleyen önceki fiyat etiketinden hareket etmektedir.
Zaman etiketleri esas olarak trend yönü işaretçileri olarak hizmet eder. Zaman etiketlerinin rengi çizgi türüne göre değiştirilebildiğinden ve Yin veya Yang çizgi türü trend yönünü veya tersine çevirmeyi gösterdiğinden, renk mevcut piyasa havasını tanımlamamıza yardımcı olabilir.
Örneğin, Şekil 9'da gösterilen #IBM hisse senedi grafiğini (H4, %1, standart yapı) alalım:
Şekil 9. Zaman etiketlerini kullanarak trend yönünü tanımlama
Grafik, mavi çizgilerin çoğunlukla grafiğin üst kısımlarında, kırmızı çizgilerin ise alt kısımlarda bulunduğunu gösterir.
Sonuç
Kagi grafiği, strateji temeli olarak veya daha hassas analiz için yardımcı bir araç olarak piyasa alım satımı için başarıyla kullanılabilir.
Bu makalede, kodun kendisini ve göstergeyi oluşturmanın bazı özelliklerini inceledim. Ana amaç, devre dışı bırakılabilen bazı ekstra özelliklere sahip gerekli tüm unsurları içeren çok fonksiyonu göstergenin oluşturulması olmuştur.
Gösterge için yeni fikirleri ve iyileştirmeleri düşünmeyi ve belki de gelecekte uygulamayı memnuniyetle karşılarım. Ayrıca, lütfen bana geri bildiriminizi sağlayın. Göstergeyle ilgili sorularınızı yanıtlamaktan mutluluk duyarım.
Bu makale, geçmişten grafikleri oluşturmak için göstergeler geliştirmeye adanmış serinin devamıdır. Önceki makale burada bulunabilir. Seri devam edecek ve umarım yakında tekrar karşılaşırız. İlginiz için teşekkür ederiz! Size başarılı alım satım ile optimize edilmiş ve istikrarlı kodlar diliyorum.
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/772





- Ücretsiz alım-satım uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz