MT5とスピードの関係 - ページ 62

 
Rorschach:
リアルタイムカーネルは何か役に立ちますか?

もっとコアを入れて、100%シングルコアロードの状況を作らないように。

おとぎ話を信じないでください。プロセッサーやスレッドスケジューラーは、あなたが想像しているようには動きません。

 
Anton:

最新のビルドでは、ティックストリーム受信は理論上も効果がありません。実質的にはSymbolInfoTickはすでにキャッシュで 動作しているが、個々の市民は黒猫を探し続けている。

しかも、テストでは8割もないんですよ。4つのコアで6つのエージェントが動作しており、つまり100%保証されています。

問題は、彼のシステムのタスクスケジューラが、この状況をどのように処理しているかだ。同時に、端末の実装にこそ原因があるとの主張も行っている。

つまり、コンピュータに負荷がかかり、文字通りコンピュータ上のあらゆるものが遅くなる状況を人為的に作り出し、「ああ、ほら、どうして時々端末がラグるんだ」という形で何らかの主張がなされるのである。

そんな状況でも「約0.01%」なのだから、細かいことはいい加減にしろ!と目をつぶることにしよう。病院の平均温度なんて誰も気にしない」「ラグがあると取引時に困る」「HFTが欲しい」というだけで十分です。

さらに、古いオフィスのデスクトップや枯れた仮想マシンで20人のエキスパートにHFTを させることも当然ながら可能です。

PS PositionSelectByTicket()の実装では、確かにアクセス同期のある共有リソースにアクセスすることができます。そして、すべてのコールでポジションを選択しなければ、古い価格を読んでいることになります。SymbolInfoDoubleを介して「スナップショット」を行う方が簡単だった。

しゃい

私が質問を受けたのは、6ヶ月前にコードを最適化してシステム関数の速度をテストしていたところ、6ヶ月前にSymbolInfoDoubleがSymbolInfoTickより遅かったからです

今日、マルチコアキャッシュに関する記事をいくつかググってみました(長い間、この情報には興味がなかったのです)。

以下は、短い記事ですhttps://i2hard.ru/publications/25666/

ポイントは、データは非常に小さいL1キャッシュからのみALUで実行されるようになり、プロセッサをフルスピードでロードした場合、実際には - テストは、オペレーティングシステムのテスト+プロセッサのキャッシュ 速度のテスト(ロード、L1 + L3データを予測する)ではなく、テストコード(アプリケーション)性能に変わるだろう。

 

fxsaber さん、タスクマネージャーでエージェントの優先度を低く、MT5の優先度を高く設定したらどうでしょうか?

すべてのプログラム/OSのスレッドを特定のCPUスレッドに割り当てるのをブロックするユーティリティが見つかりません。そうでなければ、MT5用にスレッドを予約して、他のプログラムが使用するのを自動的にブロックすることができ、理論上は遅延を減らすことができます。

 
Anton:

最新のビルドでは、ティックストリーム受信は理論上も効果がありません。実際、SymbolInfoTickはすでにキャッシュで 動作していますが、特定の市民は黒猫を探し続けています。

ある市民は、彼のズボンからMQL-codeを複製して もらい、同じ条件で通常の関数よりも松葉杖が速く動作することを示しました。

しかし、あなたは、自分の機能は良いもので、使用条件に制限があるだけだと主張します。

しかも、テストでは8割もないんですよ。4つのコアで6つのエージェントが動作しており、つまり100%保証されています。

問題は、彼のシステムのタスクスケジューラが、この状況をどのように処理しているかだ。一方で、端末の実装に問題があるとの主張もある。

つまり、コンピュータに限界まで負荷をかけて、その上ですべてが遅くなるという状況を人為的に作り出し、「ああ、ほら、どうして時々端末がラグるんだ」という形で何らかの主張がなされるのです。

6/8 - 何もラグがない。ブラウザ、コンパイル、デバッグなどが並列に動作し、遅れを感じさせません。

でも、今はわざと全部消して、4/8Agentだけにしています。機能ブレーキをかけても状況は変わりません。

さらに 言えば、もちろん、古いオフィスのデスクトップや死んだ仮想マシンで20人のエキスパートにHFTをさせたい のです。

高速マシンを使用しました。しかも、すでにブレーキを踏んでいるチャートは6つだけだった。

PS PositionSelectByTicket()の実装では、確かにアクセス同期のある共有リソースにアクセスすることができます。また、各コールでポジションを選択しない場合は、旧価格を読みます。SymbolInfoDoubleを介した「スナップショット」の方が簡単だったのです。

私もこれを使っています。

