关于MQL4文件的讨论 - 页 18

 
嗯...在我看来,这才是正确的答案。

空白的SendMail( string subject, string some_text)
向邮件标签上的设置窗口中指定的地址发送电子邮件。
该功能在测试模式下不工作。这个函数也不能从用户指标中调用。
发送可能在设置中被禁止,也可能没有指定电子邮件地址。必须调用GetLastError() 函数来获得错误信息。
[...]

在指标中,诚然,我没有检查...:)

Z.U.我反对这个话题的标题,建议将其改名为这样的内容。"改进MQL4文件:消除不准确和不足之处"。类似这样的事情。
 
OrderSelect()函数的例子中,我遇到了这样一个表达式。
if(OrderSelect(12470, SELECT_BY_TICKET)==true) ...
然后我在文件中的其他地方也看到了这一点。

请解释一下,这只是一种编程风格吗?
如果不是这样,对逻辑变量使用比较操作的原因是什么?
为什么不使用一个更简单的表达方式?
if(OrderSelect(12470, SELECT_BY_TICKET)) ...
 
Yurixx:
为什么不使用更简单的表达方式呢。

第一种表达方式在直觉上更容易理解,特别是对初学者来说没有争议,尽管第二种表达方式可能被更广泛地使用。
 
什么是形式参数,它与通过引用传递的参数有什么关系?
 
通常用于计算数值的函数需要一些参数作为输入。例如,如果我们看一下OrderSend()函数,它有很多这样的参数。
  • 符号
  • 订单类型
  • 以手为单位的持仓量
  • 发现的代价
  • 以点为单位的滑移
等等。传递给函数的参数可以有两种类型:一种是在被调用函数运行过程中不发生任何变化的参数,另一种是可以在其中进行处理的参数。
例如,让我们考虑下面这个函数。

//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   return;   
  }
有三个参数被传入SplitString():一个ArrayRes数组的引用(前面是安培号&)和两个形式参数InputStrung(要被分割成的字符串)和splitter(这是分割的分割器)。
当函数被执行时,ArraRes数组将包含几个字符串。在MQL4中,函数本身不能返回复杂的类型(如数组),但通过使用引用传递参数,我们可以避免这一限制。

完整的脚本如下:

//+------------------------------------------------------------------+
//|                                                        Split.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
 
//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   return;   
  }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string strInfo="aae|aer3|dzse|faw323";
   string strResult[] ;
   
   SplitString(strResult,strInfo,"|");
   
   int N=ArraySize(strResult);
   if (N>0)
      {
      for (int i=0;i<N;i++) Print("strResult[",i,"]=",strResult[i]);
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
在你的环境中运行它,看看结果。
 
这里有另一个不幸的文件

double OrderClosePrice( )
返回所选订单的收盘价。
该订单必须使用OrderSelect() 进行预选。
例子。
 if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true) { datetime ctm=OrderOpenTime(); if(ctm>0) Print("Open time for the order 10 " , ctm);
     ctm=OrderCloseTime(); if(ctm>0) Print("订单关闭时间10", ctm); } else Print("OrderSelect failed error code is",GetLastError();

说明是关于OrderClosePrice函数的,而例子是关于OrderClosePrice函数的。
这可能就是为什么我们审查的99%的专家顾问对订单类型进行绝对不必要的分析的原因
if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 0);
当你可以只写
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)
 
是的,这是我上周捡到的一个点。我认为这样的事情:

 if(OrderSelect(10,SELECT_BY_POS,MODE_HISTORY)==true)
    {
     datetime  ctm= OrderOpenTime();if(ctm>0)
     Print("Open time for the order 10 ", TimeToStr(ctm)); 
     double price=OrderClosePrice();
     if(price>0) Print("Close price for the order 10 ", DoubleToStr(price,MarketInfo(OrderSymbol(),MODE_DIGITS)));
    }
  else
    Print("OrderSelect failed error code is",GetLastError());
 
引用
------
有三个参数传给SplitString():ArrayRes数组的引用(前面有安培尔&)和两个形式参数 InputStrung(要解析的字符串)和splitter(这是解析的分割器)。
当函数被执行时,ArraRes数组将包含几个字符串。在MQL4中,函数本身不能返回复杂的类型(如数组),但通过使用引用传递参数,我们可以避免这一限制。
------

我明白。我不明白你为什么称他们为 "正式"。这些参数的传递是否只是为了好玩,纯粹是形式上的?C语言中没有这样的东西。

为什么参数类型的描述是在 "变量 "部分而不是在 "函数 "部分?
 
cout:
我明白这一点。我不明白你为什么称它们为 "形式",它们是纯粹的形式传递的参数吗? C语言中没有这种东西。


因为传入函数的变量是正式传入的,不是作为变量,而是作为其值。变量可以被操纵(它们的值被改变),而这种对值的操纵是没有意义的。
下面是这个例子的另一个版本。

//+------------------------------------------------------------------+
//|                                                        Split.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
 
//+------------------------------------------------------------------+
//|  fill array of strings                                           |
//+------------------------------------------------------------------+
void SplitString(string &ArrayRes[],string InputString,string splitter)
  {
   string temp,tempArray[100];
   int pos,splitLength=StringLen(splitter),InputStrLength=StringLen(InputString),counter;
 
   pos=StringFind(InputString,splitter);
   if (pos!=-1)
      {
      if (pos==0) InputString=StringSubstr(InputString,splitLength,InputStrLength-splitLength);
      while (StringFind(InputString,splitter)!=-1)
         {
         pos=StringFind(InputString,splitter);
         InputStrLength=StringLen(InputString);
         tempArray[counter]=StringSubstr(InputString,0,pos);
         InputString=StringSubstr(InputString,pos+splitLength,InputStrLength-splitLength-pos);
         counter++;
         }
      if (StringLen(InputString)!=0)
         {
         tempArray[counter]=InputString;
         counter++;
         }   
      }
   ArrayResize(ArrayRes,counter);
   for (int i=0;i<counter;i++)  
      {
      ArrayRes[i]=tempArray[i];
      Print("i=",i,"   string=",ArrayRes[i]);
      }
   InputString="Входная строка";
   splitter="разделитель";
   Print("InputString=",InputString,"    splitter=",splitter);
   return;   
  }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string strInfo="aae|aer3|dzse|faw323";
   string strResult[] ;
   string devider="|";
   SplitString(strResult,strInfo,devider);
   
   int N=ArraySize(strResult);
   if (N>0)
      {
      for (int i=0;i<N;i++) Print("strResult[",i,"]=",strResult[i]);
      }
   Print("strInfo=",strInfo,"    devider=",devider);   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
因此,称它们为" 按值传递参数"。
形式上意味着没有任何东西取决于它的价值,例如,保留给未来使用:)。但是通过值传递的参数确实依赖于某些东西,否则它们就会被称为正式的:)。