MT5 ve iş başında hız - sayfa 20

 
fxsaber :

Belki daha hızlı bir seçenek vardır. Ama bir adım sola doğru hesaplamanız gerekiyor ve mantık önemli ölçüde değişmek zorunda kalabilir. Genel olarak kolay değil.

CHashMap< ulong , ulong > DealsIn;   // По PositionID возвращает DealIn.


Önbelleğe alma değil, bu bir dizin. İşte önbelleğe alma (kodun bir parçası):

 class DealInfo {
public :
   datetime Closed;
   ulong Ticket;
   ulong Position;
   string Symbol ;
   long Type;
   long Reason;
   double Volume;
   double Price;
   double Profit;
   double Swap;
   long Magic;
};

class DealsComparer : public IComparer<DealInfo*> {
   int Compare(DealInfo* x, DealInfo* y) {
     int res = ( int )(x.Closed - y.Closed);
     if (res == 0 ) {
      res = ( int )(x.Ticket - y.Ticket);
    }
    
     return res;
  }
};

CArrayList<DealInfo*> dealsHistory;

inline bool UpdateDeals(CArrayList<DealInfo*> &deals, datetime &lastUpdated) {
  DealInfo* dealsToAdd[];
  DealsComparer comparer;
   int toAdd = 0 ;
  DealInfo* deal;
  
   if (! HistorySelect (lastUpdated, TimeLocal () + 12 * 3600 )) {
     return false ;
  }

   for ( int i = 0 , total = HistoryDealsTotal (); i < total; i++) {
    DealInfo tmp;
     ulong ticket = HistoryDealGetTicket (i);
     if (ticket == 0 ) continue ;
    
     datetime dt = ( datetime ) HistoryDealGetInteger (ticket, DEAL_TIME );
     if (lastUpdated < dt) {
      lastUpdated = dt;
    }

     if ( HistoryDealGetInteger (ticket, DEAL_ENTRY ) != DEAL_ENTRY_OUT ) continue ;

     ulong reason = HistoryDealGetInteger (ticket, DEAL_REASON );

    tmp.Ticket = ticket;
    tmp.Closed = dt;
     int idx = deals.BinarySearch(&tmp, &comparer);
     if (idx >= 0 && deals.TryGetValue(idx, deal) && deal != nullptr && deal.Ticket == ticket)
       continue ;

    deal = new DealInfo;
    deal.Ticket = ticket;
    deal.Closed = dt;
    deal.Position = HistoryDealGetInteger (ticket, DEAL_POSITION_ID );
    deal. Symbol = HistoryDealGetString (ticket, DEAL_SYMBOL );
    deal.Type = HistoryDealGetInteger (ticket, DEAL_TYPE );
    deal.Reason = HistoryDealGetInteger (ticket, DEAL_REASON );
    deal.Volume = HistoryDealGetDouble (ticket, DEAL_VOLUME );
    deal.Price = HistoryDealGetDouble (ticket, DEAL_PRICE );
    deal.Swap = HistoryDealGetDouble (ticket, DEAL_SWAP );
    deal.Profit = HistoryDealGetDouble (ticket, DEAL_PROFIT );
    deal.Magic = HistoryDealGetInteger (ticket, DEAL_MAGIC );
    
     ArrayResize (dealsToAdd, toAdd + 1 , total);
    dealsToAdd[toAdd++] = deal;
  }
  
   if (toAdd > 0 ) {
    deals.AddRange(dealsToAdd);
    deals.Sort(&comparer);
  }
  
   return (toAdd > 0 );
}

Kod aceleyle yazılmış ve ArrayResize sık sık göz önüne alındığında iyileştirilmesi gereken bir şey var, ancak yalnızca Closed'a göre sıralanmış önbelleği güncelliyor. Daha sonra aramak isterseniz - dizininizi kullanın. Ancak her seferinde yalnızca küçük bir parçayı güncellemeniz gerekir.
Neden " 12 * 3600 " orada olduğunu hatırlamıyorum, tüm işlemler bana verilmemiş gibi görünüyor.

 
Andrey Pogoreltsev :

Önbelleğe alma değil, bir dizin.

Dikkatlice oku.

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

MT5 ve iş başında hız

fxsaber , 2020.08.28 21:10

Pure MQL5, kısmi (yalnızca HistorySelectByPosition) önbelleğe alma işleminden 100 kat daha yavaştır.

Mimari olarak tam önbelleğe alma yapmak için - iyi düşünmelisiniz. Birçok tuzak var.

