서로 다른 터미널에서 작동하는 두 개의 Expert Advisor 간의 데이터 교환 - 페이지 3

 

Еще можно попробовать забить гвоздь лампочкой. У некоторых получается.

그리고 그러한 접근 방식의 비뚤어진 부분은 무엇입니까?

시스템 시간을 설정할 수도 있습니다.

따라서 시스템 시간의 동기화가 진행됩니다 :-). 설치가 아니라 읽기를 통해. 그런 종류 의 데이터 교환 .

 

모두 좋은 하루!

터미널을 안정적으로 연결하는 가장 좋은 방법 중 하나는 네트워크 1C를 사용하는 것입니다.
두 가지 주요 가능성:
1. 주 응용 프로그램은 1C에서 실행되고 터미널 및 해당 MQL4 프로그램은 실행기입니다.
2. 기본 응용 프로그램은 터미널 중 하나에서 실행되고 1C 응용 프로그램은 바인딩 프로토콜로 사용됩니다.

장점:
1. 다른 서버에서 동시에 전체 견적 내역을 저장하고 처리하는 기능;
2. 브로커의 보고서를 조정할 가능성이 있는 거래의 전체 회계 기록을 유지하는 기능.

감사합니다,
아이스

 
Andres >> :

그래서 나는 이미 작은 라이브러리를 작성했고 이미 내 고문은 레지스트리를 통해 완전히 변경되고 있습니다. 실제로 RAM을 통해 변경되며 디스크에 대한 읽기-쓰기가 관찰되지 않습니다.


제공된 라이브러리에 감사드립니다! 나는 이 교환의 구현도 다룰 것이다.

일단 분명한 질문이 있습니다. 매개변수 읽기/쓰기 제어를 어떻게 구현합니까? 즉, 다른 고문이 일부 주요 매개변수를 이미 읽을 수 있음을 어떻게 알 수 있습니까?

다른 EA에서 일종의 추가 읽기/쓰기 권한 키를 생성하고 있습니까? 아니면 테스트한 다른 가능성이 있습니까? 다시 말해, Expert Advisors가 오류를 피하기 위해 동일한 주요 매개변수와 동시에 작동하지 않도록 매개변수에 대한 단일 액세스를 제공하는 방법은 무엇입니까?

 

키 매개변수에 대한 단일 액세스를 제공하는 방법을 알아냈습니다. 문자열 GetErrorString( int ErrorCode) 함수를 통해 오류를 확인하기만 하면 됩니다.

그리고 오류가 발생하면 두 번째 작업을 수행하십시오. 사실, 나는이 반복 작업이 수행되는 라이브러리에서 이해하지 못했습니다. 아마도 이미 필요한 것을 추가해야 할 것입니다. 어쨌든 아름다운 솔루션에 감사드립니다!

 

이것은 오류 출력이 있는 Win API에 대한 간단한 래퍼로, 키의 문자열 매개변수로만 작업할 수 있습니다.

GetErrorString( int ErrorCode ) 은 오류가 발생했을 때 무엇을, 어디서, 왜, 어떻게 수정해야 하는지 알기 위해 다소 지시적입니다. 물론 이미 다양한 방식으로 키를 사용하는 논리를 기반으로, 래퍼 라이브러리 기능 외부에서 발생하는 오류 처리를 이동하고 다양한 방식으로(오류 유형이 많음) 대응하는 것이 가능하고 필요합니다. 전문가. 그 동안 실패한 시도에 대한 SetStringValue()는 시도가 실패했음을 알려줄 뿐입니다. 그리고 GetStringValue()는 실패의 경우 말할 뿐만 아니라 빈 문자열을 반환합니다. OS에서 그런 검사를 하기 때문에 추가 읽기/쓰기 권한 키가 필요하지 않다고 생각합니다. 오류를 처리 하고 적절하게 대응하는 것으로 충분합니다. "hot" 테스트에 대한 나의 Expert Advisors는 단순히 시간이 맞지 않아 동일한 필드를 동시에 읽고 쓸 때 충돌이 발생하지 않은 것 같습니다. 그러나 물론 이것은 해결책이 아닙니다. 계속 진행해야 합니다. 그래도 1박에 썼으니 엄하게 판단하지 마세요. 방법을 느끼기 위해 "베타"버전처럼 :-).

 
Andres >> :

그래서 나는 이미 작은 라이브러리를 작성했고 이미 내 고문은 레지스트리를 통해 완전히 변경되고 있습니다. 실제로 RAM을 통해 변경되며 디스크에 대한 읽기-쓰기가 관찰되지 않습니다. MSDN에 따르면 레지스트리에 수백 KB 이상의 데이터를 밀어넣지 않는 것이 좋습니다.

라이브러리는 모든 키와 매개변수가 임시 레지스트리 영역에서 생성되고 영구 레지스트리에 기록되지 않도록 구성됩니다. 재부팅 후에는 이러한 키가 더 이상 존재하지 않습니다.

단, 라이브러리는 255자(MQL 제한) 이하의 문자열 매개변수로만 작동합니다. 하지만 이것으로 충분합니다. 일반적으로 레지스트리의 매개변수는 문자열뿐만 아니라 다양한 유형이 될 수 있지만 지금까지는 다른 유형이 필요하지 않다고 생각합니다. 이제 레지스트리를 통해 두 명의 Expert Advisor를 변경하고 있지만 더 많은 것이 가능합니다 :-). 또 다른 장점은 Win API에서 네트워크 레지스트리에 연결할 수 있다는 것입니다. 누군가가 동일한 네트워크의 다른 시스템에서 실행되는 Expert Advisor 간에 정보를 교환해야 하는 경우 이 방향을 볼 수 있습니다. 제 생각에는 빠르고 간단하며 안정적이며 dll과 파일이 없습니다. 구동 라인 - 라인을 받았습니다.

안드레이, 고마워!

나를 위해 약간 편집하고 장식했습니다.

저금통 에 넣어도 될까요? 아주 좋은 결정입니다!

파일:
reglib.rar  11 kb
 

언젠가 Andrey, 그래픽 변수 작업을 위해 귀하의 라이브러리를 제 라이브러리 와 통합할 것입니다. 다른 수준의 변수 선언을 가져옵니다.

1. 글로벌 슈퍼 변수 가 있습니다 . 이러한 변수는 OS 수준에서 볼 수 있습니다.

2. 이제 GlobalVariable 이 있습니다.

3. 그리고 전역 그래픽 변수 GlobalChartVariable 이 있습니다. 한 창의 프로그램에서만 볼 수 있습니다.

일반적으로 MQL4의 OS 수준에서 고유한 구조로 작업하기 위한 라이브러리를 가져와야 합니다.

 
Zhunko >> :

1. 글로벌 슈퍼 변수 가 있습니다 . 이러한 변수는 OS 수준에서 볼 수 있습니다.

코드 베이스에 그러한 변수를 넣으면 매우 감사할 것입니다(아마 저만 그런 것은 아닙니다).

나는 이미 장인의 방법을 사용하는 것에 지쳤습니다.

 

Andrey에게 질문합니다. 여기에서 레지스터를 전송합니까?

 string GetStringValue1 ( int    hKey ,      // Код ключа реестра.
                        int    lpSize ,    // Длина считываемой строки.
                        string ValueName ) // Имя параметра ключа.
 {
  int lpType [ 1 ] ;      // Возвращаемый тип параметра.
  int lpcbData [ 1 ] ;    // Размер буфера.
  int i ;              // Переменная для подрезки последних пустых строк.
  int lres ;           // Результат.
  string lpData = "" ; // Буфер для возвращаемой строки.
  //----
  lpcbData [ 0 ] = lpSize ; // Размер буфера.
  for ( i = 0 ; i < lpSize ; i + + ) lpData = lpData + "#" ;
  lres = RegQueryValueExA ( hKey , ValueName , 0 , lpType , lpData , lpcbData ) ; // вызов API
  // Теперь в lpcbData[0] размер скопированных байт. Проверяем результат.
  if ( lres ! = ERROR_SUCCESS )
   {
    Print ( "Error in RegQueryValueExA(): " , GetErrorString ( lres ) ) ;
    return ( "" ) ;
   }
  if ( lpType [ 0 ] = = REG_SZ | | lpType [ 0 ] = = REG_EXPAND_SZ ) return ( StringSubstr ( lpData , 0 , lpcbData [ 0 ] - 1 ) ) ;
  return ( "" ) ;
 }
 
설명을하겠습니다. 사실 동적으로 증가하는 문자열을 버퍼로 사용하면 일부 오류가 관찰됩니다. 나는 전에 이것을 보았다: 
InitRegDefines();
hKey = CreateKey( HKEY_CURRENT_USER, "!MT4TestKey" );

// заносим
SetStringValue( hKey, "Param", "Test" );

// вытаскиваем при помощи Вашей функции:
Print( GetStringValue1( hKey, 20, "Param" ) );

그 후에 밝혀졌습니다.

2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1: ####
2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1: RegCreateKeyExA(): 존재하지 않는 파티션이 생성되었습니다.
2009.05.19 01:22:16 온도 테스트 시작

즉, 호출 중에 오류가 발생하지 않더라도 버퍼의 내용은 변경되지 않습니다. 그리고 레지스트리에는 정확히 "Test" 문자열이 포함되어 있습니다.

포럼 게시물에서 이것은 MQL 환경에서 DLL 함수로 문자열이 비정상적으로 전달되기 때문임을 이해했습니다. MQL 환경에서 개발자는 자체 관리자(문자열 풀)를 사용하여 문자열에 대해 작업하고 분명히 이 경계에서 잘못된 버퍼가 채워지고 있으므로 API 함수에서 반환된 결과를 볼 수 없습니다. 그러나 전체 최대 길이로 초기화된 문자열을 사용하면 내가 아는 한 문제가 없습니다. 이것이 255자 "#"으로 된 줄이 있는 이유입니다. "#" 기호는 단순히 선이 눈에 보이도록 선택되었습니다. 호출 전에 버퍼가 어떻게 채워지는지는 중요하지 않기 때문에 이것은 Win API 자체와 관련이 없습니다. 이것은 앞서 언급한 선의 길이에 대한 제한입니다. 255자보다 큰 문자열을 SetStringValue()에 전달할 수 있지만 읽을 수는 없습니다.

물론 제약이 없을 때 좋은데 큰 불편함은 못느끼겠습니다. 질문이 생깁니다. 왜 주어진 크기의 문자열을 읽어야 합니까? 제한 사항인 경우 레지스트리에 기록할 때 소스 문자열을 길이 255 + "잔여" 매개변수의 N 매개변수로 분할하는 함수를 작성하여 이를 우회할 수도 있습니다. 그리고 읽을 때 - 다시 수집합니다. 그것은 다른 방법과 같습니다. 어렵다고 생각되면 저에게 연락하십시오. 제가 하겠습니다. 모든 사람의 요구 사항이 다르고 모든 것을 예측할 수는 없으며 이것만으로도 충분하고 누군가는 여러 수준에서 전역 변수를 사용합니다.

사유: