MQL5'te OOP hakkında sorular - sayfa 17

 
Beni korkutuyorsun.
 
Anlam, biçim değil, anlam.
 
fxsaber :

CList kayıt formatına bakın. Onu görmezden geliyorsun.

kesinlikle! teşekkürler, daha fazla inceleyeceğim

...................

"Yaşasın! Kazanıldı!" (İLE)

 #include <IgorM\CDataBase.mqh>
//+------------------------------------------------------------------+
class COrderBase : public CObject
  {
public : COrderBase(){};
   //-------------------------------------
   int                OrderTicket;
   double             OrderLots;
   string             OrderComment;
                     COrderBase( int ival, double dval);
   virtual bool       Save( const int file_handle);
   virtual bool       Load( const int file_handle);
  };
//+------------------------------------------------------------------+
void COrderBase::COrderBase( int ival, double dval)
  {
   this .OrderTicket=ival;
   this .OrderLots=dval;
   OrderComment= "qwerty_" + IntegerToString (ival, 2 );
  }
//|                                                                  |
//+------------------------------------------------------------------+
bool COrderBase::Save( const int file_handle)
  {
   uint len= StringLen (OrderComment);
   return (:: FileWriteInteger (file_handle, this .OrderTicket) &&
          :: FileWriteDouble   (file_handle, this .OrderLots)   &&
          :: FileWriteInteger ( file_handle,len, INT_VALUE )    &&
          (len> 0 ? :: FileWriteString (file_handle,OrderComment,len)==len : true )
          );
  }
//-------------------------------------
bool COrderBase::Load( const int file_handle)
  {
   :: ResetLastError ();
   this .OrderTicket=:: FileReadInteger (file_handle);
   this .OrderLots=:: FileReadDouble (file_handle);
   uint len= FileReadInteger (file_handle, INT_VALUE );
   this .OrderComment=len> 0 ? FileReadString (file_handle,len) : "" ;
   return (!:: GetLastError ());
  }
//+------------------------------------------------------------------+
void OnStart ()
  {
   int i;
   CDataBase<COrderBase>data( 31 );
   for (i= 0 ; i< 5 ; i++) data.AddValue( new COrderBase(i,i* 2.0 ));     // сюда вообще только тикет ордера нужно передавать!!!
   Print ( "1. Тип БД : " ,data.TypeName(), " , количествоо записей = " ,data. ArraySize (), ",  чтение данных :" );
   for (i= 0 ; i<data. ArraySize (); i++) Print (i, " : " ,data[i].OrderTicket, " , " ,data[i].OrderLots, "," ,data[i].OrderComment);
  }
//+------------------------------------------------------------------+
//2019.07.09 17:26:14.829	tst_CDataBase (EURUSD,H1)	1. Тип БД : COrderBase , количествоо записей = 5,  чтение данных :
//2019.07.09 17:26:14.829	tst_CDataBase (EURUSD,H1)	0 : 0 , 0.0,qwerty_ 0
//2019.07.09 17:26:14.829	tst_CDataBase (EURUSD,H1)	1 : 1 , 2.0,qwerty_ 1
//2019.07.09 17:26:14.829	tst_CDataBase (EURUSD,H1)	2 : 2 , 4.0,qwerty_ 2
//2019.07.09 17:26:14.829	tst_CDataBase (EURUSD,H1)	3 : 3 , 6.0,qwerty_ 3
//2019.07.09 17:26:14.829	tst_CDataBase (EURUSD,H1)	4 : 4 , 8.0,qwerty_ 4

CDataBase şablonunun kendisini ekledim, bence uygun olacak - benimkine benzeterek herhangi bir yapı (sınıf) oluşturdum ve verileri bellekte ( parametresiz bir kurucu ) depolamasına veya yeni bir öğe olduğunda diske atmasına izin verdim eklendi ( parametreli bir kurucu )

Not: belki başka bir şey bitiririm ama genel olarak sonuç bana uyuyor

Dosyalar:
CDataBase.mqh  10 kb
 

Nadiren const ve static değiştiricileri kullanırım ve ayrıca işlevin gövdesine yanlışlıkla bir sınıfı "yapıştırmaya" çalıştım, nasıl çalıştığını bile bilmiyorlar, ancak test sırasında herhangi bir hata bulamadım

 #property strict
//+------------------------------------------------------------------+
void OnStart ()
  {
   double lot= 0.0 ;
   for ( int i= 0 ;i< 50 ; i++)
     {
       Print (lot, " = " ,_OrderSend(lot));
      lot+= 0.003 ;
     }
  }
//+------------------------------------------------------------------+
double _OrderSend( double lot_)
  {
   class CDig
     {
   public :
                        CDig( double vs){ long i= 10000000 ,k= long (vs/ 0.0000001 );dig= 0 ; while (dig< 7 && k%i> 0 ){i/= 10 ;dig++;} Print ( __FUNCSIG__ );}
       int                dig;
     };
   const static double vol_step_= f1();
   const static double vol_max_ = f2();
   const static double vol_min_ = f3();
   const static CDig ld_(vol_step_);
   const static int vol_dig_=ld_.dig;
   double l_= NormalizeDouble ( fmax ( fmin (vol_step_* round (lot_/vol_step_),vol_max_),vol_min_),vol_dig_);
   return (l_);
  }
//+------------------------------------------------------------------+
double f1()
  {
   Print ( __FUNCSIG__ );
   return ( SymbolInfoDouble ( _Symbol , SYMBOL_VOLUME_STEP ));
  }
//+------------------------------------------------------------------+
double f2()
  {
   Print ( __FUNCSIG__ );
   return ( SymbolInfoDouble ( _Symbol , SYMBOL_VOLUME_MAX ));
  }
//+------------------------------------------------------------------+
double f3()
  {
   Print ( __FUNCSIG__ );
   return ( SymbolInfoDouble ( _Symbol , SYMBOL_VOLUME_MIN ));
  }
//+------------------------------------------------------------------+

özel olarak taşınmış SymbolInfoDouble(), çıktı almak için f1()-f3() işlevlerini ayırmak için çağrılar yapar


Sorun şu ki, bu kod ne kadar verimli, nerede hatalar olabilir? , Gereksiz aramaları en aza indirmek istiyorum, ancak sınıf bir şekilde işlevin içinde çalışıyor, genel olarak çalışıyor, ama benim için böyle çalışmamalı!

 
Igor Makanu :

Nadiren const ve static değiştiricileri kullanırım ve ayrıca işlevin gövdesine yanlışlıkla bir sınıfı "yapıştırmaya" çalıştım, nasıl çalıştığını bile bilmiyorlar, ancak test sırasında herhangi bir hata bulamadım

özel olarak taşınmış SymbolInfoDouble(), çıktı almak için f1()-f3() işlevlerini ayırmak için çağrılar yapar


Sorun şu ki, kod ne kadar verimli, nerede hatalar olabilir? , Gereksiz aramaları en aza indirmek istiyorum, ancak sınıf bir şekilde işlevin içinde çalışıyor, genel olarak çalışıyor, ama benim için böyle çalışmamalı!

Herşey yolunda. Çalışacak.

 
Vladimir Simakov :

Herşey yolunda. Çalışacak.

Teşekkür ederim!

test jxpert kodunda test edildi, herhangi bir hata görmedi ve TF uzmanı değiştirip grafikten çıkardı, amaçlandığı gibi çalışıyor, const statik değiştiricili tüm değişkenler bir kez başlatıldı (ayrıca, başlatmanın ilginç olması ilginçtir) OnItin() başlatılmadan önce - tüm çağrılar yazdırılmaz)

kodu temizledim, belki birisinin bir siparişin hacmini yuvarlama ile normalleştirmesi faydalı olabilir ( çok para birimli Uzman Danışmanlar için çalışmaz !!! )

 double _OrderSend2( double lot_)
  {
   const static double vol_step_= SymbolInfoDouble ( _Symbol , SYMBOL_VOLUME_STEP );
   const static double vol_max_ = SymbolInfoDouble ( _Symbol , SYMBOL_VOLUME_MAX );
   const static double vol_min_ = SymbolInfoDouble ( _Symbol , SYMBOL_VOLUME_MIN );
   static class CDig{ public : int digits( double v){ long i= 10000000 ,k= long (v/ 0.0000001 ); int d= 0 ; while (d< 7 && k%i> 0 ){i/= 10 ;d++;} return (d);}}vol;
   const static int vol_dig_=vol.digits(vol_step_);
   double l_= NormalizeDouble ( fmax ( fmin (vol_step_* round (lot_/vol_step_),vol_max_),vol_min_),vol_dig_);
// еуе код открытия ордера
   return (l_);
  }
 
double _OrderSend( double lot_)
  {
   const static double vol_step_= f1();
   const static double vol_max_ = f2();
   const static double vol_min_ = f3();
   const static class CDig
     {
   public :
                        CDig( double vs){ long i= 10000000 ,k= long (vs/ 0.0000001 );dig= 0 ; while (dig< 7 && k%i> 0 ){i/= 10 ;dig++;} Print ( __FUNCSIG__ );}
       int                dig;
     } ld_(vol_step_);
   const static int vol_dig_=ld_.dig;
   return NormalizeDouble ( fmax ( fmin (vol_step_* round (lot_/vol_step_),vol_max_),vol_min_),vol_dig_);
  }

Onu da yazabilirsiniz. Anlam aynı, daha az harf. Derleyici, l_ değişkeninin kendisini kaldıracaktır.

 
Vladimir Simakov :

Onu da yazabilirsiniz. Anlam aynı, daha az harf. Derleyici, l_ değişkeninin kendisini kaldıracaktır.

Ben sadece yazımı yazdım ve işte buradasın ... bence kodlar neredeyse bire bir))), L_ değişkeni aşağıda gerekli, bu sipariş vermek için kodun bir parçası, taramaya karar verdim benim kutuphanem

Not: Kontrol ettim, ancak vol sınıfının bir örneğinin const değiştiricisi atlanabilir ... daha az harf)))

 
   lotDigits= MathMax (-( int ) MathFloor ( MathLog10 (lotStep)), 0 );


double CBaseTrade::NormalizeVolume( double mVolume, bool mMinIsAlways= true ){
   double x= MathPow ( 10 ,_lotDigits);
   mVolume= MathFloor ( MathRound (mVolume*x)/_lotStep/x)*_lotStep;
   if (mVolume<_lotMin) return mMinIsAlways?_lotMin: 0.0 ;
   if (mVolume>_lotMax) return _lotMax;
   return NormalizeDouble (mVolume,_lotDigits);}

Partideki işaretlerin sayısını ve partinin büyüklüğünü bulmak için.

 
Vladimir Simakov :


Partideki işaretlerin sayısını ve partinin büyüklüğünü bulmak için.

Benzer çözümler gördüm, ancak _OrderSend(....) işlevim prosedürel stil içindir, ilkel EA'ların kullanması için her zaman uygun OOP değildir,

bu yüzden önce SymbolInfoDouble() öğesine minimum sayıda çağrı yapmaya karar verdim ve sonra bir şeyler ters gitti ve NormalizeVolume() öğesine yapılan ek çağrıdan kurtulmaya karar verdim - gövdeye _OrderSend() öğesini dahil etmeye çalıştım, ancak amaç tüm işlem ortamını bir kez almak ve ardından bir emir açarken sadece emrin hacmini dikkate almak,

Test edeceğim genel olarak sonuçtan memnunum bug bulursam konuya yazarım

Neden: