초보자의 질문 MQL4 MT4 MetaTrader 4 - 페이지 137

 
Игорь Васильев :

컴파일러가 표시기 코드에서 거래 명령을 볼 때 이것을 보고하지 않는 이유는 이상합니다.

이제 ICustom()을 통해 연결하여 표시기에서 Expert Advisor로 거래 부분을 가져와야 합니다.

"암말 꼬리와 활 옆구리를 꿰매지 마십시오"와 같습니다.

컴파일러는 구문만 확인합니다. 결과 프로그램이 어떻게 작동할지(또는 작동하지 않을지) 결정하는 것은 그의 일이 아닙니다. 거래 명령의 작동 불능은 프로그램 실행 단계에서만 명확해질 수 있습니다. 즉, 런타임 오류 가 수신됩니다.

 

안녕하세요! 다음을 수행할 수 있는지 알려주십시오.

다음과 같은 구조가 있습니다.
// 일부 이벤트의 구조
구조체 MyStruct
{
정수 번호;
날짜/시간DTm;
이중 값;
문자열 유형;
}

MyStruct 유형 의 동적 구조 배열 을 선언합니다.
MyStructDataEvents[];

특정 함수에서 배열을 형성하고 채웁니다. 예를 들면 다음과 같습니다.
무효 GetDataEventsTest(MyStruct& DataEvents[], int countEvent=5)
{
MathSrand(GetTickCount());
ArrayResize(데이터 이벤트, countEvent);
정수 i = 0;
동안(i<countEvent)
{
DataEvents.Number = 나;
DataEvents.DTm = TimeCurrent();
DataEvents.Value = (더블) MathRand();
if( MathMod(i, 2)>0 ) DataEvents.Type = "위쪽"; else DataEvents.Type = "Dn";
나는 = 나는 + 1;
}
}

어딘가에서 GetDataEventsTest()를 호출하여 배열을 채웁니다.
GetDataEventsTest(데이터 이벤트);

예를 들어 배열 요소 범위의 중간인 인덱스 2 어딘가에 MyStruct 유형의 새 요소를 삽입해야 할 필요가 있었습니다.
논리는 다음 작업을 제안합니다.
ArrayResize(DataEvents, ArraySize(DataEvents)+1);
그리고 다음과 같은 것:
정수 iNew = 2;
정수 i = ArraySize(데이터 이벤트) - 2;
동안(i>=iNew)
{
// 데이터 이벤트[i+1] = 데이터 이벤트[i]; // 배열 요소가 가리키는 주소로 작업해야 하므로 당연히 작동하지 않습니다.
// 배열 요소를 DataEvents[i+1]로 쓰기 = 배열 요소를 가리키도록 쓰기 DataEvents[i];
나는 = 나는 - 1;
}
... 그런 다음 DataEvents[iNew] 배열 요소를 데이터로 채웁니다.


문제는 mql4의 구조로 이 작업을 수행할 수 있다는 것입니다.

 
GitSM :

문제는 mql4의 구조로 이를 수행할 수 있다는 것입니다.

예, 가능합니다. 구조에 복잡한 데이터 유형이 없으면(여기서는 문자열이 포함됨) 모든 것이 즉시 작동합니다. 그리고 구조에 데이터 유형이 있고 시간이 지남에 따라 데이터 크기가 변경될 수 있는 경우 할당 연산자를 오버로드해야 합니다.

 struct MyStruct
{
     int Number;
     datetime DTm;
     double Value;
     string Type;

     void operator = ( const MyStruct &stMyStruct)
    {
      Number = stMystruct.Number;
      DTm = stMyStruct.DTm;
      Value = stMyStruct.Value;
      Type = stMyStruct.Type;
    }
}
 
Ihor Herasko :

네, 가능합니다. 구조에 복잡한 데이터 유형이 없으면(여기서는 문자열이 포함됨) 모든 것이 즉시 작동합니다. 그리고 구조에 데이터 유형이 있고 시간이 지남에 따라 데이터 크기가 변경될 수 있는 경우 할당 연산자를 오버로드해야 합니다.

팁 고마워!
 

다시 이전 예와 같은 방향으로 질문이 제기되었습니다.
구조가 복잡하고 다른 구조의 배열을 포함할 수 있는 경우. 예를 들어 다음과 같이 선언합니다.

