任何菜鸟问题,为了不给论坛添乱。专业人士,不要路过。没有你就无处可去 - 6. - 页 97

 
hoz:



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

类型,int或datetime
 
artmedia70:
我曾经做了一个函数,向一个空的指示器窗口输出信息。你可以调整显示的线条的颜色。它已经被调试过了。如果你需要,我可以分享。


我很乐意看一下你的代码,Artem。对于测试打印,不是最方便的选择...
 

r772ra:

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

那是什么?


类型,int或datetime

我重写了整个混乱的内容,结果是这样的。

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
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);
}

由于某些原因,即使订单已经关闭,最后的订单关闭时间也 应该是零

我们在评论中一直得到它。

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

这就是为什么我的代码不能进一步工作,因为这个函数不起作用。

 
hoz:

所以我重写了整个乱七八糟的内容,结果是这样的。

由于某些原因,即使在订单关闭时,最后的订单关闭时间也应相应地不为零

我能够在我的评论中一直得到它。

这就是为什么按照我的代码,什么都不能用,因为这个函数不让我进去。

该EA在你的代码中考虑了挂单。那么,它将相应地查看未结订单。自然,它将返回零的关闭时间。

如果您想查看已关闭的订单,您必须在已关闭的订单列表中查看它们。

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

и

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

但是...我们需要做两个函数--一个是寻找未结订单,另一个是寻找已结订单。

 
artmedia70:

它还考虑到你的挂单。因此,它通过未平仓的订单查看。自然,它将返回零的关闭时间。

如果您想查看已关闭的订单,您应该在已关闭的订单列表中查看它们。

и

但是...我们需要做两个函数--一个是寻找未结订单,另一个是寻找已结订单。


谢谢你,阿尔乔姆。没错...接下来是一个代码优化 的问题。有关于代码结构的问题,但要写在一个新的脑袋上。
 
hoz:

我很乐意看一下你的代码,Artem。对于测试打印,这不是最方便的变体......

这里有一个测试该功能的EA。它包含函数本身和它的调用。在调用它之前,你必须准备一条信息,最多四行。如果我没记错的话,每一行的长度不应超过64个字符。这就是为什么我把一条信息分成几行。一条信息的每一行都可以用不同的颜色输出。这在代码中已经很清楚了--首先我们准备好信息行,然后我们调用函数。我没怎么在那里评论过--我很久以前就一口气写完了。现在我已经忘记了那里是干什么的。如果我有任何问题,我会记得,但我现在只记得必要的事情。

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

还有一只火鸡。

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

这就是事实...我希望你能想出办法。

当然,你可以做一个底层,而不是把它输出到主图表上,但我太懒了,不愿意做......。:)

 
artmedia70:

这里有一个测试该功能的EA。它包含函数本身和它的调用。在调用它之前,你必须准备一条信息,最多四行。如果我没记错的话,每一行的长度不应超过64个字符。这就是为什么我把一条信息分成几行。一条信息的每一行都可以用不同的颜色输出。这在代码中已经很清楚了--首先我们准备好信息行,然后我们调用函数。我没怎么在那里评论过--我很久以前就一口气写完了。现在我已经忘记了那里是干什么的。如果我有任何问题,我会记得,但我现在只记得必要的事情。

还有一只火鸡。

这就是事实...我希望你能想出办法。

当然,你可以做一个底层,而不是把它输出到主图表上,但我太懒了,不愿意做......。:)


 

善良的人们!我写了一个EA,在现实生活中一切似乎都很正常。但我在测试器上检查了它--它出现了故障。其主要内容如下。专家顾问应该通过在图表上画出的水平线 来打开订单。在测试器中,它一直在不同的层次上打开它们,就像设置了很多线一样,虽然没有任何线!但这是不可能的。你能解释一下有什么问题吗?

负责行的代码的一部分。

int New_gorizont()

{

int tip_o_buy;

int tip_o_sell;

int obj_total=ObjectsTotal()。

// 如果没有新行,退出

如果(obj_total==0)

返回。

// if(there are...

如果(obj_total!=0)

string name=ObjectName(0);

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

ObjectDelete(name); // 删除并重新设置

if(pr>Bid+(Stop_level+1)*Point) // 确定订单类型。

{

tip_o_sell=OP_SELLLIMIT。

tip_o_buy=OP_BUYSTOP。

}

如果(pr<Bid-(Stop_level+1)*Point)

{

tip_o_sell=OP_SELLSTOP。

tip_o_buy=OP_BUYLIMIT。

}

// 设置订单

OrderSend(Symb,tip_o_sell,Value,pr,3,pr+StopLoss*Point,pr-TakeProfit*Point, "订单设置")。

Prov_oshibok()。

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

}

换句话说,obj_total==0,就可以了。但由于某种原因,它把一切都设置成了无限大。

 
大家好。
日志没有显示挂单 被触发,这是否正常?它发生在测试器中。
该账户是真实的。
 
Dozol:

善良的人们!我写了一个EA,在现实生活中似乎一切正常,一切都很正常。但我在测试器上检查,它出现了故障。


我不相信,这个EA在真实网站和测试器中都不能工作。