English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
preview
Gösterge Bilgisinin Ölçülmesi

Gösterge Bilgisinin Ölçülmesi

MetaTrader 5Örnekler |
275 10
Francis Dube
Francis Dube

Giriş

Makine öğrenimi, sonuçta oldukça doğru tahminler yapmak için piyasanın genel davranışını öğrenmek üzere eğitim verilerine dayanır. Seçilen öğrenme algoritması, anlamlı bilgiler elde etmek için dikkatle seçilmiş bir örneklem üzerinden geçmek zorundadır. Birçok kişinin bu gelişmiş araçları başarılı bir şekilde uygulayamamasının nedeni, anlamlı bilgilerin çoğunun gürültülü verilerde saklı olmasıdır. Kullandığımız veri setlerinin model eğitimi için uygun olmayabileceği birçok strateji geliştiricisi için net olmayabilir.

Göstergeler, uygulandıkları temel fiyat serileri hakkında bilgi sağlayıcıları olarak düşünülebilir. Bu önermeyi kullanarak entropi, bir gösterge tarafından ne kadar bilgi iletildiğini ölçmek için kullanılabilir. Timothy Masters tarafından yazılan “Testing and Tuning Market Trading Systems” (TTMTS) (piyasa alım-satım sistemlerinin test edilmesi ve ayarlanması) kitabında belgelenen adımları ve araçları kullanarak, gösterge verilerinin yapısını nasıl değerlendirebileceğimizi göstereceğiz.


Gösterge bilgisi neden ölçülür?

Strateji geliştirmek için makine öğrenimi araçlarını kullanırken genellikle, bir şeyler çıkacağı umuduyla algoritmalara her türlü veriyi atmaya başvururuz. Nihayetinde başarı, modelde kullanılan tahmin edicilerin kalitesine bağlı olacaktır ve etkili tahmin ediciler genellikle belirli özelliklere sahiptir. Bunlardan biri bilgi içeriği yüküdür.

Model eğitimi için kullanılan değişkenlerdeki bilgi miktarı önemlidir ancak etkili model eğitimi için tek gereklilik değildir. Bu nedenle, bilgi içeriğinin ölçülmesi, aksi takdirde eğitim sürecinde körlemesine kullanılacak göstergelerin taranması için kullanılabilir.  Entropi kavramının uygulandığı yer burasıdır.


Entropi

Entropi hakkında MQL5.com'da halihazırda birkaç kez makale yazılmıştır. Başka bir tanıma katlanmak zorunda kalacakları için okuyucudan özür dilerim, ancak bunun konseptin uygulamasını anlamak için gerekli olduğuna söz veriyorum. Önceki makaleler entropi hesaplamasının tarihçesini ve türetilmesini sunmuştur, bu nedenle sadelik adına denklemle başlayacağız.

                                                        

Entropi denklemi