// 속성이 있는 요소
항목 속성 구조
{
이중 낮음;
더블 하이;
이중 중간;
이중 범위;
이중 영역;
문자열 유형;

무효 연산자 = (const ItemProperty &SourceItemProperty)
{
낮음 = SourceItemProperty.Low;
높음 = SourceItemProperty.High;
중간 = SourceItemProperty.Middle;
범위 = SourceItemProperty.Range;
영역 = SourceItemProperty.Area;
유형 = SourceItemProperty.Type;
}
}

// 통계적 속성을 가진 요소
항목 속성을 구성합니다.
{
이중 최소값;
더블 MaxHigh;
이중 평균 범위;
이중 평균 면적;
문자열 위상;

아이템 아이템[];

무효 연산자 = (const ItemProperty &SourceItemsProperty)
{
MinLow = SourceItemsProperty.MinLow;
MaxHigh = SourceItemsProperty.MaxHigh;
AvgRange = SourceItemsProperty.AvgRange;
AvgArea = SourceItemsProperty.AvgArea;
단계 = SourceItemsProperty.Phase;

// 항목 = SourceItemProperty.Items; // 여러 배열 변수가 메모리의 동일한 물리적 배열을 가리킬 수 있도록 하는 방법은 무엇입니까?
}
}

// 요소 분석에 기반한 일부 이벤트의 구조
구조체 이벤트 속성
{
정수 번호;
날짜시간DTm;
이중 값;
문자열 유형;

더블 레벨[];
정수 가중치[];

ItemsProperty ItemsProp[];

무효 연산자 = (상수 ItemProperty &SourceEventProperty)
{
숫자 = SourceEventProperty.Number;
DTm = SourceEventProperty.DTm;
값 = SourceEventProperty.Value;
유형 = SourceEventProperty.Type;

// 레벨 = SourceEventProperty.Levels; // 여기에 연결
// 가중치 = SourceEventProperty.Weigths; // 에휴

// ItemsProp = SourceEventProperty.ItemsProp; // 여기에도 문제가 있습니다.

}
}

이벤트 의 동적 배열 을 선언합니다.
EventPropertyMyEvents[];

어떤 함수에서는 이벤트 배열의 데이터를 채웁니다.
무효 GetEventsProperty(EventProperty&MyEvents)
{
// 코드 채우기
}

그리고 어딘가에 MyEvents 배열의 요소를 추가하거나 제거하여 조작할 필요가 있습니다.

정수 iNew = 2;
정수 i = ArraySize(MyEvents) - 2;
동안(i>=iNew)
{
// 내 이벤트[i+1] = 내 이벤트[i]; // 그런 다음 중지
나는 = 나는 - 1;
}

MT4의 구조 배열로 이것을 할 수 있습니까? 다른 참조 변수에서 메모리에 있는 구조 배열의 동일한 요소를 참조하고 생성 및 삭제할 수 있어야 한다는 것이 밝혀졌습니다.
구조체 참조 배열로 작업할 수 있습니까?

 
GitSM :

MT4의 구조 배열로 이것을 할 수 있습니까? 다른 참조 변수에서 메모리에 있는 구조 배열의 동일한 요소를 참조하고 생성 및 삭제할 수 있어야 한다는 것이 밝혀졌습니다.

구조체 참조 배열로 작업할 수 있습니까?

이론상 다음과 같아야 합니다.

 struct ItemsProperty;
{
     double MinLow;
     double MaxHigh;
     double AvgRange;
     double AvgArea;
     string Phase;
    
    Item Items[];
    
     void operator = ( const ItemProperty &SourceItemsProperty)
    {
        MinLow = SourceItemsProperty.MinLow;
        MaxHigh = SourceItemsProperty.MaxHigh;
        AvgRange = SourceItemsProperty.AvgRange;
        AvgArea = SourceItemsProperty.AvgArea;
        Phase = SourceItemsProperty.Phase;
 
         int nTotal = ArraySize (SourceItemProperty.Items);
         ArrayResize (Items, nTotal);
         for ( int i = 0 ; i < nTotal; ++i)
           Items[i] = SourceItemProperty.Items[i];
    }
}

다른 모든 배열에서도 마찬가지입니다. 문제:

