#property description "Gösterge, daha büyük zaman dilimlerinin mumlarını şu andaki mumun üstünde gösterir."
//--- gösterge ayarları
#property indicator_chart_window
#property indicator_buffers 16
#property indicator_plots 8
//---- plot 1
#property indicator_label1 "BearBody"
#property indicator_color1 clrSeaGreen,clrSeaGreen
//---- plot 2
#property indicator_label2 "BearBodyEnd"
#property indicator_color2 clrSeaGreen,clrSeaGreen
//---- plot 3
#property indicator_label3 "BearShadow"
#property indicator_color3 clrSalmon,clrSalmon
//---- plot 4
#property indicator_label4 "BearShadowEnd"
#property indicator_color4 clrSalmon,clrSalmon
//---- plot 5
#property indicator_label5 "BullBody"
#property indicator_color5 clrOlive,clrOlive
//---- plot 6
#property indicator_label6 "BullBodyEnd"
#property indicator_color6 clrOlive,clrOlive
//---- plot 7
#property indicator_label7 "BullShadow"
#property indicator_color7 clrSkyBlue,clrSkyBlue
//---- plot 8
#property indicator_label8 "BullShadowEnd"
#property indicator_color8 clrSkyBlue,clrSkyBlue
//--- ön tanımlı sabitler
#define INDICATOR_EMPTY_VALUE 0.0
//--- giriş parametreleri
input ENUM_TIMEFRAMES InpPeriod=PERIOD_H4; // Göstergenin hesaplanacağı zaman aralığı
input datetime InpDateStart=D'2013.01.01 00:00'; // Analiz başlangıç tarihi
//--- satış eğilimli mumlar için oluşturulan gösterge tamponları
double ExtBearBodyFirst[];
double ExtBearBodySecond[];
double ExtBearBodyEndFirst[];
double ExtBearBodyEndSecond[];
double ExtBearShadowFirst[];
double ExtBearShadowSecond[];
double ExtBearShadowEndFirst[];
double ExtBearShadowEndSecond[];
//--- alım eğilimli mumlar için oluşturulan gösterge tamponları
double ExtBullBodyFirst[];
double ExtBullBodySecond[];
double ExtBullBodyEndFirst[];
double ExtBullBodyEndSecond[];
double ExtBullShadowFirst[];
double ExtBullShadowSecond[];
double ExtBullShadowEndFirst[];
double ExtBullShadowEndSecond[];
//--- global değişkenler
datetime ExtTimeBuff[]; // daha büyük zaman aralığı için zaman tamponu
int ExtSize=0; // zaman tamponu büyüklüğü
int ExtCount=0; // zaman tamponunu indisle
int ExtStartPos=0; // gösterge hesabı için başlangıç noktası
bool ExtStartFlag=true; // başlangıç noktasının belirlenmesi için yardımcı bayrak
datetime ExtCurrentTime[1]; // daha büyük zaman aralığındaki son çubuğun oluşma zamanı
datetime ExtLastTime; // daha büyük zaman aralığında, hesaplamanın gerçekleştiği son zaman
bool ExtBearFlag=true; // alım eğilimli gösterge tamponlarına girilecek verinin sırasını belirlemek için bayrak
bool ExtBullFlag=true; // satış eğilimli gösterge tamponlarına girilecek verinin sırasını belirlemek için bayrak
int ExtIndexMax=0; // dizideki en büyük değerli elemanın indisi
int ExtIndexMin=0; // dizideki en küçük değerli elemanın indisi
int ExtDirectionFlag=0; // son mum için fiyat hareketi yönü
//--- doğru çizim için mumun açılış ve kapanış fiyatları arasında değişim yap
const double ExtEmptyBodySize=0.2*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//+------------------------------------------------------------------+
//| Mumun temel parçasının doldurulması |
//+------------------------------------------------------------------+
void FillCandleMain(const double &open[],const double &close[],
const double &high[],const double &low[],
const int start,const int last,const int fill_index,
int &index_max,int &index_min)
{
//--- dizideki en büyük ve en küçük değerlerin indislerini bul
index_max=ArrayMaximum(high,ExtStartPos,last-start+1); // High dizisinin en büyüğü
index_min=ArrayMinimum(low,ExtStartPos,last-start+1); // Low dizisinin en küçüğü
//--- mevcut zaman aralığından kaç çubuk doldurulacak
int count=fill_index-start+1;
//--- ilk çubuktaki kapanış değeri, son çubuktakini aşarsa mum satış yönlü olur
if(open[start]>close[last])
{
//--- mumlar bunun öncesinde alım yönlüyse, alım yönlü gösterge tamponlarının değerlerini temizle
if(ExtDirectionFlag!=-1)
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,start,count);
//--- satış yönlü mum
ExtDirectionFlag=-1;
//--- mumu oluştur
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open[start],
close[last],high[index_max],low[index_min],start,count,ExtBearFlag);
//--- fonksiyondan çık
return;
}
//--- ilk çubuktaki kapanış fiyatı, son çubuğunkinden az ise mum, alım yönlü olur
if(open[start]<close[last])
{
//--- mumlar bunun öncesinde satış yönlüyse, satış yönlü gösterge tamponlarının değerlerini temizle
if(ExtDirectionFlag!=1)
ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,start,count);
//--- alım yönlü mum
ExtDirectionFlag=1;
//--- mumu oluştur
FormCandleMain(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,close[last],
open[start],high[index_max],low[index_min],start,count,ExtBullFlag);
//--- fonksiyondan çıkış
return;
}
//--- eğer fonksiyonun bu bölümündeysen, ilk çubuktaki açılış fiyatı, son çubuktaki kapanış
//--- fiyatına eşitse mumun satış yönlü olduğu söylenir
//--- eğer mum bundan önce alım yönlü olmuşsa, alım yönlü gösterge tamponlarının değerlerini temizle
if(ExtDirectionFlag!=-1)
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,start,count);
//--- satış yönlü mum
ExtDirectionFlag=-1;
//--- eğer açılış ve kapanış değerleri eşitse, doğru gösterim için kaydırma kullan
if(high[index_max]!=low[index_min])
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open[start],
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],start,count,ExtBearFlag);
else
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,
open[start],open[start]-ExtEmptyBodySize,high[index_max],
high[index_max]-ExtEmptyBodySize,start,count,ExtBearFlag);
}
//+------------------------------------------------------------------+
//| Mumun sonunu doldur |
//+------------------------------------------------------------------+
void FillCandleEnd(const double &open[],const double &close[],
const double &high[],const double &low[],
const int start,const int last,const int fill_index,
const int index_max,const int index_min)
{
//--- tek çubuk varsa çizme
if(last-start==0)
return;
//--- ilk çubuktaki kapanış değeri, son çubuktakini aşarsa mum satış yönlü olur
if(open[start]>close[last])
{
//--- mumun sonunu oluştur
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,
open[start],close[last],high[index_max],low[index_min],fill_index,ExtBearFlag);
//--- fonksiyondan çık
return;
}
//--- ilk çubuktaki kapanış fiyatı, son çubuğunkinden az ise mum, alım yönlü olur
if(open[start]<close[last])
{
//--- mumun sonunu oluştur
FormCandleEnd(ExtBullBodyEndFirst,ExtBullBodyEndSecond,ExtBullShadowEndFirst,ExtBullShadowEndSecond,
close[last],open[start],high[index_max],low[index_min],fill_index,ExtBullFlag);
//--- fonksiyondan çık
return;
}
//--- eğer fonksiyonun bu bölümündeysen, ilk çubuktaki açılış fiyatı, son çubuktaki kapanış
//--- fiyatına eşitse mumun satış yönlü olduğu söylenir
//--- mumun sonunu oluştur
if(high[index_max]!=low[index_min])
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,open[start],
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],fill_index,ExtBearFlag);
else
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,open[start],
open[start]-ExtEmptyBodySize,high[index_max],high[index_max]-ExtEmptyBodySize,fill_index,ExtBearFlag);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- gösterge periyotunu kontrol et
if(!CheckPeriod((int)Period(),(int)InpPeriod))
return(INIT_PARAMETERS_INCORRECT);
//--- ön planda fiyat verisini göster
ChartSetInteger(0,CHART_FOREGROUND,0,1);
//--- gösterge tamponlarının bağlanması
SetIndexBuffer(0,ExtBearBodyFirst);
SetIndexBuffer(1,ExtBearBodySecond);
SetIndexBuffer(2,ExtBearBodyEndFirst);
SetIndexBuffer(3,ExtBearBodyEndSecond);
SetIndexBuffer(4,ExtBearShadowFirst);
SetIndexBuffer(5,ExtBearShadowSecond);
SetIndexBuffer(6,ExtBearShadowEndFirst);
SetIndexBuffer(7,ExtBearShadowEndSecond);
SetIndexBuffer(8,ExtBullBodyFirst);
SetIndexBuffer(9,ExtBullBodySecond);
SetIndexBuffer(10,ExtBullBodyEndFirst);
SetIndexBuffer(11,ExtBullBodyEndSecond);
SetIndexBuffer(12,ExtBullShadowFirst);
SetIndexBuffer(13,ExtBullShadowSecond);
SetIndexBuffer(14,ExtBullShadowEndFirst);
SetIndexBuffer(15,ExtBullShadowEndSecond);
//--- göstergeyi oluşturmak için bazı özellikleri ayarla
for(int i=0;i<8;i++)
{
PlotIndexSetInteger(i,PLOT_DRAW_TYPE,DRAW_FILLING); // grafiksel yapı tipi
PlotIndexSetInteger(i,PLOT_LINE_STYLE,STYLE_SOLID); // çizgi stilinin çizimi
PlotIndexSetInteger(i,PLOT_LINE_WIDTH,1); // çizgi genişliğinin çizimi
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- halihazırda hesaplanan hiçbir çubuk olmaması durumunda
if(prev_calculated==0)
{
//--- daha büyük zaman aralığındaki çubukların varış zamanını al
if(!GetTimeData())
return(0);
}
//--- doğrudan indislemeyi ayarla
ArraySetAsSeries(time,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(close,false);
//--- çubukların hesaplanması için başlangıç değeri
int start=prev_calculated;
//--- eğer oluşmuşsa, göstergeyi çubuğun üzerinde hesapla
if(start!=0 && start==rates_total)
start--;
//--- gösterge değerlerinin hesaplanma döngüsü
for(int i=start;i<rates_total;i++)
{
//--- gösterge tamponlarının i sayıda elemanını boş değerle doldur
FillIndicatorBuffers(i);
//--- hesaplamayı InpDateStart tarihinden başlayan çubuklar için uygula
if(time[i]>=InpDateStart)
{
//--- değerlerin ilk olarak gösterilmeye başlanacağı pozisyonunu tanımla
if(ExtStartFlag)
{
//--- başlangıç pozisyonunun numarasını kaydet
ExtStartPos=i;
//--- daha büyük zaman aralığında time[i] değerini aşan ilk tarihi tanımla
while(time[i]>=ExtTimeBuff[ExtCount])
if(ExtCount<ExtSize-1)
ExtCount++;
//--- bir daha bu bloka rastlamamak için bayrak değerini değiştir
ExtStartFlag=false;
}
//--- dizide hala elemanlar var mı kontrol et
if(ExtCount<ExtSize)
{
//--- mevcut zaman aralığındaki değerin, daha büyük zaman aralığındaki değere ulaşmasını bekle
if(time[i]>=ExtTimeBuff[ExtCount])
{
//--- mumun ana kısmını çiz (son ve sondan bir önceki çubukların arasındaki alanı doldurmadan)
FillCandleMain(open,close,high,low,ExtStartPos,i-1,i-2,ExtIndexMax,ExtIndexMin);
//--- mumun sonunu doldur (son ve sondan bir önceki çubukların arasındaki alan)
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- bir sonraki mumu çizmek için başlangıç pozisyonunu kaydır
ExtStartPos=i;
//--- dizi sayacını artır
ExtCount++;
}
else
continue;
}
else
{
//--- dizi değerlerini sıfırla
ResetLastError();
//--- daha büyük zaman aralığından son tarihi al
if(CopyTime(Symbol(),InpPeriod,0,1,ExtCurrentTime)==-1)
{
Print("Veri kopyalama hatası, kod = ",GetLastError());
return(0);
}
//--- yeni alınan tarih daha büyükse, mumun oluşturulmasını durdur
if(ExtCurrentTime[0]>ExtLastTime)
{
//--- ana gösterge tamponlarında, son ve sondan bir önceki çubukların arasında kalan alanı temizle
ClearEndOfBodyMain(i-1);
//--- yardımcı gösterge tamponlarını kullanarak alanı doldur
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- bir sonraki mumu çizmek için başlangıç pozisyonunu kaydır
ExtStartPos=i;
//--- fiyat yönü için oluşturulan bayrağı sıfırla
ExtDirectionFlag=0;
//--- yeni son tarihi kaydet
ExtLastTime=ExtCurrentTime[0];
}
else
{
//--- mumu oluştur
FillCandleMain(open,close,high,low,ExtStartPos,i,i,ExtIndexMax,ExtIndexMin);
}
}
}
}
//--- bir sonraki çağrı için prev_calculated değerine dönüş yap
return(rates_total);
}
//+------------------------------------------------------------------+
//| Belirlenen gösterge periyotunun doğruluğunu kontrol et |
//+------------------------------------------------------------------+
bool CheckPeriod(int current_period,int high_period)
{
//--- göstergenin periyotu, gösterildiği zaman aralığından büyük olmalı
if(current_period>=high_period)
{
Print("Hata! Gösterge periyotunun değeri halihazırdaki zaman aralığı değerinden büyük olmalı!");
return(false);
}
//--- gösterge periyotu bir hafta veya bir ay ise, periyot doğru
if(high_period>32768)
return(true);
//--- periyot değerlerini dakikalara dönüştür
if(high_period>30)
high_period=(high_period-16384)*60;
if(current_period>30)
current_period=(current_period-16384)*60;
//--- gösterge periyotu, üzerinde gösterildiği zaman aralığının katı olmalı
if(high_period%current_period!=0)
{
Print("Hata! gösterge periyotunun değeri, üzerinde gösterildiği zaman aralığının katı olmalı!");
return(false);
}
//--- gösterge periyotu, üzerinde gösterildiği zaman aralığını en az 3 kat aşmalı
if(high_period/current_period<3)
{
Print("Hata! Gösterge periyotu, üzerinde gösterildiği zaman aralığını en az 3 kat aşmalı!");
return(false);
}
//--- halihazırdaki zaman aralığı için gösterge periyotu doğru
return(true);
}
//+------------------------------------------------------------------+
//| Daha büyük olan zaman aralığından zaman verisi al |
//+------------------------------------------------------------------+
bool GetTimeData(void)
{
//--- hata değerini sıfırla
ResetLastError();
//--- mevcut zaman için tüm veriyi kopyala
if(CopyTime(Symbol(),InpPeriod,InpDateStart,TimeCurrent(),ExtTimeBuff)==-1)
{
//--- hata kodunu al
int code=GetLastError();
//--- hata mesajını çıktıla
PrintFormat("Veri kopyalama hatası! %s",code==4401
? "Geçmişin karşıya yüklenmesi hala devam ediyor!"
: "Kod = "+IntegerToString(code));
//--- veri yükleme denemesini tekrarlamak için false değerine dönüş yap
return(false);
}
//--- dizi büyüklüğünü al
ExtSize=ArraySize(ExtTimeBuff);
//--- dizi için oluşturulan döngü indisini sıfır yap
ExtCount=0;
//--- şu andaki çubuğun zaman aralığı üzerindeki pozisyonunu sıfır yap
ExtStartPos=0;
ExtStartFlag=true;
//--- daha büyük zaman aralığındaki son zaman değerini kaydet
ExtLastTime=ExtTimeBuff[ExtSize-1];
//--- başarılı çalıştırma
return(true);
}
//+--------------------------------------------------------------------------+
//| Fonksiyon, mumun ana parçasını şekillendirir. Bayrağın değerine |
//| bağlı olarak, fonksiyon, hangi veri ve dizilerin doğru görüntüleme |
//| amacıyla kullanılacağını belirler. |
//+--------------------------------------------------------------------------+
void FormCandleMain(double &body_fst[],double &body_snd[],
double &shadow_fst[],double &shadow_snd[],
const double fst_value,const double snd_value,
const double fst_extremum,const double snd_extremum,
const int start,const int count,const bool flag)
{
//--- bayrağın değerini kontrol et
if(flag)
{
//--- mumun gövdesini oluştur
FormMain(body_fst,body_snd,fst_value,snd_value,start,count);
//--- mumun gölgesini oluştur
FormMain(shadow_fst,shadow_snd,fst_extremum,snd_extremum,start,count);
}
else
{
//--- mumun gövdesini oluştur
FormMain(body_fst,body_snd,snd_value,fst_value,start,count);
//--- mumun gölgesini oluştur
FormMain(shadow_fst,shadow_snd,snd_extremum,fst_extremum,start,count);
}
}
//+-------------------------------------------------------------------------------+
//| Fonksiyon, mumun sonunu şekillendirir. Bayrak değerine bağlı olarak, |
//| fonksiyon, hangi veri ve dizilerin düzgün görüntüleme |
//| amacıyla kullanılacağını belirler. |
//+-------------------------------------------------------------------------------+
void FormCandleEnd(double &body_fst[],double &body_snd[],
double &shadow_fst[],double &shadow_snd[],
const double fst_value,const double snd_value,
const double fst_extremum,const double snd_extremum,
const int end,bool &flag)
{
//--- bayrağın değerini kontrol et
if(flag)
{
//--- mum gövdesinin sonunu oluştur
FormEnd(body_fst,body_snd,fst_value,snd_value,end);
//--- mum gölgesinin sonunu oluştur
FormEnd(shadow_fst,shadow_snd,fst_extremum,snd_extremum,end);
//--- bayrak değerini tersine değiştir
flag=false;
}
else
{
//--- mum gövdesinin sonunu oluştur
FormEnd(body_fst,body_snd,snd_value,fst_value,end);
//--- mum gölgesinin sonunu oluştur
FormEnd(shadow_fst,shadow_snd,snd_extremum,fst_extremum,end);
//--- bayrak değerini tersine değiştir
flag=true;
}
}
//+---------------------------------------------------------------------------------+
//| Mumun son kısmını (bir önceki çubuk ile şimdiki çubuk arasında kalan alanı) |
//| temizle) |
//+---------------------------------------------------------------------------------+
void ClearEndOfBodyMain(const int ind)
{
ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,ind,1);
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,ind,1);
}
//+--------------------------------------------------------------------------+
//| Mumu temizle |
//+--------------------------------------------------------------------------+
void ClearCandle(double &body_fst[],double &body_snd[],double &shadow_fst[],
double &shadow_snd[],const int start,const int count)
{
//--- kontrol et
if(count!=0)
{
//--- gösterge tamponlarını boş değerlerle doldur
ArrayFill(body_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(body_snd,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_snd,start,count,INDICATOR_EMPTY_VALUE);
}
}
//+--------------------------------------------------------------------------+
//| Mumun ana parçasını oluştur |
//+--------------------------------------------------------------------------+
void FormMain(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int start,const int count)
{
//--- kontrol et
if(count!=0)
{
//--- gösterge tamponlarını değerlerle doldur
ArrayFill(fst,start,count,fst_value);
ArrayFill(snd,start,count,snd_value);
}
}
//+-----------------------------------------------------------------------------+
//| Mumun sonunu oluştur |
//+-----------------------------------------------------------------------------+
void FormEnd(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int last)
{
//--- gösterge tamponlarını değerlerle doldur
ArrayFill(fst,last-1,2,fst_value);
ArrayFill(snd,last-1,2,snd_value);
}
//+------------------------------------------------------------------+
//| Gösterge tamponlarının i elemanını boş değerle doldur |
//+------------------------------------------------------------------+
void FillIndicatorBuffers(const int i)
{
//--- gösterge tamponlarının hücresinde bir boş değer ayarla
ExtBearBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
}
|