Fragen zu OOP in MQL5 - Seite 17

 
Du machst mir Angst.
 
Es geht nicht um die Form, sondern um die Bedeutung.
 
fxsaber:

Sehen Sie sich das CList-Datensatzformat an. Sie ignorieren es.

Richtig! Danke, ich werde mich weiter damit befassen.

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

Ich denke: "Juhu, es klappt!" (С)

#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

Ich habe die CDataBase-Vorlage selbst angehängt, wäre es bequem - jede Struktur (Klasse) erstellt wie meine und lassen Sie es entweder Daten im Speicher(Konstruktor ohne Parameter) oder beim Hinzufügen eines neuen Elements, dump es auf Festplatte(Konstruktor mit Parameter)

SZZ: wahrscheinlich werde ich noch etwas dopen, aber im Allgemeinen bin ich mit dem Ergebnis zufrieden.

Dateien:
CDataBase.mqh  10 kb
 

Ich benutze selten const und statische Modifikatoren, und ich habe versehentlich versucht, "Plug" eine Klasse in Funktion Körper, habe keine Ahnung, wie es funktioniert, aber ich fand keinen Fehler beim Testen

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

Ich habe die Aufrufe von SymbolInfoDouble() absichtlich in die separaten Funktionen f1()-f3() ausgelagert, um sie nicht zu drucken


Und die Frage selbst, wie viel von diesem Code funktioniert, wo können Bugs sein? Ich möchte unnötige Aufrufe minimieren, aber die Klasse funktioniert irgendwie innerhalb der Funktion, im Allgemeinen funktioniert es, aber für mich sollte es nicht funktionieren!

 
Igor Makanu:

Ich benutze selten const und statische Modifikatoren, und ich habe versehentlich versucht, "Plug" eine Klasse in Funktion Körper, habe keine Ahnung, wie es funktioniert, aber ich fand keinen Fehler beim Testen

Ich habe die Aufrufe von SymbolInfoDouble() absichtlich in die separaten Funktionen f1()-f3() ausgelagert, um sie nicht zu drucken


Und die Frage selbst, wie viel von diesem Code funktioniert, wo können Bugs sein? Ich möchte unnötige Aufrufe minimieren, aber die Klasse funktioniert irgendwie innerhalb der Funktion, im Allgemeinen funktioniert es, aber für mich sollte es nicht funktionieren!

Das ist in Ordnung. Es wird funktionieren.

 
Vladimir Simakov:

Das ist in Ordnung. Es wird funktionieren.

Ich danke Ihnen!

Ich habe im Code des Test-EAs getestet, ich habe keine Bugs gesehen, ich habe TFs verschoben und EA aus dem Chart entladen, es funktioniert wie erwartet, alle Variablen mit const statischen Modifikator werden einmal initialisiert (es ist interessant, dass die Initialisierung vor dem Start von OnItin() erfolgt - ich habe alle Aufrufe unsigniert)

Ich habe den Code verbessert, vielleicht braucht jemand eine Normalisierung des Ordervolumens mit Rundung(funktioniert nicht bei Expert Advisors mit mehreren Währungen!!!)

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

Man könnte es auch so schreiben. Die Bedeutung ist die gleiche, aber es gibt weniger Buchstaben. Die Variable l_ wird vom Compiler entfernt.

 
Vladimir Simakov:

Sie können es auch so schreiben. Der Sinn ist der gleiche, aber es gibt weniger Buchstaben. Der Compiler wird die Variable l_ selbst entfernen.

Ich habe gerade meinen Beitrag geschrieben, und hier sind Sie... Ich glaube, die Codes sind fast identisch )))) Die L_-Variable wird unten benötigt, sie ist Teil des Codes für die Bestellung, ich habe beschlossen, meine Bibliothek aufzuräumen

SZZ: Ich habe es überprüft, aber der Modifikator const für eine Instanz der Klasse vol darf nicht geschrieben werden... weniger Buchstaben ))))

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

Zur Ermittlung der Anzahl der Zeichen in einer Partie und der Partiegröße selbst.

 
Vladimir Simakov:


Zur Ermittlung der Anzahl der Zeichen in einer Partie und der Partiegröße selbst.

Ich habe ähnliche Lösungen gesehen, aber meine Funktion _OrderSend(....) ist für prozeduralen Stil, nicht immer bequem, OOP für primitive EAs zu verwenden,

Ich beschloss, eine minimale Anzahl von AufrufenSymbolInfoDouble() auf den ersten zu machen, und dann habe ich beschlossen, loszuwerden zusätzlichen Aufruf NormalizeVolume() - Ich habe versucht, _OrderSend() in den Körper, aber der Zweck war es, alle Handelsumgebung einmal zu erhalten und dann, wenn eine Bestellung öffnet, zu lesen, sein Volumen nur,

Ich werde es versuchen, und im Allgemeinen bin ich mit dem Ergebnis zufrieden, wenn ich irgendwelche Fehler finden, werde ich sie in dem Thema berichten

Grund der Beschwerde: