新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 614

 
Vitaly Muzichenko:

好吧,你已经展示了非关键性的错误。

该功能如何运作,你自己已经回答了。


在测试器中,它很好。这就是实践中的运作方式。
附加的文件:
yOXZsAXZ-X4.jpg  479 kb
 
Tigerfreerun:
在测试器中,它是好的。这就是它在实践中的作用。

在这种情况下,你需要处理代码,打印(Print(...))所有的值,看看错误来自哪里。

 
Tigerfreerun:
在测试器中,它很好。这就是它在实践中的作用。

你刚刚得到了你的答案。

关于交易、自动交易系统和交易策略测试的论坛

初学者对MQL4的任何问题,对算法和代码的帮助和讨论

Alexey Viktorov, 2018.09.06 21:00

需要思考的方向:如果利润小于零...在排序过程中,阵列会有多大?

如果完全没有订单,那么阵列的大小是多少?
想一想,如果所有的利润都不大于0,那么第一维的可排序数组a[][2]的大小将是多少。
 

下午好,这个EA叫做 "Rollover",但它没有按计划工作。 如果它以负数收盘,它就会将手数加倍,但随后的TP收盘由于某种原因不允许返回负数交易,而这些交易之前已经关闭。请告诉我哪里出了问题,我搞不清楚。我想用西班牙语提问。

extern string TimeStart    = "04:00";  //Время начала контрольного периода
extern string TimeEnd      = "09:00";  //Время окончания контрольного периода
extern string TimeCloseOrder = "23:30";//Время в которое происходит закрытие всех ордеров
extern double LOT          = 0.1;
extern int    Magic        = 777;
extern double K_martin     = 2;
extern bool   No_Loss      = true;
int slippage = 3;
double marga,Lot,SL,TP;
int tip,Orders,tipOrders,TradeDey;
//-------------------------------------------------------------------+
int init()
{
   if (Digits==5 || Digits==3) slippage = 30;
}
int start()
{
   datetime Time_Start      = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeStart,     ":00"));
   datetime Time_End        = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeEnd,       ":00"));
   datetime Time_CloseOrder = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeCloseOrder,":00"));

   if (Time_CloseOrder>Time_End) if (CurTime()>=Time_CloseOrder) CLOSEORDERS();

   int tip;
   if (Orders>OrdersTotal()) tip=CloseOrder();
   Orders=OrdersTotal();

   if (ORDERS(0)==0 && tip==0 && (CurTime()<Time_CloseOrder || Time_CloseOrder<=Time_End) && TradeDey!=TimeDay(CurTime()))
   {
      int BarStart = iBarShift(NULL,0,Time_Start,false);
      int BarEnd   = iBarShift(NULL,0,Time_End  ,false);
      double Max_Price=iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,BarStart-BarEnd,BarEnd));
      double Min_Price=iLow (NULL,0,iLowest (NULL,0,MODE_LOW, BarStart-BarEnd,BarEnd));
   
      if (TimeCurrent()>Time_End && ObjectFind("bar0"+Time_End)==-1)
      {
         ObjectCreate("bar0"+Time_End, OBJ_RECTANGLE, 0, 0,0, 0,0);
         ObjectSet   ("bar0"+Time_End, OBJPROP_STYLE, STYLE_SOLID);
         ObjectSet   ("bar0"+Time_End, OBJPROP_COLOR, Blue);
         ObjectSet   ("bar0"+Time_End, OBJPROP_BACK,  true);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME1 ,Time_Start);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE1,Max_Price);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME2 ,Time_End);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE2,Min_Price);
      }
      
      if (Bid>Max_Price) OrderSend(Symbol(),OP_BUY,LOT,Bid,slippage,Min_Price,
         NormalizeDouble(Ask + Max_Price-Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      if (Bid<Min_Price) OrderSend(Symbol(),OP_SELL,LOT,Bid,slippage,Max_Price,
         NormalizeDouble(Bid - Max_Price+Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      return;
   }
   if (No_Loss) No_Loss();
   if (tip==1 && TradeDey!=TimeDay(CurTime()))
   {
      Lot=Lot*K_martin;
      if (tipOrders==0) OrderSend(Symbol(),OP_SELL,Lot,Bid,slippage,SL,TP,"Nevalyashka",Magic,Blue);
      if (tipOrders==1) OrderSend(Symbol(),OP_BUY ,Lot,Ask,slippage,SL,TP,"Nevalyashka",Magic,Blue);
   }
   return(0);
}
//-------------------------------------------------------------------+
int CloseOrder()
{
   string txt;
   double loss;
   int i=OrdersHistoryTotal()-1;
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
   {                                     
      if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
      {
         tipOrders=OrderType();
         Lot=OrderLots();
         loss = MathAbs(OrderProfit()/MarketInfo(Symbol(),MODE_TICKVALUE)/Lot/K_martin);
         if (tipOrders==0)
         {
            TP=NormalizeDouble(Bid - loss*Point,Digits);
            SL=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (tipOrders==1)
         {
            SL=NormalizeDouble(Bid - loss*Point,Digits);
            TP=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (OrderClosePrice()==OrderTakeProfit() || OrderProfit()>=0) TradeDey=TimeDay(CurTime());
         if (OrderClosePrice()==OrderStopLoss()) return(1);
      }
   }  
   return(0);
}
//+-----------------------------------------------------------------+
int ORDERS(int tip)
{
   int N_Sell,N_Buy;
   for (int i=0; i<OrdersTotal(); i++)
   {                                               
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
         {
            if (OrderType()==OP_BUY ) N_Buy++;
            if (OrderType()==OP_SELL) N_Sell++;
         }
      }   
   }
if (tip== 0) return(N_Buy+N_Sell);
if (tip== 1) return(N_Buy);
if (tip==-1) return(N_Sell);
}                  
//-------------------------------------------------------------------+
void No_Loss()
{
   int tip;
   double TP,OOP;
   for (int i=OrdersTotal()-1; i>=0; i--) 
   {
      if (OrderSelect(i, SELECT_BY_POS)==true)
      {
         tip = OrderType();
         if (tip<2 && OrderSymbol()==Symbol())
         {
            if (OrderMagicNumber()!=Magic) continue;
            TP = OrderTakeProfit();
            OOP = OrderOpenPrice();
            if (tip==0) //Bay               
            {  
               if (OrderStopLoss()>OrderOpenPrice()+Ask-Bid) return;
               if ((TP-OOP)/2+OOP<=Bid)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP+Ask-Bid,Digits),TP,0,White);
            }                                         
            if (tip==1) //Sell               
            {                                         
               if (OrderStopLoss()<OrderOpenPrice()-Ask+Bid) return;
               if (OOP-(OOP-TP)/2>=Ask)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP-Ask+Bid,Digits),TP,0,White);
            } 
         }
      }
   }
}
//------------------------------------------------------------------+
void CLOSEORDERS()
{
   bool error;
   int err;
   while (true)
   {  error=true;
      for (int i=OrdersTotal()-1; i>=0; i--)
      {                                               
         if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
         {
            if (OrderSymbol()!=Symbol()||Magic!=OrderMagicNumber()) continue;
            if (OrderType()==OP_BUY)
               error=OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);
            if (OrderType()==OP_SELL)
               error=OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);
         }   
      }
      if (!error) {err++;Sleep(2000);RefreshRates();}
      if (error || err >5) return;
   }
}
//-------------------------------------------------------------------+
 
Tigerfreerun:
我不太明白这个函数到底是做什么的。但是,正如作者所说,其目的是在符号之间用盈利的订单覆盖亏损的订单。如果你能帮助我纠正和理解这个功能,我将很高兴。
void MaxMinProfit()
{
int i, N, MaxTic, MinTic;
double   MinProf=0, MaxProf=0, OP, g, a[][2];
string MinSym, MaxSym;
ArrayResize(a, 0);
 
for (i=OrdersTotal()-1; i>=0; i--) 
  {    
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
    { 
     if (OrderType()==OP_SELL ||  OrderType()==OP_BUY )
      {
       OP = NormalizeDouble(OrderProfit()+OrderSwap()+OrderCommission(),2);
       
      if (MinProf>OP) 
      {
       
          MinProf=OP;
          MinTic=OrderTicket();
          MinSym=OrderSymbol();
          
         }
         
      if (OP>0) 
      {
       
          N++;
            ArrayResize(a, N);
            a[N-1][0]=OP;
            a[N-1][1]=OrderTicket();
          
         }
         
         }
         }
         
         }
         
      ArraySort(a, WHOLE_ARRAY, 0, MODE_DESCEND);//MODE_ASCEND);
      
      for (i=0; i<Level; i++) 
       {
     
     g+=a[i][0];
     //int ti=a[i-2][1];
     }
         
         
     
     if(MinProf <0 && (g+MinProf)>=ProcMax)
      {
       for (i=0; i<Level; i++) 
       {
       if (OrderSelect(a[i][1], SELECT_BY_TICKET, MODE_TRADES))
        {
        //Alert(a[i][1]);
         if (OrderType()== OP_BUY)
         {
          OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
           OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }
         }
          
          
          
          if (OrderSelect(MinTic, SELECT_BY_TICKET, MODE_TRADES))
        {
         if (OrderType()== OP_BUY)
         {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }}       
return;
}

你不理解,我也不想理解这个函数的作用。你使用它。你已经为自己选择了它。你怎么能在不了解它的用途的情况下使用它。

我只是告诉你错误来自哪里,是什么原因。

还有一个澄清。

声明了一个数组。它被突出显示为绿色。它在第一维中的长度为零。蓝色的线条并不清晰。如果你想重置数组的大小,有 ArrayFree(),但即使这个函数也是无用的,因为刚刚声明的动态数组的长度为零。

2.如果没有订单,标记为红色的代码将不会被执行。因此,该数组的大小将保持为零。

3.阵列排序是在每个刻度上提供的。从代码中可以看出。而在一个空的口袋里,有什么可以被分类?除非是2个鹌鹑蛋...?


这里是错误文本...我还能说什么呢?开发者并没有预见到有人会试图对一个空数组进行排序。他们并没有为此想出一个特别的信息。

ArrayFree - Операции с массивами - Справочник MQL4
ArrayFree - Операции с массивами - Справочник MQL4
  • docs.mql4.com
При написании скриптов и индикаторов необходимость в использовании функции ArrayFree() может возникнуть не часто: так как при завершении работы скрипта вся использованная память сразу же освобождается, а в пользовательских индикаторах основная работа с массивами представляет собою доступ к индикаторным буферам, размеры которых автоматически...
 
Alexey Viktorov:

你不理解,我也不想理解这个函数的作用。你使用它。你已经为自己选择了它。你怎么能在不了解它的用途的情况下使用它。

我只是告诉你错误来自哪里,是什么原因。

还有一个澄清。

1. 声明了一个数组。它在代码中以绿色突出显示。它在第一维中的长度为零。用蓝色强调的那条线并不清楚。如果我们想重置数组的大小,有 ArrayFree() ,但即使这个函数也没有用,因为我们刚刚声明的动态数组的长度为零。

2.如果没有订单,标记为红色的代码将不会被执行。因此,该数组的大小将保持为零。

3.阵列排序是在每个刻度上提供的。从代码中可以看出。而在一个空的口袋里,有什么可以被分类呢?除非是2个鹌鹑蛋...?


这里是错误文本...我还能说什么呢?开发者并没有预见到有人会试图对一个空数组进行排序。他们并没有为此想出一个特别的信息。

阿列克谢,你错了。ArrayFree()的作用是在不再需要时释放数组中的内存,这很少需要,当然在本例中也不需要。

ZeroMemory(a), ArrayInitialize(a,xxx)应该被用来给数组清零,ArrayResize(a,xxx)应该被用来调整它的一维大小。

然而,这一修正并不影响你的推理--它是正确的。

 
Artyom Trishkin:

阿列克谢,这是不正确的。ArrayFree()是用来在不再需要这个数组的时候释放内存的,这种情况非常少见,而且绝对不是在这种情况下。

ZeroMemory(a), ArrayInitialize(a,xxx)应该被用来给数组清零,ArrayResize(a,xxx)应该被用来调整它的一维大小。

然而,这一修正并不影响你的推理--它是正确的。

根据文件规定

ArrayFree .

释放任何动态数组的缓冲区,并将零维的大小设为0。

也许我的表达不够正确,你误解了我的意思。
 
Alexey Viktorov:

根据文件规定

也许我的表达不够正确,你误解了我的意思。

还有更后面的地方。


注意事项

脚本和指标中不需要经常使用ArrayFree()函数,因为所有使用过的内存在脚本停止运行后会立即释放。 在自定义指标 中,对数组的大多数操作是访问指标缓冲区,其大小由客户终端的执行子系统自动管理。

如果一个程序需要在复杂的动态条件下独立管理内存,ArrayFree()函数将允许明确地立即释放被不必要的动态数组所占用的内存。


释放任何动态数组的缓冲区,并将零维的大小设置为0

你明白吗?你读了第二部分 而错过了第一部分--重要的--部分?它释放了分配给数组的内存。它......消失了......。为数组分配的内存空间被释放出来,然后可以被其他数据占用。为什么每次重新进入函数时,都要为这个数组重新分配内存?你是那个应该释放它的人。你所需要做的就是改变大小--ArrayResize(),或者将数组归零--ArrayInitialize(),ZeroMemory()。而数组的内存空间将不会被释放,它将一直保留给这个数组,直到程序完成。

 
Artyom Trishkin:

还有更后面的地方。


注意事项

在脚本和指标中不需要经常使用ArrayFree()函数,因为所有使用过的内存在操作完成后会立即释放。 在自定义指标 中,对数组的大多数操作是访问指标缓冲区,其大小由客户终端的执行子系统自动管理。

如果一个程序需要在复杂的动态条件下独立管理内存,ArrayFree()函数将允许明确地立即释放被不必要的动态数组所占用的内存。


它释放了任何动态数组的缓冲区,并将零维的大小设置为0

你明白吗?你读了第二部分,错过了第一个重要 部分,不是吗?它释放了为数组分配的内存。就这样......走了......。为数组分配的内存空间被释放出来,可以进一步被其他数据占用。为什么每次重新进入函数时,都要为这个数组重新分配内存?你是那个应该释放它的人。你所需要做的就是改变大小--ArrayResize(),或者将数组归零--ArrayInitialize(),ZeroMemory()。而数组的内存空间将不会被释放,它将一直保留给这个数组,直到程序完成。

好吧...如果一个局部数组在函数的每次调用中都被声明,或者最不可能的是在每次打勾时都被声明...但每次定义数组时,都要为数组分配内存。难道不是这样吗?而内存是否被释放又有什么区别,但每次都在分配内存......。

我的主要想法是,你不应该这样做...如果你这样做,你最好通过ArrayFree() 来做。

这里有一个有趣的现象:如果每次调用函数时都声明一个局部数组,相应地,每次都要为它保留内存。但这样做时使用什么地址?与第一次声明数组时一样,或者将使用什么?

 
Denis Danilov:

下午好,这个EA叫做 "Rollover",但它没有按计划工作。 如果它以负数收盘,它就会将手数加倍,但随后的TP收盘由于某种原因不允许返回负数交易,而这些交易之前已经关闭。请告诉我哪里出了问题,我搞不清楚。我想提前感谢所有的评论者。

尽量在初始批次之前检查翻倍的情况。按时间观看闭幕式。

原因: