포럼을 어지럽히 지 않도록 모든 초보자 질문. 프로, 놓치지 마세요. 너 없이는 아무데도 - 6. - 페이지 641

 
simpleton :

왜 오류를 에뮬레이트합니까?

오류 - 시스템의 한계/고장과 관련된 어떤 이유로 알고리즘을 실행하고 일부(물론 제한적이지만 - ) 보장으로 결과를 얻을 수 없음을 신호하기 위한 것입니다. FillAndPrint() 함수는 웅변적이며 잘못된 상황이 의미하는 것과 그렇지 않은 것을 보여줍니다. 오류가 발생하면 결과를 생성하려고 하지도 않습니다. 오류가 발생하지 않으면 결과를 신뢰할 수 있습니다. 이것이 "오류/오류 아님" 논리를 구축하는 방법입니다.

여기서 알고리즘의 수정도 필요합니다. 또한 추가 필터를 부과해야 합니다.

다음과 같이 해야 합니다.

먼저 개체의 유형과 매개변수를 기준으로 "필터링"하고 사용 가능한 모든 개체에서 필요한 개체만 선택한 다음 추가 필터를 적용했습니다. 사람이 어떻게 할 것인지에 대해. 인간이라면 이런 짓을 하지 않을까?

이러한 작은 하위 작업 각각에 대해 별도의 기능이 자체적으로 제안됩니다.

매우 특별한 경우를 제외하고는 표현식에 숫자가 없어야 합니다. 그런 다음 표현식에서 숫자 2를 직접 사용할 수 있습니다. 그리고 다른 유사한 매우 드문 경우.

그렇지 않으면 니모닉을 사용해야 합니다. 첫째, 주어진 장소에서 일어나는 일에 대한 이해를 크게 향상시켜 실수의 가능성을 줄이는 데 기여합니다. 그리고 둘째, 값 자체가 한곳에 설정되어 필요에 따라 쉽게 변경할 수 있고, 니모닉을 사용하지 않고 알고리즘에서 숫자를 반복해서 사용하는 경우에 비해 실수가 불가능할 것이다. , 알고리즘의 여러 위치에서 숫자를 편집해야 합니다.

실행 결과:

개체를 찾을 수 없습니다. 두 니모닉의 값을 10배 증가시켜 36000(10시간)으로 만들고 다시 실행해 보겠습니다.

하나의 추세선이 이미 필터링을 "통과"했습니다. 이제 첫 번째 니모닉 값을 3600으로 복원하고 실행해 보겠습니다.

이제 두 추세선 모두 필터링을 "통과"했음을 알 수 있습니다. 그건 그렇고, 이런 식으로 프로그램의 모든 분기(부분)를 디버깅하는 것이 좋습니다. 한 분기가 아닙니다.

어떻게든 공식화하는 데 도움이 되도록 이렇게 설명하겠습니다. 프로그램은 계획과 유사한 것으로 보입니다.

계획의 각 주요 지점은 더 작은 하위 계획의 지점으로 나눌 수 있습니다. 작게 - 더 작게. 가장 작은 하위 계획의 항목이 직접 실행됩니다.

각 계획, 하위 계획 및 가장 작은 하위 계획의 항목조차도 프로그램의 기능에 해당합니다. 가장 작은 하위 계획의 항목은 시스템 기능만 호출하거나 호출하지 않는 "종료" 기능에 해당합니다. 예를 들어 위에서 논의한 항목에서 AddValue() 또는 DiffInSecs()를 예로 사용할 수 있습니다. 위의 하위 계획의 항목은 아래의 하위 계획의 항목을 구현하는 기능을 호출하는 기능에 해당합니다. 위에서 논의한 것 중 MassTrendNumber(), AddValueIfFound(), AddValueIfFiltered()가 있습니다. "낮은 수준" 함수는 "높은 수준" 함수를 호출해서는 안 되며, "높은 수준" 함수는 일반적으로 여러 수준 아래로 점프해서는 안 됩니다. 즉, 기본적으로 한 수준 아래에서만 함수를 호출해야 합니다. "낮은 수준"의 경우 이 규칙은 "높은 수준"보다 훨씬 엄격합니다.

누가 누구를 호출하는지에 대한 의미에서 이러한 트리 구조로 연결된 (짧은) 기능의 형태로 프로그램의 작업을 구성하여 프로그램을 빌드하십시오.

이 프로그램에서 퇴화 트리가 밝혀졌습니다. 한 가지가 여러 번 "분기"됩니다. 그리고 그것은 두 개의 작은 가지가 아니라 하나로 "가지"합니다. 그러나 요점은 "고수준" 기능이 일관되게 "저수준" 기능을 호출한다는 것입니다. 이 수정에서 나는 이 구조에 하나의 레벨을 더 삽입했는데, "비분기 분기"인 AddValueIfFiltered()가 하나 더 추가되었습니다.

완성된 코드를 게시하고 있습니다.

작업: 추세선( OBJ_TREND ) 찾기, 현재 막대에 상대적인 가격 값을 배열에 씁니다. 객체 시간 매개변수(OBJ_TREND)의 존재에 대한 필터링 포함.

 #property strict

/******************************************************************************/
bool AddValue( double &array[], const double value) {
   const int size = ArraySize (array);

   if ( ArrayResize (array, size + 1 ) != size + 1 ) {
     return false ; // Ошибка, значение не может быть добавлено к массиву
  }

  array[size] = value; //записываем
   return true ; // Нет ошибки, значение добавлено к массиву
}

/******************************************************************************/
bool AddValueIfFound( double &array[], const string name) {
   const int type = ObjectType(name);

   if (type == OBJ_TREND ) {
     switch (( color )ObjectGet(name, OBJPROP_COLOR )) { // Тип color допустимо использовать в switch
     case Goldenrod:
     case Gainsboro:
     case White:
       if (!AddValueIfFiltered(array, name)) { // Пропускаем через фильтр
         return false ;
      }
    }
  }

   return true ; // Нет ошибки, значение, если найдено, добавлено к массиву
}
/******************************************************************************/
bool MassTrendNumber( double &array[], const bool buy) { // Поиск значения цены трендовой линии, текущего бара, запись в массив. Два массива: masS и masB
   const string subname = (buy ? "uptrendline" : "downtrendline" ); // существует два названия трендовых линий, первое и второе

   if ( ArrayResize (array, 0 ) != 0 ) {
     return false ; // Ошибка, массив не может быть заполнен достоверно
  }

   for ( int i = 0 , limit = ObjectsTotal ( OBJ_TREND ); i < limit + 2 ; i++) {
     if (!AddValueIfFound(array, subname + IntegerToString (i))) {
       return false ; // Ошибка, массив, если и заполнен, то недостоверно
    }
  }
 
   return true ; // Нет ошибки, массив заполнен достоверно
}
/******************************************************************************/
long DiffInSecs( const datetime dt1, const datetime dt2) {
   return dt1 - dt2;
}
/******************************************************************************/
bool AddValueIfFiltered( double &array[], const string name) {
#define MIN_SECS_BETWEEN_PRICE1_AND_PRICE2 3600
#define MAX_SECS_AFTER_PRICE2               3600

   const datetime dt1 = ( datetime )ObjectGet(name, OBJPROP_TIME1);
   const datetime dt2 = ( datetime )ObjectGet(name, OBJPROP_TIME2);
   const datetime dt = TimeCurrent ();
  
   Print ( "name = " , name, // ", dt = ", dt, ", dt1 = ", dt1,"\n", 
   " DiffInSecs = " , DiffInSecs(dt,dt2), " DiffInSecs = " , DiffInSecs(dt2,dt1));

   if ( DiffInSecs(dt,dt2)>MAX_SECS_AFTER_PRICE2 && DiffInSecs(dt2,dt1)> MIN_SECS_BETWEEN_PRICE1_AND_PRICE2 ){
     if (!AddValue(array, ObjectGetValueByShift(name, 1 ))) { // Пытаемся добавить
       return false ; // Ошибка, значение не добавлено
    }
  }

   return true ; // Нет ошибки, значение, если удовлетворило условию фильтра, добавлено к массиву
}

/******************************************************************************/
void FillAndPrint( double &array[], const bool buy) {
   if (MassTrendNumber(array, buy)) {
     const int limit = ArraySize (array);

     Print ( "Найдено объектов: " , limit);

     for ( int i = 0 ; i < limit; i++) {
       Print ( "Price[" , i, "] = " , DoubleToStr(array[i], Digits ));
    }
  } else {
     Print ( "Чёрт!" );
  }
}

/******************************************************************************/
 void OnTick()

//=============================================================================================
//====================================== Линии тренда =========================================
//=============================================================================================
 double masS[]; double masB[];

  Print("Sell:");
  FillAndPrint(masS, false);

  Print("Buy:");
  FillAndPrint(masB, true);
   simpleton Спасибо вам большое, вы за пестовали  меня на ощущения правильного кода!) (Правда я немногое понял))))
 
evillive :

저는 이제 4-sign을 가지고 있습니다. 유로달러에 1랏 1포인트 비용은 10달러이며 항상 이랬습니다. 십자가의 경우 비용은 8에서 16까지이며 공식이 조금 더 복잡합니다.

