Azatskiy0306イントロダクション前回の記事(最適化管理(パートI)と最適化管理(パート2)では、サードパーティのプロセスを通じてターミナルで最適化を開始するメカニズムを検討しました。これにより、特定のトレードプロセスを実装するトレードアルゴリズムと同様にプロセスを実装できる特定の最適化マネージャを作成できます。このアイデアは、ヒストリーの期間が事前の間隔によってシフトされ、スライディング最適化プロセスを管理するアルゴリズムを作成することです。アルゴリズムの最適化に対するこのアプローチは、両方の役割を果たしますが、純粋な最適化ではなく、戦略の堅牢性テストとして機能します。結果として、トレードシステムが安定しているかどうかを調べることができ、システムのインジケータの最適な組み合わせを決定することができます。説明したプロセスは、異なるロボット係数フィルターと最適な組み合わせ選択方法を伴う可能性があるため、各時間間隔(複数の場合がある)をチェックインする必要があるため、プロセスを手動で実施することはほとんどできません。データ転送に関連するエラーや、人的要因に関連するその他のエラーが発生する可能性があります。したがって、介入なしに外部から最適化プロセスを管理するツールが必要です。今回作成されたプログラムは、目標を満たすことができます。構造化されたプレゼンテーションでは、プログラム作成プロセスは複数の記事に分割され、各記事はプログラム作成プロセスの特定の領域を扱っています。このパートは、最適化レポートを操作するためのツールキットの作成、ターミナルからのインポート、取得したデータのフィルタリングとソートに関するツールキットの作成です。良いプレゼンテーション構造を提供するために、*xmlファイル形式を使用します。このファイルのデータは、人間とプログラムの両方で読み取ることができます。データはファイル内のブロックにグループ化できるため、必要な情報に迅速かつ容易にアクセスできます。プログラムはC#で書かれたサードパーティのプロセスであり、作成された*xml文書を作成してMQL5プログラムと同様に読み取る必要があります。したがって、レポート作成ブロックは、MQL5とC#コードの両方で使用できるDLLとして実装されます。したがって、MQL5コードを開発するためには、ライブラリが必要です。コードの説明を提供し、最適化パラメータを生成します。現在の記事でパラメータを検討します。前の記事で既に示したように、MetaTrader5は最適化パスのレポートを個別にダウンロードできますが、特定のパラメータセットを使用してテストが完了した後に[バックテスト]タブで生成されたレポートほど多くの情報は提供されません。データを追加する可能性を提供する必要があります。このために、標準レポートではなく、独自の生成されたレポートをダウンロードします。つのデータ型の定義から始めましょう。</Optimiser_Settings>パラメータは"Item"ブロックに書き込まれ、それぞれが独自の"Name"属性を持ちます。資産通貨は"通貨"属性に書き込まれます。これに基づいて、ファイル構造には、テスター設定と最適化パスの説明の2つの主要なセクションが含まれている必要があります。つのパラメータを保持する必要があります。エキスパートフォルダに対するロボットパス資産通貨と資産アカウントレバレッジ2番目のセクションには、最適化結果を持つ一連のブロックが含まれ、それぞれに係数を持つセクションとロボットパラメータのセットが含まれます。番目の最適化パスが含まれるResultブロックが繰り返されます。SymbolTFStart_DTFinish_DT最適化が実行される時間間隔によって異なるテスター設定です。属性を持つItemブロックに書き込まれます。ロボット係数は係数ブロックに書き込まれます。グループ化できない係数はItemブロックに直接列挙されます。その他の係数はブロックに分割されます。trades結果として、テスト結果を完全に記述した最適化結果の係数を含むリストが表示されます。ロボットパラメータをフィルタリングして選択するために、ロボットの性能を効率的に評価できる必要な係数の完全なリストがあります。特定の最適化パスのデータを格納する構造体から始めましょう。range}すべてのロボット係数は、文字列形式でディクショナリに格納されます。ロボットパラメータを持つファイルはデータのタイプを保存しないため、文字列フォーマットが最適です。ロボット係数のリストは、*xml最適化レポートにグループ化された他のブロックと同様に、異なる構造で提供されます。日別のトレードレポートもディクショナリに保存されます。列挙体が含まれている必要があります。構造体に格納されます。つの日付範囲を作成する可能性が必要です。等値基準は、2つの渡された範囲の両方の日付の等値、すなわち、開始日付が2番目の範囲のトレード開始と一致することによって決定されます(同じことがトレードエンドにも適用されます)。比較する関数を提供する必要があります。そのためにisキーワードを使いましょう。その後、パラメータを互いに比較することができ、それ以外の場合、nullと比較しようとすると"null参照例外"が返されます。"<="をオーバーロードする必要があります。それ以外の場合は、ステップバイステップで比較します。番目の時間間隔で比較します。等しくない場合は、最初の間隔で比較します。よって前の時間よりも古いものです。並べ替えオプションを有効にするためにオーバーロードされる次の演算子は、「次に大きいか等しい」と「等しくない」です。b2);#endregion見てわかるように、演算子のオーバーロードは内部比較ロジックの記述を必要としません。基本クラスから継承された関数をオーバーロードする必要があります。型が指定されている場合)、またはメソッドの基本的な実装を使用します。つの日付の文字列表現としてオーバーロードします。メソッドをオーバーロードするのに役立ちます。コードを返すことでオーバーロードします。コードはクラスの内容に関係なく一意になります。クラスの新しいインスタンスを作成できないようにするメカニズムを提供するため、このルールは文字列には適用されません。コードの動作を提供します。コードに基づいているため、日付範囲の一意のリストを受け取るロジックが正しいことを保証できます。インスタンスと渡されたインスタンスを比較するメソッドを実装します。その実装は簡単で、以前にオーバーロードされた演算子のオーバーロードを使用します。必要なオーバーロードを実装したら、このクラスをより効率的に処理できます。つのインスタンスを比較して、次の値以上の値を比較します。メソッドを使用します。バックテストとフォワードテストを行うローリング最適化を実装しているので、ヒストリーと前方の間隔を比較するメソッドを作成する必要があります。ans;}ご覧のとおり、このメソッドは静的です。これは、特定のクラスインスタンスにバインドすることなく、通常の関数として使用できるようにするために行われます。渡された時間間隔を昇順に並べ替えます。したがって、次のループでは、以前に渡されたすべての間隔が次の間隔以下であることを確認できます。つのループを実装します。i番目のパラメータから始まります。これより、前方リストの既に使用されている要素でループを繰り返し実行できなくなります。前方の間隔は常にヒストリーに従う必要があります。>でなければなりません。そのため、ループを転送間隔で実装し、渡されたリストに最初のヒストリー区間の前に、最初のヒストリー間隔の転送期間がある場合に、最初のヒストリー間隔が先行します。始まりますが、正しくはありません。そのため、この条件により、前方の間隔ループでスキップします。結果のディクショナリに含まれている転送間隔をスキップします。現在のヒストリカル・インターバル終了日付である場合は、必要な値が既に見つかったので、受信した値を保管し、転送間隔ループを終了します。現在の間隔が不要になるためです。ヒストリー最適化の前のチェックでは、すべてのヒストリー最適化が一意であることを確認します。したがって、結果のディクショナリで次のリストが取得されます。null提示されたデータからわかるように、最初の前方間隔は破棄され、そのような間隔が渡されていないので、直近のヒストリーの間隔は見つかりません。このロジックに基づいて、プログラムはヒストリーと前方の間隔のデータを比較し、ヒストリーの間隔のどれが前方テストの最適化パラメータを提供すべきかを理解します。構造体のラッパ構造を作成しました。つのフィールドが含まれます。SortBy;最初のフィールドは、上記で説明しました。よる並べ替えを可能にするために作成されます。変換し、この変数に格納するという考え方です。構造体には、型変換オーバーロードも含まれています。レポート要素にキャストできます。これは、フィールドの連続的なインプットよりも効率的です。構造体のすべてのフィールドはカテゴリに分かれているので、必要な値を受け取るために長いコードが必要な場合があります。スペースを節約し、より汎用的なゲッターを作成するために特別なメソッドが作成されました。介してリクエストされたロボット比率データを受け取ります。実装はシンプルですが、長すぎるため、ここでは示しません。このメソッドは、渡された列挙型をスイッチで繰り返し処理し、リクエストされた係数の値を返します。このラッパ型には比較演算子のオーバーロードも実装されています。base.Equals(obj);}ロボットパラメータの同じ名前と値を含む最適化の要素は等しいと見なされます。したがって、2つの最適化パスを比較する必要がある場合は、既にすぐに使用できるオーバーロードされた演算子があります。この構造体には、データをファイルに書き込むメソッドも含まれています。存在する場合、データはファイルに追加されます。データ書き込み要素とメソッド実装の説明を以下に示します。最適化レポートを扱い、ターミナルだけでなく作成したプログラムにも書き込みます。ファイルへのデータ書き込みのメソッドを提供しましょう、すなわち、ファイルへのデータ配列の書き込みを有効にするだけでなく、既存のファイルに別の要素を追加することができます(ファイルが存在しない場合は作成する必要があります)。実装されたレポートファイル書き込みメソッドを、ファイルにデータを追加して接続された関数で検討してみましょう。クラスが作成されました。ファイルで使用できます。ここでは、最も興味深いメソッドだけを紹介します。このクラスの仕組みを説明しましょう。MQL5へのメソッドのエクスポートを可能にします。アクセス修飾子でマークされます。型の静的フィールドと、係数とEAパラメータを交互に追加するメソッドがあります。つのメソッドは、ClearReportItem()です。インスタンスを再作成します。この場合、このオブジェクトの前のインスタンスへのアクセスが失われます。消去され、データ保存プロセスが再び開始されます。データ追加メソッドはブロックごとにグループ化されます。メソッドのシグネチャを次に示します。numberOfLoseTrades);日別に分類されたトレード統計を追加するメソッドは、5トレード日のそれぞれに対して呼び出されるべきです。日のうちに追加しないと、書き込まれたファイルは今後読み取られるわけではありません。データストレージフィールドにデータを追加したら、フィールドの記録に進むことができます。この前に、ファイルが存在するかどうかを確認し、必要に応じて作成します。ファイルを作成するためのメソッドが追加されました。writer.WriteEndElement();}また、データと要素固有の属性を持つ直近の要素をファイルに追加するための繰り返しコードを含むWriteItemメソッドの実装もここで示します。ファイル作成メソッドは、ファイルが存在するかどうかをチェックし、ファイルを作成し、必要最小限のファイル構造の形成を開始します。ファイルルート、すなわち<Optimization_Report/>タグを作成し、その中にファイルのすべての子構造が配置されます。ファイルを使ってさらに便利なタスクに実装されます。その後、変更されていないオプティマイザ設定を持つノードを作成し、指定します。次に、最適化結果を保存するセクションを作成し、すぐに閉じます。その結果、必要最小限のフォーマットを持つ空のファイルがあります。クラスを使用してこのファイルを読み取ることができるでしょう。ドキュメントの読み取りと編集に最も役立つクラスです。このクラスを使用して、既存のドキュメントにデータを追加します。繰り返しの操作は別々のメソッドとして実装されるため、終了ドキュメントにデータをより効率的に追加できます。使用して渡されたパスを介して指定されたセクションを別のセクション内に追加します。ブロックは、ファイルにデータを追加するときによく使用します。データ書き込みメソッドは長く、ブロックに分割されます。ClearReportItem();}まず、ドキュメント全体をメモリに読み込み、次にセクションを追加します。ルートノードへのパスを渡すXpathリクエスト形式を考えてみましょう。$"{xpath}/Result[last()]/Coefficients"xpath変数には、最適化パス要素が格納されるノードへのパスが含まれます。このノードには、構造体の配列として表示できる最適化結果ノードが格納されます。Result[last()]コンストラクトは配列の直近の要素を選択し、その後パスはネストされた/Coefficientsノードに渡されます。説明した原則に従って、最適化の結果を含む必要なノードを選択します。次のステップはロボットパラメータの追加です。ループ内で、結果ディレクトリに直接パラメータを追加します。次に、係数ディレクトリに係数の数を追加します。この追加はブロックに分けられます。結果として、結果を保存し、一時ストレージをクリアします。その結果、パラメータと最適化結果のリストを含むファイルが取得されます。(複数のプロセッサを使用する場合にテスターの最適化を実行する方法です)、別の書き込みメソッドが作成され、名前付きミューテックスを使用してスレッドを分離します。ブロックでラップされます。直近のは、エラーの場合でもミューテックスのインプットを有効にします。しないと、プロセスがフリーズし、最適化が続行できなくなる可能性があります。メソッドの最適化結果構造体でも使用します。}}このメソッドでは、最適化結果を一時記憶域に追加し、Writeメソッドを呼び出して既存のファイルに保存するか、まだ作成されていない場合は新しいファイルを作成します。準備されたファイルに情報を追加するには、取得したデータを書き込むメソッドが必要です。データ系列を書く必要がある場合に適した別のメソッドがあります。インターフェイスの拡張として開発されました。適切なインターフェイスから継承されたすべてのリストのデータを保存できます。ファイルに書き込みます。渡されたパスにファイルが既に存在する場合は、新しいパスに置き換えられます。ライターを作成し、構成します。次に、既に知られているファイル構造に従って、オプティマイザの設定と最適化結果を1つずつ書き込みます。上記のコード抽出からわかるように、結果は、記述されたメソッドが呼び出されたインスタンスで、コレクションの要素をループするループで記述されます。ループ内では、データ書き込みは、ファイルに特定の要素のデータを書き込むために作成されたメソッドに委任されます。#endregion}データをファイルに書き込むメソッドの実装は簡単ですが、かなり長いです。適切なセクションを作成し、属性を埋めた後、メソッドは実行された最適化パスのVaR上のデータと最大利益とドローダウンを特徴付ける値にデータを追加します。各日に書き込むために、ネストした関数が作成されました。その後、ルートパラメータおよびグルーピングを使用しない係数が追加されます。(書き込みメソッドで行われます)。したがって、以前に検討されたメソッドと比較して、データ配列を書き込む最も速い拡張メソッドです。ファイルへのデータ書き込みに関連するステップを検討しました。次に、論理部分、つまり結果のファイルからデータを読み取る部分に移ります。最適化レポート・ファイルの読み取り受信した情報を処理し、表示するためにファイルを読み取る必要があります。したがって、適切なファイル読み取りメカニズムが必要です。これは、別のクラスとして実装されます。}構造を詳しく見てみましょう。このクラスはiDisposableインターフェイスから継承されます。必須の条件ではありませんが、予防措置として行われます。クラスには、ドキュメントオブジェクトをクリアするために必要なディスタブルメソッドがあります。このオブジェクトは、メモリに読み込まれた最適化結果ファイルを格納します。構造体にラップする必要があり、'using'構造体ブロックを超えたときに指定されたメソッドを自動的に呼び出す必要があるため、このアプローチは便利です。読み取りドキュメントがメモリ内に長く保持されないため、読み込まれたメモリ量が減少することを意味します。クラスは、読み取りドキュメントから受信した列挙子を使用します。読み取り値は特殊プロパティに書き込まれるため、データへのアクセスを提供します。クラスのインスタンス化中に、メインオプティマイザ設定、ファイル作成日時を指定するプロパティのデータもインプットされます。(書き込み時とファイルの読み取り時の両方)、倍精度の数値区切り書式が示されます。ファイルを初めて読み込むときは、クラスをリストの先頭にリセットする必要があります。このために、列挙子をリストの先頭にリセットするResetReaderメソッドを使用します。クラスコンストラクタは、必要なすべてのプロパティを埋め、クラスをさらに使用できるように実装されています。Convert.ToInt32(document.SelectSingleNode(xpath("Leverage")).InnerText);}まず、渡されたドキュメントを読み込み、作成日をインプットします。<Result/>を持つノードに配置されているドキュメントの子ノードに属します。ノードへのパスを指定します。ノード間のアイテムへのパスを示します<Item/>Name属性に従います。ノードをデイリートレードレポートの適切な構造に変換します。ここでは簡潔な形での実装を以下に示します。フィールドの読み取りデータのインプットが含まれます。この操作には、文字列形式を必要な形式に変換する同様のアクションが含まれます。ループは、ファイルから行ごとに読み取られたデータを使用してロボットパラメータを埋めます。この操作は、完了したファイル行に達していない場合にのみ実行されます。操作の結果は、行が読み取られたかどうかを示す結果です。ファイルのトレーリングストップに到達するインジケータとしても機能します。最適化レポートの多要素フィルタリングと並べ替えこの目的を達成するために、ソートの方向を示す2つの列挙を作成しました(SortMethdとOrderBy)。これらは似ていて、おそらくそのうちの1つだけで十分です。つの列挙が作成されました。列挙体の目的は、昇順または降順です。渡された値を持つ係数の比率タイプはフラグで示されます。目的は比較条件を設定することです。インターフェイスから継承されたコレクションを展開するメソッドとして実装されます。フィルタリングメソッドでは、各係数項目を項目ごとにチェックし、指定された基準を満たすかどうかを確認し、いずれかの係数が基準を満たさない最適化パスを拒否します。このメソッドは次のように実装されます。フィルタ処理タスクの独自の部分を実行します。して提示し、メソッドで指定された値を比較することです。大きい/より小さい、等しい比較に加えて、他の条件をチェックする必要があるかもしれません。このために、フラグを利用します。同時に設定または削除できます。フラグは、複数のループや巨大な条件を作成する必要なく、順番にチェックすることができ、したがって、3つの条件があります。後で検討するグラフィカルインタフェースでは、必要な比較パラメータを設定するためにフラグを使用することも便利です。この関数のフラグを順番にチェックし、データがフラグに対応しているかどうかをチェックします。なく、複数の書き込みパラメータをチェックするように設計されています。フィルタ処理に渡されたすべてのフラグを項目ごとのループで実行し、前述の関数を使用して、選択したパラメータが指定した条件を満たしているかどうかを調べます。メソッドを使用します。返し、不適切な値を破棄します。メソッドを使用します。このメソッドは、適切な条件の一覧を自動的に生成し、拡張メソッドの実行結果として返します。データフィルタリングは理解しやすいです。並べ替えでは困難が発生する可能性があります。例を用いてソートメカニズムを考えてみましょう。プロフィットファクターとリカバリファクターのパラメータがあるとします。つのパラメータでデータを並べ替える必要があります。実行した場合でも、直近のパラメータで並べ替えられたデータが受け取られます。値を何らかの方法で比較する必要があります。つの係数は、境界値内では正規化されません。互いに相対的な値の広い範囲があります。論理的には、まずシーケンスを維持しながら正規化する必要があります。正規化された形式にデータを取り込む標準的な方法は、各データを系列の最大値で除算することです。この一連の値の極値を見つける必要があります。9表からわかるように、リカバリーファクターは負の値があるので、上記のアプローチはここでは適していません。この効果を排除するために、剰余を取った負の値で系列全体をシフトします。各パラメータの正規化値を計算できます。0.52正規化された形式のすべての係数が得られたので、加重付けされた合計を使用できます。その結果、ソート基準として使用できる正規化された列が得られます。引いて、最大の係数と最小の係数を入れ替える必要があります。番目のメソッドは並べ替え機構を実装します。番目のメソッドに移りましょう。つのパラメータで実行する場合は、系列の正規化を行わずに並べ替えを実行します。その後、すぐに結果を返します。ソートが複数のパラメータによって実行される場合、まず、考慮された系列の最大値と最小値からなるディクショナリを生成します。しないと、各繰り返しの間にパラメータをリクエストする必要があるため、計算を高速化できます。この実装で考えたよりもはるかに多くのループが生成されます。次に、加重付けされた合計に対して加重付けを形成し、その合計に系列を正規化する操作が実行されます。ここでは2つのループが再び使用され、上記の操作が内部ループで行われます。結果の加重合計は、適切な配列要素のSortBy変数に追加されます。配列メソッドを使用します。降順の並べ替えが必要な場合。して渡されたデリゲートによって設定されます。このデリゲートがデフォルトのパラメータ化された値として残っている場合は、前述のメソッドが使用します。それ以外の場合は、渡されたデリゲートを使用します。今後、アプリケーション内で積極的に使用する仕組みを作り上げます。コレクション拡張メソッドがあります。標準ターミナルテスターでは利用できない多要素分類機構を実装しました。一連の要因を考慮する能力です。その欠点は、結果が与えられたシリーズ内でのみ比較することができるということです。これは、選択した時間間隔の加重合計が他の間隔と比較できないことを意味します。次の記事では、アルゴリズムのアプリケーションまたは自動化されたオプティマイザを有効にするアルゴリズム変換メソッドと、そのような自動化されたオプティマイザの作成について検討します。Ltd.が保有していますこれらのマテリアルの全部または一部のコピーや再プリントは禁じられています。本稿では、取引クラスの不正な取引注文パラメータ値に対する制御と取引イベントの音声通知において開発を続けています。ピボット平均オシレータの開発:累積移動平均の新規インジケータこの記事では、MetaTraderプラットフォームのトレードインジケータとして累積移動平均(CMA)であるピボット平均オシレータ(PMO)を紹介します。データポイントとCMAの間の分数を計算する時系列の正規化インデックスとしてピボット平均(PM)を導入しました。次に、2つのPMシグナルに適用される移動平均の差としてPMOを構築します。提案されたインジケータの有効性をテストするためにEURUSDシンボルで行われた予備的な実験も行いましたが、さらなる検討と改善の余地があります。本稿では、無効な取引注文パラメータのハンドラを一瞥して、取引イベントクラスを改善します。これによって、すべての取引イベント(単一のイベントと1ティック内で同時に発生したイベントの両方)がプログラムで正しく定義されるようになります。Boxplotによる金融時系列のシーズンパターンの探索この記事では、Boxplotを使用して価格時系列のシーズン特性を表示します。データセットに沿って値がどのように分布しているかを示す優れたものです。Boxplotは、視覚的に似ていますが、ローソク足チャートと混同しないでください。