MQL5의 OOP에 대한 질문 - 페이지 17

 
너 때문에 놀랐다.
 
의미는 형식이 아니라 의미입니다.
 
fxsaber :

CList 레코드 형식을 살펴보십시오. 당신은 그를 무시하고 있습니다.

바로 그거죠! 감사합니다 더 알아보겠습니다

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

"만세! 벌었다!" (와 함께)

 #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 템플릿 자체를 첨부했습니다. 제 생각에는 편리할 것입니다. 내 것과 유사하게 모든 구조(클래스)를 만들고 메모리( 매개변수 없는 생성자 )에 데이터를 저장하거나 새 요소가 생성될 때 디스크에 덤프하도록 했습니다. 추가됨( 매개변수가 있는 생성자 )

추신: 다른 작업을 완료할 수도 있지만 일반적으로 결과가 저에게 적합합니다.

파일:
CDataBase.mqh  10 kb
 

나는 const와 static modifier를 거의 사용하지 않으며 실수로 클래스를 함수 본문에 "붙여넣기"하려고 했습니다. 그들은 어떻게 작동하는지조차 모릅니다. 그러나 테스트 중에 오류를 찾지 못했습니다.

 #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 ));
  }
//+------------------------------------------------------------------+

특별히 이동된 SymbolInfoDouble() 호출은 출력을 위해 f1()-f3() 함수를 분리합니다.


글쎄요, 문제 자체는 코드가 얼마나 효율적인지, 어디에 버그가 있을 수 있습니까? , 불필요한 호출을 최소화하고 싶지만 클래스는 함수 내부에서 어떻게든 작동합니다. 일반적으로 작동하지만 저에게는 그렇게 작동해서는 안됩니다!

 
Igor Makanu :

나는 const와 static modifier를 거의 사용하지 않으며 실수로 클래스를 함수 본문에 "붙여넣기"하려고 했습니다. 그들은 어떻게 작동하는지조차 모릅니다. 그러나 테스트 중에 오류를 찾지 못했습니다.

특별히 이동된 SymbolInfoDouble() 호출은 출력을 위해 f1()-f3() 함수를 분리합니다.


글쎄요, 문제 자체는 코드가 얼마나 효율적인지, 어디에 버그가 있을 수 있습니까? , 불필요한 호출을 최소화하고 싶지만 클래스는 함수 내부에서 어떻게든 작동합니다. 일반적으로 작동하지만 저에게는 그렇게 작동해서는 안됩니다!

모든 것이 정상입니다. 작동합니다.

 
Vladimir Simakov :

모든 것이 정상입니다. 작동합니다.

고맙습니다!

테스트 jxpert의 코드에서 테스트되었으며 버그가 없었으며 TF가 차트에서 전문가를 전환하고 언로드했으며 의도한 대로 작동하며 const 정적 수정자가 있는 모든 변수가 한 번 초기화됩니다(또한 초기화가 흥미롭다는 점에서 흥미롭습니다. OnItin() 시작 전 - 모든 호출을 인쇄하지 않음)

코드를 정리했습니다. 누군가가 반올림하여 주문량을 정규화하는 것이 유용할 것입니다( 다중 통화 전문가 고문 에게는 작동하지 않습니다!!! )

 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_);
  }

적어두셔도 됩니다. 의미는 동일하며 글자가 적습니다. 컴파일러는 l_ 변수 자체를 제거합니다.

 
Vladimir Simakov :

적어두셔도 됩니다. 의미는 동일하며 글자가 적습니다. 컴파일러는 l_ 변수 자체를 제거합니다.

나는 방금 내 게시물을 썼고 여기에 당신이 있습니다 ... 제 생각에는 코드가 거의 일대일입니다))) 아래에 L_ 변수가 필요합니다. 이것은 주문을위한 코드의 일부입니다. 빗질하기로 결정했습니다. 내 도서관

추신: 확인했지만 vol 클래스의 인스턴스에 대한 const 수정자를 생략할 수 있습니다 ... 더 적은 글자 수)))

 
   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);}

부지에 있는 표지판의 수와 부지 자체의 크기를 찾습니다.

 
Vladimir Simakov :


부지에 있는 표지판의 수와 부지 자체의 크기를 찾습니다.

비슷한 솔루션을 보았지만 내 _OrderSend(....) 함수는 절차적 스타일을 위한 것이며 기본 EA가 사용하기에 항상 편리한 OOP는 아닙니다.

그래서 먼저 SymbolInfoDouble() 에 대한 최소 호출 횟수를 결정한 다음 문제가 발생하여 NormalizeVolume()에 대한 추가 호출을 제거하기로 결정했습니다. 본문에 _OrderSend()를 포함하려고 했지만 목표는 전체 거래 환경을 한 번 수신 한 다음 주문을 열 때 주문의 양만 고려하고,

나는 일반적으로 테스트하고 결과에 만족합니다. 버그를 찾으면 주제에 쓸 것입니다.