mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 229

 

영어(원문): MQL 언어 기능 요청을 하고 싶습니다. 이 스레드가 올바른 스레드가 아닌 경우 알려주세요. 원래 요청은 영어 포럼에 있습니다...

러시아어(Google 번역): MQL 언어 기능 요청을 하고 싶습니다. 이 스레드가 올바른 스레드가 아니라면 알려주세요. 원래 요청은 영어 포럼에 있습니다...

 

배열을줄로 채우는 방법은 무엇인가요?

struct clr_struct{
   color uncheck;
};
clr_struct clr[];

//clr[0].uncheck=0x999999;
//clr[1].uncheck=0x999999;

clr[].uncheck={0x999999,0x999999};//как правильно?
 
Pavel Kolchin 배열을 한 줄로 채우는 방법은 무엇인가요?
clr_struct clr[] = {{0x999999}, {0x999999}};
 

액세스 권한에 대한 또 하나의 라이프핵입니다: 한 클래스의 비공개 필드/함수에 대한 액세스 권한을 다른 클래스에게 부여하고 싶은 경우 표준 MQL 도구를 사용하여 다음과 같이 할 수 있습니다:

B에서 A::f1()에 액세스해야 합니다.

//--------- как было
class   A
  {
   int               m;
   int               f1() {return m;}                       // нужно дать к нему доступ классу B
public:
                     A(int a): m(a) {}
  };

class B {};

다음과 같이 다시 작성해 보겠습니다:

class A;
class B
  {
private:
   class AB
     {
   public:
      virtual int    CallAf1(A&) const  = 0;
                     AB() {ABptr = &this;}
     } static *ABptr;

   // внутри B используем  этот метод для получения доступа к A::f1()
   static int        CallAf1(A & obj)
     {
      return ABptr.CallAf1(obj);
     }

public:
   class AB2: AB {};

   // вспомогательный метод - только для проверки
   static void       _f1_test(A & obj)
     {
      Print("test ", CallAf1(obj));
     }
  };
B::AB *B::ABptr = NULL;

class   A
  {
   int               m;
   int               f1() {return m;}
public:
                     A(int a): m(a) {}

   //--  добавлено
private:
   class AB3: B::AB2
     {
      int            CallAf1(A &obj) const {return obj.f1();}
     }   static  const     ABlink;
  };
const A::AB3 A::ABlink;

B 내에서 (A)a.f1()을 호출하려면 CallAf1(a)를 호출합니다. f1()에 매개변수가 있는 경우 CallAf1()에 매개변수를 추가합니다.

테스트:

void OnStart()
  {
    A f(2);
    B::_f1_test(f);
  }

CallAf1()을 보호할 수는 있지만, 코드의 어느 곳에서나 B 클래스의 하위 클래스를 만들고 그 안에 CallAf1()을 호출하는 공용 메서드를 만들 수 있으므로 접근 권한에 큰 구멍이 생기게 됩니다 - 즉, 모든 사람이 A::f1()에 접근할 수 있게 됩니다.


추신 이 구조는 매우 번거롭지만(원한다면 매크로에 넣을 수 있습니다), 친구 C++에 비해 한 가지 장점이 있습니다: 모든 클래스 멤버가 아니라 선택한 멤버에게만 액세스 권한을 부여한다는 점입니다.

 
mktr8591 #:

액세스 권한에 대한 또 하나의 라이프핵입니다: 한 클래스의 비공개 필드/함수에 대한 액세스 권한을 다른 클래스에 부여하고 싶은 경우, 표준 MQL 도구를 사용하여 이를 수행할 수 있습니다.

그것에 들어가는 데 오랜 시간이 걸렸습니다... 가상화에 대한 좋은 움직임, 감사합니다!
 
fxsaber #:
오랜 시간이 걸렸습니다... 가상화에 대한 좋은 움직임, 감사합니다!
내가 처음에 쓰지 않은 유일한 것은 B::AB2 클래스 (및 그 자손)의 객체를 더 이상 만들 수 없다는 것입니다. 그렇지 않으면 모든 것이 무너질 것입니다 :-)
 
테스터에서 이 전문가용 어드바이저를 모든 종목 모드에서 실행하면
input int inTmp = 0; // https://www.mql5.com/ru/forum/321656/page90#comment_44727856

bool Res = true;

// Проверяет, нормализована ли цена по алгоритму NormalizeDouble.
bool IsNDPrice( const double &Price )
{
  return(Price == NormalizeDouble(Price, 5));
}

// Проверяет, нормализована ли цена, как при парсинге или ручном вводе.
bool IsNDPrice2( const double &Price )
{
  return(Price == (double)DoubleToString(Price, 5));
}

void OnTick()
{
  MqlTick Tick;
  
  if (SymbolInfoTick(_Symbol, Tick))
//    Res &= IsNDPrice(Tick.bid) && IsNDPrice(Tick.ask); // OnTester == 1.
    Res &= IsNDPrice2(Tick.bid) && IsNDPrice2(Tick.ask); // OnTester == 0.
}

double OnTester()
{
  return(Res);
}
를 실행하면 모든 가격이 NormalizeDouble 알고리즘을 사용해 정규화된 것을 확인할 수 있습니다. 터미널이 아닌 파싱 또는 수동 입력을 통해 얻은 가격으로 작업하는 경우 올바른 작동을 위해 정규화가 필요합니다. 착각할 필요가 없습니다.
 

이유_계정이 변경되지 않고 재로그인만 완료된 경우에도 Expert Advisor가 완전히 언로드되고 새 사본이 로드됩니다 .

따라서 OnDeinit의 ExpertRemove는 언로드된 복사본을 건드리기 때문에 새 복사본에는 영향을 미치지 않습니다.

void OnInit() { Print(__FUNCSIG__); }

void OnDeinit( const int ) { Print(__FUNCSIG__); }


재로그인 후 결과.

2023.02.07 11:33:12.717 Test5-3 (EURUSD,M1)     void OnDeinit(const int)
2023.02.07 11:33:13.926 Test5-3 (EURUSD,M1)     void OnInit()


Deinit 후 새 EA 복사본이 시작될 때까지 1초 이상(최대 2초) 대기합니다. 이렇게 오래 기다리는 이유는 무엇이며 속도를 높일 수 있나요?

 

SymbolInfoTick은이 세 번의 호출 각각에서 최신 틱을 반환합니다. 즉, 지표를 건너 뛰지 않고 소위 틱을 수집하는 것은 가볍게 말하면 의심 스럽습니다.


지표로 틱을 수집 할 수 없다는 증거 (건너 뛰지 않음).

// Аналог Sleep для индикатора.
void Sleep2( const uint Pause )
{
  const uint StartTime = GetTickCount();
  
  while (!IsStopped() && (GetTickCount() - StartTime) < Pause)
    ;
}

#define  TOSTRING(A) #A + " = " + (string)(A) + " "

int OnCalculate( const int rates_total,
                 const int,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[] )
{  
  static const int period = PeriodSeconds();
  
  Sleep2(1000); // Расчеты.
  
  MqlTick Tick[1];
  
  if (SymbolInfoTick(_Symbol, Tick[0]) &&
      ((Tick[0].bid != close[rates_total - 1]) || // Свежий бар не соответсвует последнему тику.
       Tick[0].time / period > time[rates_total - 1] / period))
  {
    ArrayPrint(Tick);
    Print(TOSTRING(time[rates_total - 1]) + TOSTRING(close[rates_total - 1]));
  }

  return(rates_total);
}


결과.

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:39 1.54951 1.54959 0.0000        0 1675787319322      98       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.5495 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:40 1.54948 1.54959 0.0000        0 1675787320719      98       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.5495 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:41 1.54952 1.54960 0.0000        0 1675787321823     100       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54954 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:42 1.54954 1.54961 0.0000        0 1675787322223     102       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54951 00000000002 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:43 1.54955 1.54964 0.0000        0 1675787323721     100       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54948 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:44 1.54954 1.54962 0.0000        0 1675787324323     100       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54952 

                 [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2023.02.07 16:28:45 1.54956 1.54962 0.0000        0 1675787325421     102       0.00000
time[rates_total-1] = 2023.02.07 16:28:00 close[rates_total-1] = 1.54952
 
가능한 MQL5 언어 구조 중 하나입니다.

트레이딩, 자동매매 시스템 및 트레이딩 전략 테스트 포럼

오류, 버그, 질문

fxsaber, 2023.02.14 13:11

input string inStr = "B2";

class A {};

class B1 : public A {};
class B2 : public A {};
// .....
class B100 : public A {};

void OnStart()
{
  A* a = New2(inStr); // создает объект, который прописан в inStr.
}

// Решение.
template <typename T>
A* New( const string &ClassName ) { return((typename(T) == ClassName) ? new T : NULL); }

typedef A* (*TNew)( const string& );
static const TNew FuncNew[] = {New<B1>, New<B2>, /*....,*/ New<B100>};

A* New2( string ClassName )
{  
  A* Res = NULL;
  
  ClassName = "class " + ClassName;
  
  for (int i = ArraySize(FuncNew) - 1; !Res && (i >= 0); i--)
    Res = FuncNew[i](ClassName);  
    
  return(Res);
}

안타깝게도 MQL4는 아직 이런 종류의 작업을 지원하지 않습니다.