Belirli bir komisyoncu ile gerçek hesap için Çoklu Sipariş Girişi Sorunu - sayfa 2

 
Malacarne :

Merhaba BlindMist , hesabınızın aracı sunucusuyla senkronize olup olmadığını doğrulamak için yerel veritabanınızı kontrol etmeniz mantıklıdır .

Lütfen bu sorunu çözmek için önerilen gönderiye bir göz atın.

Az önce önerilen gönderiyi inceledim ve emirlerin birden çok kez yürütülmesinin nasıl önleneceğinden bahsetmiyor ...

Sleep() işleviyle bile, ticaretin başarısız olduğundan emin olmak için ne kadar beklemeniz gerekiyor?...

EA'mda, tekrar denemeden önce 10 saniye sonra bir sipariş gönderme isteği zaman aşımına uğradım... ama bazen sipariş, ilk istekten 15-20 saniye sonra gerçekleştirilir; bu da istenmeyen çifte ticaretle sonuçlanır.

 
BlindMist :

Az önce önerilen gönderiyi inceledim ve emirlerin birden çok kez yürütülmesinin nasıl önleneceğinden bahsetmiyor ...

Sleep() işleviyle bile, ticaretin başarısız olduğundan emin olmak için ne kadar beklemeniz gerekiyor?...

EA'mda, tekrar denemeden önce 10 saniye sonra bir sipariş gönderme isteği zaman aşımına uğradım... ama bazen sipariş, ilk istekten 15-20 saniye sonra gerçekleştirilir; bu da istenmeyen çifte ticaretle sonuçlanır.

Merhaba BlindMist , bu konudaki fikrim, hala kontrol etmenin tek yolu olduğunu düşündüğüm (sadece bir PositionSelect testi veya sadece bir Uyku yerine), uzun bir süre bekledikten sonra ölümcül bir hata gibi bir şey yaratmak veya sembol pozisyonuna sahip olduğunuz anda (aşağıdaki kod).

Bu problemle ilgili tek iyi şey, muhtemelen PositionSelect'in er ya da geç sunucudan güncellenmiş pozisyonu almasıdır, bu yüzden yapmamız gereken, ölümcül bir hatayı belirtmek için maksimum bir süre (zaman aşımımız) beklemek ve küçük örnekler yapmaktır. tamam olup olmadığını kontrol edin (örneğimde 100 ms).

 bool fatalError= false ; // atention: declare this as global

....

if (fatalError== false ) {
   if (m_Trade.PositionOpen( Symbol (), ORDER_TYPE_BUY , LotSize, Price, 0 , 0 )) {
     Print ( "Position opened in " , Symbol ());
     int maxTimeout= 0 ;
     while (! PositionSelect ( Symbol ())) {
       Sleep ( 100 );
       maxTimeout++;
       if (maxTimeout> 100 ) {
           Print ( "### PositionSelect fatal error!" );
          fatalError= true ;
           break ;
       }
    }
     Print ( "--> PositionSelect delay=" ,maxTimeout* 100 );
     break ;
  }
}

Bunu daha modüler yapmanın başka bir yolu da zaman aşımını kontrol etmek için bir fonksiyon oluşturmaktır, örneğin:

 bool PositionSelectTimeout( string symbol, int timeout) 
  { // timeout in seconds
   int maxTimeout= 0 ;
   while (! PositionSelect (symbol)) 
     {
       Sleep ( 100 );
      maxTimeout++;
       if (maxTimeout>(timeout* 10 )) return ( false ); // fatal error (timeout)
     }
   return ( true ); // position selected
  }

Buradaki ana fikir benim PositionSelectTimeout()'umdur, tabii ki geçici bir çözüm olarak orijinal PositionSelect()'in yerini alır, çünkü sadece MQ gerçekten iyi ve kesin bir çözüme hitap edebilir.

Örneğin:

 if (PositionSelectTimeout( Symbol (),6 0 )) { // 60 seconds timeout
 ...
}

// instead of ...

if (PositionSelect( Symbol ())) {
 ...
}

Bu yüzden, bence, FinanceEngineer sorunu çözmek için aynısını yapmalı ve bu testi kendi döngüsüne sokarak pozisyonun bir mola vermek için uygun olup olmadığını iki kez kontrol etmelidir.

 
figurelli :

Merhaba BlindMist , bu konudaki fikrim, hala kontrol etmenin tek yolu olduğunu düşündüğüm (sadece bir PositionSelect testi veya sadece bir Uyku yerine), uzun bir süre bekledikten sonra ölümcül bir hata gibi bir şey yaratmak veya sembol pozisyonuna sahip olduğunuz anda (aşağıdaki kod).

Bu problemle ilgili tek iyi şey, muhtemelen PositionSelect'in er ya da geç sunucudan güncellenmiş pozisyonu almasıdır, bu yüzden yapmamız gereken, ölümcül bir hatayı belirtmek için maksimum bir süre (zaman aşımımız) beklemek ve küçük örnekler yapmaktır. tamam olup olmadığını kontrol edin (örneğimde 100 ms).

Bunu daha modüler yapmanın başka bir yolu da zaman aşımını kontrol etmek için bir fonksiyon oluşturmaktır, örneğin:

Buradaki ana fikir benim PositionSelectTimeout()'umdur, tabii ki geçici bir çözüm olarak orijinal PositionSelect()'in yerini alır, çünkü sadece MQ gerçekten iyi ve kesin bir çözüme hitap edebilir.

Örneğin:

Bu yüzden, bence, FinanceEngineer sorunu çözmek için aynısını yapmalı ve bu testi kendi döngüsüne sokarak pozisyonun bir mola vermek için uygun olup olmadığını iki kez kontrol etmelidir.

Teşekkürler Figurelli, çok ayrıntılı cevap. Bir şans vereceğim ve sistemimi iyileştirip iyileştirmediğini göreceğim.
 
BlindMist :
Teşekkürler Figurelli, çok ayrıntılı cevap. Bir şans vereceğim ve sistemimi iyileştirip iyileştirmediğini göreceğim.
Teşekkürler, hoş geldiniz.
 
BlindMist :

Az önce önerilen gönderiyi inceledim ve emirlerin birden çok kez yürütülmesinin nasıl önleneceğinden bahsetmiyor ...

Sleep() işleviyle bile, ticaretin başarısız olduğundan emin olmak için ne kadar beklemeniz gerekiyor?...

EA'mda, tekrar denemeden önce 10 saniye sonra bir sipariş gönderme isteği zaman aşımına uğradım... ama bazen sipariş, ilk istekten 15-20 saniye sonra gerçekleştirilir; bu da istenmeyen çifte ticaretle sonuçlanır.

Bir siparişin yürütülmesi için 15 saniye. Bu gerçekten kötü. Buradaki sorun, Broker'ın sunucusundan hiçbir şey alamamamızdır (Örneğin, basit durum kontrolü bile kod parçası, vb.)
 
FinanceEngineer :
Bir siparişin yürütülmesi için 15 saniye. Bu gerçekten kötü. Buradaki sorun, Broker'ın sunucusundan hiçbir şey alamamamızdır (Örneğin, basit durum kontrolü bile kod parçası, vb.)

Merhaba FinanceEngineer , haklısınız, ancak ilk yapmanız gereken düşük gecikmeli bir broker seçmektir, çünkü piyasalar her seferinde daha hızlıdır ve bu tür sorunlar olağan olacaktır.

Ayrıca, en kötü durumu düşünmek her zaman iyidir, çünkü düşük gecikmeli bir aracınız olabilir, ancak günün bazı anlarında, örneğin ilgili haberleriniz olduğunda, büyük bir gecikme olabilir.

Her neyse, MT5'teki OrderSend()'i yönetmek MT4 kadar kolay değildir, çünkü MT4'ün döndürülen değeri bir Bilettir. Bu değişiklik MT5'te gerekliydi, çünkü MQL5 mimarisinde tanıtılan borsaların asenkron iletişimi, komisyoncu OMS protokolü (örneğin FIX gibi) ile iletişim kurmayı mümkün kıldı.

Ancak bence bu, gerçek zamanlı bir Bilet almak çok zor olduğu için bugün sipariş yönetimi için OMS'deki büyük değişikliktir ve MT5, özellikle daha fazla gecikmeye sahip olduğumuz borsaları kullanırsak, bu yeni senaryoya güncellenir.

Bu anlamda, MT5'te OrderSend()'den sonra yapacağınız daha alakalı şey PositionSelect()'i kontrol etmektir ve yukarıdaki tüm nedenlerden dolayı önerilen PositionSelectTimeout() geçici çözümümü kullanmanızı şiddetle tavsiye ederim.

En kötü durumları düşünmenin tek yolu, piyasaya bir emir gönderdikten sonra tüm if { } else { } koşullarını, herhangi bir durumu yönetebilecek şekilde yönetmektir.

Ben de { } yakalamak istiyorum, ancak buna yakın bir şey yapmak için GetLastError() kullanabiliriz.

Bunun nedeni, bir pozisyonu onaylamak için Bilet'e de ihtiyacınız olması ve MT5 OrderSend()'in bileti MT4'ün yaptığı gibi senkronize olarak döndürmemesidir.

 
BlindMist :

Az önce önerilen gönderiyi inceledim ve emirlerin birden çok kez yürütülmesinin nasıl önleneceğinden bahsetmiyor ...

Sleep() işleviyle bile, ticaretin başarısız olduğundan emin olmak için ne kadar beklemeniz gerekiyor?...

EA'mda, tekrar denemeden önce 10 saniye sonra bir sipariş gönderme isteği zaman aşımına uğradım... ama bazen sipariş, ilk istekten 15-20 saniye sonra gerçekleştirilir; bu da istenmeyen çifte ticaretle sonuçlanır.

Bu benim şu anda kullandığım kodum. Şimdiye kadar, herhangi bir sorunum yok. Bu kodu deneyebilirsiniz ve eğer o komisyoncu için çalışıyorsa.

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

 
FinanceEngineer :

Bu benim şu anda kullandığım kodum. Şimdiye kadar, herhangi bir sorunum yok. Bu kodu deneyebilirsiniz ve eğer o komisyoncu için çalışıyorsa.

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

checkOrderSend değişkeni ile ne yaparsınız?

Sunucu anlaşmasının tamamlandığını kontrol etmeden birden fazla emrin yürütülmesini nasıl önlersiniz?

 
figurelli :

checkOrderSend değişkeni ile ne yaparsınız?

Sunucu anlaşmasının tamamlandığını kontrol etmeden birden fazla emrin yürütülmesini nasıl önlersiniz?

merhaba figürlü

Amacım OrderSend işlevinin sonunda hem 10009 hem de 10008 kodunu kontrol etmekti. Çünkü birçok insanın yalnızca bir iade kodundan birini (yani 10009 veya 10008) kontrol ettiğini ve normalde bir sipariş durumundan kaçınmak için bir for döngüsü yerleştirdikleri için çok sayıda sipariş aldığını gördüm.

Benim durumumda, o komisyoncudan herhangi bir sipariş alamazsam for döngüm 10 kez deneyecek. Bu nedenle, muhtemelen birinin birden fazla sipariş alıp almadığını açıklığa kavuşturmaya değer, o zaman hem 10009 hem de 10008'i kontrol ederek Sipariş Gönderme döngüsünü durdurup durdurmadıklarını kontrol etmelidirler.

Ancak, ironik bir şekilde, demo hesapta yalnızca bir iade kodunu kontrol etmek iyidir. Size herhangi bir çoklu sipariş sorunu vermeyecektir. Yani burada canlı hesap ve demo hesabın biraz farklı davrandığını buldum.

Saygılarımla.

 
FinanceEngineer :

merhaba figürlü

Amacım OrderSend işlevinin sonunda hem 10009 hem de 10008 kodunu kontrol etmekti. Çünkü birçok insanın yalnızca bir iade kodundan birini (yani 10009 veya 10008) kontrol ettiğini ve normalde bir sipariş durumundan kaçınmak için bir for döngüsü yerleştirdikleri için çok sayıda sipariş aldığını gördüm.

Benim durumumda, o komisyoncudan herhangi bir sipariş alamazsam for döngüm 10 kez deneyecek. Bu nedenle, muhtemelen birinin birden fazla sipariş alıp almadığını açıklığa kavuşturmaya değer, o zaman hem 10009 hem de 10008'i kontrol ederek Sipariş Gönderme döngüsünü durdurup durdurmadıklarını kontrol etmelidirler.

Ancak, ironik bir şekilde, demo hesapta yalnızca bir iade kodunu kontrol etmek iyidir. Size herhangi bir çoklu sipariş sorunu vermeyecektir. Yani burada canlı hesap ve demo hesabın biraz farklı davrandığını buldum.

Saygılarımla.

Merhaba FinanceEngineer , belki orijinal kodunuzu çoklu sipariş probleminizi kontrol etmeye başlamanız daha iyi olur, çünkü bunu yaparsak muhtemelen burada diğer kritik noktaları ele alacağız ve odağı kaybetmeyeceğiz, ne düşünüyorsunuz?