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

 

Mashka 표준 코드

 #property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//--- indicator parameters
input int             InpMAPeriod= 13 ;         // Period
input int             InpMAShift= 0 ;           // Shift
input ENUM_MA_METHOD InpMAMethod= MODE_SMA ;   // Method
//--- indicator buffer
double ExtLineBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ( void )
  {
   string short_name;
   int     draw_begin=InpMAPeriod- 1 ;
//--- indicator short name
   switch (InpMAMethod)
     {
       case MODE_SMA   : short_name= "SMA(" ;                 break ;
       case MODE_EMA   : short_name= "EMA(" ;  draw_begin= 0 ; break ;
       case MODE_SMMA : short_name= "SMMA(" ;               break ;
       case MODE_LWMA : short_name= "LWMA(" ;               break ;
       default :         return ( INIT_FAILED );
     }
   IndicatorShortName(short_name+ string (InpMAPeriod)+ ")" );
   IndicatorDigits( Digits );
//--- check for input
   if (InpMAPeriod< 2 )
       return ( INIT_FAILED );
//--- drawing settings
   SetIndexStyle( 0 , DRAW_LINE );
   SetIndexShift( 0 ,InpMAShift);
   SetIndexDrawBegin( 0 ,draw_begin);
//--- indicator buffers mapping
   SetIndexBuffer ( 0 ,ExtLineBuffer);
//--- initialization done
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//|  Moving Average                                                  |
//+------------------------------------------------------------------+
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[])
  {
//--- check for bars count
   if (rates_total<InpMAPeriod- 1 || InpMAPeriod< 2 )
       return ( 0 );
//--- counting from 0 to rates_total
   ArraySetAsSeries (ExtLineBuffer, false );
   ArraySetAsSeries (close, false );
//--- first calculation or number of bars was changed
   if (prev_calculated== 0 )
       ArrayInitialize (ExtLineBuffer, 0 );
//--- calculation
   switch (InpMAMethod)
     {
       case MODE_EMA :  CalculateEMA(rates_total,prev_calculated,close);         break ;
       case MODE_LWMA : CalculateLWMA(rates_total,prev_calculated,close);       break ;
       case MODE_SMMA : CalculateSmoothedMA(rates_total,prev_calculated,close); break ;
       case MODE_SMA :  CalculateSimpleMA(rates_total,prev_calculated,close);   break ;
     }
//--- return value of prev_calculated for next call
   return (rates_total);
  }

나는 모든 코드를 게시하지 않습니다. 왜냐하면 추가 계산, 질문은 초기화와 관련이 있습니다.

기간을 변경할 때 " InpMAPeriod " 값을 변경하는 방법입니다.

예: M15에서 - " InpMAPeriod "

M30에서 - " InpMAPeriod2 "

저는 프로그래머가 아닙니다. 도와주세요.

 

나는 길을 잃었습니다 - 내 눈이 거짓말을 하거나 뭔가를 놓쳤습니다


다음은 계산 공식입니다.

 double Phase_Value_2( int index, double point, int period)
  {
   
   double muving = 0 , flat = 0 , up = EMPTY_VALUE , down = EMPTY_VALUE ;
   int limit = index + (period > 1 ? period : 1 );
   for ( int i = index; i < limit; i++)
     {
       if (High[i] <= High[i+ 1 ] && Low[i] >= Low[i+ 1 ])
        {
         flat += High[i] - Low[i];
        }
       else if ( MathMax (High[i],High[i+ 1 ]) - MathMin (Low[i],Low[i+ 1 ]) < High[i] - Low[i] + High[i+ 1 ] - Low[i+ 1 ])
        {
         muving += High[i] - Low[i];
        }
       else
        {
         up     = (High[i] > High[i+ 1 ] ? High[i] - High[i+ 1 ] : 0 );
         down   = (Low[i] < Low[i+ 1 ] ? Low[i+ 1 ] - Low[i] : 0 );
         muving += up + down;
         up     = MathMin (High[i],High[i+ 1 ]);
         down   = MathMax (Low[i],Low[i+ 1 ]);
         flat   += up - down;
        };
     };
   
   muving = (muving == 0 ? 1 * point : muving);
   flat   = (flat == 0 ? 1 * point : flat);
   if (flat <= muving && flat / muving > 1 ) Print ( "index " ,( string )index, " " ,( string )flat, " / " ,( string )muving, " = " ,( string )(flat/muving));
   //-----------------------------------------------------------------
   return (muving < flat ? ( 1 - (muving / flat)) * (- 1 ) : 1 - (flat / muving));
  }

...이 시점에서 모든 값은 1 ~ -1 범위에서 올바르게 반환됩니다.


그러나 이러한 값이 버퍼에서 인쇄되면 범위가 위반됩니다 (버퍼에서 범위는 이미 100에서 -100까지입니다)

다음은 주기입니다.

 for ( int i = limit_slowing; i >= 0 ; i--)
     {
       if (p_slowing > 1 ) {Slowing(i,( int )p_slowing,p_method,P);}
       else               {P[i] = Phase_Value_2(i, _Point ,( int )p_period) * 100 ;}; if (P[i] > 100 || P[i] < - 100 ) Print ( "index " ,( string )i, ", value " ,( string )P[i]);
     };


중재자 내부에서는 추가가 발생하지 않고 100을 곱하기만 합니다.

 void Slowing( int index, int slowing, ENUM_MA_METHOD method, double &Bufer[])
  {
   
   double value = 0 , c = 2 / ( double )(slowing+ 1 ); int limit, period = slowing, sum_period = 0 ;
   
   if (method == MODE_SMA)
     {
      limit = index + slowing;
       for ( int i = index; i < limit; i++) value += Inhibitor[i];
       Bufer[index] = ( value / ( double )slowing) * 100 ;
     }
   
   else if (method == MODE_EMA)
     {
       if (Bufer[index+ 1 ] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for ( int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = ( value / ( double )slowing) * 100 ; return ;
        };
       Bufer[index] = (c * Inhibitor[index] + ( 1 -c) * (Bufer[index+ 1 ]/ 100 )) * 100 ;
     }
   
   else if (method == MODE_SMMA)
     {
       if (Bufer[index+ 1 ] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for ( int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = ( value / ( double )slowing) * 100 ; return ;
        };
       if (Bufer[index+ 1 ] != EMPTY_VALUE && Bufer[index+ 2 ] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for ( int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = (( value - (Bufer[index+ 1 ]/ 100 ) + Inhibitor[index]) / ( double )slowing) * 100 ; return ;
        };
       value = (Bufer[index+ 1 ]/ 100 ) * ( double )slowing;
       Bufer[index] = (( value - (Bufer[index+ 1 ]/ 100 ) + Inhibitor[index]) / ( double )slowing) * 100 ;
     }
   
   else
     {
      limit = index + slowing;
       for ( int i = index; i < limit; i++)
        {
         value += Inhibitor[i] * ( double )period;
         sum_period += period; period--;
        };
       Bufer[index] = value / ( double )sum_period * 100 ;
     };
   
  }


문제가 무엇입니까?

 
Alexandr Sokolov :

나는 길을 잃었습니다 - 내 눈이 거짓말을 하거나 뭔가를 놓쳤습니다

문제가 무엇입니까?

코드를 전혀 이해하지 못했습니다.

 *100
100.0으로 교체해 보세요.
 
Vitaly Muzichenko :

코드를 전혀 이해하지 못했습니다.

100.0으로 교체해 보세요.

시도했지만 도움이되지 않았습니다

 
ukrop1203 :
안녕하세요, 전문가 테스트가 끝난 후 삭제되지 않은 개체에 대한 오류가 발생하고 내가 이해하는 한 절대적으로 모든 개체를 스택에서, 즉 새 개체 없이 생성합니다. 이 질문에 대해 설명해 주십시오.

2번을 시도하고 질문에 답하십시오.

 
ukrop1203 :

2번을 시도하고 질문에 답하십시오.

기적은 일어나지 않습니다. 그가 누출되었다고 쓴다면, 그것은 그가 그것을 힙 어딘가에서 골라내고 잊어 버렸다는 것을 의미합니다. 검색. 또는 생성자를 입력하십시오.

 if ( CheckPointer (& this )== POINTER_DYNAMIC ) DebugBreak ();

디버거 아래에 위치를 잡습니다.

 
bool CloseByBu(OpenModel& open_model) { 
   bool closed_by_bu = False;
   if ( OrderSelect (open_model.bu_ticket, SELECT_BY_TICKET, MODE_TRADES) && OrderType() <= 1 ) {
      closed_by_bu = OrderCloseBy(open_model.bu_ticket, open_model.ticket);   
       if (!closed_by_bu) {         
         PrintMessageInLog( StringFormat ( "DIDN'T CLOSE order by opposite order first ticket=%i, second ticket=%i, error=%i" , 
			   		open_model.ticket, open_model.bu_ticket, GetLastError ()));         
         PrintMessageInLog( StringFormat ( "First order selected=%s, order type=%i, order price=%f" , 
                           		string ( OrderSelect (open_model.ticket, SELECT_BY_TICKET, MODE_TRADES)), OrderType(), OrderOpenPrice()));
         PrintMessageInLog( StringFormat ( "Second order selected=%s, order type=%i, order price=%f" , 
                           		string ( OrderSelect (open_model.bu_ticket, SELECT_BY_TICKET, MODE_TRADES)), OrderType(), OrderOpenPrice()));                                       
      }
   }   
   return closed_by_bu;
}

2018.01.02 08:01:30 DIDN'T CLOSE 반대 순서로 주문 첫 번째 티켓=2, 두 번째 티켓=3, 오류=3

2018.01.02 08:01:30 첫 번째 주문 선택=true, 주문 유형=1, 주문 가격=1.351920

2018.01.02 08:01:30 두 번째 주문 선택=true, 주문 유형=0, 주문 가격=1.351590


두 개의 카운터 주문을 마감하지 않습니다. 설명하십시오.

 

수직선 을 그리기 위한 2개의 오버로드된 함수가 컴파일러에서 승인된 이유(첫 번째 - 색상 선택, 두 번째 - 색상 및 창) 및 둘 다 사용할 수 있지만 세 번째 기능을 추가할 때 색상 선택, 창 및 스타일, 맹세하고 모든 기능을 세 번째 유형에 따라 작성하도록 강제합니다.


 void VLine( int window= 0 ) {
 
  
 string nm= "VLINE" +( string )(Time[ 0 ]);
 
   if ( ObjectFind (nm)< 0 ) ObjectCreate (nm, OBJ_VLINE , window, 0 , 0 );
  ObjectSet(nm, OBJPROP_TIME1, Time[ 0 ]);
  ObjectSet(nm, OBJPROP_COLOR , Red);
  ObjectSet(nm, OBJPROP_STYLE , 0 );
  ObjectSet(nm, OBJPROP_WIDTH , 1 );
   ObjectSetString ( 0 ,nm, OBJPROP_TOOLTIP , "\n" );
}


void VLine( color cl, int window= 0 ) {
 
  
 string nm= "VLINE" +( string )(Time[ 0 ]);
 
   if ( ObjectFind (nm)< 0 ) ObjectCreate (nm, OBJ_VLINE , window, 0 , 0 );
  ObjectSet(nm, OBJPROP_TIME1, Time[ 0 ]);
  ObjectSet(nm, OBJPROP_COLOR , cl);
  ObjectSet(nm, OBJPROP_STYLE , 0 );
  ObjectSet(nm, OBJPROP_WIDTH , 1 );
   ObjectSetString ( 0 ,nm, OBJPROP_TOOLTIP , "\n" );
}




void VLine( color cl, int window= 0 , int style= 0 ) {
 
 
 string nm= "STOPLINE" +( string )(Time[ 0 ]);
 
   if ( ObjectFind (nm)< 0 ) ObjectCreate (nm, OBJ_VLINE , window, 0 , 0 );
  ObjectSet(nm, OBJPROP_TIME1, Time[ 0 ]);
  ObjectSet(nm, OBJPROP_COLOR , cl);
  ObjectSet(nm, OBJPROP_STYLE , style);
  ObjectSet(nm, OBJPROP_WIDTH , 1 );
   ObjectSetString ( 0 ,nm, OBJPROP_TOOLTIP , "\n" );
}
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
  • www.mql5.com
При создании графического объекта функцией ObjectCreate() необходимо указать тип создаваемого объекта, который может принимать одно из значений перечисления ENUM_OBJECT. Дальнейшие уточнения свойств созданного объекта возможно с помощью функций по работе с графическими объектами.
 
Viatcheslav Pashkov :

수직선 을 그리기 위한 2개의 오버로드된 함수가 컴파일러에서 승인된 이유(첫 번째 - 색상 선택, 두 번째 - 색상 및 창) 및 둘 다 사용할 수 있지만 세 번째 기능을 추가할 때 색상 선택, 창 및 스타일, 맹세하고 모든 기능을 세 번째 유형에 따라 작성하도록 강제합니다.


기본값은 입력 매개변수의 존재를 무효화합니다. 존재하지 않는다고 생각하십시오. 그리고 컴파일러가 올바른 함수를 선택할 수 있는지 확인하십시오.

 
ukrop1203 :

두 개의 카운터 주문을 마감하지 않습니다. 설명하십시오.

이론상으로는 코드가 작동해야 합니다. 제가 틀릴 수도 있지만 모든 브로커가 이 작업을 수행할 수 있는 것은 아닙니다. Metaquotes 데모에서 확인해보세요. 확실히 작동했습니다.