错误、漏洞、问题 - 页 2377

 
Slava:
是的,从OnInit开始的任何打印

谢谢你。有趣的是,如果我没有碰巧注意到它,怎么可能发现它呢......


ZS 我只想把它留给当地的代理商。在云端,你可以很容易地以这种方式对日志进行拼写。

 
fxsaber:

谢谢你。有趣的是,如果我没有碰巧注意到它,怎么可能发现它呢......


ZS 我只想把它留给当地的代理商。在云端,你可以很容易地以这种方式对日志进行拼写。

在云端,它不会显示出来。因为没有理由这样做。
 
Slava:

当你运行遗传学时,你是否根据你的自定义标准进行优化?

根据提交的日志,OnTester在所有情况下都返回0

我通常根据我的标准进行优化,但在这里我也尝试了自定义的标准。其结果是一样的。

OnTester返回0,这就是为什么它在结果中返回0--这是可以理解的。问题是,为什么在一般运行(优化)时返回 "0",而在从 "零结果 "开始的单次运行中(参数相同)却返回正常结果、图表等?也就是说,有些东西在 "完全过冲 "中不工作,而遗传学却能正常工作。有什么其他想法/主意吗?

 
Kuzmich:

有什么其他想法/主意吗?

以这种方式拉动所有的优化通道的信息

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

MT5。战略测试员。测试和优化结果的分歧。

fxsaber, 2017.08.22 11:06

在EA中插入这些行

#define  REPORT_TESTER // В тестере будут автоматически записываться отчеты
#include <Report.mqh>

和运行优化。然后运行一个不匹配的单次运行。

然后比较从优化和单次运行中保存的两份相应的运行报告。

对比两份报告的结果将很快揭示出原因。

 
在熟悉Socket*功能的框架内,出现了一些关于当前实现的问题。
我们的目标是尽可能地改进所做的事情,我要求开发者不要被可能的批评所冒犯。



1.我不明白为什么Socket读函数的 "接口 "有如此大的差异
:a)对于加密连接有两个读函数,对于未加密的有一个。
b)在SocketRead 中必须明确指定timeout_ms,而在SocketTlsReadSocketTlsReadAvailable
中根本没有这样的参数(由独立函数SocketTimeouts设置)。
int  SocketTlsRead(int socket, uchar& buffer[], int buffer_maxlen);
int  SocketTlsReadAvailable(int socket, uchar& buffer[], int buffer_maxlen);

int  SocketRead(int socket, uchar& buffer[], int buffer_maxlen, uint timeout_ms);


2.函数SocketIsReadable的 名字与它实际执行的任务无关。

bool  SocketIsWritable(const int  socket); // Return true if writing is possible, otherwise false.
uint  SocketIsReadable(const int  socket); // Number of bytes that can be calculated. In case of an error, 0 is returned.
bool  SocketIsConnected(const int socket); // New function without description. May be, it returns true if connection is not closed.

事实上,SocketIsReadable类似于Ws2_32.dll中带有FIONREAD标志的ioctlsocket()函数。


3.如果服务器在数据传输后没有中断连接,用户如何在非加密连接上使用Socket*功能从服务器获得最小时间延迟的响应?

- 没有明确使用时间延迟的SocketIsReadable函数(例如没有Sleep)会返回0。
- SocketRead函数不知道要读多少,你指定缓冲区_maxlen 时要有保留 - 你必须等待timeout_ms

是的,就是这样做的。

- 等待SocketRead中的1个字节的数据。
- 然后用SocketIsReadable找出整个响应的大小。
- 将剩余的长度读入SocketRead。
- 通过复制数组来合并结果。

#define  PRINT(x) Print(#x, ": ", string(x))
                
void OnStart() {
   string domain = "www.mql5.com";
   int port = 80;
 
   string request = "GET / HTTP/1.1\r\nHost: " + domain + "\r\n\r\n";
   char req[];
   
   int socket = SocketCreate();
   PRINT(SocketConnect(socket, domain, port, 5000));
   int len=StringToCharArray(request,req)-1;
   PRINT(SocketSend(socket,req,len));
   
   
   
   uchar resp[];
   uchar result[];
   
   int resp_result;
   uint resp_len;
   int start_write;
   
   
   resp_len = 1;
   resp_result = SocketRead(socket, resp, resp_len, 5000);
   if (resp_result <= 0){
      PRINT(GetLastError());
      return;
   }
   start_write = ArraySize(result);
   ArrayResize(result, start_write + resp_result);
   ArrayCopy(result, resp, start_write);
   
   
   resp_len = SocketIsReadable(socket);
   resp_result = SocketRead(socket, resp, resp_len, 5000);
   if (resp_result <= 0){
      PRINT(GetLastError());
      return;
   }
   start_write = ArraySize(result);
   ArrayResize(result, start_write + resp_result);
   ArrayCopy(result, resp, start_write);
   
   
   PRINT(CharArrayToString(result));
};

这不是太多的代码吗?


4.SocketIsReadable返回错误信息。
关掉互联网,执行上述代码。
因此,SocketIsReadable返回一个合理的值1。奇迹。


我设法描述了所有与Socket*有关的问题和难题的大约三分之一。
不幸的是,我需要大量的时间来检查、描述和重复检查一切......。(这样就不会有续集的事实了)

一般的印象是,要么一切都做得很匆忙,要么Socket*的功能被初级开发人员所掌握。
在任何情况下,目前的解决方案是非常粗糙的,涵盖了使用套接字的相当狭窄的方法。

 
MQL5\Include\Math\AlgLib\dataanalysis.mqh - CLinReg::LRLine 对1M以上的值不起作用?
 
Kuzmich:

我通常根据自己的标准进行优化,但在这里我也尝试了标准的标准。其结果是类似的。

OnTester返回0,这就是为什么结果中出现了0--这是可以理解的。问题是,为什么在一般运行(优化)时返回 "0",而在从 "零结果 "开始的单次运行中(参数相同)却返回正常结果、图表等?也就是说,有些东西在 "完全过冲 "中不工作,而遗传学却能正常工作。有什么其他想法/主意吗?

你能分享一个EA(ex5在私下)和优化条件吗?

我们想重现你提到的问题。

研究结束后,EA将被不可逆转地删除。

 
Slava:

你能分享一下EA(ex5在私人信息中)和优化条件吗?

我们想重现你提到的问题。

研究结束后,EA将被不可逆转地删除。

你能看一下我的EA吗?我有一个类似的问题--利润没有被计算在内,因此,优化工作无法进行。
 
Slava:

你能分享一下EA(ex5在私人信息中)和优化条件吗?

我们想重现你提到的问题。

研究结束后,EA将被不可逆转地删除。

在私人信息中回复了。

 
Sergey Dzyublik:
在熟悉Socket*功能的框架内,出现了一些关于当前实现的问题。
我们的目标是尽可能地改进所做的事情,我要求开发者不要被可能的批评所冒犯。



1.我不明白为什么Socket读函数的 "接口 "有如此大的差异
:a)对于加密连接有两个读函数,对于未加密的有一个。
b)在SocketRead 中必须明确指定timeout_ms,而在SocketTlsReadSocketTlsReadAvailable
中根本没有这样的参数(由独立函数SocketTimeouts设置)。


2.函数SocketIsReadable的 名字与它实际执行的任务无关。

事实上,SocketIsReadable类似于Ws2_32.dll中带有FIONREAD标志的ioctlsocket()函数。


3.如果服务器在数据传输后没有中断连接,用户如何在非加密连接上使用Socket*功能从服务器获得最小时间延迟的响应?

- 没有明确使用延时的SocketIsReadable函数(例如,没有Sleep)返回0。
- SocketRead函数不知道要读多少,如果你用保留值指定buffer_maxlen- 你将不得不等待timeout_ms

是的,就是这样做的。

- 等待SocketRead中的1个字节的数据。
- 然后用SocketIsReadable找出整个响应的大小。
- 将剩余的长度读入SocketRead。
- 通过复制数组来合并结果。

这不是太多的代码吗?


4.SocketIsReadable返回错误信息。
关掉互联网,执行上述代码。
因此,SocketIsReadable返回一个合理的值1。奇迹。


我设法描述了所有与Socket*有关的问题和难题的大约三分之一。
不幸的是,我需要大量的时间来检查、描述和重复检查一切......。(这样就不会有续集的事实了)

一般的印象是,要么一切都做得很匆忙,要么Socket*功能被初级开发人员所掌握。
在任何情况下,目前的解决方案是非常粗糙的,涵盖了使用套接字的相当狭窄的方法。

1.这是个接口。

TLS函数是辅助性的,以支持复杂的情况。设置SocketTimeouts没有问题--这些是最好用的。


2.它正确地履行其职能。

你一定没有意识到TCP连接中断检测的问题。要检测一个连接是否保证正确断开是相当困难的(以额外的调用为代价的资源密集)。所有的网络实施都存在这个问题。

我们对SocketIsReadible的实现足够聪明,并且有一个中断检测器。当它检测到一个干净的0字节时,它会做额外的工作来检查套接字是否完整。

   //+------------------------------------------------------------------+
   //| Доступно для чтения?                                             |
   //+------------------------------------------------------------------+
   UINT32 IsReadible(void)
     {
      unsigned long size=1;    // специально, чтобы убиться при попытке чтения, если сокет мертв
      //--- проверка
      if(m_socket!=INVALID_SOCKET)
        {
         //--- считаем количество доступных для чтения байт
         if(ioctlsocket(m_socket,FIONREAD,&size)!=0)
           {
            Close();
            return(1);        // вернем 1, чтобы убиться при попытке чтения
           }
         //--- если нет данных, проверим сокет на завершенность
         if(size==0)
           {
            timeval wait_time;
            fd_set  fd;
            //--- ждём
            FD_ZERO(&fd);
            FD_SET(m_socket,&fd);

            wait_time.tv_sec =0;          // секунды
            wait_time.tv_usec=1000;       // микросекунды
            //--- ждём
            if(select(0,&fd,NULL,NULL,&wait_time)>0)
               return(1);                 // вернем 1, чтобы убиться при попытке чтения
           }
        }
      //--- размер
      return(size);
     }

因为它返回的是没有终止标志的字节数,所以它输出1个字节,这样后续/即将进行的SocketRead读取尝试通常会返回一个错误。

为什么这是对的?因为大部分的代码都是由程序员以这种方式写的。

if(SocketIsReadible(...)>0)
  {
   if(SocketRead( )<1)
     return(false);
   ...
  }
... уходим на следующий круг ожидания

操作的实际结果是在直接读取尝试中检查的。


3. 如果你不知道要读的数据的确切大小,它需要在实际读取之前做SocketIsReadible()。

SocketisReadible/SocketRead绑定使你能够不失去对程序执行流程的控制(最小化到几乎零损失的控制)。这就避免了飞入网络超时。

是的,多了几行代码,但你不会失去一毫秒的控制权(大致如此)。在没有网络数据的间隙,由你来决定做什么。


4. 在第二段中解释。

为了读和输出刺激而发出1,作为一个读错误。



你的结论是错误的。

这就是TCP/IP传输的本质,根本没有任何保证。当没有TCP信令部分时,你也可以在过滤器/防火墙上进入网络黑洞。原始超时和数据流控制允许你检测它们并自行终止连接。

我们已经给了网络功能一个原始/直接访问的接口,包括TLS的实现。如果你使用它们,你需要在安全/受控的SocketIsReadible/SocketRead处理程序中正确包装原始函数。

如果你想在不考虑细枝末节的情况下提出高级请求,有WebRequest 函数。所有的保护措施都内置在那里。