エラー、バグ、質問 - ページ 2377

 
Slava:
OnInitからの任意のプリント

ありがとうございます。面白いですね、たまたま気づかなかったとしたら、どうやって調べるのでしょう...。


ZS 私ならローカルエージェントだけにします。クラウドでは、このように簡単にログをスパムにすることができます。

 
fxsaber:

ありがとうございます。面白いですね、たまたま気づかなかったとしたら、どうやって調べるのでしょう...。


ZS 私ならローカルエージェントだけにします。クラウドでは、このように簡単にログをスパムにすることができます。

クラウドでは、表示されません。だって、理由がないんだもの。
 
Slava:

ジェネティクスを実行する際、カスタム基準に従って最適化しているのでしょうか?

提示されたログに基づき、OnTesterはすべてのケースで0を返した

いつもは自分の基準で最適化するのですが、ここではカスタムの基準も試してみました。結果は同じです。

OnTesterが0を返すから、結果に0が返ってくるんですねー、納得です。問題は、一般的な実行(最適化)では「0」が返されるのに、「ゼロの結果」からの単一実行(同じパラメータ)では、通常の結果やグラフなどが返されるのはなぜか、ということです。例えば、"Full overshoot "で何かが動作していないのに、Geneticsは正常に動作している。他にご意見・ご感想があればお聞かせください。

 
Kuzmich:

他にご意見・ご感想があればお聞かせください。

最適化パスの情報はすべてこのように引き出します

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

MT5です。戦略テスターテストと最適化の結果の乖離。

fxsaber さん 2017.08.22 11:06

以下の行をEAに挿入してください。

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

そして、Optimizationを実行する。次に、ミスマッチのシングルランを実行します。

次に、最適化から対応する実行の保存された2つのレポートと単一実行を比較します。

2つのレポートを比較した結果、その原因がすぐに判明します。

 
Socket*の機能を理解する過程で、現在の実装に対する多くの疑問が生まれました。
目標は、できたものをできるだけ改善することなので、批判される可能性があっても怒らないようにお願いします。



1.

b)SocketReadではtimeout_msを
明示
的に指定する必要がありますが、SocketTlsReadとSocketTlsReadAvailableでは
その
ようなパラメータは全くありません(別の関数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関数はどれだけ読み込むか分からないので、buffer_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*に関連する質問と問題の約1/3を記述することができました。
残念ながら、すべてを確認し、記述し、再確認するのに多くの時間を必要としました......。(続編があることが事実でないように)

一般的な印象としては、すべてが大急ぎで行われたか、Socket*の機能が若い開発者の手に渡ったかのどちらかでしょう。
いずれにせよ、現在のソリューションは非常に粗雑で、ソケットを使うという狭い範囲でのアプローチにとどまっています。

 
MQL5 Filter-IncludeMath
 
Kuzmich:

普段は自分なりの基準で最適化していますが、今回は標準的なものも試してみました。結果も似たようなものです。

OnTesterは0を返すので、結果に0があるのはそのためです - それは理解できます。問題は、一般的な実行(最適化)では「0」が返されるのに、「ゼロの結果」からの単一実行(同じパラメータ)では、通常の結果やグラフなどが返されるのはなぜか、ということです。例えば、"Full overshoot "で何かが動作していないのに、Geneticsは正常に動作している。他にご意見・ご感想があればお聞かせください。

EA(非公開のex5)と最適化条件を教えてください。

ご指摘の問題を再現したいのです。

研究終了後、EAは不可逆的に消去されます。

 
Slava:

EA(ex5をプライベートメッセージで)と最適化条件を教えてください。

ご指摘の問題を再現したいのです。

研究終了後、EAは不可逆的に消去されます。

私のEAを見てくれませんか?私も同じような問題を抱えています。利益が計算されず、結果として最適化がうまくいきません。
 
Slava:

EA(ex5をプライベートメッセージで)と最適化条件を教えてください。

ご指摘の問題を再現したいのです。

EAは研究終了後、回復不能な形で消去されます

プライベートメッセージで返信しました。

 
Sergey Dzyublik:
Socket*の機能を理解する過程で、現在の実装に対する多くの疑問が生まれました。
目標は、できたものをできるだけ改善することなので、批判される可能性があっても怒らないようにお願いします。



1.

b)SocketReadではtimeout_msを
明示
的に指定する必要がありますが、SocketTlsReadとSocketTlsReadAvailableでは
その
ようなパラメータは全くありません(別の関数SocketTimeoutsで設定
されます)。


2.関数SocketIsReadableの 名前は、それが実際に実行される内容とは関係がない。

実際、SocketIsReadableは、Ws2_32.dllのFIONREADフラグ付きioctlsocket()関数に類似している。


3.暗号化されていない接続でSocket*機能を使用するユーザーが、データ転送後にサーバーが接続を切断しない場合、どのようにして最小限の時間遅れでサーバーから応答を得ることができますか?

- SocketIsReadable関数で明示的に遅延時間を使用しない場合(例:Sleepを使用しない場合)、0を返します。
- SocketRead関数は、どれだけ読み込むか分からないので、buffer_maxlenを reserveで指定すると、timeout_msの 間待つ必要があります。

ああ、そういうことなんだ。

- SocketReadで1バイトのデータを待ちます。
- で、SocketIsReadable を使ってレスポンス全体のサイズを調べます。
- は、SocketRead に残りの長さを読み込む。
- は、配列をコピーして結果をマージします。

これではコードが多すぎるのでは?


4.SocketIsReadableが偽情報を返す。
インターネットをオフにして、上記のコードを実行します。
その結果、SocketIsReadableはまともな値である1を返します。不思議。


Socket*に関連する質問と問題の約1/3を記述することができました。
残念ながら、すべてを確認し、記述し、再確認するのに多くの時間を必要としました......。(続編があることが事実でないように)

一般的な印象としては、すべてが大急ぎで行われたか、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);
     }

終了フラグを立てずにバイト数を返すので、その後のSocketReadの読み込み試行で通常エラーが出るように1バイトを出力する。

なぜ、これが正しいのか?なぜなら、ほとんどのコードがプログラマーによってこのように書かれているからです。

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

の場合、実際の操作結果は直読の際に確認される。


3. 読み込むデータの正確なサイズがわからない場合、実際に読み込む前に SocketIsReadible() を実行する必要があります。

SocketisReadible/SocketReadバインドは、プログラムの実行フローに対する制御を失わない(制御の損失をほぼゼロに抑える)機能を備えています。これにより、ネットワークのタイムアウトに飛ぶことを回避することができます。

そう、数行のコードが増えるだけで、1ミリ秒(だいたい)コントロールを失うことはありません。ネットワークデータがない間隔をどうするかは、あなた次第です。


4.第2パラグラフで説明した。

読み取りエラーとして、読み取りと出力の刺激のために1を発行する。



あなたの結論は間違っている。

これはTCP/IPトランスポートの性質上、全く保証がない。TCPシグナリングの部分がない場合、フィルタやファイアウォールでそこもネットワークブラックホールになることがあります。生のタイムアウトとデータフロー制御により、それらを検知して自分で接続を終了させることができます。

TLSの実装を含むネットワーク機能への生/直接アクセスのインタフェースを与えました。もしそれらを使用するならば、あなた自身が、安全で制御されたSocketIsReadible/SocketReadハンドラで生の関数を適切にラップする必要があるのです。

細かいことを考えずに高度なリクエストをしたい場合は、WebRequestという 関数があります。そこにすべてのプロテクションが組み込まれているのです。