
Bulanık Mantık Kullanarak Gösterge Oluşturmanın Basit Örneği
Giriş
Finansal piyasaların analizi için çeşitli yöntemlerin kullanılması, son yıllarda yatırımcılar arasında giderek daha popüler hale geliyor. Ben de katkıda bulunmak ve birkaç düzine kod satırı yazarak iyi bir göstergenin nasıl yapılacağını göstermek istiyorum. Ayrıca, size bulanık mantığın temellerini kısaca açıklayacağım.
Bu konuya ilgi duyan ve daha derinlemesine araştırmak isteyen herkes aşağıdaki eserleri okuyabilir:
2. Bocharnikov V."Fuzzy Technology: Mathematical Background. Simulation Practice in Economics" (Rusça).
3. S.N. Sivanandam, S. Sumathi, S.N. Deepa. Introduction to Fuzzy Logic using MATLAB.
4. C. Kahraman. Fuzzy Engineering Economics with Applications (Studies in Fuzziness and Soft Computing).
1. Fuzzy Logic Basics
"...biraz daha...", "...çok hızlı...", "...neredeyse hiçbir şey..." gibi basit ifadelerin anlamlarını bilgisayarlarımıza nasıl açıklayabiliriz? Aslında, bu, bulanık küme teorisi öğelerini veya daha doğrusu "üyelik işlevleri" olarak adlandırılanları kullanarak oldukça mümkündür. А. Leonenkov'un kitabından bir örnek verelim:
"Sıcak kahve" ifadesinin üyelik işlevini tanımlayalım: Kahve sıcaklığı 0 ila 100 santigrat derece aralığında kabul edilmelidir; zira 0 derecenin altındaki sıcaklıklarda buza dönüşürken, 100 derecenin üzerindeki sıcaklıklarda buharlaşacaktır. 20 derecelik bir sıcaklığa sahip bir fincan kahvenin sıcak olarak adlandırılamayacağı oldukça açıktır; yani "sıcak" kategorisindeki üyelik işlevi 0'a eşit iken, 70 derecelik bir sıcaklığa sahip bir fincan kahve ise kesinlikle "sıcak" kategorisine aittir ve bu nedenle, bu durumda işlev değeri 1'e eşittir.
Bu iki sınır değer arasındakisıcaklık değerlerine gelince; durum o kadar da kesin değil. Bazıları 55 derece sıcaklıktaki bir fincan kahveyi "sıcak" olarak değerlendirirken, diğerleri "çok sıcak olmadığını" söyleyebilir. "Bulanıklık" budur.
Yine de üyelik işlevinin yaklaşık görünümünü hayal edebiliriz: "Tekdüze artan":
Yukarıdaki şekil "parçalı doğrusal" üyelik işlevini göstermektedir.
Dolayısıyla, işlev aşağıdaki analitik ifade ile tanımlanabilir:
Göstergemiz için bu tür işlevleri kullanacağız.
2. Üyelik İşlevi
Şu veya bu şekilde, herhangi bir teknik göstergenin görevi, mevcut piyasa durumunun (düz, yükseliş trendi, düşüş trendi) belirlenmesi ve ayrıca piyasaya giriş/çıkış sinyallerinin oluşturulmasıdır. Bu, üyelik işlevlerinin yardımıyla nasıl yapılabilir? Yeterince kolay.
Her şeyden önce, sınır koşullarını tanımlamamız gerekir. Şu sınır koşullarını alalım: «%100 yükseliş trendi» için, tipik fiyata (H+L+C)/3 göre 2. döneme sahip EMA'nın 8, 0,08, SMA, Açılış, parametrelerine sahip Zarflar üst sınırı ile geçişi olacakken, «%100 düşüş trendi» için Zarflar alt sınırı ile aynı EMA'nın geçişi olacaktır. Bu koşullar arasında yer alan her şey düz kabul edilecektir. 32, 0,15, SMA, Close parametrelerine sahip bir zarf daha ekleyelim.
Sonuç olarak, iki özdeş üyelik işlevi elde edeceğiz. Sırasıyla her iki işlev de 1'e eşit olduğunda al sinyali etkinleşecek, her iki işlev de -1'e eşit olduğunda sat sinyali etkinleşecektir. -1 ile 1 aralığında grafikler oluşturmak uygun olduğu için ortaya çıkan grafik iki işlevin aritmetik ortalaması F(x)= (f1(x)+f2(x))/2 olarak elde edilecektir.
Bu, grafikte şu şekilde görünür:
Bu durumda üyelik işlevi aşağıdaki grafiksel gösterime sahip olacaktır:
Analitik olarak şu şekilde yazılabilir:
,
Burada a ve b sırasıyla üst ve alt zarf çizgileridir, х ise EMA(2)'nin bir değeridir.
Tanımlanan işlev ile artık gösterge kodunu yazmaya geçebiliriz.
3. Program Kodunu Oluşturma
Öncelikli olarak, neyi ve nasıl çizeceğimizi belirlemeliyiz.
Üyelik işlevi hesaplama sonuçları, sırasıyla kırmızı ve mavi çizgi olarak görüntülenecektir.
Aritmetik ortalama, sıfır çizgisinden bir histogram olarak görüntülenecek ve ortaya çıkan işlev değerine bağlı olarak beş renkten birinde boyanacaktır:
Bunun için DRAW_COLOR_HISTOGRAM çizim stili kullanılacaktır.
Değerleri 1 veya -1'e eşit olan histogram çubuklarının üzerine al/çık sinyalleri olarak mavi ve kırmızı dikdörtgenler çizelim.
Şimdi MetaEditor'u çalıştırma ve başlama zamanı. Yeni->Özel Gösterge->Sonraki... "Parametreler" alanını doldurun:
Arabellekleri oluşturun:
"Bitir" düğmesine tıkladıktan sonra bir kaynak kodu alıyoruz ve bunu geliştirmeye başlıyoruz.
İlk olarak, arabellek sayısını tanımlayalım. Bunlardan yedi tanesi Sihirbaz tarafından zaten oluşturulmuştur (5'i veri için, 2'si renk için). Bu 5 tane daha gerekli.
#property indicator_minimum -1.4 // Setting fractional values #property indicator_maximum 1.4 // Expert Advisors wizard ignores fractional parts for some reason #property indicator_buffers 12 // Changing the value from 7 to 12 (5 more buffers have been added)Giriş parametrelerini düzenleyelim:
input string txt1="----------"; input int Period_Fast=8; input ENUM_MA_METHOD Method_Fast = MODE_SMA; /*Smoothing method*/ //moving average smoothing method input ENUM_APPLIED_PRICE Price_Fast = PRICE_CLOSE; input double Dev_Fast=0.08; input string txt2="----------"; input int Period_Slow=32; input ENUM_MA_METHOD Method_Slow = MODE_SMA; input ENUM_APPLIED_PRICE Price_Slow = PRICE_CLOSE; input double Dev_Slow=0.15; /*Deviation parameter*/ input string txt3="----------"; input int Period_Signal=2; input ENUM_MA_METHOD Method_Signal = MODE_EMA; input ENUM_APPLIED_PRICE Price_Signal = PRICE_TYPICAL; input string txt4="----------";
Bildirilen değişkeni takip eden açıklamalar çok kullanışlıdır. Açıklamaların metni, gösterge parametreleri penceresine eklenir.
Liste oluşturma olanağı da çok kullanışlıdır:
Gösterge tanıtıcıları ve arabellekler için değişkenleri ayırma:
int Envelopes_Fast; // Fast envelope int Envelopes_Slow; // Slow envelope int MA_Signal; // Signal line double Env_Fast_Up[]; // Fast envelope upper border double Env_Fast_Dn[]; // Fast envelope lower border double Env_Slow_Up[]; // Slow envelope upper border double Env_Slow_Dn[]; // Slow envelope lower border double Mov_Sign[]; // Signal line
Şimdi, OnInit() işlevine gidin.
İşe biraz güzellik katalım: Gösterge adını belirtin ve fazladan ondalık sıfırları kaldırın:
IndicatorSetInteger(INDICATOR_DIGITS,1); // setting display accuracy, we do not need some outstanding accuracy values string name; // indicator name StringConcatenate(name, "FLE ( ", Period_Fast, " , ", Dev_Fast, " | ", Period_Slow, " , ", Dev_Slow, " | ", Period_Signal, " )"); IndicatorSetString(INDICATOR_SHORTNAME,name);
ve eksik arabellekleri ekleyin:
SetIndexBuffer(7,Env_Fast_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(8,Env_Fast_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(9,Env_Slow_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(10,Env_Slow_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(11,Mov_Sign,INDICATOR_CALCULATIONS);
INDICATOR_HESAPLAMALAR parametresi, arabellek verilerinin yalnızca ara hesaplamalar için gerekli olduğu anlamına gelir. Bu, grafikte gösterilmeyecektir.
Renk arabelleklerini içeren göstergelerin nasıl bildirildiğine dikkat edin:
SetIndexBuffer(4,SignalBuffer1,INDICATOR_DATA); // All indicator buffers at first SetIndexBuffer(5,SignalBuffer2,INDICATOR_DATA); // as this is Color Histogram2, then it has 2 data buffers SetIndexBuffer(6,SignalColors,INDICATOR_COLOR_INDEX);// the color buffer comes next.
Tanıtıcıları doldurma:
Envelopes_Fast = iEnvelopes(NULL,0,Period_Fast,0,Method_Fast,Price_Fast,Dev_Fast); Envelopes_Slow = iEnvelopes(NULL,0,Period_Slow,0,Method_Slow,Price_Slow,Dev_Slow); MA_Signal = iMA(NULL,0,Period_Signal,0,Method_Signal,Price_Signal);
OnInit() işlevi ile yapılan tüm işler tamamlandı.
Şimdi üyelik işlevi değerini hesaplayacak işlevi oluşturalım:
double Fuzzy(double x,double a, double c) { double F; if (a<x) F=1; // 100% uptrend else if (x<=a && x>=c) F=(1-2*(a-x)/(a-c));// Flat else if (x<c) F=-1; // 100% downtrend return (F); }
Hazırlıklar tamamlandı. Değişkenler ve arabellekler bildirildi, tanıtıcılar atandı.
Şimdi OnCalculate() temel işlevine geçme zamanı.
İlk önce, gerekli göstergelerin değerlerini ara belleklere yazalım. CopyBuffer() işlevini kullanın:
CopyBuffer(Envelopes_Fast, // Indicator handle UPPER_LINE, // Indicator buffer 0, // The point to start 0 - from the very beginning rates_total, // How many to be copied - All Env_Fast_Up); // The buffer the values are written in // - the rest are done in a similar way CopyBuffer(Envelopes_Fast,LOWER_LINE,0,rates_total,Env_Fast_Dn); CopyBuffer(Envelopes_Slow,UPPER_LINE,0,rates_total,Env_Slow_Up); CopyBuffer(Envelopes_Slow,LOWER_LINE,0,rates_total,Env_Slow_Dn); CopyBuffer(MA_Signal,0,0,rates_total,Mov_Sign);
Buraya hesaplama optimizasyonu için kodu eklemeliyiz (yalnızca son çubuğu yeniden hesaplama işlemi gerçekleştirilir):
// declaring start variable for storing the index of the bar, recalculation of the indicator buffers will be // carried out from. int start; if (prev_calculated==0) // in case no bars have been calculated { start = Period_Slow; // not all indicators have been calculated up to this value, therefore, there is no point in executing the code } else start=prev_calculated-1; for (int i=start;i<rates_total;i++) { // All remaining code will be written here }
Çok fazla kod kalmadı.
X, a, b parametrelerini ayarlama, üyelik işlevi değerini hesaplama işlemini gerçekleştirme ve uygun arabelleğe yazma:double x = Mov_Sign[i]; // Signal // Setting the first membership function parameters: double a1 = Env_Fast_Up[i]; // Upper border double b1 = Env_Fast_Dn[i]; // setting the first membership function value and writing it to the buffer Rule1Buffer[i] = Fuzzy(x,a1,b1); // Setting the second membership function parameters: double a2 = Env_Slow_Up[i]; // Upper border double b2 = Env_Slow_Dn[i]; // setting the second membership function value and writing it to the buffer Rule2Buffer[i] = Fuzzy(x,a2,b2);
İki gösterge çizgisi oluşturuldu.
Şimdi ortaya çıkan değeri hesaplayalım.
ResultBuffer[i] = (Rule1Buffer[i]+Rule2Buffer[i])/2;
Daha sonra histogram çubuklarını uygun renklerle boyamalıyız: Elimizde beş renk olduğu için ResultColors[i] 0 ila 4 arasında herhangi bir değer alabilir.
Genel olarak, olası renk sayısı 64'tür. Dolayısıyla, bu, kişinin yaratıcı yeteneklerini uygulaması için mükemmel bir fırsat.
for (int ColorIndex=0;ColorIndex<=4;ColorIndex++) { if (MathAbs(ResultBuffer[i])>0.2*ColorIndex && MathAbs(ResultBuffer[i])<=0.2*(ColorIndex+1)) { ResultColors[i] = ColorIndex; break; } }
O zaman, sinyal dikdörtgenlerini çizmeliyiz. DRAW_COLOR_HISTOGRAM2 çizim stilini kullanacağız.
Bu, bir histogram çubuğu içeren iki veri arabelleğine ve aralarında oluşturulmuş bir renk arabelleğine sahiptir.
Veri arabelleği değerleri her zaman aynı olacaktır: Sırasıyla al sinyali için 1,1 ve 1,3, sat sinyali için -1,1 ve -1,3.
EMPTY_VALUE, sinyalin olmadığı anlamına gelecektir.
if (ResultBuffer[i]==1) { SignalBuffer1[i]=1.1; SignalBuffer2[i]=1.3; SignalColors[i]=1; } else if (ResultBuffer[i]==-1) { SignalBuffer1[i]=-1.1; SignalBuffer2[i]=-1.3; SignalColors[i]=0; } else { SignalBuffer1[i]=EMPTY_VALUE; SignalBuffer2[i]=EMPTY_VALUE; SignalColors[i]=EMPTY_VALUE; }
"Derle" seçeneğine tıklayın ve işte!
Sonuç
Başka ne eklenebilir? Bu makalede bulanık mantığa en temel yaklaşıma değindim.
Burada çeşitli denemeler için yeterince alan var. Örneğin, aşağıdaki işlevi kullanabiliriz:
Bunun için analitik ifadeyi yazmanızın ve uygun koşulları bulmanızın zor olmayacağını düşünüyorum.
İyi şanslar!
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/178





- Ü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