H(X) X'in entropisi anlamına gelir, X rastgele bir değişkeni, örneğin bir mesajı temsil eden ayrık bir değişkendir. Mesajın içeriği yalnızca sonlu sayıda değer alabilir. Bu, denklemde küçük x olarak gösterilir. Küçük x'ler, mesajların gözlemlenen değerleridir (öyle ki, x'in tüm olası değerleri bir N kümesinde sıralanır).

Adil bir zar örneği düşünelim. Zar, atıldığında, oyunun sonucunu belirleyen bir bilgi sağlıyormuş gibi algılanabilir. Zarın 1'den 6'ya kadar numaralandırılmış 6 benzersiz yüzü vardır. Rakamlardan herhangi birinin yukarı bakma olasılığı 1/6'dır.

Bu örnekte büyük X zar, küçük x ise zarın kenarlarına boyanmış sayılardan herhangi biri olabilir. Bunların hepsi N = {1,2,3,4,5,6} kümesine yerleştirilir. Formül uygulandığında bu zarın entropisi 0.7781'dir.

                                                         

Adil zar


Şimdi üretim hatası olan başka bir zar düşünelim. Üzerinde aynı numaranın yazılı olduğu iki tarafı vardır. Bu kusurlu zar için olası değerlerin N kümesi {1,1,3,4,5,6}'dır. Formülü tekrar kullanarak ortalama entropi değerini 0.6778 olarak elde ederiz.

                                                 

Kusurlu zar

Değerleri karşılaştırdığımızda bilgi içeriğinin azaldığını görüyoruz. Her iki zar da analiz edildiğinde, her bir olası değeri gözlemleme olasılıkları eşit olduğunda, entropi denklemi mümkün olan en büyük değeri üretir. Bu nedenle entropi, tüm olası değerlerin olasılıkları eşit olduğunda maksimum ortalamaya ulaşır.

Çıktı olarak geleneksel reel sayılar üreten bir gösterge için kusurlu zarı atarsak. X gösterge haline gelir ve küçük x göstergenin alabileceği değer aralığı olacaktır. Daha fazla ilerlemeden önce bir sorunumuz var çünkü entropi denklemi katı bir şekilde ayrık değişkenlerle ilgileniyor. Denklemi sürekli değişkenlerle çalışacak şekilde dönüştürmek mümkündür, ancak bunun uygulanması zor olacaktır, bu nedenle ayrık sayılar alanına bağlı kalmak daha kolaydır.


Bir göstergenin entropisinin hesaplanması

Entropi denklemini sürekli değişkenlere uygulamak için göstergenin değerlerini ayrıştırmamız gerekir. Bu, değer aralığını eşit büyüklükteki aralıklara bölerek ve ardından her aralığa düşen değerlerin sayısını sayarak yapılır. Bu yöntem kullanılarak, göstergenin tüm değerlerinin maksimum aralığını numaralandıran orijinal küme, her biri seçilen aralıklar olan alt kümelerle değiştirilir.

Sürekli değişkenlerle uğraşırken, değişkenin alabileceği olası değerlerin olasılıklarındaki varyasyon önemli hale gelir, çünkü entropinin göstergelere uygulanmasında anlamlı bir yön sağlar.

Zar örneğine geri dönelim. Her birinin nihai entropi değerini, kendi ilgili n'si için log(N)'ye bölersek. İlk zar 1, kusurlu zar ise 0.87 değerini verir. Entropi değerinin değişkenin alabileceği değer sayısının logaritmasına bölünmesi, değişkenin teorik maksimum entropisine göre bir ölçü ortaya çıkarır. Orantılı veya göreceli entropi olarak adlandırılır.

Bu değer, göstergelerin entropisinin teorik maksimum ortalamasına ne kadar yakın olduğuna işaret edeceğinden, göstergeleri değerlendirmemizde faydalı olacaktır. Maksimum değer olan 1'e ne kadar yakınsa o kadar iyidir ve diğer uçtaki herhangi bir şey, herhangi bir makine öğrenimi çabasında kullanılmak için zayıf bir aday olacak bir göstergeye dair ipucu verebilir. 

                                  

Göreceli entropi denklemi

Uygulanacak nihai denklem yukarıda gösterilmiştir ve kod aşağıda bir MQL5 komut dosyası olarak uygulanmıştır. Bu komut dosyası makalenin sonuna da eklenmiştir ve buradan indirilebilir. Komut dosyasını kullanarak çoğu göstergeyi analiz edebileceğiz.


Bir göstergenin entropisini hesaplamak için bir komut dosyası

Komut dosyası kullanıcı tarafından ayarlanabilen aşağıdaki parametrelerle çağrılır:

  • TimeFrame - gösterge değerlerini analiz etmek için seçilen zaman dilimi.
  • IndicatorType - burada kullanıcı analiz için yerleşik göstergelerden birini seçebilir. Özel bir gösterge belirlemek için, “Custom indicator” seçeneğini seçin ve bir sonraki parametre değerine göstergenin adını girin.
  • CustomIndicatorName - önceki parametre için “Custom indicator” seçeneği seçilmişse, kullanıcı buraya göstergenin adını girmelidir.
  • UseDefaults - true olarak ayarlanırsa, göstergeye önceden kodlanmış varsayılan kullanıcı girdileri kullanılır.
  • IndicatorParameterTypes - bu, göstergenin veri türlerini doğru sırada listeleyen virgülle ayrılmış bir dizgedir. Olası girdi örneği: analiz edilecek göstergenin sırasıyla double, integer, integer ve string türünde 4 girdi kabul ettiğini varsayarsak, kullanıcının basitçe "double, integer, integer, string" girmesi gerekir, "d, i, i, s" kısa formu da desteklenir, burada d=double, i=integer ve s=string'dir. Enum değerleri integer türüyle eşlenir.
  • IndicatorParameterValues - önceki girdide olduğu gibi, bu da virgülle ayrılmış bir değer listesidir. Önceki örnekle devam edersek, dizge şu şekilde görünecektir: "0.5, 4, 5, string_değeri". IndicatorParameterValues veya IndicatorParameterTypes parametrelerinin biçimlendirilmesinde herhangi bir hata varsa, çözümlenemeyen veya eksik olan belirli değerler için göstergenin varsayılan değerlerinin kullanılmasına neden olur.
    Hata mesajları için Uzmanlar sekmesini kontrol edin. Göstergenin adını buraya dahil etmeye gerek olmadığını, özel bir gösterge kullanılıyorsa CustomIndicatorName ile belirtilmesi gerektiğini unutmayın.
  • IndicatorBuffer - kullanıcı, gösterge arabelleklerinden hangisinin analiz edileceğini belirtebilir.
  • HistoryStart - geçmiş örnekleminin başlangıç tarihi.
  • HistorySize - bu, HistoryStart'a göre analiz edilecek çubuk sayısıdır.
  • Intervals - bu parametre ayrıklaştırma işlemi için oluşturulacak aralık sayısını belirtmek için kullanılır. TTMTS kitabının yazarı, birkaç bin örneklem büyüklüğü için 20 aralık belirlemiş ve 2'yi sabit bir minimum değer olarak tanımlamıştır.  Örneklem büyüklüğüne göre aralık sayısını değiştirme olanağını uygulayarak burada kullanmak için uygun bir değere kendi yorumumu ekledim, özellikle her 1000 örneklem için 51. Bu seçenek, kullanıcı 2'den küçük herhangi bir değer girerse kullanılabilir. Açık olmak gerekirse, aralık 2'den küçük herhangi bir sayıya ayarlandığında, kullanılan aralık sayısı analiz edilen çubuk sayısına göre değişecektir.

//--- input parameters
input ENUM_TIMEFRAMES Timeframe=0;
input ENUM_INDICATOR  IndicatorType=IND_BEARS;
input string   CustomIndicatorName="";
input bool     UseDefaults=true;
input string   IndicatorParameterTypes="";
input string   IndicatorParameterValues="";
input int      IndicatorBuffer=0;
input datetime HistoryStart=D'2023.02.01 04:00';
input int HistorySize=50000;
input int      Intervals=0;

int handle=INVALID_HANDLE;
double buffer[];
MqlParam b_params[];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   if(!processParameters(UseDefaults,b_params))
      return;

   int y=10;
   while(handle==INVALID_HANDLE && y>=0)
     {
      y--;
      handle=IndicatorCreate(Symbol(),Timeframe,IndicatorType,ArraySize(b_params),b_params);
     }
//---
   if(handle==INVALID_HANDLE)
     {
      Print("Invalid indicator handle, error code: ",GetLastError());
      return;
     }

   ResetLastError();
//---
   if(CopyBuffer(handle,IndicatorBuffer,HistoryStart,HistorySize,buffer)<0)
     {
      Print("error copying to buffer, returned error is ",GetLastError());
      IndicatorRelease(handle);
      return;
     }
//---
   Print("Entropy of ",(IndicatorType==IND_CUSTOM)?CustomIndicatorName:EnumToString(IndicatorType)," is ",relativeEntroy(Intervals,buffer));
//---
   IndicatorRelease(handle);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool processParameters(bool use_defaults,MqlParam &params[])
  {

   bool custom=(IndicatorType==IND_CUSTOM);

   string ind_v[],ind_t[];

   int types,values;

   if(use_defaults)
      types=values=0;
   else
     {
      types=StringSplit(IndicatorParameterTypes,StringGetCharacter(",",0),ind_t);
      values=StringSplit(IndicatorParameterValues,StringGetCharacter(",",0),ind_v);
     }

   int p_size=MathMin(types,values);

   int values_to_input=ArrayResize(params,(custom)?p_size+1:p_size);

   if(custom)
     {
      params[0].type=TYPE_STRING;
      params[0].string_value=CustomIndicatorName;
     }

//if(!p_size)
//  return true;

   if(use_defaults)
      return true;

   int i,z;
   int max=(custom)?values_to_input-1:values_to_input;

   for(i=0,z=(custom)?i+1:i; i<max; i++,z++)
     {
      if(ind_t[i]=="" || ind_v[i]=="")
        {
         Print("Warning: Encountered empty string value, avoid adding comma at end of string parameters");
         break;
        }

      params[z].type=EnumType(ind_t[i]);

      switch(params[z].type)
        {
         case TYPE_INT:
            params[z].integer_value=StringToInteger(ind_v[i]);
            break;
         case TYPE_DOUBLE:
            params[z].double_value=StringToDouble(ind_v[i]);
            break;
         case TYPE_STRING:
            params[z].string_value=ind_v[i];
            break;
         default:
            Print("Error: Unknown specified parameter type");
            break;
        }
     }

   return true;

  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ENUM_DATATYPE EnumType(string type)
  {
   StringToLower(type);
   const ushort firstletter=StringGetCharacter(type,0);

   switch(firstletter)
     {
      case 105:
         return TYPE_INT;
      case 100:
         return TYPE_DOUBLE;
      case 115:
         return TYPE_STRING;
      default:
         Print("Error: could not parse string to match data type");
         return ENUM_DATATYPE(-1);
     }

   return ENUM_DATATYPE(-1);
  }
//+------------------------------------------------------------------+

Aralık için seçilen değerle ilgili bir not: Hesaplamada kullanılan aralık sayısının değiştirilmesi nihai entropi değerini değiştirecektir. Analiz yaparken, kullanılan bağımsız girdinin etkilerini en aza indirmek için bir miktar tutarlılığa sahip olmak akıllıca olacaktır. Komut dosyasında, göreceli entropi hesaplaması Entropy.mqh dosyasında tanımlanan bir fonksiyonda kapsüllenmiştir.


Komut dosyası basitçe ortaya çıkan entropi değerini Uzmanlar sekmesine yazdırır. Komut dosyasını çeşitli yerleşik ve özel göstergeler için çalıştırmak aşağıda gösterilen sonuçları verir. William's Percent Range göstergesinin mükemmele yakın göreceli entropiye sahip olması ilginçtir. Bunu, hayal kırıklığı yaratan bir sonuç gösteren Market Facilitation Index göstergesi ile karşılaştıralım.

Sonuçlar

Bu sonuçlarla, verileri işleyerek makine öğrenimi algoritmalarına uygun hale getirmek için daha ileri adımlar atabiliriz. Bu, göstergenin istatistiksel özelliklerinin titiz bir şekilde analiz edilmesini içerir. Gösterge değerlerinin dağılımının incelenmesi, çarpıklık ve aykırı değerlerle ilgili sorunları ortaya çıkaracaktır. Bunların hepsi model eğitimini bozabilir.

Örnek olarak yukarıda analiz edilen iki göstergenin bazı istatistiksel özelliklerini inceleyelim.

William's Percent Range

William's Percent Range göstergesinin dağılımı, neredeyse tüm değerlerin tüm aralığa nasıl yayıldığını ortaya koymaktadır, çok modlu olmanın yanı sıra dağılım oldukça tekdüzedir. Böyle bir dağılım idealdir ve entropi değerine yansır.

Market Facilitation Index
Bu, uzun bir kuyruğa sahip olan Market Facilitation Index dağılımından farklıdır. Böyle bir gösterge çoğu öğrenme algoritması için sorunlu olacaktır ve değerlerin dönüştürülmesini gerektirir. Değerlerin dönüştürülmesi, göstergenin göreceli entropisinde bir iyileşmeye yol açmalıdır.


Bir göstergenin bilgi içeriğinin iyileştirilmesi

Gösterge entropisini artıran değişikliklerin, gösterge tarafından sağlanan sinyallerin doğruluğunu artırmanın bir yolu olarak görülmemesi gerektiği not edilmelidir. Entropiyi artırmak, işe yaramaz bir göstergeyi kutsal kaseye dönüştürmeyecektir. Entropinin iyileştirilmesi, tahmin modellerinde etkin kullanım için gösterge verilerinin işlenmesiyle ilgilidir.

Bu seçenek, entropi değeri umutsuzca kötü olduğunda, 0.5'in çok altında ve sıfıra yakın olduğunda düşünülmelidir. Üst sınır eşikleri tamamen keyfi olarak belirlenmiştir. Kabul edilebilir bir minimum değer seçmek geliştiriciye bağlıdır. Bütün mesele, mümkün olduğunca tekdüze bir gösterge değerleri dağılımı elde etmektir. Bir dönüşüm uygulama kararı, gösterge değerlerinin büyük ve temsili bir örneklemi üzerinde yapılan analize dayanmalıdır.

Uygulanan dönüşüm göstergenin temel davranışını değiştirmemelidir. Dönüştürülmüş gösterge ham gösterge ile benzer bir şekle sahip olmalıdır, örneğin çukurların ve tepelerin konumu her iki seride de benzer olmalıdır. Eğer durum böyle değilse, potansiyel olarak faydalı bilgileri kaybetme riskiyle karşı karşıya kalırız.

Test verisi kusurlarının farklı yönlerini hedef alan çok sayıda dönüştürme yöntemi vardır. Sadece temel istatistiksel analiz yoluyla ortaya çıkan bariz kusurları düzeltmeye yönelik birkaç basit dönüşümü ele alacağız. Ön işleme, makine öğreniminin geniş bir dalıdır. Makine öğrenimi yöntemlerinin uygulanmasında ustalaşmayı uman herkesin bu alanda daha fazla bilgi edinmesi tavsiye edilir.

Bazı dönüşümlerin etkisini göstermek için, çeşitli dönüşümleri uygulayabilen ve aynı zamanda analiz edilen verilerin dağılımını gösteren bir komut dosyasına bakacağız. Komut dosyası, 6 adet dönüştürme fonksiyonu örneği uygular:

  • Karekök dönüşümü, çoğunluktan önemli ölçüde sapan nadir gösterge değerlerini ezmek için uygundur.
  • Küpkök dönüşümü, negatif değerlere sahip göstergelere en iyi şekilde uygulanan bir başka ezme fonksiyonudur.
  • Log dönüşümü, değerleri daha önce bahsedilen sıkıştırma dönüşümlerinden daha büyük ölçüde sıkıştırır.
  • Hiperbolik tanjant ve lojistik dönüşümler, geçersiz sayılar (nan hataları) üretme sorunlarından kaçınmak için uygun ölçekteki veri değerlerine uygulanmalıdır.
  • Aşırı dönüşüm, bir veri setinde aşırı tekdüzeliğe neden olur. Yalnızca çok az sayıda benzer veriyle çoğunlukla benzersiz değerler üreten göstergelere uygulanmalıdır.

    Dönüştürülmüş gösterge değerlerini karşılaştırmak için bir komut dosyası

    Önceki komut dosyasıyla karşılaştırıldığında, analiz edilecek göstergeyi belirtmek için aynı kullanıcı girdilerini içerir. Yeni girdiler aşağıda açıklanmaktadır:

    • DisplayTime - komut dosyası, göstergenin dağılımının bir grafiğini görüntüler. DisplayTime, saniyeyi ifade eden integer bir değeridir ve grafiğin kaldırılmadan önce görünür olacağı süreyi belirtir.
    • ApplyTransfrom - komut dosyası için modu ayarlayan boolean bir değerdir. false olduğunda, komut dosyası dağılımı çizer ve göreceli entropi ile birlikte örneklemin temel istatistiklerini görüntüler. true olarak ayarlanırsa, ham gösterge değerlerine bir dönüşüm uygular ve dönüşüm öncesi ve sonrası göreceli entropi değerlerini görüntüler. Değiştirilmiş örneklemlerin dağılımı da kırmızı renkli bir eğri olarak çizilir.
    • Select_transform - göstergenin entropisini muhtemelen artırmak için uygulanabilecek daha önce açıklanan dönüşümleri sağlayan bir numaralandırmadır.
    //+------------------------------------------------------------------+
    //|                                            IndicatorAnalysis.mq5 |
    //|                        Copyright 2023, MetaQuotes Software Corp. |
    //|                                             https://www.mql5.com |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2023, MetaQuotes Software Corp."
    #property link      "https://www.mql5.com"
    #property version   "1.00"
    #property script_show_inputs
    #include<Entropy.mqh>
    //--- input parameters
    input ENUM_TIMEFRAMES Timeframe=0;
    input ENUM_INDICATOR  IndicatorType=IND_CUSTOM;
    input string   CustomIndicatorName="";
    input bool     UseDefaults=false;
    input string   IndicatorParameterTypes="";
    input string   IndicatorParameterValues="";
    input int      IndicatorBuffer=0;
    input datetime HistoryStart=D'2023.02.01 04:00';;
    input int HistorySize=50000;
    input int DisplayTime=30;//secs to keep graphic visible
    input bool ApplyTransform=true;
    input ENUM_TRANSFORM Select_transform=TRANSFORM_LOG;//Select function transform
    
    int handle=INVALID_HANDLE;
    double buffer[];
    MqlParam b_params[];
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
      {
    //---
       if(!processParameters(UseDefaults,b_params))
          return;
    
       int y=10;
       while(handle==INVALID_HANDLE && y>=0)
         {
          y--;
          handle=IndicatorCreate(_Symbol,Timeframe,IndicatorType,ArraySize(b_params),b_params);
         }
    //---
       if(handle==INVALID_HANDLE)
         {
          Print("Invalid indicator handle, error code: ",GetLastError());
          return;
         }
    
       ResetLastError();
    //---
       if(CopyBuffer(handle,IndicatorBuffer,HistoryStart,HistorySize,buffer)<0)
         {
          Print("error copying to buffer, returned error is ",GetLastError());
          IndicatorRelease(handle);
          return;
         }
    //---
       DrawIndicatorDistribution(DisplayTime,ApplyTransform,Select_transform,IndicatorType==IND_CUSTOM?CustomIndicatorName:EnumToString(IndicatorType),buffer);
    //---
       IndicatorRelease(handle);
      }
    //+------------------------------------------------------------------+
    bool processParameters(bool use_defaults,MqlParam &params[])
      {
    
       bool custom=(IndicatorType==IND_CUSTOM);
    
       string ind_v[],ind_t[];
    
       int types,values;
    
       if(use_defaults)
          types=values=0;
       else
         {
          types=StringSplit(IndicatorParameterTypes,StringGetCharacter(",",0),ind_t);
          values=StringSplit(IndicatorParameterValues,StringGetCharacter(",",0),ind_v);
         }
    
       int p_size=MathMin(types,values);
    
       int values_to_input=ArrayResize(params,(custom)?p_size+1:p_size);
    
       if(custom)
         {
          params[0].type=TYPE_STRING;
          params[0].string_value=CustomIndicatorName;
         }
    
       if(use_defaults)
          return true;
    
       int i,z;
       int max=(custom)?values_to_input-1:values_to_input;
    
       for(i=0,z=(custom)?i+1:i; i<max; i++,z++)
         {
          if(ind_t[i]=="" || ind_v[i]=="")
            {
             Print("Warning: Encountered empty string value, avoid adding comma at end of string parameters");
             break;
            }
    
          params[z].type=EnumType(ind_t[i]);
    
          switch(params[z].type)
            {
             case TYPE_INT:
                params[z].integer_value=StringToInteger(ind_v[i]);
                break;
             case TYPE_DOUBLE:
                params[z].double_value=StringToDouble(ind_v[i]);
                break;
             case TYPE_STRING:
                params[z].string_value=ind_v[i];
                break;
             default:
                Print("Error: Unknown specified parameter type");
                break;
            }
         }
    
       return true;
    
      }
    
    
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    ENUM_DATATYPE EnumType(string type)
      {
       StringToLower(type);
       const ushort firstletter=StringGetCharacter(type,0);
    
       switch(firstletter)
         {
          case 105:
             return TYPE_INT;
          case 100:
             return TYPE_DOUBLE;
          case 115:
             return TYPE_STRING;
          default:
             Print("Error: could not parse string to match data type");
             return ENUM_DATATYPE(-1);
         }
    
       return ENUM_DATATYPE(-1);
      }
    //+------------------------------------------------------------------+
    


    Örneklerle devam ederek hem karekök hem de küpkök dönüşümlerinin uygulanmalarını karşılaştıralım.

    MFI karekök dönüşümü


    MFI küpkök dönüşümü


    Her ikisi de entropide bir iyileşme sağlar, ancak bu sağ kuyruk sorunlu olabilir, şimdiye kadar uygulanan iki dönüşüm bununla etkili bir şekilde başa çıkamamıştır.

    MFI log dönüşümü


    Log dönüşümü daha da iyi bir entropi değeri üretir. Yine de kuyruklar oldukça belirgindir. Son çare olarak aşırı dönüşümü uygulayabiliriz.


    Sonuç

    Tahmine dayalı model eğitiminde kullanılmadan önce gösterge değerlerinin dönüştürülmesi ihtiyacını değerlendirmek için entropi kavramını araştırdık.

    Bu konsept iki komut dosyasında uygulanmıştır. EntropyIndicatorAnalyis, Uzmanlar sekmesinde bir örneklemin göreceli entropisini yazdırır. Diğer komut dosyası IndicatorAnalysis, ham ve dönüştürülmüş gösterge değerlerinin dağılımını çizerek ve önceki ve sonraki göreceli entropi değerlerini görüntüleyerek bir adım daha ileri gider.

    Bu araçlar faydalı olsa da her türlü göstergeye uygulanamayacağı unutulmamalıdır. Genel olarak, boş değerler içeren ok tabanlı göstergeler burada açıklanan komut dosyaları için uygun olmayacaktır. Bu gibi durumlarda başka kodlama teknikleri gerekli olacaktır.

    Veri dönüşümü konusu, her türlü tahmine dayalı model oluşturulurken dikkate alınması gereken olası ön işleme adımlarının yalnızca bir alt kümesidir. Bu tür tekniklerin kullanılması, piyasaları yenmek için gereken avantajı sağlayabilecek gerçekten benzersiz ilişkilerin ortaya çıkarılmasına yardımcı olacaktır.

    Dosya adı
     Açıklama
    Mql5/Include/Entropy.mqh
    Entropiyi hesaplamak için kullanılan fonksiyonlar için çeşitli tanımlar ve ayrıca ekli komut dosyaları tarafından kullanılan yardımcı fonksiyonlar içeren include dosyası.
    Mql5/Scripts/IndicatorAnalysis.mq5
    Entropisi ile birlikte gösterge değerlerinin dağılımını gösteren bir grafik görüntüleyen komut dosyası.
     Mql5/Scripts/EntropyIndicatorAnalysis.mq5  Bir göstergenin entropisini hesaplamak için kullanılabilecek komut dosyası.


    MetaQuotes Ltd tarafından İngilizceden çevrilmiştir.
    Orijinal makale: https://www.mql5.com/en/articles/12129

    Ekli dosyalar |
    Mql5.zip (5.26 KB)
    Son yorumlar | Tartışmaya git (10)
    niouininon
    niouininon | 18 Tem 2025 saat 09:21
    Aleksey Vyazmikin değer aralığını eşit büyüklükte aralıklara böleriz ve ardından her aralıktaki değerlerin sayısını sayarız. Bu yöntem kullanılarak, tüm gösterge değerlerinin maksimum aralığını listeleyen başlangıç kümesi, seçilen aralıkların her birini temsil eden alt kümelerle değiştirilir.

    ...

    Aralıklar - örneklenecek aralıkların sayısı. TTMTS'nin yazarı, birkaç bin kişilik bir örneklem için 20 aralık belirtir ve 2 mutlak minimumdur. Örneklem büyüklüğüne göre aralık sayısını değiştirme özelliğini uygulayarak uygun bir değere kendi yaklaşımımı ekledim, özellikle 1000 örnek için 51. Bu seçenek, kullanıcı 2'den küçük bir değer girerse kullanılabilir. Böylece, Aralık 2'den küçük bir sayıya ayarlandığında, kullanılan aralıkların sayısı analiz edilen çubuk sayısına göre değişecektir.

    "

    Soru: Bu aynı şey mi? Eğer öyleyse, gösterge değerleri aralığındaki ayırıcıların sayısı neden çubuk sayısına bağlıdır? Bunun arkasındaki mantık nedir? Şimdiye kadar, bunun yalnızca birikimli bir bileşene sahip göstergeler için yararlı olduğunu varsayabilirim.

    Eğer durum böyle değilse, aralıktaki bölenlerin sayısı neye karşılık gelir?


    Makalede, gösterge değerlerini dönüştürmenin faydasını açıkça gösteren bir tablo bulunmamaktadır.

    Sürekli bir değişkenin entropisini tahmin etmek için, değer aralığını eşit aralıklara böleriz ve her aralıktaki gözlemleri sayarız. Kod,aralık sayısını seçmenize izin verir. < 2 girerseniz (veya varsayılan değeri bırakırsanız), komut dosyası kendi sezgiselini tetikler: 1.000 gözlem başına 51 aralık, yani örneklem boyutuyla orantılı bir sayı. Eğer > 2 değerini girerseniz, olduğu gibi kullanır, yani bunlar birbiriyle yarışan iki yöntem değildir. Biri kavramı açıklıyor, diğeri ise parametreyi kendiniz ayarlamadığınızda kodun nasıl seçtiğini açıklıyor.


    Çok az aralığa sahip olduğunuzda, değerleri yapay olarak birbirine yapıştırırsınız. Entropi düşük tahmin edilir (yanlılık). Küçük bir örnek için çok fazla aralığa sahip olduğunuzda, çok sayıda boş kutu veya 1 gözlemli kutu vardır. Entropi çok gürültülüdür (varyans). Histogramlar için çeşitli otomatik kurallar mevcuttur: Sturges, karekök, Freedman-Diaconis, Scott, vb.) Hepsinin fikri aynı: Daha fazla veriye sahip olduğunuzda çözünürlüğü artırın, çünkü o zaman varyansı patlatmadan daha ince olasılıkları tahmin edebilirsiniz.


    1.000 çubuk için, 51 aralık => dağılım tekdüze olsaydı kutu başına 20 puan. Bu oran (15 ila 30 gözlem / sınıf arasında) yazarın literatürden aldığı klasik bir uzlaşmadır. Bunun bir göstergenin birikimli olup olmamasıyla hiçbir ilgisi yoktur. Mantık tamamen istatistikseldir. Izgaranın inceliği, mevcut bilgi miktarına göre uyarlanır.


    Histogramdaki dikey çubukların sayısı ne kadar yüksekse :
    • göstergenin ince dağılımı daha görünür hale gelir,

    • entropi hesaplaması ne kadar çok ayrıntı (tepe ve çukurlar) yakalayabilirse,

    • ancak bu frekansların kararlı olması için daha fazla veri gereklidir.


    Makalenin, örneğin dönüşümlerden önce ve sonra aynı göstergenin entropisini göstermekten fayda sağlayacağı doğrudur. Ancak gösterimi kendiniz yapmak kolaydır. Kodda ApplyTransform=true seçeneğini işaretleyin ve çift çıktıyı okuyun: önce / sonra. Kod, herkesin kendi varlıklarını ve ufuklarını test edebilmesi için bu kısmı kasıtlı olarak etkileşimli bırakmıştır.

    Aleksey Vyazmikin
    Aleksey Vyazmikin | 18 Tem 2025 saat 09:48
    niouininon #:
    Histogramda ne kadar çok dikey çubuk varsa:
    • endeksin dağılımındaki incelik daha da dikkat çekicidir,

    • entropi hesaplaması ne kadar çok ayrıntı (tepe ve çukurlar) yakalayabilirse,

    • ancak bu frekansları istikrarlı hale getirmek için daha fazla veriye ihtiyaç vardır.

    Anladığım kadarıyla, bir örneklemdeki gösterge puanlarının bir histogram aracılığıyla görselleştirilmesinin yazarın veri dönüştürme yöntemleriyle hiçbir ilgisi yok. Doğru mu anlıyorum?

    Ben daha çok bu dönüşümlerin eğitim etkisi sorusuyla ilgileniyorum. Sinir ağları için bunu varsayabilirim, ancak ağaç yöntemleri için değil.

    niouininon
    niouininon | 18 Tem 2025 saat 13:31
    Aleksey Vyazmikin #:

    Doğru anladıysam, bir örneklemdeki gösterge puanlarının bir histogram kullanılarak görselleştirilmesinin yazarın veri dönüştürme yöntemleriyle hiçbir ilgisi yoktur. Haksız mıyım?

    Ben daha çok bu dönüşümlerin zincirleme etkisi sorusuyla ilgileniyorum. Bunu sinir ağları için varsayabilirim, ancak ağaç yöntemleri için değil.

    Kod tarafından çizilen histogram sadece görsel bir teşhis aracıdır. Bir göstergenin değerlerinin dönüşümden önce veya sonra örnekte nasıl dağıldığını gösterir. Sqrt, log, tanh vb. fonksiyonlar veriler üzerinde işlem yapar. Histogram sadece sonucu gösterir. Bu nedenle iki aşama birbirinden bağımsızdır. Önce seri dönüştürülür (ya da dönüştürülmez), ardından entropinin değişip değişmediğini görmek için histogramı çizilir.

    Oldukça monoton hale gelen bir göstergeyi dönüştürmek (log, sqrt) genellikle skoru değiştirmez. Öte yandan, monotonik olmayan dönüşümler (doygunluğa ulaşan tanh) belirli noktaların sırasını değiştirir. Bu, belirli dönüşümlerin doğrusal olmayan etkileşimler oluşturmak için daha iyi zemin hazırladığı anlamına gelir.

    Aleksey Vyazmikin
    Aleksey Vyazmikin | 18 Tem 2025 saat 14:11
    niouininon #:

    Kod tarafından oluşturulan histogram sadece görsel bir tanı aracıdır. Gösterge değerlerinin dönüşümden önce veya sonra örnekte nasıl dağıldığını gösterir. Sqrt, log, tanh vb. fonksiyonlar verileri etkiler. Histogram sadece sonucu gösterir. Dolayısıyla, iki adım birbirinden bağımsızdır. Önce seri dönüştürülür (ya da dönüştürülmez), ardından entropinin değişip değişmediğini görmek için histogramı çizilir.

    Tamam, şimdi konuyu anladım. Ben aslında başka bir şey düşünüyordum.

    niouininon #:

    Oldukça monotonik hale gelen bir üssü dönüştürmek (log, sqrt) genellikle sonucu değiştirmez. Öte yandan, monotonik olmayan dönüşümler (tanh, saturates) belirli noktaların sırasını değiştirir. Bu, belirli dönüşümlerin doğrusal olmayan etkileşimler yaratmak için daha iyi zemin hazırladığı anlamına gelir.

    Bu, noktaların sırasını nasıl değiştirir? Böyle bir dönüşüme örnek verebilir misiniz? Şimdiye kadar söylenenleri, özdeğerleri artan sırada olan ABC noktaları olduğu ve dönüşümden sonra artan sıradaki sıranın alternatif olarak BAC olduğu şeklinde anladım.

    niouininon
    niouininon | 18 Tem 2025 saat 21:12
    Aleksey Vyazmikin #:

    Tamam, şimdi anladım. Aslında başka bir şey düşünüyordum.

    Noktaların sırasını nasıl değiştirir? Böyle bir dönüşüme örnek verebilir misiniz? Şimdiye kadar özdeğerleri artan sırada ABC noktaları olduğunu ve dönüşümden sonra artan sıranın dönüşümlü olarak BAC haline geldiğini anladım.

    Koddaki fonksiyonların (root, log, tanh, vb.) hepsi monoton olarak artmaktadır. Hepsi noktaların sırasını korur. Önceki cümlem muğlaktı. Sıralama yalnızca monotonik olmayan bir dönüşüm kullanılırsa ABC'den BAC'ye değişir. Örneğin, yanılmıyorsam, f(x)=∣x-50∣ fonksiyonu monotonik değildir çünkü ekseni x= 50 etrafında katlar. Bu nedenle, düzen BAC olur. Makalenin yazarı giriş bölümünde biziTimothy Masters'ın "Testing and Tuning Market Trading Systems (TTMTS)" kitabına yönlendiriyor. Bana kalırsa, kitabı elime almayı planlıyorum çünkü sizin gibi benim de hala birkaç sorum var. Dahası, öğrenme modellerine ya da sinir ağlarına pek aşina değilim. Görünüşe göre, çevrimiçi satış sitelerinde bulmak oldukça kolay. İçeriği bize çok yardımcı olacaktır, çünkü makale ne kadar ilginç olursa olsun şüphesiz eksik ve/veya her durumda oldukça sentetik.

    Model aramada brute force yaklaşımı (Bölüm VI): Döngüsel optimizasyon Model aramada brute force yaklaşımı (Bölüm VI): Döngüsel optimizasyon
    Bu makalede, MetaTrader 4 ve 5’te alım-satım için tüm otomasyon zincirini tamamlamamı sağlayan ve aynı zamanda çok daha ilginç bir şey yapmamı sağlayan iyileştirmelerin ilk bölümünü göstereceğim. Şu andan itibaren, bu çözüm hem Uzman Danışman oluşturmayı hem de optimizasyonu tamamen otomatikleştirmeme ve etkili alım-satım konfigürasyonları bulmak için harcanan emeği en aza indirmeme olanak tanıyor.
    MQL5 Algo Forge'a Geçiş (Bölüm 4): Sürümlerle Çalışma MQL5 Algo Forge'a Geçiş (Bölüm 4): Sürümlerle Çalışma
    MQL5 Algo Forge sürüm kontrol sistemi ve deposunu kullanmanın ince detaylarını açıklayarak Simple Candles ve Adwizard projelerini geliştirmeye devam edeceğiz.
    Python ve MQL5'te bir robot geliştirme (Bölüm 1): Veri ön işleme Python ve MQL5'te bir robot geliştirme (Bölüm 1): Veri ön işleme
    Makine öğrenimine dayalı bir alım-satım robotu geliştirme: Ayrıntılı bir rehber. Serinin ilk makalesi veri ve özelliklerin toplanması ve hazırlanması ile ilgilidir. Projenin uygulanması için Python programlama dili ve kütüphaneleri ile MetaTrader 5 platformu kullanılmıştır.
    MQL5'te Grafiksel Paneller Oluşturmak Artık Daha Kolay MQL5'te Grafiksel Paneller Oluşturmak Artık Daha Kolay
    Bu makalede, alım-satımdaki en değerli ve kullanışlı araçlardan biri olan, alım-satım görevlerini basitleştiren grafiksel paneller oluşturmak isteyen herkes için basit ve net bir rehber sunacağız. Grafiksel paneller zamandan tasarruf etmenizi ve alım-satımın kendisine daha fazla odaklanmanızı sağlar.