Hangi tasarım doğru? - sayfa 8

 
valenok2003 :

Çok teşekkür ederim, hataları işliyorum, bir mesaj geliyor - fiyat yanlış, ama neyin yanlış olduğunu anlayamıyorum.

sonra satırı ekleyin

 int err = GetLastError ();

işlevin başlangıcına kadar - hata arabelleğini temizleyin: bazen "bir başkasının" hatasını okuyabilirsiniz, aksi takdirde işlev başladığında hata arabelleği temizlenir.

Bu gerekli değildir, ancak programlar gerçek hayat içinse, her şeyi mümkün olduğunca doğru yapmak çok arzu edilir.

İyi şanlar.

 
VladislavVG :

sonra satırı ekleyin

işlevin başlangıcına kadar - hata arabelleğini temizleyin: bazen "bir başkasının" hatasını okuyabilirsiniz, aksi takdirde işlev başladığında hata arabelleği temizlenir.

Bu gerekli değildir, ancak programlar gerçek hayat içinse, her şeyi mümkün olduğunca doğru yapmak çok arzu edilir.

İyi şanlar.


Evet, teşekkürler, gerçek programlarda bunu yapıyorum.
 
İyi insanlar, açık sipariş olmamasına rağmen işlevin neden 0 döndürdüğünü söyleyin. Bir hata atılmalı mı?
 //+------------------------------------------------------------------+
//| функция закрытия ордеров по символу
//+------------------------------------------------------------------+
int Close_This_Symbol_All( string _Symbol_Name, string _Type_Order, int _Slippage, bool _Alert_ON)
{
  bool _Result;
  ERROR = 0 ;
//----
  if ( OrdersTotal () == 0 ) return (- 1 );
  for ( int _Cnt = OrdersTotal ()- 1 ; _Cnt >= 0 ; _Cnt--) 
  {
    if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) break ;
    if (OrderSymbol() == _Symbol_Name)
    { 
      while (!IsTradeAllowed()) Sleep ( 1000 );
      RefreshRates();
      if (OrderType() == OP_BUY   && _Type_Order == "BUY" ) 
      {
        _Result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_BID), _Slippage, CLR_NONE );
        ERROR = GetLastError ();
      }
      if (OrderType() == OP_SELL && _Type_Order == "SELL" ) 
      {
        _Result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_ASK), _Slippage, CLR_NONE );
        ERROR = GetLastError ();
      }
      if (_Result == true) PlaySound (Name_Sound_Close);
      else 
      {
        Error(Name_Expert, " Close " +_Type_Order+ ": " ,ERROR,_Alert_ON);
        break ;
      }
    }  
  }
//----
  return (ERROR);
}
//+------------------------------------------------------------------+
 
Bir kez daha, kemikleri mi sökeceğiz?
 
valenok2003 :
İyi insanlar, açık sipariş olmamasına rağmen işlevin neden 0 döndürdüğünü söyleyin. Bir hata atılmalı mı?
int Sipariş Toplamı ( )

Açık ve bekleyen siparişlerin toplam sayısını verir.

Hala sipariş için yazıyor musunuz?

 

-- Alt çizgi ve çift alt çizgi ile başlayan adların kullanılması kötü bir biçimdir. Sonunda altını çizmekten daha iyidir.


-- _Type_Order neden bir dizedir? IMHO, gerçekçi olmayan bir şekilde elverişsizdir. O zaman getirmek gerekli olacaktır. Çünkü "Sat" veya "sat" yazarsanız, hiçbir şey sürmez.


-- Hata istiyorsan hata yap:

ERROR = -1 ;

Ve böylesi daha iyi

#define ERROR_NOTHING_TO_CLOSE -1
...

...
ERROR = ERROR_NOTHING_TO_CLOSE;


--

 if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) break ;

Neden kırmak? Diyelim ki bir milisaniye önce sipariş TP tarafından kapatıldı - bu nedenle geri kalanının kapatılması gerekmiyor mu? Böyle daha iyi:

 if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) continue ;

--

 while (!IsTradeAllowed()) Sleep ( 1000 );

Bir dize işe yaramazdan daha kötüdür - zararlıdır. Belki de bu kastedilmiştir?

 while (IsTradeContextBusy()) Sleep ( 1000 );


--

 else 
      {
        Error(Name_Expert, " Close " +_Type_Order+ ": " ,ERROR,_Alert_ON);
         break ;
      }

Onlar. aniden emir kapatılamazsa, "direksiyonunu bırak, gözlerimizi kapat ve çığlık atmaya başla."

Gerisi kapatılmalı mı? Tekrar denemen gerekmez mi?


Neden burada bir hata döndürün? Örneğin, her şey başarıyla kapatıldıysa true ve değilse false döndürmek çok daha uygundur.


Şimdilik her şey gibi.

 
TheXpert :

-- Alt çizgi ve çift alt çizgi ile başlayan adların kullanılması kötü bir biçimdir. Sonunda altını çizmekten daha iyidir.


