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

 
안녕하세요, 도움을 요청합니다.
이제 하나의 악기에서만 상태를 확인합니다.
 string SYMBOL_N = "EURUSD" ;

if ( iOpen (SYMBOL_N, PERIOD_CURRENT , 1 )< iClose (SYMBOL_N, PERIOD_CURRENT , 1 )&& iOpen (SYMBOL_N, PERIOD_CURRENT , 2 )> iClose (SYMBOL_N, PERIOD_CURRENT , 2 ));
{ Alert ( "UP" SYMBOL_N); }

다른 도구의 상태를 확인하고 싶습니다.

외부에서 쓸 수 있도록

 input string SYMBOL_N = "EURUSD, GBPUSD, USDJPY, USDCHF" ;


 
Sile Si :
안녕하세요, 도움을 요청합니다.
이제 하나의 악기에서만 상태를 확인합니다.

다른 도구의 상태를 확인하고 싶습니다.

외부에서 쓸 수 있도록



변수 대신 배열 사용

 string SYMBOL_N[4] = "EURUSD, GBPUSD, USDJPY, USDCHF" ;

루프에서 확인

 for ( int i = 0 ; i < 4 ; i++)
 {
   if ( iOpen (SYMBOL_N[i], PERIOD_CURRENT , 1 )< iClose (SYMBOL_N[i], PERIOD_CURRENT , 1 )&& iOpen (SYMBOL_N[i], PERIOD_CURRENT , 2 )> iClose (SYMBOL_N[i], PERIOD_CURRENT , 2 ));
   Alert ( "UP" SYMBOL_N[i]);
 }

이 모든 것을 입력을 통해 입력하려면 한 줄이 필요합니다.

 "EURUSD, GBPUSD, USDJPY, USDCHF"

init에서 배열을 나누고 푸시합니다. 이를 위한 문자열 함수가 있습니다. 그리고 CodeBase에서 그러한 조작의 예를 찾을 수 있습니다.

 
Alexey Viktorov : 변수 대신 배열 사용
 string SYMBOL_N[4] = "EURUSD, GBPUSD, USDJPY, USDCHF" ;

배열은 다음과 같이 설정해야 합니다.

   string SYMBOL_N[ 4 ] = { "EURUSD" , "GBPUSD" , "USDJPY" , "USDCHF" };
 
STARIJ :

배열은 다음과 같이 설정해야 합니다.

맞아요. 그러나 컴파일러는 우리에게 부주의에 대해 아주 명확하게 알려줍니다.
 

안녕하세요. 표시기에 문제가 있습니다. 일반적으로 m1 및 m5에서 발생합니다. 지하실 창과 주 창의 모든 표시기가 동시에 점프하는 것처럼 보입니다. 스크린샷에서 볼 수 있습니다. 지표 중 하나에 대한 코드입니다.

 #property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 Blue 
#property indicator_color2 Green
#property indicator_color3 Green
#property indicator_color4 Red 
#property indicator_color5 LightSeaGreen
#property indicator_color6 Red
#property indicator_color7 LightSeaGreen
#property indicator_color7 LightSeaGreen

extern bool sig_Vred= false ;
extern bool sig_Vsea= false ;
extern bool sig_Vgreen= false ;
extern bool sig_Ngreen= false ;
extern bool sig_Nsea= false ;
extern bool sig_Nred= false ;
extern int     BandsPeriod= 70 ;
extern int     BandsShift= 0 ;
extern int     PeriodsATR= 70 ;
static int sig, my;
static double plus;
//static string gn2, gnm, gns;

double MovingBuffer[];
double UpperBuffer[];
double UpperBmax[];
double UpperBuffer2[];
double LowerBuffer[];
double LowerBmax[];
double LowerBuffer2[];

int init()
  {
   SetIndexBuffer ( 0 ,MovingBuffer);     SetIndexStyle ( 0 , DRAW_NONE ); 
   SetIndexBuffer ( 1 ,UpperBuffer);     SetIndexStyle ( 1 , DRAW_LINE );
   SetIndexBuffer ( 2 ,LowerBuffer);     SetIndexStyle ( 2 , DRAW_LINE );
   SetIndexBuffer ( 3 ,UpperBmax);       SetIndexStyle ( 3 , DRAW_LINE );
   SetIndexBuffer ( 4 ,UpperBuffer2);     SetIndexStyle ( 4 , DRAW_LINE ); //,STYLE_SOLID,2);
   SetIndexBuffer ( 5 ,LowerBmax);       SetIndexStyle ( 5 , DRAW_LINE );  
   SetIndexBuffer ( 6 ,LowerBuffer2);     SetIndexStyle ( 6 , DRAW_LINE ); //,STYLE_SOLID,2);
   SetIndexDrawBegin ( 0 ,BandsPeriod+BandsShift);
   SetIndexDrawBegin ( 1 ,BandsPeriod+BandsShift);
   SetIndexDrawBegin ( 2 ,BandsPeriod+BandsShift);
   SetIndexDrawBegin ( 3 ,BandsPeriod+BandsShift);
   SetIndexDrawBegin ( 4 ,BandsPeriod+BandsShift);
   SetIndexDrawBegin ( 5 ,BandsPeriod+BandsShift);
   SetIndexDrawBegin ( 6 ,BandsPeriod+BandsShift);
   
   if ( Digits == 5 ){ if ( Close [ 0 ]> 1 )plus= 0.0001 ; else plus= 0.00007 ;}
   if ( Digits == 3 ){ if ( Close [ 0 ]> 100 )plus= 0.01 ; else plus= 0.007 ;}    
   if ( Period ()< 10 )plus= 0 ;   if ( Period ()> 60 )plus=plus* 2 ;
   if ( Period ()> 1 ) my= 0 ; else   my= 3 ;

   return ( 0 );
  }

int start()
  {
   static datetime time0;
   static double hig, loww;
   if (time0!= Time [ 0 ]){ time0= Time [ 0 ]; hig= 0 ; loww= 1000 ;}
   if (( High [ 0 ]>hig)||( Low [ 0 ]<loww))  {hig= High [ 0 ]+plus; loww= Low [ 0 ]-plus;
   
   int     i,k,counted_bars= IndicatorCounted ();
   double deviation;
   double sum,oldval;
   
   if ( Bars <=BandsPeriod) return ( 0 );

   if (counted_bars< 1 )
       for (i= 1 ;i<=BandsPeriod;i++)
        {
         MovingBuffer[ Bars -i]= EMPTY_VALUE ;
         UpperBuffer[ Bars -i]= EMPTY_VALUE ;
         UpperBmax[ Bars -i]= EMPTY_VALUE ;
         UpperBuffer2[ Bars -i]= EMPTY_VALUE ;
         LowerBuffer[ Bars -i]= EMPTY_VALUE ;
         LowerBmax[ Bars -i]= EMPTY_VALUE ;
         LowerBuffer2[ Bars -i]= EMPTY_VALUE ;
        }

   int limit= Bars -counted_bars;
   if (counted_bars> 0 ) limit++;
   for (i= 0 ; i<limit; i++)
      MovingBuffer[i]= iMA ( NULL , 0 ,BandsPeriod,BandsShift,my, PRICE_CLOSE ,i);

   i= Bars -BandsPeriod+ 1 ;
   if (counted_bars>BandsPeriod- 1 ) i= Bars -counted_bars- 1 ; if ( Period ()== 1 )i++;
   while (i>= 0 )
     {
      sum= 0.0 ;
      k=i+BandsPeriod- 1 ;
      oldval=MovingBuffer[i];
      
      deviation= iATR ( NULL , 0 ,PeriodsATR,i);
      UpperBmax[i]=oldval+deviation* 6.618 ;
      UpperBuffer2[i]=oldval+deviation* 4.236 ;
      UpperBuffer[i]=oldval+deviation* 1.618 ;
      LowerBuffer[i]=oldval-deviation* 1.618 ;
      LowerBuffer2[i]=oldval-deviation* 4.236 ;
      LowerBmax[i]=oldval-deviation* 6.618 ; 
      i--; 
     }
          
     if (sig_Vred== true && sig== 0 && Close [ 0 ]>UpperBmax[ 0 ]){sig= 1 ; Alert ( Symbol ()+ " Vred " + Period ());} // if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if (sig_Nred== true && sig== 0 && Close [ 0 ]<LowerBmax[ 0 ]){sig= 1 ; Alert ( Symbol ()+ " Nred " + Period ());} // if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}  
     if (sig_Vsea== true && sig== 0 && Close [ 0 ]>UpperBuffer2[ 0 ]){sig= 1 ; Alert ( Symbol ()+ " Vsea " + Period ());} // if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if (sig_Nsea== true && sig== 0 && Close [ 0 ]<LowerBuffer2[ 0 ]){sig= 1 ; Alert ( Symbol ()+ " Nsea " + Period ());} // if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if (sig_Vgreen== true && sig== 0 && Close [ 0 ]>UpperBuffer[ 0 ]){sig= 1 ; Alert ( Symbol ()+ " Vgreen " + Period ());} // if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
     if (sig_Ngreen== true && sig== 0 && Close [ 0 ]<LowerBuffer[ 0 ]){sig= 1 ; Alert ( Symbol ()+ " Ngreen " + Period ());} // if((Hour()>7)&&(Hour()<23)) PlaySound("sigvhod");}
      
     }
   return ( 0 );
  }
 
Alexey Viktorov :

변수 대신 배열 사용

루프에서 확인

이 모든 것을 입력을 통해 입력하려면 한 줄이 필요합니다.

init에서 배열을 나누고 푸시합니다. 이를 위한 문자열 함수가 있습니다. 그리고 CodeBase에서 그러한 조작의 예를 찾을 수 있습니다.


덕분에 잘 되는 것 같지만 여러 쌍에서 동시에 조건이 충족되면 한 쌍에 대해서만 경고가 발생합니다.

때로는 통화 쌍 없이 "UP"만 씁니다. 어떻게 고치는 지?


 #property strict
#property indicator_chart_window

extern string Symbols = "EURUSD, GBPUSD, USDJPY" ; //

string symbols_arr[ 100 ];
datetime time_b;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
         IndicatorShortName ( "UP DN" );
        SetSymbols(Symbols);
//---
   return ( INIT_SUCCEEDED );
  }
   void SetSymbols( string text) {

   int i = 0 , j;

   for (i= 0 ; i< 100 ; i++)
   symbols_arr[i]= "" ;

   i= 0 ;
   string fValue;
   string Str = text;

   while ( StringLen (Str)> 0 ) 
   {
      j = StringFind (Str, "," );
       if (j>= 0 ) 
      {
         fValue = StringSubstr (Str, 0 , j);
         Str    = StringSubstr (Str, j+ 1 );
      } else {
         fValue = Str;
         Str    = "" ;
      }
      fValue= StringTrimLeft (fValue);
      fValue= StringTrimRight (fValue);
      symbols_arr[i]=fValue;
      i++;
   }
   
   //colCount = i;
}
// ----------------- 
//+------------------------------------------------------------------+
//| 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[])
  {
//---


for ( int i = 0 ; i < 100 ; i++)
 {
   if ( iOpen (symbols_arr[i], PERIOD_CURRENT , 1 )< iClose (symbols_arr[i], PERIOD_CURRENT , 1 )&& iOpen (symbols_arr[i], PERIOD_CURRENT , 2 )> iClose (symbols_arr[i], PERIOD_CURRENT , 2 ))
  {
   if (time_b!= iTime (symbols_arr[i], PERIOD_CURRENT , 0 ))
   {
   Alert ( "UP - " ,symbols_arr[i]);
   time_b= iTime (symbols_arr[i], PERIOD_CURRENT , 0 );
   }
  }
 }
   
//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+----


 
Sile Si :

덕분에 잘 되는 것 같지만 여러 쌍에서 동시에 조건이 충족되면 한 쌍에 대해서만 경고가 발생합니다.

때로는 통화 쌍 없이 "UP"만 씁니다. 어떻게 고치는 지?



100회 반복에 루프가 필요한 이유는 무엇입니까? 크기가 100인 배열이 필요한 이유는 무엇입니까?

초기화 문자열 에서 새 문자를 찾을 때 동적으로 만들고 크기를 늘리고 배열을 채우지 않겠습니까?

그리고 채워진 배열의 크기에 따라 반복 횟수에 루프가 있습니다.

어레이에 무엇이 있는지 확인했습니까?

 
Sile Si :

덕분에 잘 되는 것 같지만 여러 쌍에서 동시에 조건이 충족되면 한 쌍에 대해서만 경고가 발생합니다.

때로는 통화 쌍 없이 "UP"만 씁니다. 어떻게 고치는 지?




이렇게 하세요

 int Size_symbols= ArraySize (symbols_arr)
 
for ( int i = 0 ; i < Size_symbols; i++)
  { 
   //  бла..бла..бла
  }


내선 그리고 초기화에서 값을 추가할 때 배열을 늘립니다.

 
Sile Si :

덕분에 잘 되는 것 같지만 여러 쌍에서 동시에 조건이 충족되면 한 쌍에 대해서만 경고가 발생합니다.

때로는 통화 쌍 없이 "UP"만 씁니다. 어떻게 고치는 지?

그래서 시도:

 //+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|              Copyright 2017, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Artem A. Trishkin, Skype artmedia70"
#property link        "https://login.mql5.com/ru/users/artmedia70"
#property version    "1.00"
#property strict
#property indicator_chart_window

input string Symbols = "EURUSD, GBPUSD, USDJPY" ; // Список символов, разделитель - запятая

string symbols_array[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   IndicatorShortName ( "UP DN" );
   ushort sz=SetSymbols(Symbols,symbols_array);
   if (sz== 0 ) {
       Print ( "Список символов пуст!" );
       return ( INIT_FAILED );
      }
//---
   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[])
  {
//---
   static datetime time_b= 0 ,time_s= 0 ;
   for ( int i= 0 ; i< ArraySize (symbols_array); i++) {
       if (Condition(symbols_array[i], 1 )== ORDER_TYPE_BUY ) {
         if (time_b!= iTime (symbols_array[i], PERIOD_CURRENT , 0 )) {
             Alert ( "UP - " ,symbols_array[i]);
            time_b= iTime (symbols_array[i], PERIOD_CURRENT , 0 );
            }
         }
       if (Condition(symbols_array[i], 1 )== ORDER_TYPE_SELL ) {
         if (time_s!= iTime (symbols_array[i], PERIOD_CURRENT , 0 )) {
             Alert ( "Down - " ,symbols_array[i]);
            time_s= iTime (symbols_array[i], PERIOD_CURRENT , 0 );
            }
         }
      }
//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Condition( string symbol_name, int shift) {
   MqlRates array[];
   if ( CopyRates (symbol_name, PERIOD_CURRENT ,shift, 2 ,array)== 2 ){
       if (array[ 0 ].open<array[ 0 ].close && array[ 1 ].open>array[ 1 ].close) return ( ORDER_TYPE_BUY );
       if (array[ 0 ].open>array[ 0 ].close && array[ 1 ].open<array[ 1 ].close) return ( ORDER_TYPE_SELL );
      }
   return ( WRONG_VALUE );
}
//+------------------------------------------------------------------+
ushort SetSymbols( string symbols_list, string &array[]){
   symbols_list+= "," ; // Добавим признак конца строки
   short beg= WRONG_VALUE , end= 1 , len=( short ) StringLen (symbols_list);
   string sy= "" ;
   Print ( __FUNCTION__ , " > " ,symbols_list); // Посмотрим символы в строке
   while (beg<len) {
      beg++;
      end=( short ) StringFind (symbols_list, "," ,beg);
       if (end==beg || end< 0 ) continue ;
      sy= StringSubstr (symbols_list,beg,end-beg);
       if (CheckSymbol(sy,array) || !IsPresentSymbol(sy)) continue ;
       ushort sz=( ushort ) ArraySize (array);
       ArrayResize (array,sz+ 1 );
      array[sz]=sy;
       //--- Посмотрим корректность найденного символа и записи его в массив
       Print ( "beg=" , IntegerToString (beg, 2 , '0' ), ", end=" , IntegerToString (end, 2 , '0' ), ", sy=|" ,sy, "|" , ", in array[" ,sz, "]=" ,array[sz]);
      }
   return (( ushort ) ArraySize (array));
}
//+------------------------------------------------------------------+
bool CheckSymbol( string symbol_name, string &array[]){
   for ( short i= 0 ; i< ArraySize (array); i++) if (array[i]==symbol_name) return ( true );
   return ( false );
}
//+------------------------------------------------------------------+
bool IsPresentSymbol( string symbol_name){
   for ( ushort i= 0 ; i< SymbolsTotal ( false ); i++){
       if ( SymbolName (i, false )==symbol_name) {
         SymbolSelect (symbol_name, true );
         return ( true );
         }
      }
   return ( false );
}
//+------------------------------------------------------------------+

"...하지만 조건이 동시에 여러 쌍에서 충족되면 한 쌍에 대해서만 경고 ..."에 관해서는 다음과 같이 말할 것입니다.

당신은 캐릭터의 시간을 확인하지만 당신이 가지고 있는 모든 캐릭터에 대한 단일 변수에 그것을 씁니다. 당연히 이 현재 막대의 맨 처음 기호에 대해서만 경고가 표시됩니다. 각 심볼에 대해 두 개의 필드(이름 필드와 시간 필드)를 포함하는 구조의 배열이 필요하고 이미 각 심볼에 대한 경고 시간을 여기에 기록합니다.

예를 들면 다음과 같습니다.

 //+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|              Copyright 2017, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Artem A. Trishkin, Skype artmedia70"
#property link        "https://login.mql5.com/ru/users/artmedia70"
#property version    "1.00"
#property strict
#property indicator_chart_window

input string Symbols = "EURUSD, GBPUSD, USDJPY" ; // Список символов, разделитель - запятая
//---
struct SSymbolsData
  {
   string    name;       // Имя символа
   datetime time_alert; // Время последнего алерта
  };
SSymbolsData symbols_array[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   IndicatorShortName ( "UP DN" );
   ushort sz=SetSymbols(Symbols,symbols_array);
   if (sz== 0 ) {
       Print ( "Список символов пуст!" );
       return ( INIT_FAILED );
      }
//---
   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[])
  {
//---
   for ( int i= 0 ; i< ArraySize (symbols_array); i++) {
       if (Condition(symbols_array[i].name, 1 )== ORDER_TYPE_BUY ) {
         datetime tm= iTime (symbols_array[i].name, PERIOD_CURRENT , 0 );
         if (symbols_array[i].time_alert!=tm) {
             Alert ( "UP - " ,symbols_array[i].name, ", time: " , TimeToString (tm, TIME_DATE | TIME_MINUTES ));
            symbols_array[i].time_alert=tm;
            }
         }
       if (Condition(symbols_array[i].name, 1 )== ORDER_TYPE_SELL ) {
         datetime tm= iTime (symbols_array[i].name, PERIOD_CURRENT , 0 );
         if (symbols_array[i].time_alert!=tm) {
             Alert ( "Down - " ,symbols_array[i].name, ", time: " , TimeToString (tm, TIME_DATE | TIME_MINUTES ));
            symbols_array[i].time_alert=tm;
            }
         }
      }
//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Condition( string symbol_name, int shift) {
   MqlRates array[];
   if ( CopyRates (symbol_name, PERIOD_CURRENT ,shift, 2 ,array)== 2 ){
       if (array[ 0 ].open<array[ 0 ].close && array[ 1 ].open>array[ 1 ].close) return ( ORDER_TYPE_BUY );
       if (array[ 0 ].open>array[ 0 ].close && array[ 1 ].open<array[ 1 ].close) return ( ORDER_TYPE_SELL );
      }
   return ( WRONG_VALUE );
}
//+------------------------------------------------------------------+
ushort SetSymbols( string symbols_list,SSymbolsData &array[]){
   symbols_list+= "," ; // Добавим признак конца строки
   short beg= WRONG_VALUE , end= 1 , len=( short ) StringLen (symbols_list);
   string sy= "" ;
   Print ( __FUNCTION__ , " > " ,symbols_list); // Посмотрим символы в строке
   while (beg<len) {
      beg++;
      end=( short ) StringFind (symbols_list, "," ,beg);
       if (end==beg || end< 0 ) continue ;
      sy= StringSubstr (symbols_list,beg,end-beg);
       if (CheckSymbol(sy,array) || !IsPresentSymbol(sy)) continue ;
       ushort sz=( ushort ) ArraySize (array);
       ArrayResize (array,sz+ 1 );
      array[sz].name=sy;
      array[sz].time_alert= 0 ;
       //--- Посмотрим корректность найденного символа и записи его в массив
       Print ( "beg=" , IntegerToString (beg, 2 , '0' ), ", end=" , IntegerToString (end, 2 , '0' ), ", sy=|" ,sy, "|" , ", in array[" ,sz, "]=" ,array[sz].name);
      }
   return (( ushort ) ArraySize (array));
}
//+------------------------------------------------------------------+
bool CheckSymbol( string symbol_name,SSymbolsData &array[]){
   for ( short i= 0 ; i< ArraySize (array); i++) if (array[i].name==symbol_name) return ( true );
   return ( false );
}
//+------------------------------------------------------------------+
bool IsPresentSymbol( string symbol_name){
   for ( ushort i= 0 ; i< SymbolsTotal ( false ); i++){
       if ( SymbolName (i, false )==symbol_name) {
         SymbolSelect (symbol_name, true );
         return ( true );
         }
      }
   return ( false );
}
//+------------------------------------------------------------------+
 
Sile Si :

덕분에 잘 되는 것 같지만 여러 쌍에서 동시에 조건이 충족되면 한 쌍에 대해서만 경고가 발생합니다.

때로는 통화 쌍 없이 "UP"만 씁니다. 어떻게 고치는 지?



문제는 이 줄에 있다

 if (time_b!= iTime (symbols_arr[i], PERIOD_CURRENT , 0 ))

하나의 막대에서 여러 개의 통화를 체크하기 때문에 시간 외에 하나의 막대와 하나의 기호에 대한 경고의 반복을 배제하되 같은 막대에 다른 경고를 허용하기 위해서는 통화도 확인해야 합니다. 상징. 언뜻보기에 플래그가 있는 다른 배열은 문자를 보았는지 여부를 나타냅니다.

일반적으로 이 줄에 기호를 추가하려면 체크를 추가하거나 일반적 으로 새 막대 가 열리는 경우에만 주기를 반복합니다. 그러나 이 표시기가 있는 심볼에 새 막대가 나타날 때 아직 다른 심볼에 새 막대가 그려지지 않은 것입니다.

따라서 결론 : 각 기호에 대한 새로운 막대의 모양을 별도로 결정하기 위해 머리 근육을 긴장시켜야하지만 동시에 라인 수를 무한대로 늘리지 않아야합니다. 준비된 솔루션이 없습니다. 그리고 나는 코드 작성을 제안하고 싶지 않습니다 ...