Cualquier pregunta de novato, para no saturar el foro. Profesionales, no pasen de largo. En ninguna parte sin ti - 6. - página 97

 
hoz:



 double lastOrderCloseTime = -1,                   // Время закрытия последнего ордера
        lastOrderOpenTime = -1;                     // Время открытия последнего ордера
¿Qué es?

Tipo, int o datetime
 
artmedia70:
Una vez hice una función que emite mensajes a una ventana indicadora vacía. Puede ajustar los colores de las líneas mostradas. Ya está depurado. Si lo necesitas, puedo compartirlo.


Con mucho gusto miraré tu código Artem. Para probar la impresión, no es la opción más conveniente...
 

r772ra:

 double lastOrderCloseTime = -1,                   // Время закрытия последнего ордера
        lastOrderOpenTime = -1;                     // Время открытия последнего ордера

¿Qué es esto?


Tipo, int o datetime

Reescribí todo el lío y quedó así:

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
datetime GetLastOrderState()
{
   datetime lastOrderCloseTime = -1,                   // Время закрытия последнего ордера
            lastOrderOpenTime = -1;                     // Время открытия последнего ордера
   
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
  
      if (lastOrderOpenTime < OrderOpenTime())
      {
          lastOrderOpenTime = OrderOpenTime();
          lastOrderCloseTime = OrderCloseTime();
      }
   }
   Comment("Время закрытия последнего открытого ордера = ", lastOrderCloseTime);
   return (lastOrderCloseTime);
}

Por alguna razón, incluso cuando las órdenes están cerradas y la última hora de cierre de la orden no debe ser cero.

Lo tenemos en el comentario todo el tiempo:

Время закрытия последнего открытого ордера = 0

Por eso mi código no funciona más, porque esta función no funciona.

 
hoz:

Así que reescribí todo el lío y quedó así:

Por alguna razón, incluso cuando las órdenes están cerradas y la última hora de cierre de la orden debe ser correspondientemente no cero.

Yo pude conseguirlo en mi comentario todo el tiempo:

Por eso nada funciona según mi código, porque esta función no me deja entrar.

Este EA considera las órdenes pendientes en su código. Pues bien, buscará entre las órdenes abiertas en consecuencia. Naturalmente, devolverá el tiempo de cierre cero.

Si quiere ver las órdenes cerradas, tiene que verlas en la lista de órdenes cerradas:

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

и

if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;

Pero... tenemos que hacer dos funciones - una busca las órdenes abiertas y la otra busca las órdenes cerradas.

 
artmedia70:

También tiene en cuenta sus órdenes pendientes. Y, en consecuencia, busca entre las órdenes abiertas. Naturalmente, devolverá el tiempo de cierre cero.

Si quiere ver las órdenes cerradas, debe verlas en la lista de las cerradas:

и

Pero... tenemos que hacer dos funciones - una busca las órdenes abiertas y la otra busca las órdenes cerradas.


Gracias, Artyom. Exactamente... Lo siguiente es una cuestión de optimización del código. Hay preguntas sobre la estructura del código, pero habrá que escribirlo con la cabeza fría.
 
hoz:

Con mucho gusto miraré tu código, Artem. Para probar la impresión, no es la variante más conveniente...

Aquí hay un EA para probar la función. Contiene la propia función y su llamada. Antes de llamarlo, hay que preparar un mensaje, que puede tener hasta cuatro líneas. La longitud de cada línea, si no recuerdo mal, no debe superar los 64 caracteres. Por eso he dividido un mensaje en varias líneas. Cada línea de un mensaje puede salir en un color diferente. Está bastante claro en el código: primero preparamos las líneas de mensajes y luego llamamos a la función. No he comentado mucho ahí, lo escribí de un tirón hace tiempo. Ahora ya he olvidado para qué sirve. Si tengo alguna duda, lo recordaré, pero ahora sólo recuerdo las cosas necesarias.

//+------------------------------------------------------------------+
//|                                                Test iPrint().mq4 |
//|                             Copyright © 2013, Artyom A. Trishkin |
//|                                                skype: artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2013, Artyom A. Trishkin"
#property link      "skype: artmedia70"
//+------------------------------------------------------------------+
//| expert variables                                                 |
//+------------------------------------------------------------------+
int            a,b,c;
string         Exp_Name, Prefix, pref,
               message1, message2, message3, message4, 
               Mass_Name_Message[10];
//+----------------------------------------------------------------------------+
int init() {
   Exp_Name=WindowExpertName(); 
   pref="_r";
   if (IsDemo()) pref="_d";
   if (IsTesting()) pref="_t";
   if (IsVisualMode()) pref="_v";
   Prefix=Exp_Name+"_"+Symbol()+pref;  
//----------------------------
   return;                                         // Выход из init() 
}
//+----------------------------------------------------------------------------+
int deinit() {
   if (!IsTesting()) {
      Comment("");
// -------- Блок удаления всех объектов, построенных на графике --------
      string Name_Del[1]; 
      int Quant_Del=0;                    
      int Quant_Objects=ObjectsTotal();   
      int LenPref=StringLen(Prefix);
      ArrayResize(Name_Del,Quant_Objects);
      for(int k=0; k<Quant_Objects; k++) {
         string Obj_Name=ObjectName(k);   
         string Head=StringSubstr(Obj_Name,0,LenPref);
         if (Head==Prefix) {                              
            Quant_Del+=1;        
            Name_Del[Quant_Del-1]=Obj_Name;
            }
        }
      for(int i=0; i<Quant_Del; i++)    
         ObjectDelete(Name_Del[i]); 
// ----- Конец блока удаления всех объектов, построенных на графике -----
      }
   return;                                // Выход из deinit()
}
//+----------------------------------------------------------------------------+
int start()
  {
//-------------------------------------------------------
// Подготавливаем первое сообщение
   message1=StringConcatenate("Первое сообщение из двух строк: Тик: ",GetTickCount()," ");
   message2=StringConcatenate("Цена Bid: ", DoubleToStr(Bid,Digits));
   iPrint(false, message1, message2, "", "", 9, Aqua, DarkOrange);   // Выводим первое
   Sleep(3000);
//-------------------------------------------------------
// Подготавливаем второе сообщение
   b=4; c=7;
   a=b+c;
   message1=StringConcatenate("Второе сообщение из трёх строк: a=",a," ");
   message2=StringConcatenate("b=",b," ");
   message3=StringConcatenate("c=",c);
   iPrint(false, message1, message2, message3, "", 9, Aqua, LimeGreen, DarkOrange); // Выводим второе
   Sleep(3000);
//-------------------------------------------------------
// Подготавливаем третье сообщение
   message1=StringConcatenate("Третье сообщение из четырёх строк: Время: ", TimeToStr(TimeCurrent())," ");
   message2=StringConcatenate("Тик: ",GetTickCount()," ");
   message3=StringConcatenate("Время бара: ",TimeToStr(Time[0])," ");
   message4=StringConcatenate("Цена Bid: ", DoubleToStr(Bid,Digits));
   iPrint(false, message1, message2, message3, message4, 9, Aqua, Aqua, Aqua, DarkOrange);// Выводим третье
   Sleep(3000);
//-------------------------------------------------------
   return(0);
  }
//+----------------------------------------------------------------------------+
// Если bool print = true или нет окна индикатора, то функция будет выводить сообщения в журнал
void iPrint(bool print, string mess1, string mess2="", string mess3="", string mess4="", 
            int sz=9, color cl1=Aqua, color cl2=Aqua, color cl3=Aqua, color cl4=Aqua) {
   string   NameGrafText, message, nm;
   int      i, y, k, LenStr, shift, Win_Num=-1, num=0;
   color    cl;
   if (mess1=="") {
      Print("Func iPrint: Передана пустая строка, выходим");
      return;
      }
   Win_Num=WindowFind("Win_Inform");
   if (print || Win_Num<0) {
      message=mess1+mess2+mess3+mess4;
      Print(message); 
      return;
      }
   k=ArraySize(Mass_Name_Message)-1;
   if (StringLen(mess1)>0) num++;
   if (StringLen(mess2)>0) num++;
   if (StringLen(mess3)>0) num++;
   if (StringLen(mess4)>0) num++;
   for (i=k; i>=0; i--) {                             
      NameGrafText=Mass_Name_Message[i];           
      if (StringLen(NameGrafText)>0)
      if (ObjectFind(NameGrafText)==Win_Num) {
         if (i+num>k) {
            ObjectDelete(NameGrafText);  
            Mass_Name_Message[i]="";
            }
         else if (i+num<=k) {             // Сдвигаем и перекрашиваем старые сообщения
            Mass_Name_Message[i+num]=Mass_Name_Message[i];
            y=ObjectGet(NameGrafText, OBJPROP_YDISTANCE);               // координата Y
            ObjectSet  (NameGrafText, OBJPROP_YDISTANCE, y+(sz+1)*num); // координата Y
            ObjectSet  (NameGrafText, OBJPROP_COLOR, DimGray);          // цвет
            }
         }
      }
   shift=num;
   int v=GetTickCount();
   for (i=0; i<num; i++) {
      shift--;
      NameGrafText=Prefix+"_Graf_Text_"+i+"_"+Symbol()+"_"+v;  // Уникальное имя объекта
      int app=0;
      while (ObjectFind(NameGrafText)==Win_Num) {
         app++;
         NameGrafText=Prefix+"_Graf_Text_"+i+"_"+Symbol()+"_"+v+"_"+app;
         }
      Mass_Name_Message[num-1-i]=NameGrafText;
      switch (i) {
         case 0: message=mess1; cl=cl1; break;
         case 1: message=mess2; cl=cl2; break;
         case 2: message=mess3; cl=cl3; break;
         case 3: message=mess4; cl=cl4; break;
         default:message=mess1; cl=cl1; break;
         }
      ObjectCreate (NameGrafText, OBJ_LABEL, Win_Num, 0, 0);
      ObjectSetText(NameGrafText, message, sz, "Courier New", cl);
      ObjectSet    (NameGrafText, OBJPROP_COLOR, cl);                   // цвет
      ObjectSet    (NameGrafText, OBJPROP_CORNER,    2);                // угол
      ObjectSet    (NameGrafText, OBJPROP_XDISTANCE, 150);              // координата Х
      ObjectSet    (NameGrafText, OBJPROP_YDISTANCE, 2+(sz+1)*shift);   // координата Y
      WindowRedraw();
      }
//---------------------------------      
   nm=Prefix+"_Balance_txt";
   message="Баланс :";
   cl=Yellow;
   SetText(message, cl, nm, 2, 4, 20, "Arial", 9, Win_Num);
   nm=Prefix+"_Balance";
   message=DoubleToStr(AccountBalance(),2);
   cl=DarkTurquoise;
   SetText(message, cl, nm, 2, 70, 20, "Arial", 9, Win_Num);
//---------------------------------      
   nm=Prefix+"_Equity_txt";
   message="Средства :";
   cl=Yellow;
   SetText(message, cl, nm, 2, 4, 8, "Arial", 9, Win_Num);
   nm=Prefix+"_Equity";
   message=DoubleToStr(AccountEquity(),2);
   cl=DarkTurquoise;
   SetText(message, cl, nm, 2, 70, 8, "Arial", 9, Win_Num);
//---------------------------------      
}
//+----------------------------------------------------------------------------+
void SetText(string Text, color cl, string nm, int angle, int x, int y, string font, int sz=0, int wnd=0) {
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_LABEL, wnd, 0, 0);
   ObjectSet(nm, OBJPROP_CORNER   , angle);
   ObjectSet(nm, OBJPROP_XDISTANCE, x);
   ObjectSet(nm, OBJPROP_YDISTANCE, y);
   ObjectSet(nm, OBJPROP_WIDTH    , sz);
   ObjectSetText(nm, Text, sz, font, cl);
   }
//+----------------------------------------------------------------------------+

Y un pavo:

//+------------------------------------------------------------------+
//|                                                   Win_Inform.mq4 |
//|                                Copyright © 2012, Artyom Trishkin |
//|                                                skype: artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, Artyom Trishkin"
#property link      "skype: artmedia70"

#property indicator_separate_window
int start()
  {
  }
//+------------------------------------------------------------------+

Así es... Espero que lo descubras.

Por supuesto, se puede hacer una subcapa en lugar de emitirla en el gráfico principal, pero soy demasiado perezoso para hacerlo... :)

 
artmedia70:

Aquí hay un EA para probar la función. Contiene la propia función y su llamada. Antes de llamarlo, hay que preparar un mensaje, que puede tener hasta cuatro líneas. La longitud de cada línea, si no recuerdo mal, no debe superar los 64 caracteres. Por eso he dividido un mensaje en varias líneas. Cada línea de un mensaje puede salir en un color diferente. Está bastante claro en el código: primero preparamos las líneas de mensajes y luego llamamos a la función. No he comentado mucho ahí - lo escribí de un tirón hace tiempo. Ahora ya he olvidado para qué sirve. Si tengo alguna duda, lo recordaré, pero ahora sólo recuerdo las cosas necesarias.

Y un pavo:

Así es... Espero que lo descubras.

Por supuesto, se puede hacer una subcapa en lugar de emitirla en el gráfico principal, pero soy demasiado perezoso para hacerlo... :)


 

¡Buena gente! He escrito un EA, todo parece funcionar bien en la vida real, todo es normal. Pero lo compruebo en el probador: falla. La idea es la siguiente. El Asesor Experto debe abrir las órdenes mediante líneas horizontales dibujadas en el gráfico. En el probador, los abre en varios niveles todo el tiempo, como si se hubieran puesto muchas líneas, ¡aunque no hay ninguna! ¿Puede explicar qué es lo que está mal?

Una parte del código responsable de las líneas:

int Nuevo_gorizont()

{

int consejo_o_compra;

int tip_o_sell;

int obj_total=ObjectsTotal();

// si no hay nuevas líneas, salir

if(obj_total==0)

volver;

// si(hay...

if(obj_total!=0)

string name=Nombre del objeto(0);

double pr=NormalizeDouble(ObjectGet(name,1),Digits);

ObjectDelete(nombre); // borrar y volver a poner

if(pr>Bid+(Nivel_de_parada+1)*Punto) // determinar el tipo de orden

{

tip_o_sell=OP_SELLLIMIT;

tip_o_buy=OP_BUYSTOP;

}

if(pr<Bid-(Nivel_de_parada+1)*Punto)

{

tip_o_sell=OP_SELLSTOP;

tip_o_buy=OP_BUYLIMIT;

}

// establecer órdenes

OrderSend(Symb,tip_o_sell,Value,pr,3,pr+StopLoss*Point,pr-TakeProfit*Point, "Order set");

Prov_oshibok();

................................

}

En otras palabras, obj_total==0 y eso es todo. Pero se pone y pone todo al infinito por alguna razón.

 
Hola a todos.
¿Es normal que el registro no muestre que una orden pendiente se ha activado? Sucede en el probador.
La cuenta es real.
 
Dozol:

¡Buena gente! He escrito un EA, todo parece funcionar bien en la vida real, todo es normal. Pero lo compruebo en el probador y falla.


No me lo creo, este EA no puede funcionar ni en el sitio real ni en el tester.