Fonksiyonların içinde alt çizgi ile başlayan isimler kullanarak değişkenleri yeniden tanımlama riskini ortadan kaldırıyorum. O. start() içinde aynı adları güvenle kullanabilirim, ancak alt çizgi olmadan. bu da kodun şeffaflığını artırır.

- _Type_Order neden bir dizedir? IMHO, gerçekçi olmayan bir şekilde elverişsizdir. O zaman getirmek gerekli olacaktır. Çünkü "Sat" veya "sat" yazarsanız, hiçbir şey sürmez.

Haklısın tabi ki. Ancak, bir dize kullanmak kodun şeffaflığını arttırır ve şu anda sahip olduğum kod miktarı ile bir döküme gerek yoktur. Gerçekten bu sorunla karşılaştığımda yapacağım ama şimdilik buna gerek yok. Sadece SAT veya AL yazarım.


Neden kırmak? Diyelim ki bir milisaniye önce sipariş TP tarafından kapatıldı - bu nedenle geri kalanının kapatılması gerekmiyor mu? Böyle daha iyi:

 if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) continue ;

Kesinlikle haklısın, teşekkürler.


Bir dize işe yaramazdan daha kötüdür - zararlıdır. Belki de bu kastedilmiştir?

IsTradeContextBusy() işlevi yalnızca iş parçacığının meşguliyeti hakkında bilgi verir, IsTradeAllowed() biraz daha geniştir


Onlar. Aniden emir kapatılamazsa "direksiyonunu bırak, gözlerimizi kapat ve çığlık atmaya başla"


evet, tam olarak böyle hata ayıklama dönemi için

Neden burada bir hata döndürün? Örneğin, her şey başarıyla kapatıldıysa true ve değilse false döndürmek çok daha uygundur.


Teşekkürler, sanırım neyin yanlış olduğunu anladım. Şimdi kontrol edip tekrar yazacağım.
 

Hata şu şekildeydi:

bool _Result değişkeni başlatılmadı, bu, orada false olacağı anlamına gelir, bu nedenle, koşulların hiçbiri karşılanmadığından, _Result değişkenini değiştirmedik ve zaten false içeriyor. Ve işlev, gerçekte var olmayan hata işlemeye geçer.

Fonksiyonu düzelttim ve buraya gönderdim, birilerinin işine yarayacağını düşünüyorum.

 //+------------------------------------------------------------------+
//| функция закрытия ордеров по символу
//+------------------------------------------------------------------+
int Close_This_Symbol_All( string _Symbol_Name, string _Type_Order, int _Slippage, bool _Alert_ON)
{
int _Cnt_Close_Orders = 0 ;
//----
  if ( OrdersTotal () == 0 ) return (_Cnt_Close_Orders);
  for ( int _Cnt = OrdersTotal ()- 1 ; _Cnt >= 0 ; _Cnt--) 
  {
    if (! OrderSelect (_Cnt, SELECT_BY_POS, MODE_TRADES)) continue ;
    if (OrderSymbol() == _Symbol_Name)
    { 
      while (!IsTradeAllowed()) Sleep ( 1000 );
      RefreshRates();
      if (OrderType() == OP_BUY   && _Type_Order == "BUY" ) 
      {
        if (OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_BID), _Slippage, CLR_NONE ))
        {
          _Cnt_Close_Orders++;
          PlaySound (Name_Sound_Close);        
        } 
        else 
        {
          Error(Name_Expert, " Close " +_Type_Order+ ": " , GetLastError (),_Alert_ON);
          continue ;
        }
      }
      if (OrderType() == OP_SELL && _Type_Order == "SELL" ) 
      {
        if (OrderClose(OrderTicket(), OrderLots(), MarketInfo(_Symbol_Name,MODE_ASK), _Slippage, CLR_NONE ))
        {
          _Cnt_Close_Orders++;
          PlaySound (Name_Sound_Close);        
        } 
        else 
        {
          Error(Name_Expert, " Close " +_Type_Order+ ": " , GetLastError (),_Alert_ON);
          continue ;
        }
      }
    }  
  }
//----
  return (_Cnt_Close_Orders);
}
//+------------------------------------------------------------------+

PS Moderatörleri . Böyle bir şube tesadüfen ortaya çıktı - siparişlerin doğru şekilde kapatılmasıyla ilgili hazır bir eğitim. Belki yeniden adlandırmaya değer, örneğin - ayrıştırma örnekleriyle siparişler nasıl doğru bir şekilde kapatılır?

PPS Katılan herkese çok TEŞEKKÜR EDERİZ . Belki daha fazla soru olacaktır.

 
valenok2003 :

Hata şu şekildeydi:

bool _Result değişkeni başlatılmadı, bu, orada false olacağı anlamına gelir, bu nedenle, koşulların hiçbiri karşılanmadığından, _Result değişkenini değiştirmedik ve zaten false içeriyor. Ve işlev, gerçekten var olmayan hataları işlemeye devam eder.

Fonksiyonu düzelttim ve buraya gönderdim, birilerinin işine yarayacağını düşünüyorum.

PS Moderatörleri . Böyle bir şube tesadüfen ortaya çıktı - siparişlerin doğru şekilde kapatılmasıyla ilgili hazır bir eğitim. Belki yeniden adlandırmaya değer, örneğin - ayrıştırma örnekleriyle siparişler nasıl doğru bir şekilde kapatılır?

