Uzman Danışmanlar: Yatırımcılar için MQL5 Programlama - Kitaptan kaynak kodları. Bölüm 6 - sayfa 3

 
hini #property tester_set "FrameTransfer.set" (geçersiz tester set dosya uzantısı, '*.set' beklenen FrameTransfer.mq5)

Başarılı bir şekilde derlenmesi için bu şekilde değiştirilmelidir: #property tester_set "\\Presets\\FrameTransfer.set"

Hatta `#property tester_set "/Presets/FrameTransfer.set"` bile başarısız olacaktır.

Belki de algoritma kitabındaki açıklamayı değiştirebilirsiniz:


Düzeltme 5506 numaralı derlemede mevcuttur.
 
Alain Verleyen #:
Düzeltme 5506 numaralı derlemede mevcuttur.
Teşekkür ederim.
 
Stanislav Korotky optimizasyon kriteri hesaplama dosyasının güncellenmiş bir versiyonunu ekliyorum - RSquared.mqh, burada değişken lotlar için hesaplama düzeltilmiştir.

Tahmin kalitesi önemli ölçüde iyileştirilmiştir - optimizasyon sonuçları tablosuna bakılırsa, geri kazanım faktörü ve Sharpe parametrelerinin kombinasyonu elde edilmiştir.

Kullanım örneği.

Dikkat! Farklı semboller alınıp satılıyorsa, hacimlerin yeterli bir tahminini elde etmek için, bunlar lotlardan mevduat para birimindeki değere dönüştürülmelidir, örneğin (basitleştirilmiş varyantlardan biri):

#include <MQL5Book/DealFilter.mqh>
#include <MQL5Book/RSquared.mqh>

template<typename T>
union Type2Bytes
{
   T d;
   uchar bytes[sizeof(T)];
};

double OnTester()
{
   HistorySelect(0, LONG_MAX);
   
   #define   STAT_PROPS 5
   
   const ENUM_DEAL_PROPERTY_DOUBLE props[STAT_PROPS] =
   {
      DEAL_PROFIT, DEAL_SWAP, DEAL_COMMISSION, DEAL_FEE, DEAL_VOLUME
   };
   double expenses[][STAT_PROPS];
   ulong tickets[]; // burada sadece 'select' prototipini eşleştirmek için kullanılır, ancak hata ayıklama için kullanışlıdır
   
   DealFilter filter;
   filter.let(DEAL_TYPE, (1 << DEAL_TYPE_BUY) | (1 << DEAL_TYPE_SELL), IS::OR_BITWISE)
      .let(DEAL_ENTRY, (1 << DEAL_ENTRY_OUT) | (1 << DEAL_ENTRY_INOUT) | (1 << DEAL_ENTRY_OUT_BY), IS::OR_BITWISE)
      .select(props, tickets, expenses);

   const int n = ArraySize(tickets);
   
   double balance[];
   double volumes[]; // R2 kriterini kullanmak için ticaret hacimlerini dikkate alın
   
   ArrayResize(balance, n + 1);
   balance[0] = 0;
   ArrayResize(volumes, n + 1);
   volumes[0] = 0;

   MapArray<ulong,double> sym2value; // sembol karması 1 lot değerine
   
   for(int i = 0; i < n; ++i)
   {
      const string s = HistoryDealGetString(tickets[i], DEAL_SYMBOL);

      double value = 1;
      Type2Bytes<ulong> sym;
      ArrayInitialize(sym.bytes, 0);
      StringToCharArray(s, sym.bytes);
      int idx = sym2value.find(sym.d);
      if(idx == -1) // lot başına sembol değeri için henüz kayıt yok
      {
         const double price = SymbolInfoDouble(s, SYMBOL_ASK);
         const double pt = SymbolInfoDouble(s, SYMBOL_POINT);
         double profit = 1;
         ResetLastError();
         if(!OrderCalcProfit(ORDER_TYPE_BUY, s, 1, price, price + pt, profit)) // NB: hesap para birimi için cari kuru kullandığından yaklaşık olarak tahmin edilmiştir
         {
            // WARN(StringFormat("OrderCalcProfit Error: %s %d ", s, _LastError));
         }
         value = profit * (price / pt); // NB: kaldıraç burada uygulanmaz
         idx = sym2value.put(sym.d, value);
      }
      else
      {
         value = sym2value.getValue(idx);
      }
   
      double result = 0;
      for(int j = 0; j < STAT_PROPS - 1; ++j) // anlaşma hacmi hariç istenen tüm aksesuarlar arasında döngü
      {
         result += expenses[i][j];
      }
      // hacimleri model olarak kullanın - daha fazla yatırım - daha fazla getiri bekleniyor
      volumes[i + 1] = expenses[i][STAT_PROPS - 1] * value + volumes[i];
      balance[i + 1] = result + balance[i];
   }
   
   const double r2 = RSquaredTest(balance, volumes);
   
   #undef   STAT_PROPS
   
   return r2 * 100;
}

Bir sembolün alım satım hesaplamasına kıyasla eklenmesi gerekenler sarı renkle işaretlenmiştir (önceki örnekten).