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

 
Stanislav Korotky #:
Emirler, anlaşmalar, pozisyonlar zaten zaman dilimleriyle ilgili değildir. Ya bir şeyi yanlış anladınız ya da ifadeniz yanlış.
Özür dilerim, sanırım kelime seçimim kafa karıştırıcı"zaman dilimi" ile "tarih aralığını" kastediyorum. Diyelim ki 2025-10-01 00:00:00 ile 2025-10-22 23:59:59 arasındaki Anlaşmalar gibi belirli bir tarih aralığında işlem gören Anlaşmaları / Siparişleri seçmek istiyorum.
 
pauldic #:
Üzgünüm, sanırım kelime seçimim kafa karıştırıcı"zaman çerçevesi" ile "tarih aralığı" demek istiyorum. Diyelim ki 2025-10-01 00:00:00 ile 2025-10-22 23:59:59 arasındaki Fırsatlar gibi belirli bir tarih aralığında işlem gören Fırsatları/Siparişleri seçmek istiyorum.

Bir işlem geçmişinin bir alt aralığını analiz etmek istiyorsanız, filtreleme kodunun kendisini etkilemeden, filtrelemeden önce geçmişin yalnızca bu bölümünü talep etmek daha verimli olduğunda:

input datetime SubrangeFrom = 0;
input datetime SubrangeTo = 0;

...

{
   HistorySelect(SubrangeFrom, SubrangeTo);
   // ... filtre kodu olduğu gibi buraya gider
}

Herhangi bir nedenle, HistorySelect ile uyguladığınız genel aralık içinde (daha dar) bir alt aralık seçmek isterseniz, bunu filtreleme kodunda şu şekilde yapabilirsiniz:

{
      // bunlardan bazıları buraya gider

      // HistorySelect(0, LONG_MAX);
      // HistorySelectByPosition(PositionID);
      ...
      DealTuple deals[];
      if(SubrangeFrom != SubrangeTo && SubrangeFrom < SubrangeTo)
      {
         filter.let(DEAL_TIME, SubrangeFrom - 1, IS::GREATER).let(DEAL_TIME, SubrangeTo + 1, IS::LESS);
      }
      filter.let(DEAL_POSITION_ID, PositionID).select(deals, true);
      ...
}

Sarı renkle vurgulanan satır, IS::GREATER ve IS::LESS ek niteleyicilerini kullanarak tarih-saat aralığı [SubrangeFrom, SubrangeTo] için 2 koşul belirler (varsayılan olarak, let() işlevine yapılan diğer çağrılarda belirtilmezler ve daha sonra IS::EQUAL normalde tek değerli alanlar için kullanılır).

Alt filtreyi tarih aralığına göre uygulamak için tek bir neden biliyorum - bu, emirlerin kurulum zamanı (ORDER_TIME_SETUP) içindir, çünkü HistorySelect emirlerin başka bir tarih-zaman özelliğine uygulanır - yani emir gerçekleştirme zamanı (ORDER_TIME_DONE). Ayrıca, çok sayıda aktif emir varsa, aktif emirlerin bir alt aralığını (geçmişte olmayan) filtrelemek ilginç olabilir.

Başlangıç noktası olarak MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5 örnek koduna bakabilirsiniz.
 
Stanislav Korotky #:

Bir işlem geçmişinin bir alt aralığını analiz etmek istiyorsanız, filtreleme kodunun kendisini etkilemeden, filtrelemeden önce geçmişin yalnızca bu bölümünü talep etmek daha verimli olduğunda:

Herhangi bir nedenle, HistorySelect ile uyguladığınız genel aralık içinde (daha dar) bir alt aralık seçmek isterseniz, bunu filtreleme kodunda şu şekilde yapabilirsiniz:

Sarı renkle vurgulanan satır, IS::GREATER ve IS::LESS ek niteleyicilerini kullanarak tarih-saat aralığı [SubrangeFrom, SubrangeTo] için 2 koşul belirler (varsayılan olarak, let() işlevine yapılan diğer çağrılarda belirtilmezler ve daha sonra IS::EQUAL normalde tek değerli alanlar için kullanılır).

Alt filtreyi tarih aralığına göre uygulamak için tek bir neden biliyorum - bu, emirlerin kurulum zamanı (ORDER_TIME_SETUP) içindir, çünkü HistorySelect emirlerin başka bir tarih-zaman özelliğine uygulanır - yani emir gerçekleştirme zamanı (ORDER_TIME_DONE). Ayrıca, çok sayıda aktif emir varsa, aktif emirlerin bir alt aralığını (geçmişte olmayan) filtrelemek ilginç olabilir.

Başlangıç noktası olarak MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5 örnek betiğine bakabilirsiniz.
@StanislavKorotky Bir kez daha teşekkürler... Benim için harika bir başlangıç noktası ve onunla çalışmaya başlayacağım
 

Hata Düzeltmesi MQL5/Include/MQL5Book/TradeUtils.mqh.

   bool Equal(const double v1, const double v2)
   {
      return v1 == v2 || fabs(v1 - v2) < DBL_EPSILON * fmax(1.0, fmax(fabs(v1), fabs(v2)));
   }
Dosyalar:
TradeUtils.mqh  12 kb
 
pauldic #:

Kod eklerken KOD düğmesini (Alt-S) kullanın.

Bir moderatör yanlış yapıştırılan kodu biçimlendirdi. Genellikle bu tür kodlar kaldırılır.

StanislavKorotky Lütfen bu hatayı incelemeye yardımcı olabilir misiniz, MT5 güncellemelerinden sonra başladığına inanıyorum çünkü kodun önceki aylarda herhangi bir değişiklik yapılmadan çalıştığını biliyordum.

parametre dönüştürme türü 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20

'double[][2]' ile 'string[][] &' parametre dönüştürme türüne izin verilmiyor TradeFilter.mqh 332 20
parametre dönüştürme türü 'long[][2]' ile 'string[][] &' arasında izin verilmiyor TradeFilter.mqh 163 17


Aşağıdaki kodun sorunu tekrarlamaya yardımcı olacağından şüpheleniyorum:


Merhaba @Paul Dick

Dizileri sıralamak için bu https://www.mql5.com/tr/code/57233 adresini deneyin

Introsort (Introspective sort) using Function Pointers
Introsort (Introspective sort) using Function Pointers
  • 2025.03.18
  • www.mql5.com
A hybrid sorting algorithm that provide fast performance for sorting arrays of simple types, structures or object pointers.
 

Değişken lotlar için hesaplamanın düzeltildiği R2 - RSquared.mqh'ye dayalı özeloptimizasyon kriterinin hesaplama dosyasının güncellenmiş bir sürümünü ekliyorum.

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.

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;
   
   for(int i = 0; i < n; ++i)
   {
      double result = 0;
      for(int j = 0; j < STAT_PROPS - 1; ++j)
      {
         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] + volumes[i];
      balance[i + 1] = result + balance[i];
   }
   
   const double r2 = RSquaredTest(balance, volumes);
   
   #undef  STAT_PROPS
   
   return r2 * 100;
}
Dosyalar:
RSquared.mqh  4 kb