Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 208

 
Hola, ayuda por favor.
Ahora mismo sólo estoy probando la condición en un instrumento.
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); }

Quiero comprobar el estado de diferentes instrumentos.

De modo que los externos pueden escribirse como sigue

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


 
Sile Si:
Hola, ayuda por favor.
Ahora mismo sólo estoy probando la condición en un instrumento.

Quiero comprobar el estado de diferentes instrumentos.

Quiero poder escribirlo en los externos así



Utilizar una matriz en lugar de una variable

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

y comprobarlo en el bucle.

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]);
 }

Para introducir todo esto a través de la entrada, se necesita una cadena

"EURUSD, GBPUSD, USDJPY, USDCHF"

en la entrada para dividirla y ponerla en un array. Hay funciones de cadena para esto. Y puede encontrar ejemplos de tales manipulaciones en CodeBase.

 
Alexey Viktorov:    Utilizar una matriz en lugar de una variable
string SYMBOL_N[4] = "EURUSD, GBPUSD, USDJPY, USDCHF";

La mejor manera de definir una matriz es la siguiente

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

Es mejor establecer la matriz de la siguiente manera

Eso es exactamente así. Pero el compilador nos habla de la falta de atención con bastante claridad.
 

Hola. Tengo un problema con los indicadores, suele ocurrir en m1 y m5. Parece un salto en todos los indicadores de la ventana del sótano y la principal al mismo tiempo, se puede ver en las capturas de pantalla. El código de uno de los indicadores.

#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:

Utilizar una matriz en lugar de una variable

y comprobarlo en el bucle.

Para introducir todo esto a través de la entrada se necesita una cadena

Inite split y mételo en un array. Hay funciones de cadena para esto. Y puede encontrar ejemplos de tales manipulaciones en CodeBase.


Gracias, parece que funciona, pero si una condición se cumple en varios pares al mismo tiempo, la alerta es sólo en un par.

A veces sólo dice "UP" sin par de divisas. ¿Cómo solucionarlo?


#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:

Gracias, parece que funciona, pero si la condición en varios pares se cumple al mismo tiempo, la alerta es sólo en un par.

A veces sólo dice "UP" sin el par de divisas. ¿Cómo solucionarlo?



¿Por qué hay que hacer un bucle de 100 iteraciones? ¿Por qué necesitas 100 de matriz?

¿Por qué no hacerlo dinámico, y aumentar su tamaño y llenar el array a medida que se encuentra un nuevo símbolo en la cadena de inicialización?

Y luego el bucle en el número de iteraciones en el tamaño de la matriz llena.

¿Has comprobado lo que tienes en la matriz?

 
Sile Si:

Gracias, parece que funciona, pero si la condición en varios pares se cumple al mismo tiempo, la alerta es sólo en un par.

A veces sólo dice "UP" sin el par de divisas. ¿Cómo puedo solucionarlo?




Hazlo así

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


Dob. Y en el inite, incrementa el array a medida que le añades un valor

 
Sile Si:

Gracias, parece que funciona, pero si la condición en varios pares se cumple al mismo tiempo, la alerta es sólo en un par.

A veces sólo dice "UP" sin el par de divisas. ¿Cómo solucionarlo?

Bueno, pruébalo:

//+------------------------------------------------------------------+
//|                                                         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);
}
//+------------------------------------------------------------------+

Sobre "...pero si simultáneamente en varios pares se cumple la condición, la alerta es sólo en un par..." diré esto:

Compruebas el tiempo de un símbolo, pero lo escribes en una sola variable para todos los símbolos que tengas. Naturalmente, y sólo habrá una alerta en el primer símbolo de esta barra actual. Necesitas un array de estructuras con dos campos para cada símbolo - campo nombre y campo tiempo, y ya escribir los tiempos de alerta para cada símbolo en él.

Por ejemplo, así:

//+------------------------------------------------------------------+
//|                                                         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:

Gracias, parece que funciona, pero si la condición en varios pares se cumple al mismo tiempo, la alerta es sólo en un par.

A veces sólo dice "UP" sin el par de divisas. ¿Cómo puedo solucionarlo?



El problema está en esta línea

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

Dado que compruebo varias divisas en una barra, además de la hora debería comprobar también la divisa para no repetir la alerta en una barra y un símbolo pero permitir hacer una alerta en la misma barra con un símbolo diferente. A primera vista, necesitamos un array más con banderas de si el símbolo es visto o no.

En general, se puede añadir una comprobación del símbolo a esta línea, o repetir el ciclo sólo con la condición de que se abra una nueva barra. Pero tengo el temor de que cuando hay una nueva barra en el símbolo con este indicador, la nueva barra aún no ha aparecido para otro símbolo.

La conclusión: debemos forzar los músculos de la cabeza para determinar si aparece una nueva barra en cada símbolo por separado, pero al mismo tiempo no estirar el número de líneas hasta el infinito. No tengo ninguna solución preparada. Y no me gusta sugerirlo escribiendo código...

Razón de la queja: