if (Use_Shakala==false)
{
ChartSetInteger(0,CHART_SHOW_PRICE_SCALE ,0);//Показывать или нет ценовую шкалуint TotalPixel=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); // Ширина графика в пикселяхint WidthBar=int(1<<ChartGetInteger(0,CHART_SCALE)); // сколько пикселей между барамиint FirstBar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR); // номер первого (левого) бара на экранеint VisibleBars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS); // количество видимых баров на экранеint BarNr= FirstBar-(Shift_Start-Shift_Stop)*(-1); // номер искомого бара, допустим на 12 баров правее самого левого бара int LeftPixelOfBar=((FirstBar-BarNr)>=VisibleBars || FirstBar<BarNr)?(-1):((FirstBar-BarNr)*WidthBar); // левый пиксель искомого бара, если бара нет на экране тогда -1int RightPixelOfBar =(LeftPixelOfBar<0)?(-1):LeftPixelOfBar+WidthBar-1; //правый пиксель искомого бара, если бара нет на экране тогда -1if (RightPixelOfBar>=TotalPixel) RightPixelOfBar=TotalPixel-1; // проверяем не за пределами ли экрана if (Zoom==0)ZoomX=6;
if (Zoom==1)ZoomX=5;
if (Zoom==2)ZoomX=5;
if (Zoom==3)ZoomX=4;
if (Zoom==4)ZoomX=2;
if (Zoom==5)ZoomX=0;
pp=WidthBar*((Shift_Start-Shift_Stop)*(-1)+2)+ZoomX;
}
if (Use_Shakala==true)
{
ChartSetInteger(0,CHART_SHOW_PRICE_SCALE ,1);//Показывать или нет ценовую шкалуint TotalPixel=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); // Ширина графика в пикселяхint WidthBar=int(1<<ChartGetInteger(0,CHART_SCALE)); // сколько пикселей между барамиint FirstBar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR); // номер первого (левого) бара на экранеint VisibleBars=(int)ChartGetInteger(0,CHART_WIDTH_IN_BARS); // количество видимых баров на экранеint BarNr= FirstBar-(Shift_Start-Shift_Stop)*(-1); // номер искомого бара, допустим на 12 баров правее самого левого бара int LeftPixelOfBar=((FirstBar-BarNr)>=VisibleBars || FirstBar<BarNr)?(-1):((FirstBar-BarNr)*WidthBar); // левый пиксель искомого бара, если бара нет на экране тогда -1int RightPixelOfBar =(LeftPixelOfBar<0)?(-1):LeftPixelOfBar+WidthBar-1; //правый пиксель искомого бара, если бара нет на экране тогда -1if (RightPixelOfBar>=TotalPixel) RightPixelOfBar=TotalPixel-1; // проверяем не за пределами ли экрана if (Zoom==0)ZoomX=1;
if (Zoom==1)ZoomX=1;
if (Zoom==2)ZoomX=1;
if (Zoom==3)ZoomX=3;
if (Zoom==4)ZoomX=2;
if (Zoom==5)ZoomX=0;
pp=WidthBar*((Shift_Start-Shift_Stop)*(-1)+2-0.5)+ZoomX+Schkala;
}
//pp - ширина скриншота//Shift_Start - номер левого бара, который целиком должен попасть на скрин//Shift_Stop - номер правого бара, который целиком должен попасть на скрин//Schkala - ширина цифровой шкалы по методу fxsaber//Zoom - степень приближение экрана
それを実証するベンチマークコードを提供してもらえますか?
結果(リリース)
そして、プロファイリングモードで実行すると、このような結果が得られます。
残念ながら、この場合、プロファイラを信用することはできません。
結果(リリース)
HH そして、プロファイリングモードで実行すると、このようになります。
この場合、プロファイラを信用できないだけでなく、Bench1はRelease版に比べて10倍も高速に動作しています
ありがとうございます。
結果(リリース)
戦略別Expert Advisorでテストしています。
2018.04.16 14:24:28.049 Core 1 OnTester result 39725470 (µs bench1)
2018.04.16 14:26:14.629 Core 1 OnTester result 39270950 (µs bench2)
2018.04.16 14:27:13.566 Core 1 OnTester result 20467067 (µs bench3)
さらに2倍高速化(ただし10倍以上はない、これはコンパイラの最適化によるものであることは間違いない)。
ストラテジーアドバイザーでテスト。
2018.04.16 14:24:28.049 Core 1 OnTester result 39725470 (µs bench1)
2018.04.16 14:26:14.629 Core 1 OnTester result 39270950 (µs bench2)
2018.04.16 14:27:13.566 Core 1 OnTester result 20467067 (µs bench3)
それでも2倍は速い(ただし、10倍以上はない、これは明らかにコンパイラの最適化によるもの)。
OnTickの計算だけでなく、ティックを生成するための時間をまだ計測していることになります。
以下はOnTickの計測のみです。
ベンチ1
ベンチ3
3倍の差で。BenchX関数を何度も呼び出すから10倍速くなるわけではないのです。StringToDouble2そのものは確かに10倍速いです。
OnTickの計算だけでなく、ティックを生成するための時間を静止画で計測しているのです。
...その通りです。
10倍速いというのは本当に驚きですが、あなたの関数は、文字列が有効なdouble値を含んでいることが分かっている場合にしか使えませんね。
2018.04.16 17:14:16.183 170952_180416 (EURUSD, H1) StringToDouble2 (abcdef) = 5456784.0
ありがとうございます。しかし、このスクリプトも保存が正しくありません。
私のモニターでは、右側の制限に縦線が引かれており、スクリーンショットはその線をはるかに超えています。
サービスデスクからの回答を引用します。
この場合、ChartScreenShotの ヘルプは文字通りに解釈してください。
align_mode=ALIGN_RIGHT
[in] 細かいスクリーンショットの出力のモード。ENUM_ALIGN_MODE 列挙型の値。ALIGN_RIGHT は、右の境界線にアライメントする(端から出力する) ことを示す。ALIGN_LEFTは左寄せを指定する。
つまり、アラインメント ALIGN_RIGHT を指定すると、グラフは強制的に右のボーダーにスクロールされ、これは、以下のコマンドを実行するのと同じことになります。
この動作は、まだChartNavigate()関数がなかった何年も前(つまり歴史的に)に確立されたものです。align_mode=ALIGN_RIGHTを設定すると、グラフの右側のボーダーが正確に削除されることが保証されます。
ChartNavigate()関数が追加されても、ChartScreenShot 関数の動作は変更されないようにしました。
従って、期待する効果(グラフが右端にスクロールされない)を得たい場合は、align_modeパラメータにALIGN_LEFT値を使用します。
この関数は、文字列が有効な double 値を含んでいることが分かっている場合にのみ使用することができます。
2018.04.16 17:14:16.183 170952_180416 (EURUSD, H1) StringToDouble2 (abcdef) = 5456784.0
修正され、オリジナルのように動作するようになった
トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム
mql5言語の特徴、微妙なニュアンスとコツ
fxsaber さん 2018.04.16 13:23
ハイライトされたconstを削除すると、関数の実行時間が2倍になります。これは、コンパイラが常に最適なコードを作成するわけではなく、このようなヒントが必要であることを示している。
マークされたconstを削除すると、関数の実行時間が2倍になる。これは、コンパイラが常に最適なコードを作成するわけではなく、このようなヒントが必要であることを示しています。
面白いですね、ありがとうございます。
一度回答があったコードを編集しないでください、更新した通知が届きません。
マークされたconstを削除すると、関数の実行時間が2倍になる。これは、コンパイラが常に最適なコードを作成するわけではなく、このようなヒントが必要であることを示しています。
非常に興味深い...
なぜこのようなことが起こるのか、何かお考えはありますか?
その仕組みとは?
MQL5で撮影したスクリーンショットの幅を、ある期間のすべてのバーを含むように決定するために、以下のソリューションを提供します。
スクリーンショットの幅は、チャートの近似度によって補正する必要があることが判明した。
実際の「係数」は、スケールのあるバリアントとないバリアントで(特に私の場合)異なることが判明しました。