예를 들어, 유로 파운드에 대한 마케팅 정보는 16.984, 달러에 대한 파운드 환율 = 1.6984를 반환했습니다. *0.0001=10.0 또는 100000 * 0.00010 \u003d 10.0 - 원하는 대로).


이 모든 계산은 계정이 달러인 경우에만 정확합니다.

이 경우 xUSD(EURUSD, GBPUSD 등)의 경우 tickvalue = lot*point = 100000*0.0001 = 10.0

USDx의 경우(USDCHF, USDJPY 등) 틱값 = 랏*포인트/입찰가 = 100000*0.01/101.93=9.8107

교차 환율 xUSD/yUSD(EURGBP) 틱값 = 입찰가(yUSD)*랏*포인트 = 1.6980*100000*0.0001 = 16.98

xUSD/USDy(EURJPY) 교차 틱값 = lot*point/Bid(USDy) = 100000*0.01/101.91=9.8126


당신이 망친 것! 시간을 내어 코드를 살펴보고 표현식을 선택하고 다음을 살펴보았습니다.

   double TV = MarketInfo( Symbol (),MODE_TICKVALUE); 
   string sTV = DoubleToStr(TV, 4 ); 
   Comment ( "TV " ,sTV); //sTV = 1.0/Bid

이보다 더 쉬울 수는 없습니다! 10번, 16번 등

 
evillive :

저는 이제 4-sign을 가지고 있습니다. 유로달러에 1랏 1포인트 비용은 10달러이며 항상 이랬습니다. 십자가의 경우 비용은 8에서 16까지이며 공식이 조금 더 복잡합니다.

예를 들어, 유로 파운드에 대한 마케팅 정보는 16.984, 달러에 대한 파운드 환율 = 1.6984를 반환했습니다. *0.0001=10.0 또는 100000 * 0.00010 \u003d 10.0 - 원하는 대로).


이 모든 계산은 계정이 달러인 경우에만 정확합니다.

이 경우 xUSD(EURUSD, GBPUSD 등)의 경우 tickvalue = lot*point = 100000*0.0001 = 10.0

USDx의 경우(USDCHF, USDJPY 등) 틱값 = 랏*포인트/입찰가 = 100000*0.01/101.93=9.8107

교차 환율 xUSD/yUSD(EURGBP) 틱값 = 입찰가(yUSD)*랏*포인트 = 1.6980*100000*0.0001 = 16.98

xUSD/USDy(EURJPY) 교차 틱값 = lot*point/Bid(USDy) = 100000*0.01/101.91=9.8126


보릴루나드 :

옳지 않다! 견적의 의미는 중요하지 않습니다! 그리고 min.tick의 값은 현재 가격 에서 계산되어야 합니다! TICK_VALUE이(가) 무엇입니까! 위는 내 코드의 예입니다.
 
borilunad :

보릴루나드 :

옳지 않다! 견적의 의미는 중요하지 않습니다! 그리고 min.tick의 비용은 현재 가격에서 계산되어야 합니다! TICK_VALUE이(가) 무엇입니까! 위는 내 코드의 예입니다.

그리고 무엇이 잘못되었나요? MarketingInfo는 위에서 제공한 수식으로 얻은 것과 동일한 값을 반환합니다. 나는 이 공식을 생각해내지 않았으며 터미널에서 TickValue를 계산하는 데 사용합니다)))

마케팅 정보에서 값을 구하는 것이 더 편리한 것은 분명한데 공식이나 계산 방법을 정확히 물어본 사람이 더 높기 때문이다.

그리고 나는 5자리 포인트 = 10pips 가 고려되고 이것은 4자리 포인트에서 동일한 포인트이기 때문에 중요하지 않은 중요성에 대해 이전에 썼습니다.

 
evillive :

그리고 무엇이 잘못되었나요? MarketingInfo는 위에서 제공한 수식으로 얻은 것과 동일한 값을 반환합니다. 나는 이 공식을 생각해내지 않았으며 터미널에서 TickValue를 계산하는 데 사용합니다)))

마케팅 정보에서 값을 구하는 것이 더 편리한 것은 분명한데 공식이나 계산 방법을 정확히 물어본 사람이 더 높기 때문이다.

그리고 나는 5자리 포인트 = 10pips가 고려되고 이것은 4자리 포인트에서 동일한 포인트이기 때문에 중요하지 않은 중요성에 대해 이전에 썼습니다.


예, MarketInfo( Symbol (),MODE_TICKVALUE) = 1.0/Bid; 아마도 유로달러에 대해서만, 나는 다른 사람들에게 스프레이하지 않습니다!
 
borilunad :

예, MarketInfo( Symbol (),MODE_TICKVALUE) = 1.0/Bid; 아마도 유로달러에 대해서만, 나는 다른 사람들에게 스프레이하지 않습니다!

