初級から中級まで:MetaTrader 5のサンドボックスにおけるファイル操作
はじめに
前回の「初級から中級まで:オブジェクトイベント(IV)」では、チャート上に存在する特定のオブジェクトを直接リサイズするための方法を開発し、その方法を実際に示しました。ここでの目的はアプリケーションを開発することではなく、MQL5を使用してMetaTrader 5のプロセスをどのように制御・管理できるのかを、実例を通して示すことです。そのため、現時点では、前回の記事で扱った内容をさらに掘り下げる理由はないと考えています。
もちろん、この種の実装を大幅に拡張して、さらに多くの機能を実現することもできます。しかし、今回の私の関心と目的は別のところにあります。したがって、ここからは別のテーマについて学んでいきます。このテーマについても、今後ほかのプログラミング関連の作業に取り組む前に理解しておくことが非常に重要です。
いつものように、新しいテーマへ進み、この記事と次回の記事で何を扱うのかについて説明していきましょう。
ファイルの操作
まさに何を行いたいのかによっては、非常に複雑になる可能性があるテーマの一つが、ファイルを扱う必要性です。多くの人は、普段行っていることや目にしていることから判断して、ファイルを扱うことは簡単、あるいは些細なことだと考えています。しかし、実際にはそうではありません。
ファイル操作は、間違いなく習得するのが最も複雑で難しいテーマの一つです。これは単純な事実によるものです。ファイルには何でも含めることができるからです。本当に、それだけです。ファイルの扱いが過小評価されることが多いのは、そこに含まれる情報が通常、最も単純で分かりやすい形で提示されるためです。
しかし、ファイルにはバイナリ情報を含めることもできます。それは、数値やアプリケーションの設定情報から、オブジェクトコードという形のプログラムそのもの、さらには多くの場合、マシンオペコードにまで及びます。したがって、ファイルが持つ可能性のある内部形式を考えれば、このテーマが非常に急速に複雑になることも不思議ではありません。
ここで説明する内容と実装方法を、皆さんが確実に理解し、身につけられるようにするため、最初から急いで進めることはしません。そして、皆さんが概念を理解し、吸収していくにつれて、より詳細で複雑なトピックへと進んでいきます。その際も、常に分かりやすい説明を心がけます。
まず、MetaTrader 5プラットフォームそのものについて、そしてMetaTrader 5がファイルをどのように扱うのかについて、理解する必要があります。そうです。MetaTrader 5を純粋なMQL5でプログラミングする場合と、機能の一部をMQL5の外部で実装する場合とでは違いがあります。ファイルを実際に扱い始める前に、この点を理解しておく必要があります。
純粋なMQL5を使用してMetaTrader 5を制御・操作する場合、私たちはいわゆるサンドボックスに制限されます。「サンドボックス」という言葉は、今日では広く使われています。これは、現代のオペレーティングシステムなどにおいて、未知のアプリケーションを比較的安全に実行するための環境を作る仕組みです。これは、アプリケーションがあたかも何でも自由にできるように見える一方で、そこで行われた変更がサンドボックス内に限定され、サンドボックスが閉じられると破棄されるようにすることで実現されています。
これによって、たとえ悪意のある可能性のあるアプリケーションであっても、ファイルを破壊したり、オペレーティングシステムを動作不能にしたりすることを防げます。つまり、サンドボックスとは、その外側にあるものには何も影響を与えない安全な領域です。
MetaTrader 5も、同様の原則で動作します。純粋なMQL5を使用する場合、標準的なサンドボックスがあります。しかし、第三者製のプログラムやDLLライブラリを使用すると、MetaTrader 5のサンドボックスを回避したり、侵害したりできる可能性があります。これによって、通常はアクセスできないディスク上の領域やファイルシステムの領域へアクセスできるようになります。「でも、それは良いことではないでしょうか。結局のところ、通常はアクセスできないデバイスやファイルシステム上の領域にデータを書き込めるようになるのですから。」
これは、現時点では説明するのが少し複雑な問題です。サンドボックスの外側にあるものへアクセスすることには、メリットとデメリットがあります。しかし、今のところ理解しておいていただきたいのは、メリットよりも危険性のほうが大きいということです。MetaTrader 5上で実行されているアプリケーションがサンドボックスの外側へアクセスできるようになると、本来アクセスできないはずのものへアクセスできてしまう可能性があります。多くの場合、これは手元のファイル全体の整合性を脅かすおそれがあります。
MetaTrader 5では、金銭を扱うアプリケーションを実行することになる点を考えてみてください。十分に注意しないと、MetaTrader 5上でアプリケーションを実行した結果、本来であればサンドボックスによる制限によってアクセスできないはずのファイルにまで、そのアプリケーションがアクセスできてしまう場合があります。ただし、実際にこれが起こるためには、ユーザーである皆さん自身が、アプリケーションにそのための権限を与える必要があります。
通常、これは次の図に示されているオプションを有効にした場合に発生します。

図01
図01には、MetaTrader 5上で実行されているアプリケーションがサンドボックスの外側へ出ることを可能にする重要な項目が示されています。この項目には、システムにとって危険な可能性があるという警告も表示されています。これは、MetaTrader 5による適切な制御なしにファイルを操作することによって生じる危険性があるためです。一度サンドボックスの外側へ出てしまうと、MetaTrader 5はそこで何が起こるのかを制御できなくなります。その場合、制御をおこなうのはアプリケーション自身であり、場合によってはオペレーティングシステムのDLLライブラリが呼び出されることになります。これは安全なように思えるかもしれません。しかし、悪意のあるアプリケーションは、オペレーティングシステム自身のDLLライブラリを利用して、壊滅的な被害を引き起こす可能性があります。十分に注意してください。
「分かりました。それでは、そのような場合にサンドボックスはどのように私たちを保護してくれるのでしょうか。」ここからが、最も興味深いところです。MetaTrader 5の開発者は、非常に先見的なアプローチを採用しました。すべてを小さなブロックに分割し、それぞれのブロックを、ほかのブロックから完全に分離された独立したサンドボックスとして扱えるようにしたのです。実際には、正確にはそのような仕組みになっているわけではありません。しかし、これらのプロセスについて詳しく理解するのは、ここで示す方法や資料を実際に使いながら学習を進めていけば、時間とともにできるようになります。
まず最初の段階では、サンドボックスの内部だけで作業します。できるだけ単純な方法を使用し、不必要な複雑さを持ち込まないようにします。これによって、不要なストレスやデータ損失のリスクを伴うことなく、ファイルやディレクトリを作成・変更できるようになります。サンドボックスは、まさにそのために設計されたものです。
それでは、非常に単純で理解しやすいところから始めましょう。これは、次のコードで確認できます。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. const string szText = "This file was created by a script written in MQL5."; 07. uchar info[]; 08. 09. StringToCharArray(szText, info); 10. 11. FileSave("Hello.txt", info); 12. } 13. //+------------------------------------------------------------------+
コード01
これは、ファイルへ書き込むための非常に単純で分かりやすいコードです。しかし、このコードを実行すると、少し興味を引かれるようなことが起こります。ただし、一つずつ順番に見ていきましょう。まず、コード01の06行目には、ファイルへ書き込まれるメッセージが含まれています。しかし、具体的にはどのファイルなのでしょうか。「分かりました。ファイル名は11行目で指定されています。しかし、このファイルはどこに保存されるのでしょうか。もっと正確に言えば、ディスク上のどのディレクトリを探せば、このファイルが存在する、あるいは保存されていると考えればよいのでしょうか。」これは、いくつかの条件によって変わります。現在のコードのように記述されている場合、ファイルはMetaTrader 5の標準的なサンドボックスディレクトリに保存されます。
ディレクトリ構造上の正確な場所は、MetaTrader 5でコードを実行するのか、それともテストエージェントで実行するのかによって異なります。いずれにしても、ここではすべてのコードをMetaTrader 5上で直接実行すると仮定しましょう。この場合、ファイルはMQL5\Filesサブフォルダに保存されます。これは以下の図で確認できます。

図02
さて、図02を見ると、矢印が奇妙な文字を指していることが分かります。この文字はファイルの一部です。ファイル内に保存されたためです。しかし、06行目のメッセージを見ると、この文字を示すものは何もありません。では、この文字はどこから来たのでしょうか。さて、この文字は09行目によって現れました。11行目の関数が文字列をファイルへ書き込めるようにするため、文字列を文字配列へ変換しています。そのため、配列へ変換された文字列から終端文字が削除されていないので、文字列の終端文字も保存される内容の一部になってしまいます。
分かりました。しかし、これは問題を引き起こすのでしょうか。原則として、それが存在することを知っているのであれば、問題にはなりません。しかし、コード01は非常に単純で、ファイルシステムについて初めて学ぶためのものです。したがって、現段階ではこの点について心配する理由はないと考えています。
そこで、この段階では、ファイル内にこの奇妙に見える文字が存在している図02の内容が私たちにとって問題ではないことを証明するために、コード01を変更します。書き込んだファイルを読み込み、その内容をターミナルに出力するようにします。これは下記のコード02で確認できます。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. #define szFileName "Hello.txt" 07. 08. const string szText = "This file was created by a script written in MQL5."; 09. 10. uchar W[], R[]; 11. 12. StringToCharArray(szText, W); 13. 14. FileSave(szFileName, W); 15. 16. FileLoad(szFileName, R); 17. 18. Print(CharArrayToString(R)); 19. } 20. //+------------------------------------------------------------------+
コード02
さて、書き込んだファイルと同じファイルを確実に読み込めるようにするため、コード02の06行目にある定義を使用して、使用するファイルの名前を指定しています。最初の行についてはすでに説明しているので、16行目へ進みましょう。ここでは、ファイルの内容を読み込み、それを配列に格納しています。18行目では、この文字配列を文字列に変換しています。これによって、08行目と同じメッセージを出力できます。
これを確認するために、コード02を実行すると、次の結果が表示されます。

図03
つまり、すべてが期待どおりに動作しました。これは可能な限り単純なケースです。最小限のコードによって、ファイルの内容を保存し、その後で読み込むことができました。しかも、不要なストレスや複雑さはありません。
それでは、ここから作業を少し複雑にしてみましょう。そうすることで、ファイルの読み込みと書き込みに関係する、いくつかのニュアンスを理解し始めることができます。まず、サンドボックスを変更してみましょう。これをおこなうには、上で示したコードを、以下のコードに置き換えるだけです。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. #define szFileName "Hello.txt" 07. 08. const string szText = "This file was created by a script written in MQL5."; 09. 10. uchar W[], R[]; 11. 12. StringToCharArray(szText, W); 13. 14. FileSave(szFileName, W, FILE_COMMON); 15. 16. FileLoad(szFileName, R, FILE_COMMON); 17. 18. Print(CharArrayToString(R)); 19. } 20. //+------------------------------------------------------------------+
コード03
コード03を実行すると、図03と同じ結果が表示されます。しかし、このファイルを探してみると、MQL5\Filesサブフォルダには作成されていないことに気づくでしょう。別の場所に作成されています。では、どこにあるのでしょうか。それについて説明する前に、まず注意してください。コード02とコード03の唯一の違いは、コード03の14行目と16行目に追加された、まさにこの追加パラメータです。
ここでよく注意してください。14行目でファイルを保存するとき、この追加パラメータによって、ファイルをどのサンドボックスに保存するのかをMetaTrader 5に伝えています。しかし、16行目で行っているファイルの読み込み時に、このパラメータを指定しなかった場合、MetaTrader 5は標準のサンドボックス、つまりMQL5\Filesサブフォルダ内でファイルを探します。その結果、期待していたものとは異なる結果になる可能性があります。たとえば、ファイルの読み込みやアクセス時にエラーが発生したり、場合によっては、期待していたものとは大きく異なる理解不能な内容が読み込まれたりすることがあります。
したがって、処理全体を正しく動作させるためには、読み込み時と書き込み時でファイルの保存場所を一致させる必要があります。書き込み時には一方のサンドボックスを指定し、読み込み時には別のサンドボックスを指定しても意味がありません。あるいは、その逆も同じです。MetaTrader 5が、皆さんが何をしようとしているのか、あるいはどのファイルにアクセスしようとしているのかを理解してくれると期待しても意味がありません。MetaTrader 5には、そのようにする義務もありませんし、そうする理由もありません。
場合によっては正しいファイルを見つけることもあるかもしれません。しかし、それを当てにしてはいけません。おそらく最終的には、間違った場所にファイルを書き込んだり、間違った場所にあるファイルを読み込んだりすることになります。これは、必要としている情報の種類に関する期待を満たさないだけではありません。皆さんのミスによって、既存のファイルに新しいデータが上書きされ、その結果、すでに存在していたデータを破損させてしまう可能性もあります。
それでは、コード03の14行目と16行目にある、この追加パラメータが具体的にどのサンドボックスを指しているのか、ようやく確認してみましょう。これは、必要であれば、ほかのエディタを使用してファイルを見つけられるようにするためにも必要です。FILE_COMMONパラメータは、MetaTrader 5に\\Terminal\Common\Filesサブフォルダを使用するよう指示します。非常に簡単です。「ちょっと待ってください。何が起こっているのか理解させてください。FILE_COMMONパラメータが存在しない場合はMQL5\Filesサンドボックスを指し、それが存在する場合は\\Terminal\Common\Filesサンドボックスを指す、ということですか。それだけですか。」はい、その通りです。「しかし、私は、この変更を有効にするためには、ディレクトリを指定する必要があると思っていました。ある意味では、これは少し分かりにくいように思えます。」
実際には、それほど複雑なことではありません。そう見えるのは、まさに皆さんがまだサンドボックスという概念を理解していないからかもしれません。しかし、急ぐのはやめましょう。この概念を十分に理解し、さまざまな状況で利用できるようにするためです。MetaTrader 5をさまざまな状況で最大限に活用したいのであれば、この処理を正しく理解することは非常に重要です。
サンドボックスを理解する
サンドボックスという概念を正しく理解するためには、ファイルシステムがどのように動作するのかについて、ある程度理解しておく必要があります。ここでは簡単な説明をおこないます。これは、後で使用する用語について、まだそれらに慣れていない方にも理解していただくためです。
まず理解する必要がある用語は、ルート(root)、つまりルートディレクトリという概念です。ルートディレクトリは、ディレクトリツリーの開始点だと考えることができます。「ツリー」という考え方は、ツリーのそれぞれの枝が、同じディレクトリ内にあるサブフォルダに相当することから来ています。そして、これらの枝のそれぞれにある葉は、ファイルに相当します。したがって、簡単に考えれば、ルートは最初のディレクトリです。それぞれのディレクトリツリーには、1つだけルートがあります。このルートから、最初に1本の枝が伸びています。その枝にある葉は、ルートに直接関連付けられたファイルになります。1本のツリーが、別のツリーと直接接触することはありません。言い換えれば、2つの異なるルートを持つツリーは存在しません。そして、それらはすべて地面に接続されています。
ここまで理解したところで、MetaTrader 5におけるサンドボックスの構成を、視覚的な類推によって考えてみましょう。これは次の図に示されています。

図04
図04には、前のセクションで使用したものとまったく同じように、2つのサンドボックスが示されています。ここで、ベースとなるフォルダがMetaQuotes\Terminalサブフォルダであることに注意してください。ただし、これはルートではありません。これは、これらのツリーが配置されている基盤です。
ここで、次の点に注意してください。ツリーNo.1にはルートがあり、この場合、そのルートはCommon\Filesフォルダにあります。ツリーNo.2には別のルートがあり、そのルートはMQL5\Filesフォルダにあります。一方のツリーからもう一方のツリーへ直接移動することはできません。まず、その下にある基盤を通過する必要があります。通常、ある枝から別の枝へ移動する場合、その下にある基盤を通過する必要があります。しかし、ここでは同じ種類の移動をおこなうことはできません。なぜなら、一方のツリーは1つのサンドボックスであり、もう一方のツリーは別のサンドボックスだからです。
これをもう少し分かりやすくすると同時に、ここまでの内容を実際にどのように実装できるのかを学習し、理解する機会を設けるため、前のセクションで説明したコードを変更してみましょう。これによって、私たちの枝にディレクトリを追加できるようにします。これは非常に簡単におこなえます。しかし、その結果は非常に興味深いものになります。そして、実際にサンドボックスがどのように動作するのかを理解する助けになるかもしれません。これは、すべてを制御下に置いておくために必要なことです。以下は、最初に使用するコードです。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. #define szFileName "Hello.txt" 07. #define macro_Save(A) Print("Attempting to write in [",A,"] resulted in: ", FileSave(A, buff)); 08. //+----------------+ 09. const string szText = "This file was created by a script written in MQL5.\nThis would be the contents of file number #%02d."; 10. //+----------------+ 11. uchar buff[]; 12. ushort counter = 1; 13. //+----------------+ 14. StringToCharArray(StringFormat(szText, counter++), buff); 15. macro_Save(szFileName); 16. //+----------------+ 17. StringToCharArray(StringFormat(szText, counter++), buff); 18. macro_Save(".\\Test\\" + szFileName); 19. //+----------------+ 20. StringToCharArray(StringFormat(szText, counter++), buff); 21. macro_Save(".\\Temp\\" + szFileName); 22. //+----------------+ 23. StringToCharArray(StringFormat(szText, counter++), buff); 24. macro_Save("..\\SandBox\\" + szFileName); 25. } 26. //+------------------------------------------------------------------+
コード04
コード04では、MQL5\Filesサンドボックス内の異なる枝に、4つの異なるファイルを書き込んでみます。ただし、そのうちの1つでは、サンドボックスから出て、MQL5ディレクトリにデータを書き込もうとします。これらがどのように試行され、また、その結果をどのように解釈すればよいのかを理解できるように、ゆっくりと見ていきましょう。
まず、MetaTrader 5でコード04を実行すると、ターミナルに次のような結果が表示されます。

図05
3つのケースでは、ファイルの内容が正しく書き込まれていることに注目してください。ほかの関数を使ってディレクトリを作成する処理を一切記述していないにもかかわらず、MetaTrader 5は、コード04を実行する前にそれらが存在していなかった場合に備えて、2つの新しいディレクトリを作成する必要があることを検出しました。
それでは、ファイルにどのような内容が書き込まれ、どこに配置されているのかを見てみましょう。これは以下の図で確認できます。

図06

図07

図08
これら3つの図では、場所とファイル名を緑色で示していることに注意してください。しかし、それぞれの内容をよく見てください。ほとんど同じであることが分かるでしょう。異なっているのは2行目の数値だけです。この値は、ファイルの内容を区別し、同じ方法で異なるファイルを書き込めることを示すためだけに使用されています。
それでは、コード04そのものに戻りましょう。15行目、18行目、21行目、24行目では、使用するディレクトリの名前だけを変更していることに注目してください。しかし、図05に示されているように、4つ目のファイルを作成しようとしたときにエラーが発生しました。なぜでしょうか。現在のサンドボックスの外側に何かを作成しようとしているからです。言い換えれば、サンドボックスのルートディレクトリの外側にある枝へ移動しようとしているのです。これをおこなおうとすると、MetaTrader 5はそれをエラーとして解釈し、ディスク操作をブロックします。これは、ファイルの内容を書き込む場合でも、読み込む場合でも同じです。
多くの人にとって、これは少し奇妙に思えるかもしれないことは理解しています。18行目、21行目、24行目の違いは、24行目に追加されたドットだけです。しかし、このドットによって、システムに対して現在の場所とは異なる方向へ移動するよう指示しています。ところが、私たちはサンドボックスの内部におり、MQL5を介してMetaTrader 5の関数を使用しています。そのため、サンドボックスの外側へ出ることは許可されていません。これは、オペレーティングシステム自身の書き込み関数を使用した場合には起こりません。その場合、OSはMetaTrader 5によって作成・維持されているサンドボックスについて認識していません。したがって、サンドボックスの外側では、あらゆるファイルに対して、書き込み、読み込み、さらには何でも行うことが可能になります。
ここでの説明がMetaTrader 5のファイルシステムについて初めて学ぶ皆さんにとって、必要以上に複雑なものになってしまうことは望んでいません。そこで最後にもう一度コードを変更し、アプリケーションが書き込んだファイルの一部を読み込んでテストできるようにします。
そのために、以下のコードを使用します。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. void OnStart(void) 05. { 06. #define szFileName "Hello.txt" 07. #define macro_Save(A) Print("Attempting to write in [",A,"] resulted in: ", FileSave(A, buff)); 08. #define macro_Load(A) Print("Attempt to read the [",A,"] file resulted in: ", FileLoad(A, buff) != INVALID_HANDLE); 09. //+----------------+ 10. const string szText = "This file was created by a script written in MQL5.\nThis would be the contents of file number #%02d."; 11. //+----------------+ 12. uchar buff[]; 13. ushort counter = 1; 14. //+----------------+ 15. StringToCharArray(StringFormat(szText, counter++), buff); 16. macro_Save(szFileName); 17. //+----------------+ 18. StringToCharArray(StringFormat(szText, counter++), buff); 19. macro_Save(".\\Test\\" + szFileName); 20. //+----------------+ 21. StringToCharArray(StringFormat(szText, counter++), buff); 22. macro_Save(".\\Temp\\" + szFileName); 23. //+----------------+ 24. StringToCharArray(StringFormat(szText, counter++), buff); 25. macro_Save("..\\SandBox\\" + szFileName); 26. //+----------------+ 27. Print("+----------------+"); 28. ArrayResize(buff, 0); 29. macro_Load(".\\Test\\" + szFileName); 30. if (buff.Size() > 0) 31. Print("File content:\n", CharArrayToString(buff)); 32. Print("+----------------+"); 33. ArrayResize(buff, 0); 34. macro_Load(".\\Test 1\\" + szFileName); 35. if (buff.Size() > 0) 36. Print("File content:\n", CharArrayToString(buff)); 37. } 38. //+------------------------------------------------------------------+
コード05
コード05は、サンドボックスシステムがどのように動作するのかを理解する助けになります。少なくとも、これがコード05の最初の目的です。ここでは、特定の場所にある任意のファイルについて、その内容を書き込むことと読み込むことの両方を試みています。一見すると少し分かりにくいように思えるかもしれません。しかし、記事の最初から説明してきた内容をきちんと理解できていれば、図に示されているように、すべては単純です。

図09
これらすべてのメッセージを理解するためには、コード04で何を実装し、どのような結果を得たのかを理解する必要があります。コード04を実行した結果が図05であり、それぞれのファイルの内容が図06、図07、図08に示されていることを考えると、ここでコード05について考える必要があるのは、いくつかの重要な点だけです。本質的には、26行目以降で何が起こるのかを説明すれば十分です。ここから、ファイルの読み込み、あるいはファイルを読み込もうとする処理が始まります。
ご覧のとおり、29行目と34行目では、08行目にあるマクロを実行しています。ここで重要なのは、08行目のこのマクロが実行されると、どのファイルを読み込もうとしているのか、そしてその結果が成功したのかどうかを示すメッセージがターミナルに出力されることです。ここまでは、すべて非常に正常で、理解しやすいものです。では、なぜこのコードでは28行目と33行目を使用しているのでしょうか。その理由は、まさにデータ配列をクリアするためです。読み込みを試みた際にエラーが発生する可能性があるため、以前のデータを残したくはありません。したがって、30行目と35行目のチェックが実行されたときには、配列に実際に何らかのデータが含まれている場合にのみ、ターミナルへメッセージを出力します。
34行目では、原則として存在してはいけないファイルを読み込もうとしているため、ターミナルにはエラーメッセージが出力され、35行目のチェックも失敗します。
まず、コード05で指定されているファイルとディレクトリは、最初の時点では存在していないはずだということを覚えておいてください。このようにすることで、図09に示されているように、正しい結果が得られ、適切に表示されます。もし異なる結果が得られた場合は、コード05で使用しているファイル名、あるいはディレクトリそのものを変更してみてください。目的は、存在しないファイルを読み込もうとしたときに発生するエラーと、指定したディレクトリにあるファイルを読み込もうとしたときの結果の両方を発生させることです。
また、この記事で説明したもう一つのサンドボックスを使用するようにコードを変更してみてください。つまり、追加のFILE_COMMONパラメータを指定してみます。これは、異なるルートを持つ2つのツリーが表示されている図04が、実際に何を示しているのかを正確に理解する助けになります。
最終的な考察
本記事では、MetaTrader 5のファイルシステムについて学ぶ最初の一歩を踏み出しました。その目的は、サンドボックスがどのように動作するのかを理解し、オペレーティングシステムのディレクトリツリー内にある、本来変更すべきではないフォルダを誤って変更してしまうことを避けることです。初心者の視点から見ると、最初は複雑に見えるかもしれません。しかし、今後のプロジェクトを進めるうえで、サンドボックスの使い方を理解することは絶対に必要です。特に、ファイルを積極的に使用してデータを保存したり、時間の経過に応じて保存・更新されていく設定を作成したりしたいのであれば、これは非常に重要です。
読者の皆さん、焦らずにこの内容を学習してみてください。このステップは、正しく行う必要があります。サンドボックスがどのように動作するのかを理解していなければ、将来、特定のタスクを解決することが非常に難しくなります。
| MQ5ファイル | 説明 |
|---|---|
| コード01 | ファイルアクセスの実演 |
| コード02 | ファイルアクセスの実演 |
| コード03 | ファイルアクセスの実演 |
| コード04 | ファイルアクセスの実演 |
| コード05 | ファイルアクセスの実演 |
MetaQuotes Ltdによりポルトガル語から翻訳されました。
元の記事: https://www.mql5.com/pt/articles/16167
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
最強のML搭載取引プラットフォームが生まれるまで:アーカイブ、フォーラム、リリースからたどるMQLとMetaTraderの進化
競争学習アルゴリズム(CLA)
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
取引におけるニューラルネットワーク:高精度分類のための効果的な特徴量抽出(Mantis)
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索