MQL4 및 MQL5에 대한 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 - 페이지 531

 
Vitaly Muzichenko :

다음 막대를 비교하고 시퀀스가 끊어지면 플래그를 재설정하고 몇 개나 맞았는지 기록하고 루프를 계속 진행합니다.

막대가 강세이고 다음 막대가 약세이고 다음 막대가 이전 막대와 같으면 값을 기록하고 플래그를 재설정한다는 것을 알아내는 것으로 충분합니다. 자, 끝까지

그러나 첫 번째는 어떻게 해서든 황소가 아닐 수 있습니다.

   for(int i=limit-1; i>0; i--)

     {


      if(open[i]<close[i]&&open[i+1]>close[i+1]&&open[i+3]<close[i+3])

        {

         up++;

        }

      else up=0;

    
    
if(max_c<up)max_c=up;

Comment(max_c);
}

//--- return value of prev_calculated for next call

   return(rates_total);

  }

 
PolarSeaman :

그러나 첫 번째 사람은 어떻게 해서든 황소가 아닐 수 있습니다.

여기에 옵션이 있습니다. 완전히 정확하지는 않지만 카운트다운은 항상 약세 양초에서 시작됩니다.

파일:
aCandle.mq4  8 kb
 
Vitaly Muzichenko :

여기에 옵션이 있습니다. 완전히 정확하지는 않지만 카운트다운은 항상 약세 양초에서 시작됩니다.

고맙습니다. 결과 숫자를 제곱하고 1을 더하면 결과가 정확합니다.

이것이 우리가 if(i%2==0) 확인하는 것입니까?
 
PolarSeaman :

그러나 첫 번째는 어떻게 해서든 황소가 아닐 수 있습니다.


다음은 동일한 양초와 체인 방향의 변화에 대한 대략적인 검색입니다.

 //+------------------------------------------------------------------+
//|                                              CandlesSequence.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link        "https://mql5.com/ru/users/artmedia70"
#property version    "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots    1
//--- plot Sequence
#property indicator_label1    "Sequence"
#property indicator_type1    DRAW_COLOR_HISTOGRAM
#property indicator_color1    clrGreen , clrRed , clrGray
#property indicator_style1    STYLE_SOLID
#property indicator_width1    2
//--- enums
enum ENUM_CANDLE_TYPE
  {
   CANDLE_TYPE_BULL  =   0 ,       // Bullish candle
   CANDLE_TYPE_BEAR  =   1 ,       // Bearish candle
   CANDLE_TYPE_DOJI  = - 1          // Doji candle
  };
//--- indicator buffers
double          BufferSeq[];
double          BufferSeqColors[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   SetIndexBuffer ( 0 ,BufferSeq, INDICATOR_DATA );
   SetIndexBuffer ( 1 ,BufferSeqColors, INDICATOR_COLOR_INDEX );
//--- setting indicator parameters
   IndicatorSetString ( INDICATOR_SHORTNAME , "Candles sequence" );
   IndicatorSetInteger ( INDICATOR_DIGITS , Digits ());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries (BufferSeq, true );
   ArraySetAsSeries (BufferSeqColors, true );
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 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[])
  {
//--- Проверка на минимальное колиество баров для расчёта
   if (rates_total< 2 ) return 0 ;
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries (open, true );
   ArraySetAsSeries (high, true );
   ArraySetAsSeries (low, true );
   ArraySetAsSeries (close, true );
   ENUM_CANDLE_TYPE type_refs=CANDLE_TYPE_DOJI;
   ENUM_CANDLE_TYPE type_curr=CANDLE_TYPE_DOJI;
//--- Проверка и расчёт количества просчитываемых баров    
   int limit=rates_total-prev_calculated;
   if (limit> 1 )
     {
      limit=rates_total- 2 ;
       ArrayInitialize (BufferSeq, EMPTY_VALUE );
      BufferSeq[rates_total- 1 ]=open[rates_total- 1 ];
     }
//--- Расчёт индикатора
   for ( int i=limit; i>= 0 && ! IsStopped (); i--)
     {
      type_refs=GetTypeCandle(i+ 1 ,open,close);
      type_curr=GetTypeCandle(i,open,close);
   //--- смена направления цепочки свечей
       if (!CheckCandle(type_refs,type_curr))
        {
         BufferSeq[i]=(type_curr==CANDLE_TYPE_BULL ? low[i]: type_curr==CANDLE_TYPE_BEAR ? high[i]: open[i]);
        }
   //--- свечи одного типа
       else
        {
         BufferSeq[i]=BufferSeq[i+ 1 ];
        }
      BufferSeqColors[i]=(type_curr==CANDLE_TYPE_BULL ? 0 : type_curr==CANDLE_TYPE_BEAR ? 1 : 2 );
     }

//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает тип свечи                                             |
//+------------------------------------------------------------------+
ENUM_CANDLE_TYPE GetTypeCandle( const int shift, const double &open[], const double &close[])
  {
   return (close[shift]>open[shift] ? CANDLE_TYPE_BULL : close[shift]<open[shift] ? CANDLE_TYPE_BEAR : CANDLE_TYPE_DOJI);
  }
//+------------------------------------------------------------------+
//| Сравнивает два типа свечей                                       |
//+------------------------------------------------------------------+
bool CheckCandle( const ENUM_CANDLE_TYPE reference_candle_type, const ENUM_CANDLE_TYPE checked_candle_type)
  {
   return (reference_candle_type==checked_candle_type ? true : false );
  }
//+------------------------------------------------------------------+

이제 체인이 계속되는 곳에서 체인의 양초 수를 세어 목록에 저장할 수 있으며 체인이 새 것으로 변경되는 곳에서 새 카운트를 시작합니다.

각 체인의 양초 수는 정렬된 목록에 저장할 수 있습니다. 또한 목록을 정렬 하여 최대 및 최소 시퀀스를 찾을 수 있습니다.

 
PolarSeaman :

고맙습니다. 결과 숫자를 제곱하고 1을 더하면 결과가 정확합니다.

이것이 우리가 if(i%2==0) 확인하는 것입니까?

i가 2의 배수인 경우.

이것은 i를 2 로 나눈 나머지입니다.

 
Juer :

컴파일할 때 로컬 변수의 크기가 너무 큽니다(512kb 이상).

어디를보고 무엇을해야합니까? 이 함수에는 CArrayString 문자열 배열이 있습니다. 오류가 관련되었을 수 있습니다.

Add() 메서드로 채운 다음 Clear() 를 수행한 다음Shutdown() 을 수행합니다. 그런 다음 Add() 메서드를 사용하여 새 데이터로 다시 채웁니다. 이 경우 배열은 0 요소부터 다시 채워집니다.

이미 컴파일 단계에서 메모리를 차지하는 클래스에서 이러한 멤버를 제거해야 합니다. 이 데이터는 항상 매우 작은 스택 메모리에 배치됩니다. 문제에 대한 해결책은 동적으로 많은 메모리를 차지하는 클래스 멤버에 대해 메모리를 할당하는 것입니다.

예를 들어 클래스 구성원이 있는 경우:

 class A
{
   double m_arrfArray[ 9999999 ];
};

다음으로 대체되어야 합니다.

 class A
{
   double m_arrfMyArray[];
};

bool A::Init()
{
   if ( ArrayResize (m_arrfMyArray, 9999999 ) != 9999999 )
       return false ;
   ....
}
 
Ihor Herasko :

이미 컴파일 단계에서 메모리를 차지하는 클래스에서 이러한 멤버를 제거해야 합니다. 이 데이터는 항상 매우 작은 스택 메모리에 배치됩니다. 문제에 대한 해결책은 동적으로 많은 메모리를 차지하는 클래스 멤버에 대해 메모리를 할당하는 것입니다.

예를 들어 클래스 구성원이 있는 경우:

다음으로 대체되어야 합니다.

고맙습니다. 어떻게든 각 함수의 매개변수에서 클래스를 제거하여 이 문제를 제거했습니다. 일반적으로 모든 메서드에 대해 이 개체를 한 번만 초기화할 수 있습니다.

CArray 클래스 또는 CArrayObj에 대한 또 다른 질문이 있습니다. Delete() 메서드가 있지만 배열의 요소를 이동하지 않습니까? 즉, Delete(18)를 삭제하면 이 위치에 있는 요소가 삭제되고 예를 들어 이 인덱스에 있는 요소를 요청하면 잘못된 포인터를 얻게 됩니다. 이 경우 19번째 요소가 제거 후 18번째에 끝나도록 요소를 제거하고 이동하는 방법이 있습니까?

 
Juer :

고맙습니다. 어떻게든 각 함수의 매개변수에서 클래스를 제거하여 이 문제를 제거했습니다. 일반적으로 모든 메서드에 대해 이 개체를 한 번만 초기화할 수 있습니다.

CArray 클래스 또는 CArrayObj에 대한 또 다른 질문이 있습니다. Delete() 메서드가 있지만 배열의 요소를 이동하지 않습니까? 즉, Delete(18)를 삭제하면 이 위치에 있는 요소가 삭제되고 예를 들어 이 인덱스에 있는 요소를 요청하면 잘못된 포인터를 얻게 됩니다. 이 경우 19번째 요소가 제거 후 18번째에 끝나도록 요소를 제거하고 이동하는 방법이 있습니까?

표준 라이브러리에서는 작동하지 않았지만 도움말에 따르면 Delete() 메서드는 배열 크기를 조정하여 요소를 물리적으로 제거해야 합니다. 예외: 메모리 관리 메커니즘이 비활성화된 경우. 이 메커니즘은 기본적으로 활성화되어 있습니다. 메모리 관리 플래그의 상태를 확인하기 위해 FreeMode 방법이 사용됩니다.

필자는 CArray 클래스에서 특별한 편리함이나 이점을 보지 못하기 때문에 MQL에서 고유한 배열을 사용하고(C++에서는 벡터와 목록을 사용하지만) 메모리를 직접 관리하는 것이 좋습니다. 내 자신의 배열에서 다음 방법을 사용하여 배열 요소를 충분히 빠르게 삭제합니다.

 template < typename Array>
bool DeleteArrayElement(Array &array[], int nIndex)
{
   int nArraySize = ArraySize (array);
   if (nIndex < 0 || nIndex >= nArraySize)
       return true ;
   
   array[nIndex] = array[nArraySize - 1 ];
   return ( ArrayResize (array, nArraySize - 1 , ARRAY_RESERVE_SIZE) == nArraySize - 1 );
}

유일한 단점은 배열 요소의 순서를 유지하지 않는다는 것입니다. 즉, 정렬된(정렬된) 배열을 제외한 모든 배열에 적용할 수 있습니다.

 

안녕하세요 , 현재 가격에서 일정 포인트, 즉 수동으로 계산하지 않고 주문 창에 들어가지 않도록? 고맙습니다.

추신: 아마도 제가 뭔가 잘못된 것을 묻고 있는 것 같습니다. 저는 스크립트를 사용한 적이 없습니다.

 

" StopLoss 또는 TakeProfit 값이 FreezeLevel 매개변수에 대한 요구 사항을 위반하는 경우 시장 주문 마감은 수행되지 않습니다."

이것은 문자 그대로 TakeProfit 또는 StopLoss가 동결 수준과 일치하지 않으면 시장 주문을 닫을 수 없다는 것을 의미합니까? 나는 공개 시장 주문이 StopLevel 또는 FreezeLevel 규칙을 위반하는 중지를 가질 수 있다는 것을 이해하지 못합니다. 결국 잘못된 중지를 설정하면 서버는 단순히 오류를 제공하고 중지는 설정되지 않습니다.

또한 브로커가 FreezeLevel을 사용할 때 시장가 주문을 마감할 때 알아야 할 기타 사항을 알려주십시오.

Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
  • book.mql4.com
В таблицах указаны расчётные значения, ограничивающие проведение торговых операций при открытии, закрытии, установке, удалении и модификации ордеров. Для получения значения минимальной дистанции StopLevel и дистанции заморозки FreezeLevel необходимо вызвать функцию MarketInfo(). Требования. Правильные цены, используемые при осуществлении...