İşte önbelleğe alma (kodun bir parçası):

Kod aceleyle yazılmıştı ve ArrayResize'ın sık kullanıldığı göz önüne alındığında iyileştirilmesi gereken bir şey var, ancak yalnızca Closed'a göre sıralanmış önbelleği güncelliyor. Daha sonra aramak isterseniz - dizininizi kullanın. Ancak her seferinde yalnızca küçük bir parçayı güncellemeniz gerekir.

Bu, gerçek şakalar olmadan tarihin önden korunmasının bir örneğidir. MT4Orders'ta bile, kısmi önbelleğe alma, beş saniyelik bir marjla yapılır...

Neden " 12 * 3600 " orada olduğunu hatırlamıyorum, tüm işlemler bana verilmemiş gibi görünüyor.

Her zaman INT_MAX olarak ayarlayın.

 
fxsaber :

Mimari olarak tam önbelleğe alma yapmak için - iyi düşünmelisiniz. Birçok tuzak var.

Aslında, orada karmaşık bir şey yok. Örneğin, geçmişe dönük olarak görünebilecek tüm siparişler için (bu arada çok garip) bir saat rezervi ile seçim yapabilirsiniz.

Bu, gerçek şakalar olmadan tarihin önden korunmasının bir örneğidir. MT4Orders'ta bile, kısmi önbelleğe alma, beş saniyelik bir marjla yapılır...

Her zaman INT_MAX olarak ayarlayın.

Geçişin amacını anlamıyorum. Geçerli bir zaman damgası varmış gibi, ona göre almak istiyorum ve var olmayan bir zaman belirtmeniz garip. Mantıklı bir açıklama istiyorum.

Bu arada nakitim 10k+ işlemli gerçek hesaplarda çalışıyor.

Ve şimdiye kadar koddaki ana frenler ağ fonksiyonlarıdır.

 
Yanlışlıkla geçti, burada daha önce ima edilenleri özetlemeye karar verdim. Ne pahasına olursa olsun süper hızlı performansa ihtiyacınız varsa, o zaman geleneksel olarak elde edilir - bellek gibi diğer kaynakları tüketerek. Başka bir deyişle, bir toplam değeri (belki sadece toplam süreyi değil) her hesaplamanız gerektiğinde tüm geçmiş boyunca bir döngü çalıştırmanız gerekmez, ancak her şeyi bir "dizi" (veya başka bir optimize edilmiş veri yapısı ) içinde önceden hesaplamanız gerekir. ) ve ardından yalnızca ekleyin. Ve konum tanımlayıcısına göre (veya bozulmanın yapıldığı başka bir parametreye göre) bir değer talebi, bir bellek hücresi erişimine yozlaşacaktır. En genel haliyle, bu OLAP gibi bir şeydir (uygulamam çevrimiçi güncellemeyi tamamlamamış olsa da), ancak belirli bir görev için daha basit bir şekilde yapılabilir.
 

En son beta 2588'de , HistorySelect işlevi çok iyi önbelleğe alır ve hemen hemen her zaman (ilk sefer hariç) ücretsizdir.

Büyük olasılıkla, sürümden önce bir dizi iyileştirme yapacağız.



Daha önce açıkladığım gibi, MT5'te, MT4'te olduğu gibi, her olaydan önce her uzman için otomatik olarak piyasa anlık görüntüleri oluşturmak için ek bir maliyet yoktur. Bu, gecikmeleri azaltır ve robotların daha hızlı çalışmasına olanak tanır. Her geliştirici tam olarak ihtiyaç duyduğu şeyi talep eder.

Bu nedenle, "tüm geçmiş üzerinde HistorySelect'i çağırın ve ardından hemen bir HistorySelectByPosition seçimi yapın" yaklaşımının önceden oluşturulmuş geçmiş önbelleklerini öldüreceğini açıkça anlamanız gerekir. Bu ayağından bir atış.


Yayınlandıktan sonra, algoritmik ticaretin basitleştirilmesi ve hızlandırılması için yeni ve daha verimli MQL5 işlevleri ve açık yerel sipariş/anlaşma veri yapıları eklemek için birçok çalışmaya başlayacağız.

 
Renat Fatkhullin :

En son beta 2588'de , HistorySelect işlevi çok iyi önbelleğe alır ve hemen hemen her zaman (ilk sefer hariç) ücretsizdir.

 #include <fxsaber\Benchmark.mqh> // https://c.mql5.com/3/321/Benchmark.mqh

input int inAlertTime = 1 ; // Нижний порог в миллисекундах

#define _B2(A) _B(A, inAlertTime)
#define ALERT(A) Alert ( #A + " = " + ( string )(A))

void OnInit ()
{
   if ( HistorySelect ( 0 , INT_MAX ))
  {
    ALERT( HistoryDealsTotal ());
    ALERT( HistoryOrdersTotal ());
  }
}

void OnTick ()
{
   static int i = 0 ;
  
  ALERT(i++);
  
  _B2( HistorySelect ( TimeCurrent (), INT_MAX ));
  _B2( HistorySelect ( 0 , INT_MAX ));
}


Sonuç.

 2020.09 . 01 22 : 56 : 46.089 Test6 (EURAUD,M1)       Alert : HistoryDealsTotal () = 9435
2020.09 . 01 22 : 56 : 46.089 Test6 (EURAUD,M1)       Alert : HistoryOrdersTotal () = 12529
2020.09 . 01 22 : 56 : 46.575 Test6 (EURAUD,M1)       Alert : i++ = 0
2020.09 . 01 22 : 56 : 46.579 Test6 (EURAUD,M1)       Alert : Time[Test6.mq5 25 : HistorySelect ( 0 , INT_MAX )] = 3 ms.
2020.09 . 01 22 : 56 : 47.424 Test6 (EURAUD,M1)       Alert : i++ = 1
2020.09 . 01 22 : 56 : 47.428 Test6 (EURAUD,M1)       Alert : Time[Test6.mq5 25 : HistorySelect ( 0 , INT_MAX )] = 3 ms.
2020.09 . 01 22 : 56 : 47.765 Test6 (EURAUD,M1)       Alert : i++ = 2
2020.09 . 01 22 : 56 : 47.768 Test6 (EURAUD,M1)       Alert : Time[Test6.mq5 25 : HistorySelect ( 0 , INT_MAX )] = 3 ms.
2020.09 . 01 22 : 56 : 47.902 Test6 (EURAUD,M1)       Alert : i++ = 3
2020.09 . 01 22 : 56 : 47.906 Test6 (EURAUD,M1)       Alert : Time[Test6.mq5 25 : HistorySelect ( 0 , INT_MAX )] = 3 ms.
2020.09 . 01 22 : 56 : 48.453 Test6 (EURAUD,M1)       Alert : i++ = 4
2020.09 . 01 22 : 56 : 48.456 Test6 (EURAUD,M1)       Alert : Time[Test6.mq5 25 : HistorySelect ( 0 , INT_MAX )] = 3 ms.
2020.09 . 01 22 : 56 : 48.516 Test6 (EURAUD,M1)       Alert : i++ = 5
2020.09 . 01 22 : 56 : 48.521 Test6 (EURAUD,M1)       Alert : Time[Test6.mq5 25 : HistorySelect ( 0 , INT_MAX )] = 4 ms.


Her kene bir sorun vardır.


ZY Yüklü Win10, LatencyMon her şeyin yolunda olduğunu gösteriyor.

 
Şu anda vakaların %99'unda yalnızca HistorySelect(0, INT_MAX ) kullanmanız gerektiğini görüyorum. Diğer seçenekleri kullanmamaya çalışın.
 
Renat Fatkhullin :

Yayınlandıktan sonra, algoritmik ticaretin basitleştirilmesi ve hızlandırılması için yeni ve daha verimli MQL5 işlevleri ve açık yerel sipariş/anlaşma veri yapıları eklemek için birçok çalışmaya başlayacağız.

MqlDeal, MqlOrder ve MqlPosition harika olurdu. Hatta daha da kolaylaşabilir.

 
fxsaber :
Şu anda vakaların %99'unda yalnızca HistorySelect(0, INT_MAX ) kullanmanız gerektiğini görüyorum. Diğer seçenekleri kullanmamaya çalışın.

Tarihte yüz binlerce siparişim varsa, son dakikalar için geçmişi almaktan da daha hızlı olur mu?

Peki, o zaman ne, tüm bu hikayeyi mi gözden geçireyim yoksa ne? Bu biraz saçmalık.

 
Dmi3 :

Tarihte yüz binlerce siparişim varsa, son dakikalar için geçmişi almaktan da daha hızlı olur mu?

Savaş robotlarında sadece 0- INT_MAX seçeneğini bıraktım. Frenler fark etmeyi bıraktı.

Neden: