OrderSend() Soruları - sayfa 5

 

Görünüşe göre, önceki sorunu oldukça anlaşılır bir şekilde açıklamadı. Tekrar deneyeceğim.

ENUM_ORDER_TYPE_FILLING numaralandırmasının değerler listesinin açıklaması geçen yıl içinde en az üç kez değişti. Önceki açıklama şöyle görünüyordu:

ENUM_ORDER_TYPE_FILLING

tanımlayıcı

Tanım

ORDER_FILLING_FOK

İşlem, yalnızca belirtilen hacimde ve siparişte belirtilene eşit veya daha iyi bir fiyattan yapılabilir. Şu anda piyasada emir sembolü için yeterli teklif yoksa emir gerçekleşmez. Bu doldurma türü, SYMBOL_TRADE_EXECUTION_INSTANT yürütme modunda kullanılır. veya SYMBOL_TRADE_EXECUTION_REQUEST .

ORDER_FILLING_IOC

Piyasada bulunan maksimum hacimde, siparişte belirtilen limitler dahilinde ve belirtilene eşit veya daha iyi bir fiyatla işlem yapma sözleşmesi. Aynı zamanda, eksik hacim için ek siparişler verilmez. Bu tür doldurma yalnızca SYMBOL_TRADE_EXECUTION_MARKET yürütme modlarında kullanılabilir. ve SYMBOL_TRADE_EXECUTION_EXCHANGE ticaret sunucusundaki sembol ayarlarına bağlı olarak.

ORDER_FILLING_RETURN

Piyasada bulunan maksimum hacimde, siparişte belirtilen limitler dahilinde ve belirtilene eşit veya daha iyi bir fiyatla işlem yapma sözleşmesi. Bu durumda eksik miktar için bu siparişte belirtilen fiyattan ek sipariş verilecektir. Bu doldurma türü yalnızca bekleyen siparişler için kullanılır ( TRADE_ACTION_PENDING ).

Görüldüğü gibi ORDER_FILLING_RETURN ile bekleyen emirler arasında bire bir yazışma vardı, yani: ORDER_FILLING_RETURN sadece bekleyen emirlere uygulanabiliyordu ve tüm bekleyen emirlerin type_filling alanı sadece ORDER_FILLING_RETURN değeri ile doldurulabiliyordu.

Piyasa emirleri için ( action== TRADE_ACTION_DEAL ), sunucu tarafında ayarlanan yürütme modlarına bağlı olarak type_filling alanının doldurulması gerekiyordu.

Böylece belirli bir paradigma oluştu: bekleyen bir emir varsa, o zaman ORDER_FILLING_RETURN; bir piyasa emri ise, ORDER_FILLING_FOK veya ORDER_FILLING_IOC (moda bağlı olarak).

Şimdi her şey tersine döndü, yani:

ENUM_ORDER_TYPE_FILLING

tanımlayıcı

Tanım

ORDER_FILLING_FOK

Bu yürütme politikası, siparişin yalnızca belirtilen hacimde yürütülebileceği anlamına gelir. Şu anda piyasada yeterli miktarda finansal araç yoksa emir gerçekleşmez. Gerekli hacim, şu anda piyasada mevcut olan çeşitli tekliflerden oluşabilir.

ORDER_FILLING_IOC

Piyasada bulunan maksimum hacim üzerinden, siparişte belirtilen limitler dahilinde işlem yapma anlaşması anlamına gelir. Tam olarak gerçekleştirilememesi durumunda, mevcut miktar için emir gerçekleştirilir ve gerçekleşmeyen emir hacmi iptal edilir.

ORDER_FILLING_RETURN

Bu mod yalnızca ORDER_TYPE_BUY_LIMIT ve ORDER_TYPE_SELL_LIMIT siparişler için kullanılır. Kısmi işlem yapılması durumunda kalan hacim ile limit emri iptal edilmez, işlemeye devam eder.

ORDER_TYPE_BUY_STOP_LIMIT ve ORDER_TYPE_SELL_STOP_LIMIT emirleri için, aktivasyon üzerine, ORDER_FILLING_RETURN yürütme tipine sahip ilgili limit emri ORDER_TYPE_BUY_LIMIT/ORDER_TYPE_SELL_LIMIT oluşturulacaktır.

ORDER_FILLING_FOK ve ORDER_FILLING_IOC'yi yalnızca piyasa emirleriyle kullanma kısıtlaması ortadan kalktı. ORDER_FILLING_FOK ve ORDER_FILLING_IOC'nin sunucu üzerinde ayarlanan yürütme moduna bağlı olarak piyasa emirleri ile kullanımına ilişkin kısıtlama da ortadan kalktı. ORDER_FILLING_RETURN'in yalnızca limitli ve stop_limitli emirlerle kullanımına ilişkin bir kısıtlama vardı.

Bu nedenle soru şudur: ORDER_FILLING_FOK ve ORDER_FILLING_IOC modlarını limit ve stop_limit emirleri dahil tüm emirlere (hem piyasa hem de bekleyen) uygulamak kabul edilebilir mi? Değişiklikleri anlayan var mı?

 

Standart Kitaplık bu yönteme sahiptir (şematik olarak):

 bool CTrade::PositionClose( const string symbol, ulong deviation)
  {
   do
     {
       //--- checking
       if ( PositionSelect (symbol))
        {
         if (( ENUM_POSITION_TYPE ) PositionGetInteger ( POSITION_TYPE )== POSITION_TYPE_BUY )
           {
             //--- prepare request for close BUY position
            m_request.type = ORDER_TYPE_SELL ;
            m_request.price= SymbolInfoDouble (symbol, SYMBOL_BID );
           }
         else
           {
             //--- prepare request for close SELL position
            m_request.type = ORDER_TYPE_BUY ;
            m_request.price= SymbolInfoDouble (symbol, SYMBOL_ASK );
           }
        }
       else
        {
         //--- position not found
         m_result.retcode=retcode;
         return ( false );
        }
      m_request.action      =TRADE_ACTION_DEAL;
      m_request.volume      = PositionGetDouble ( POSITION_VOLUME );
       //--- check volume
       double max_volume= SymbolInfoDouble (symbol, SYMBOL_VOLUME_MAX );
       if (m_request.volume>max_volume)
        {
         m_request.volume=max_volume;
         partial_close= true ;
        }
       else
         partial_close= false ;
       //--- order send
       if (! OrderSend (m_request,m_result))
        {
         if (--retry_count!= 0 ) continue ;
         if (retcode== TRADE_RETCODE_DONE_PARTIAL )
            m_result.retcode=retcode;
         return ( false );
        }
      retcode= TRADE_RETCODE_DONE_PARTIAL ;
       if (partial_close) Sleep ( 1000 );
     }
   while (partial_close);
   return ( true );
  }

Burada, pozisyon hacminin bir anlaşma yapmak için maksimum hacimden daha büyük olması durumunda, pozisyonu kısmen kapatmak için art arda girişimlerde bulunulur.

Bu durumda, OrderSend() işlevine başarılı bir çağrı yapıldıktan sonra, ikinci bir gecikme ayarlanır ve ardından do-while döngüsünün gövdesinde PositionSelect() işlevi çağrılır. Onlar. sunucunun bir piyasa emrini başarılı bir şekilde kabul etmesi durumunda, terminal veritabanındaki açık pozisyon hakkındaki bilgileri güncellemek için bir saniyenin yeterli olduğu ve böylece bir sonraki iterasyonda pozisyon hakkında güncellenmiş verilerin alınmasının mümkün olacağı varsayılmaktadır (bunda örneğin, konum hacmi hakkında). Ancak iki yıl önce, aynı yöntemde PositionSelect() işlevi çağrılmadan önceki gecikme üç saniyeydi. Yani soru şu:

OrderSend() işlevine başarılı bir çağrıdan sonra uçbirim veritabanının güncellenmiş konum verilerini almasının (ve böylece uçbirim tarafında kalan konum hacmini doğru şekilde işlemesinin) garanti edilmesini sağlamak için her durumda bir saniye yeterli midir? Açıklanan durumda terminal veritabanının güncellenmiş konum verilerini alması için garanti edilmesi gereken maksimum süre nedir?

 

Şampiyonanın şu kuralı vardır:

Ticaret koşulları mümkün olduğunca gerçeğe yakın olacaktır:

  • ticaret talepleri işleme süresi 2 ila 7 saniye arasında
Gerçek hayatta bir broker (para çektikten sonra) yaklaşık 3 saniye (açma-kapama-değişiklik) işlem yaptı.Hemen NDD'ye geçtim.Şimdiye kadar memnunum.
 
Karlson :

Şampiyonanın şu kuralı vardır:

Ticaret koşulları mümkün olduğunca gerçeğe yakın olacaktır:

  • ticaret talepleri işleme süresi 2 ila 7 saniye arasında

Tamam, ipucu için teşekkürler! OrderSend() işlevine yapılan başarılı bir çağrıdan sonra, terminal veritabanının güncellenmiş konum verilerini almasının garanti edilmesini sağlamak için bir saniyenin yeterli olmadığı ortaya çıktı?

Bu sonuçtan, verdiğim Standart Kitaplık yönteminin, pozisyonu kapatmak yerine geri dönüş olacağını hiçbir şekilde garanti etmediğini takip ediyor. Onlar. PositionClose() yöntemi sonraki yinelemeyi bir saniye geciktirirse ve ticaret talepleri 2 - 7 kat daha uzun süre işlenebilirse, o zaman yeni yinelemelerde PositionSelect() işlevinin konumların durumu hakkında aynı bilgileri alması mümkündür. terminal üssünü ve sunucuyu emirlerle bombalayın - bu durumda toplam hacmi kapatılan pozisyonun ilk hacminden daha büyük olacak.

O halde, bir pozisyonun kapatılması yerine tersine çevrilmesine izin veriyorsa, PositionClose() yönteminde neden bir saniyelik bir gecikme ayarlanır? Ve " gerçeğe mümkün olduğunca yakın ticaret koşulları " ile tutarlı değil mi?

Genel olarak, OrderSend() işlevine yapılan başarılı bir çağrıdan sonra terminal veritabanının güncellenmiş konum verilerini almasının ne kadar süre garanti edildiği ve standart PositionClose() yöntemindeki bir saniyelik gecikmenin nedeni hakkında daha ayrıntılı bilgiye ihtiyacımız var.

 
başlayalım
 if ( PositionSelect (symbol))

hiçbir şeyi garanti etmez. Uygulanamaz.

ikinci olarak, terminal verilerinin güncellenmesi için de hiçbir garanti yoktur. Kendiniz yapay bir TradeContextBusy düzenlemeniz ve tüm siparişlerinizin işlenmesini beklemeniz gerekir.
MQL5'te hemen yapamazsınız. Geçici garantiler yoktur.

 

sergeev :

начнем с того, что

if ( PositionSelect (symbol))

hiçbir şeyi garanti etmez. Uygulanamaz.

ikinci olarak, terminal verilerinin güncellenmesi için de hiçbir garanti yoktur. Kendiniz yapay bir TradeContextBusy düzenlemeniz ve tüm siparişlerinizin işlenmesini beklemeniz gerekir.
MQL5'te hemen yapamazsınız. Geçici garantiler yoktur.

Evet, düşünmeye devam etmem gerekecek. İşleme örneği olarak kütüphaneden boşuna standart bir yöntem aldığım ortaya çıktı.

Söyle bana ama tarihte bir mülkle anlaşma çıkarsa

DEAL_ENTRY_OUT

Pazar çıkışı

bu, terminal veritabanındaki tüm bilgilerin otomatik olarak değiştiği (mevcut duruma güncellendiği) anlamına mı geliyor? Yoksa ticaret geçmişte ortaya çıkmış olabilir mi ve pozisyon detayları hala güncellenmemiş olabilir mi? Başka bir deyişle, şu soruyla ilgileniyoruz: Geçmişteki işlemlerle ilgili bilgiler ve karşılık gelen pozisyonlarla ilgili bilgiler aynı anda değişiyor mu? Yoksa bu durumda da fırsatlar ve pozisyonlar terminalde eşzamansız olarak güncelleniyor mu? Bunu Roche'un makalesinden anlayamadım - anladığım kadarıyla, terminal tabanının güncellenmesi ile bir ticaret talebinin sonucunun döndürülmesi arasındaki uyumsuzluğu açıklıyor.

 

terminaldeki veri alışverişi modeli, fark ettiğiniz gibi, eşzamansız.

bu nedenle alım satım yaparken (emirlerin/anlaşmaların/pozisyonların özelliklerini alırken), veri elde etme başarısını analiz etmek gerekir. Ve herhangi bir hata durumunda (yanlış/0), işlem mantığının analizini sonlandırın.

Gerçekleştirilen ve onaylanmayan tüm OrderSend'ler hatırlanacak ve son gönderimden henüz bir yanıt gelmemişse yeni sipariş gönderimlerini bağımsız olarak engelleyerek siparişin görünmesini bekleyecektir.

Ve örneğin, PositionSelect'i yapı ile değiştirmek daha iyidir.

 for ( int i= PositionsTotal ()- 1 ;i>= 0 ;i--) 
{
   if ( PositionGetSymbol (i)== Symbol ())
  {
    ....
  }

Genel olarak, ticaret işlemlerinin mantığı asenkron olmalıdır. Terminal eşzamansız olduğundan, MT sunucusu ve likidite sağlayıcısının sunucusu da eşzamansızdır.

Senkronizasyonu kontrol etme görevi tamamen MQL programlayıcısına düşer.

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Типы торговых операций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Типы торговых операций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Типы торговых операций - Документация по MQL5
 

Geçen şampiyonada bu cevabı kullanmakta sorun yaşamadım.

https://www.mql5.com/ru/forum/4342#comment_88688

Дублирование запросов на открытие позиций.
Дублирование запросов на открытие позиций.
  • www.mql5.com
Дублирование запросов на открытие позиций.
 
sergeev :

Ve örneğin, PositionSelect'i yapı ile değiştirmek daha iyidir.

 for ( int i= PositionsTotal ()- 1 ;i>= 0 ;i--) 
{
   if ( PositionGetSymbol (i)== Symbol ())
  {
    ....
  }

Lütfen açıklayın, eğer zor değilse, PositionsTotal() + PositionGetSymbol() kullanmanın PositionSelect() kullanımına göre avantajı nedir? Her üç işlev de aynı uçbirim tabanına başvururken, PositionGetSymbol() ve PositionSelect() işlevleri başarısız olabilir. Yani, eğer pozisyon uçbirimin tabanında mevcutsa, hem PositionSelect() fonksiyonu hem de önerilen yapı başarısız olabilir. Hala hata kodunu kontrol etmeniz gerekiyor.

Tasarımınızın özelliği/güvenilirliği nedir? O yüzden çözemedim.

Документация по MQL5: Торговые функции / PositionSelect
Документация по MQL5: Торговые функции / PositionSelect
  • www.mql5.com
Торговые функции / PositionSelect - Документация по MQL5
 

bütün kafasını kırdı .. durmadı ve bu kadar .. ve bir sürü hata. uzmandan geriye kalan bu ve sonra işe yaramıyor

 void OnTick (){ if ( PositionsTotal ()< 1 ){OPEN();}}

bool OPEN(){
             MqlTradeRequest request;
             MqlTradeResult result;
             

             request.symbol       = _Symbol ;
             request.action       = TRADE_ACTION_DEAL ;
             request.type_filling = ORDER_FILLING_FOK ;
             request.deviation    = 100 ;
             request.volume       = NormalizeDouble ( 2 , 2 );
             request.type         = ORDER_TYPE_BUY ;
             request.price        = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_ASK ), _Digits );
             request.tp           = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_ASK ) + 500 * _Point , _Digits );
             request.sl           = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_ASK ) - 500 * _Point , _Digits );

             OrderSend (request,result);     
                        
             if (result.retcode== 10009 || result.retcode== 10008 )   Print ( "Succsesful open" );
             else                                                Print ( "Error open: " , DoubleToString ( GetLastError (), 0 ), "  response code: " ,result.retcode);
    
   return ( true );}

bunu yaparsanız, hata olmaz, ancak kaybı durdurma hala ayarlanmamıştır.

 MqlTradeRequest request={ 0 }; MqlTradeResult result={ 0 };