이것은 인증서에 제공된 정의에 따라 유로달러에 대해 잘못된 것입니다.

MODE_TICKVALUE

열여섯

예금 통화로 표시된 상품 가격의 최소 변동 금액


그리고 그것은 곱하기를 의미합니다

MODE_POINT

열하나

견적 통화의 포인트 크기. 현재 도구의 경우 사전 정의된 변수 Point에 저장됩니다.



MODE_LOTSIZE

열 다섯

상품 기준 통화의 계약 규모


물론 유로로 된 계좌가 있다면 유로에서 춤을 출 필요가 있지만 여전히 달러로 계좌가 있는 거래자(대부분)의 경우 위의 공식이 유효합니다 . 그리고 주요 거래 쌍과 가장 많이 거래되는 쌍이 미국 달러를 기반으로 하기 때문에 이러한 공식이 가장 자주 사용됩니다.

 
evillive :

도움말에 제공된 정의에 따라 이것은 잘못된 것입니다.

MODE_TICKVALUE

열여섯

예금 통화로 표시된 상품 가격의 최소 변동 금액


그리고 그것은 곱하기를 의미합니다

MODE_POINT

열하나

견적 통화의 포인트 크기. 현재 도구의 경우 사전 정의된 변수 Point에 저장됩니다.



MODE_LOTSIZE

열 다섯

상품 기준 통화의 계약 규모


물론 유로로 된 계정이 있으면 유로에서 춤을 출 필요가 있지만 대부분의 거래자는 여전히 달러로 된 계정을 가지고 있습니다.


글쎄, 나는 특별한 경우가 있지만 유로존에 살고있는 나를 위해 모든 계산을 유로로 수행하는 것이 더 편리합니다!
 

여러분, 다음 지표에 대한 코드 예제를 알려주세요. 얼마나 많은 버퍼가 필요한지, 어떤 유형의 디스플레이와 어디에 어떤 속성을 등록해야 하는지 알 수 없습니다.

표시기는 다음과 같습니다.

1 세그먼트는 모든 세 번째 막대의 저음과 인접한 막대를 연결합니다. 라인 레드.

2개의 세그먼트는 각 5번째 마디의 고음과 인접한 마디를 연결합니다. 라인 블루.

가장 중요한 것은 세그먼트가 어떤 식으로든 교차하지 않는다는 것입니다. 각 세그먼트의 시작과 끝은 다른 세그먼트와 독립적입니다.

표시기는 각 세그먼트의 시작 값과 끝 값을 계산합니다. 조건에 따라 다른 색상으로 칠해야 합니다.

대략적으로 어떻게 보일지


 

그리고 또 다른 질문.

디버그 모드 에서 표시기로 작업할 수 없는 것이 정상입니까?

프로그램이 중단점에 도달하면 MT4 터미널이 멈추고 창이 흰색(XP에서)으로 바뀌어 차트에 그려진 내용을 볼 수 없습니다.

[삭제]  
Top2n :

완성된 코드를 게시하고 있습니다.

작업: 추세선(OBJ_TREND) 찾기, 현재 막대와 관련된 가격 값을 배열에 씁니다. 개체 시간 매개변수(OBJ_TREND)의 존재 여부에 따라 필터링됩니다.

simpleton : 정말 감사합니다 . 올바른 코드를 느낄 수 있도록 키워주셨어요!) (사실, 조금 이해했습니다))))

훈련하면 이해가 점점 더 많아질 것입니다. 집중과 주의가 필요합니다. 프로그램 알고리즘이 하나의 큰 기능에 분산되면 집중과 주의를 기울여 구현하기가 어렵습니다. 너무 많은 연결이 형성됩니다. 프로그램이 기능적으로 완전한 부분(작은 기능)으로 분할되면 각 개별 작은 기능에 대해 이 작업을 수행하는 것이 훨씬 쉽습니다. 기능의 각 수준에서 등등. 그런데:

   if ( DiffInSecs(dt,dt2)>MAX_SECS_AFTER_PRICE2 && DiffInSecs(dt2,dt1)> MIN_SECS_BETWEEN_PRICE1_AND_PRICE2 ){
     if (!AddValue(array, ObjectGetValueByShift(name, 1 ))) { // Пытаемся добавить
       return false ; // Ошибка, значение не добавлено
    }
  }
아마도 니모닉 이름을 MAX_SECS_AFTER_PRICE2로 지정하지 못했을 것입니다(처음에는 조건이 반대로 되어야 한다는 것을 이해했기 때문에). 의미에 따라 아마도 MIN_SECS_AFTER_PRICE2, 즉 최대 허용이 아닌 최소 허용일 것입니다.