여러 배열 변수가 메모리의 동일한 물리적 배열을 가리킬 수 있도록 하는 방법은 무엇입니까?

이해하지 못했습니다.

추신: 코드를 삽입 하려면 "</>" 아이콘 또는 Alt+S를 사용하십시오.

 

Как сделать так чтобы на один и тот же физический массив в памяти могло указывать несколько переменных массива?

이해하지 못했습니다.

죄송합니다. 질문을 올바르게 표현하지 못했습니다. 내가 올바르게 이해한다면 구조의 배열은 본질적으로 배열 인덱스에 의한 링크 주소이며, 각각은 데이터 구조에 따라 특정 방식으로 분산된 메모리의 물리적 주소를 가리킵니다. "여러 배열 변수가 메모리의 동일한 물리적 배열을 가리키도록 하려면 어떻게 해야 합니까?" 예를 들어 MyEvents[2] 및 MyEvents[5]가 메모리의 동일한 구조를 가리키도록 하는 기능을 의미합니다. 즉, MyEvents[2] 및 MyEvents[5]는 두 개의 동일한 구조를 가리키지 않고 하나의 동일한 구조.

동일한 연산자를 오버로딩하면 구조 사본이 생성됩니다. 데이터 구조는 매우 무겁거나 많을 수 있으며 복사할 필요가 없지만 배열에서 데이터 구조에 대한 주소 지정은 한 인덱스에서 다른 인덱스로 점프하는 것이 필요합니다. *MyEvents[2] = *MyEvents[1]과 같은 것입니다. 여기서 제가 포인터를 잘못 사용했을 수도 있으니 이렇게 설명하겠습니다. MyEvents[2]에서 주소를 가져와 MyEvents[1]에서 주소로 변경해야 합니다.

그런 다음 데이터 구조가 아무리 복잡하고 무거워도 필요한 순서대로 배열에서 "셔플"할 수 있으며 실제로 컴퓨팅 리소스 비용이 들지 않습니다. 결국 메모리 주소를 한 위치에서 다른 위치로 복사하는 것이 훨씬 쉽고 훨씬 빠르며 복잡성이 크게 달라질 수 있는 구조의 전체 복사를 수행하여 인덱스를 변경하는 것보다 추가 메모리를 사용할 필요가 없습니다. 이 구조가 참조된 배열입니다.

Распределенные вычисления в сети MQL5 Cloud Network
Распределенные вычисления в сети MQL5 Cloud Network
  • cloud.mql5.com
Большую часть времени современные компьютеры простаивают и не используют всех возможностей процессора. Мы предлагаем задействовать их с пользой. Вы можете сдавать мощности вашего компьютера другим участникам нашей сети для выполнения разнообразных...
 
내가 이해하는 바와 같이, 배열의 구조에 대한 참조를 "셔플링"하는 메커니즘을 구현하려면 이러한 구조가 클래스를 통해 구현되어야 합니다.
이 예제를 시도했는데 작동하는 것 같습니다. new를 통해 생성된 클래스 객체의 삭제를 모니터링하는 것이 여전히 필요하다는 것을 이해합니다.
변수 선언에서 나는 테스트 클래스와 클래스에 대한 포인터의 동적 배열(내가 이해하는 바, 사실 동일한 링크)을 설명했습니다.
 class MyClassTest
{
         public :
         int a;
         double b;
         string c;
};

MyClassTest* arrayRefsMyClassTest[];
그리고 다음을 확인했습니다.
 Print ( "Тест операций над массивом ссылок на классы: начало" );

// создаём объекты классов и сохраняем ссылки на них в массиве ссылок.
i = 0 ;
while ( i< 5 )
{
         ArrayResize (arrayRefsMyClassTest, i+ 1 );
        arrayRefsMyClassTest[i] = new MyClassTest();
        arrayRefsMyClassTest[i].a = i;
        arrayRefsMyClassTest[i].b = 3.14 +i;
        arrayRefsMyClassTest[i].c = "testclass" + i;
        i = i + 1 ;
}

i = 0 ;
while ( i< ArraySize (arrayRefsMyClassTest) ) { if ( CheckPointer (arrayRefsMyClassTest[i])!= POINTER_INVALID ) Print ( "arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1 ; }

Print ( "Изменяем размер массива ссылок на классы" );
ArrayResize (arrayRefsMyClassTest, ArraySize (arrayRefsMyClassTest)+ 2 );

i = 0 ;
while ( i< ArraySize (arrayRefsMyClassTest) ) { if ( CheckPointer (arrayRefsMyClassTest[i])!= POINTER_INVALID ) Print ( "arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1 ; }

Print ( "Присваиваю последнему элементу ссылку во втором элементе" );
i =   ArraySize (arrayRefsMyClassTest) - 1 ;
arrayRefsMyClassTest[i] = arrayRefsMyClassTest[ 2 ];

i = 0 ;
while ( i< ArraySize (arrayRefsMyClassTest) ) { if ( CheckPointer (arrayRefsMyClassTest[i])!= POINTER_INVALID ) Print ( "arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1 ; }

Print ( "Присваиваю 2 элементу ссылку в 5 элементе" );
arrayRefsMyClassTest[ 1 ] = arrayRefsMyClassTest[ 5 ];

i = 0 ;
while ( i< ArraySize (arrayRefsMyClassTest) ) { if ( CheckPointer (arrayRefsMyClassTest[i])!= POINTER_INVALID ) Print ( "arrayRefsMyClassTest[" + i + "]: a = " + arrayRefsMyClassTest[i].a, ", b = " + arrayRefsMyClassTest[i].b + ", c = " + arrayRefsMyClassTest[i].c); i = i + 1 ; }

Print ( "\nТест операций над массивом ссылок на классы: конец" );
로그에서 다음과 같은 결과를 얻었습니다.
Тест операций над массивом ссылок на классы: начало
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 0 ]: a = 0 , b = 3.14 , c = testclass0
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 1 ]: a = 1 , b = 4.14 , c = testclass1
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 2 ]: a = 2 , b = 5.14 , c = testclass2
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 3 ]: a = 3 , b = 6.14 , c = testclass3
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 4 ]: a = 4 , b = 7.14 , c = testclass4
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: Изменяем размер массива ссылок на классы
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 0 ]: a = 0 , b = 3.14 , c = testclass0
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 1 ]: a = 1 , b = 4.14 , c = testclass1
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 2 ]: a = 2 , b = 5.14 , c = testclass2
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 3 ]: a = 3 , b = 6.14 , c = testclass3
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 4 ]: a = 4 , b = 7.14 , c = testclass4
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: Присваиваю последнему элементу ссылку во втором элементе
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 0 ]: a = 0 , b = 3.14 , c = testclass0
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 1 ]: a = 1 , b = 4.14 , c = testclass1
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 2 ]: a = 2 , b = 5.14 , c = testclass2
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 3 ]: a = 3 , b = 6.14 , c = testclass3
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 4 ]: a = 4 , b = 7.14 , c = testclass4
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 6 ]: a = 2 , b = 5.14 , c = testclass2
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: Присваиваю 2 элементу ссылку в 5 элементе
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 0 ]: a = 0 , b = 3.14 , c = testclass0
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 1 ]: a = 4 , b = 7.14 , c = testclass4
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 2 ]: a = 2 , b = 5.14 , c = testclass2
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 3 ]: a = 3 , b = 6.14 , c = testclass3
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 4 ]: a = 4 , b = 7.14 , c = testclass4
0        21 : 59 : 14.658      2018.02 . 01 00 : 00 : 00   Tester3 EURUSD,M5: arrayRefsMyClassTest[ 6 ]: a = 2 , b = 5.14 , c = testclass2
Тест операций над массивом ссылок на классы: конец
제대로 작동한 것 같습니다. 이 경우 데이터의 추가 사본은 내가 이해하는 한 생성되지 않습니다. 내가 틀렸다면 저를 수정하십시오. 의견이나 설명이 있습니까?
 
MQL5(또는 WinAPI 사용)에서 차트를 전체 화면으로 확장하는 방법???
 
GitSM :
내가 이해하는 바와 같이, 배열의 구조에 대한 참조를 "셔플링"하는 메커니즘을 구현하려면 이러한 구조가 클래스를 통해 구현되어야 합니다.

예, 불행히도 MQL에서 구조에 대한 포인터를 만들 수 없습니다. 클래스에서 가능하다면 왜 그러한 제한을 했는지는 분명하지 않습니다. 결국 구조는 클래스와 크게 다르지 않습니다.