// Снепшот SymbolInfoTick для текущего символа.
bool SymbolInfoTick( MqlTick &Tick )
{
  static MqlTick PrevTick = {0};
  static ulong PrevTime = 0;
  
  const ulong NewTime = GetMicrosecondCount();
  const bool Res = (NewTime - PrevTime < 1000) || (::SymbolInfoTick(_Symbol, PrevTick) && (bool)(PrevTime = NewTime));
  
  Tick = PrevTick;
  
  return(Res);
}
 

端末に問題があるのに、戦闘性能の速さはどのようなものなのでしょうか。

Expert Advisorは、すべての金融商品をスキャンし、所定のパターンを検索します。

シンボルにつまずいて、しっかりハングアップ!!!

ヘルプのコードには、ステップと問題のある金融商品とタイマーだけを入れています。

//+------------------------------------------------------------------+ 
//|                                              TestLoadHistory.mq5 | 
//|                        Copyright 2009, MetaQuotes Software Corp. | 
//|                                              https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "2009, MetaQuotes Software Corp." 
#property link      "https://www.mql5.com" 
#property version   "1.02" 
#property script_show_inputs 
//--- input parameters 
input string          InpLoadedSymbol="RTSCHH1";   // Symbol to be load 
input ENUM_TIMEFRAMES InpLoadedPeriod=PERIOD_H1;  // Period to be load 
input datetime        InpStartDate=D'2006.01.01'; // Start date 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart() 
  { 
   Print("Start load",InpLoadedSymbol+","+GetPeriodName(InpLoadedPeriod),"from",InpStartDate); 
//--- 
   int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate); 
   switch(res) 
     { 
      case -1 : Print("Unknown symbol ",InpLoadedSymbol);             break; 
      case -2 : Print("Requested bars more than max bars in chart "); break; 
      case -3 : Print("Program was stopped ");                        break; 
      case -4 : Print("Indicator shouldn't load its own data ");      break; 
      case -5 : Print("Load failed ");                                break; 
      case  0 : Print("Loaded OK ");                                  break; 
      case  1 : Print("Loaded previously ");                          break; 
      case  2 : Print("Loaded previously and built ");                break; 
      default : Print("Unknown result "); 
     } 
//--- 
   datetime first_date; 
   SeriesInfoInteger(InpLoadedSymbol,InpLoadedPeriod,SERIES_FIRSTDATE,first_date); 
   int bars=Bars(InpLoadedSymbol,InpLoadedPeriod); 
   Print("First date ",first_date," - ",bars," bars"); 
//--- 
  } 
//+------------------------------------------------------------------+ 
//|                                                                  | 
//+------------------------------------------------------------------+ 
int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date) 
  { 
  Print(" === 1 === ");
   datetime first_date=0; 
   datetime times[100]; 
//--- check symbol & period 
   if(symbol==NULL || symbol=="") symbol=Symbol(); 
   if(period==PERIOD_CURRENT)     period=Period(); 
//--- check if symbol is selected in the MarketWatch 
   if(!SymbolInfoInteger(symbol,SYMBOL_SELECT)) 
     { 
      if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) return(-1); 
      SymbolSelect(symbol,true); 
     } 
     
     ulong time = GetMicrosecondCount();
     Print(" === 2 === ",first_date);
//--- check if data is present 
  bool date = SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
   
   Print(" === 2.1 === ",(time - GetMicrosecondCount()));
   
   if(first_date>0 && first_date<=start_date) return(1); 
//--- don't ask for load of its own data if it is an indicator 

Print(" === 2.2 === ");
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol) 
      return(-4); 
//--- second attempt 
Print(" === 2.3 === ");
   if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date)) 
     { 
      //--- there is loaded data to build timeseries 
      Print(" === 2.4 === ");
      if(first_date>0) 
        { 
         //--- force timeseries build 
         CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times); 
         //--- check date 
         Print(" === 2.5 === ");
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(2); 
        } 
     } 
     
     Print(" === 3 === ");
     
//--- max bars in chart from terminal options 
   int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS); 
//--- load symbol history info 
   datetime first_server_date=0; 
   while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped()) 
      Sleep(5); 
//--- fix start date for loading 

Print(" === 4 === ");


   if(first_server_date>start_date) start_date=first_server_date; 
   if(first_date>0 && first_date<first_server_date) 
      Print("Warning: first server date ",first_server_date," for ",symbol, 
            " does not match to first series date ",first_date); 
//--- load data step by step 

Print(" === 5 === ");

   int fail_cnt=0; 
   while(!IsStopped()) 
     { 
      //--- wait for timeseries build 
      while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped()) 
         Sleep(5); 
      //--- ask for built bars 
      int bars=Bars(symbol,period); 
      if(bars>0) 
        { 
         if(bars>=max_bars) return(-2); 
         //--- ask for first date 
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(0); 
        } 
      //--- copying of next part forces data loading 
      int copied=CopyTime(symbol,period,bars,100,times); 
      if(copied>0) 
        { 
         //--- check for data 
         if(times[0]<=start_date)  return(0); 
         if(bars+copied>=max_bars) return(-2); 
         fail_cnt=0; 
        } 
      else 
        { 
         //--- no more than 100 failed attempts 
         fail_cnt++; 
         if(fail_cnt>=100) return(-5); 
         Sleep(10); 
        } 
     } 
     
     Print(" === 6 === ");
//--- stopped 
   return(-3); 
  } 
//+------------------------------------------------------------------+ 
//| Возвращает строкое значение периода                              | 
//+------------------------------------------------------------------+ 
string GetPeriodName(ENUM_TIMEFRAMES period) 
  { 
   if(period==PERIOD_CURRENT) period=Period(); 
//--- 
   switch(period) 
     { 
      case PERIOD_M1:  return("M1"); 
      case PERIOD_M2:  return("M2"); 
      case PERIOD_M3:  return("M3"); 
      case PERIOD_M4:  return("M4"); 
      case PERIOD_M5:  return("M5"); 
      case PERIOD_M6:  return("M6"); 
      case PERIOD_M10: return("M10"); 
      case PERIOD_M12: return("M12"); 
      case PERIOD_M15: return("M15"); 
      case PERIOD_M20: return("M20"); 
      case PERIOD_M30: return("M30"); 
      case PERIOD_H1:  return("H1"); 
      case PERIOD_H2:  return("H2"); 
      case PERIOD_H3:  return("H3"); 
      case PERIOD_H4:  return("H4"); 
      case PERIOD_H6:  return("H6"); 
      case PERIOD_H8:  return("H8"); 
      case PERIOD_H12: return("H12"); 
      case PERIOD_D1:  return("Daily"); 
      case PERIOD_W1:  return("Weekly"); 
      case PERIOD_MN1: return("Monthly"); 
     } 
//--- 
   return("unknown period"); 
  }

作品の結果

2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)   Start loadRTSCHH1,H1from2006.01.01 00:00:00
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 1 === 
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 2 === 1970.01.01 00:00:00
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.1 === 18446744073475877138    Время выполнения SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.2 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.3 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 3 === 

スクリプトの実行が終了するのを待ったことはありません。

端末にこのようなバグがある以上、戦闘の実行は論外だ!!!

ある証券がマーケットレビューに入ったとき、少なくともその証券のすべてのプロパティと履歴の開始日が引き出されることが予想されたのです。サーバーに履歴がない場合は

SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)

即座にNULLを返すべきなのに、なぜ実行時間が18446744073475877138なのか?


私が知らないだけかもしれませんが、CopyXXX機能も16-29秒間ハングアップ します!

ブローカーが3000~6000の金融商品を持っているのは普通ではありません。

 
Vladimir Pastushak:

もしかしたら、CopyXXXの機能も16~29秒ハングアップ するのかもしれません!!!

ブローカーが3000~6000もの金融商品を持っているのは普通ではありません。

バーは悪だ。なので、それらについては別のスレッドで投稿してください。

 
fxsaber:

バーは悪だ。なので、それらについては別のスレッドで投稿してください。

金融商品をプログラム上で選択し、何度もハングアップしない方法をご存知ですか?

 
Vladimir Pastushak:

金融商品をプログラム上で選択し、何度もハングアップしない方法をご存知ですか?

そんな課題には出会っていません。

 
Aleksey Vyazmikin:

fxsaber さん、タスクマネージャーでエージェントの優先度を低く、MT5の優先度を高く設定したらどうでしょうか?

特定のCPUスレッドをすべてのプログラム/OSスレッドに割り当てるのをブロックするユーティリティが見つかりません。そうでなければ、MT5用にスレッドを予約して、他のプログラムによる占有を自動的にブロックすることができ、理論上は遅延を減らすことができます。

すべてのAgentを最低のプライオリティに設定します。

機能しない。


ZZZ 実行中の EA の数が結果に影響する。

 

開発者の皆様、MQL_MEMORY_USEDの計算方法を教えていただけませんか?

EAの全変数が占めるメモリを計算してみました。

MQL_MEMORY_USED = 60 MB, Virtual = 3.40 MB ( 5.7%)

10%未満である。私の理解が正しければ、MQL_MEMORY_USEDはHistoryキャッシュとCopyTicksキャッシュを含んでいます。それでもだいぶ減りましたね。

同時に、パラレルExpert Advisorの消費電力は数倍少なくなっています。しかし、原理は同じです。

一般的に、この値には何が含まれているのでしょうか?


Expert Advisorでテンプレートを保存し、リロードを発生させて同じチャートに適用しています。こんな風に見たことがあります。

MQL_MEMORY_USED = 7 MB, Virtual = 3.40 MB ( 48.6%)

メモリ使用量がほぼ一桁変わりました。これが何を意味するのか、今のところ説明するのは難しいですね。