PPS Katılan herkese çok TEŞEKKÜR EDERİZ . Belki daha fazla soru olacaktır.


CodeBase'e bakarsanız ve forumu dikkatlice okursanız, siparişlerin doğru şekilde kapatılmasına dair yüzden fazla örnek olacaktır, ancak bu, tüm şubelerin hemen yeniden adlandırılması gerektiği anlamına gelmez. Yeterince kahraman var.
 
valenok2003 :

Hata şu şekildeydi:

bool _Result değişkeni başlatılmadı, bu, orada false olacağı anlamına gelir, bu nedenle, koşulların hiçbiri karşılanmadığından, _Result değişkenini değiştirmedik ve zaten false içeriyor. Ve işlev, gerçekten var olmayan hataları işlemeye devam eder.

Fonksiyonu düzelttim ve buraya gönderdim, birilerinin işine yarayacağını düşünüyorum.

PS Moderatörleri . Böyle bir şube tesadüfen ortaya çıktı - siparişlerin doğru şekilde kapatılmasıyla ilgili hazır bir eğitim. Belki yeniden adlandırmaya değer, örneğin - ayrıştırma örnekleriyle siparişler nasıl doğru bir şekilde kapatılır?

PPS Katılan herkese çok TEŞEKKÜR EDERİZ . Belki daha fazla soru olacaktır.

IMHO: İşlevin mantığıyla anlaşılmaz olduğu ortaya çıktı. Bir testçi için, o zaman çok fazla gereksizse, eğer gerçekse, o zaman hataları ele almaya değer. Döndürülen değerin hiçbir anlamı yoktur - dış düzeye (çağrı düzeyine) çağrının bir hatayla sona erdiğini, hatanın kendisini kaybederken, günlüğe yazdığını bildirirsiniz - uzman ne düşünüyor?

Nasıl daha doğru olurdu: (yine IMHO)

1. Hata numarasını okuyun ve saklayın.

2. Hataları kurtarılabilir ve kurtarılamaz olarak ayırın. Bunu yapmak için bir işleyici yapın - siparişin hala kapatılabilmesi durumunda (meşgul iş parçacığı, bağlantı kesilmesi ... vb.) Bu hatalar hemen işlenir. Bunu yaptım (önce kurtarılamaz, sonra ne "düzeltilebilir"):

 #define MAXCYKLESCNT 20

int ErrReaction( int err)
{
     switch (err)
    {
         case ERR_TRADE_NOT_ALLOWED    :
                 Print ( "TRADE NOT ALLOWED ! SWITCH ON option \' Allow live trading\' (Необходимо включить опцию \'Разрешить советнику торговать\')" );
         case ERR_INVALID_FUNCTION_PARAMSCNT :    
         case ERR_INVALID_FUNCTION_PARAMVALUE :    
         case ERR_INVALID_STOPS        : 
         case ERR_INVALID_TRADE_VOLUME : 
         case ERR_MARKET_CLOSED        : 
         case ERR_TRADE_DISABLED       : 
         case ERR_NOT_ENOUGH_MONEY     : 
                 return (-err);
         case ERR_NO_CONNECTION        :
                 ReScanServers();
         case ERR_BROKER_BUSY          : 
         case ERR_TRADE_CONTEXT_BUSY   : 
        case ERR_ORDER_LOCKED         :
                 int n= 0 ;
                 while ((!IsTradeAllowed())&&(n< 20 )){ Sleep ( 500 );n++;}
         case ERR_PRICE_CHANGED : 
         case ERR_OFF_QUOTES    : 
         case ERR_REQUOTE       : 
                 RefreshRates();
                 break ;
         default : break ;
    } //switch(err)
     return ( 0 );
} //int ErrReaction(int err)

3. Önemli bir hata olması durumunda, bu durumun harici modülde ele alınabilmesi için hata bayrağını değil, numarasını döndürün. İşlemin sonucunu analiz ederken:

 bool res    = false;
int   ncykls =     0 ;

     while ((!res)&&(ncykls<MAXCYKLESCNT))
    {
        res = ...............
         if (!res)
        { 
            ncykls++;
            err= GetLastError ();
             Print (ncykls, " Err(" ,err, ") : " ,ErrorDescription(err)); 
            err_res = ErrReaction(err); 
            if (err_res< 0 ) return (err_res);
        } 
    } //while((!res)&&(ncykls<MAXCYKLESCNT))

İyi şanlar.

mola/devam hakkında not

 if ( ! OrderSelect (i,SELECT_BY_POS,MODE_TRADES) ) break ;     // No more Orders
soru muamma. Hala siparişler varsa, al/durdur tetiklendiğinde, siparişlerin numaralandırması değişecektir - yani, sipariş yine seçilecektir: bilete göre değil, seri numarasına göre seçersiniz. Sipariş seçilmemişse sipariş yok demektir. Her seferinde sipariş sayısını kontrol etmediğiniz için, döngüyü birkaç kez boşta olacak şekilde çalıştırın.