//+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ stringMyGlobalVariable; // This global variable which holds a string i.e text value has been declared // but as yet has no value in it. It is a 'container' which at this point in time holds // only an empty or null string.
int init()
{
MyGlobalVariable = "Nick"; // Now we assign i.e put a value in the variable. Our 'container' which is named // MyGlobalVariable now holds the string value of "Nick"
return(0); }
//+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() {
return(0); }
//+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() {
MyFunction(MyGlobalVariable); // This calls the function named MyFunction which is declared below // This function requires one string parameter.
// In this case we have passed it our global variable as a parameter.
// MyFunction("Fred"); // We could also pass this function the literal string "Fred"
// MyFunction(12.739); // This would not work. The passed value must be a string because that is what we // have declared the parameter as in the function declaration below.
// MyFunction(DoubleToStr(12.739,3)); // This would work because we have used an inbuilt MT4 function to convert the decimal // number to a string i.e "12.739"). // We can also pass other functions as parameters as we have shown here, provided the // function that we are using as a parameter returns the correct data type which in // this case is a string.
return(0); }
//+------------------------------------------------------------------+ //| A function with one parameter | //+------------------------------------------------------------------+
void MyFunction(string MyFunctionParameter) // The function is declared with a parameter in the same way that a varible is declared // but it is a function parameter not a variable. It can be used just like a variable // but only inside the function. The big difference is that it can be passed a different value // from outside the function whenever the function is called. This enables functions to // be used as general purpose blocks or modules. // Function parameters are also used in some circumstances to return values from the // function to the outside world but that is another more complex story for another day!
{ Comment(MyFunctionParameter); // The value passed to 'MyFunctionParameter' will be displayed at the top, left hand // corner of the screen
Your wish is my command (I was gonna say 'high flyer' but then checked dictionary online and apparently that is rude comment, nevermind)
OK、ちょっと見ただけですが、あなたは今、私の好みに合わないようです。
あなたは私のコードの最新版に基づいて変更をしていません。
したがって、あなたが以前のバージョンにさらに何かを追加し始める前に、私のコードの最新バージョンがあなたが必要としたことを行っていたかどうか、私には全くわかりません。
しかし、私が気づいたのは、start()関数の 最初の部分で、中カッコが抜けていることです。もういいでしょ?
コントロールする必要があります。もし何かを変更するのであれば、必ずその変更を最新バージョンに追加してください。そして、その変更の内容と理由を私たちに教えてください。
CBです。
Timです。
ストラテジーテスターではまだ何も取引していませんが、コンパイル時にエラーが報告されないところまでコードを修正しました(あなたが強調したいくつかのバグを修正しただけです)。しかし、私は何かで困惑しています: ...
こんにちは、Nick。
ここでのあなたのコメントと、あなたがコードに加えたいくつかの変更を見ると、あなたの「困惑」は、変数と関数のパラメータを混同しているために生じているのではないかと思います。この2つは見た目も動作も似ていますが、実際には全く別のものです。
以下のコメント付きコード例で、少しは分かりやすくなったのではないでしょうか。
私は、開発コードをもう少し整理し、いくつかの関数のパラメータ名を少し変えて、他の変数と区別するようにしました。また、余計なメモやコメントなどは、ファイルの最後にある「付録」に移動しましたので、お好きなように使ってください。
コードはいい感じです。まだ、ファイル内にTODOとしてマークしてあるような、ちょっとしたやり残したことがいくつかありますが、これからの主な仕事は、デバッグとテストです。
テストは開発サイクルの中で非常に重要な部分です。取引システムの場合、適切なテストを行わないと、微妙な問題が発生し、取引戦略、ひいては口座に大混乱をもたらす可能性があります。テストの主な仕事は、コードが期待通りに動作しているかどうかを確認することです。このような場合、私はこのような結果を期待します」と書き留めるか、自分自身に言い聞かせる必要があるのです。そして、それが実際に起こるかどうかを確認するために、テストを考案し、実行します。そうでない場合は、その問題を修正しなければなりません。このプロセスを、想定できるすべての状況、そしておそらくは想定外の状況についても繰り返すのです。もちろん、ランタイムエラーや、MetaTraderシステムのエラーメッセージで表示されるかどうかわからないバグも探します。
MT4では、ストラテジーテスターとログファイル(ジャーナルタブ)、そして結果、グラフ、レポート機能が主なテストツールとなります。
ログファイルについては、ジャーナルビューワで一部を見るよりも、マイクロソフトのメモ帳でファイル全体を開く方が簡単なことがよくあります。ログファイルやジャーナルを毎回クリアしないと、古い情報や関連性のない情報に目を通すことになります。ストラテジーテスターでテストを実行した後、デバッグステートメントのメッセージとメタトレーダーのシステムメッセージの両方をログファイルから調べます。MetaTraderのオンラインマニュアルを使用して、追加情報のためのapエラーコードを探すことができます。また、結果、グラフ、およびレポート機能を使用して、特定の条件下でプログラムが何を行っているかを確認します。
ヒント - 最初のテスト実行を行うときは、ログファイルのデータ量を最小限にするために、テスト期間を短くしてください。
すでにいくつかのデバッグ機能をコードに組み込んでいますが、おそらくこれらを拡張する必要があります。必要に応じて個々のデバッグステートメントを無効にして、ログファイル内の情報を凝縮し、適切な状態に保ってください。デバッグステートメントを削除したり、コメントアウトしたりせずに、これを行う方法の例がコードに記載されていますが、これは非常に時間がかかるものです。私は、主なデバッグ文をプログラムファイルに無期限に残し、テストが終了したら、プログラムのDEBUG_ONフラグでそれらをすべてオフにするだけです。
ログファイルとデバッグステートメントを効率的に管理することは、MetaTrader環境における優れた効率的なテストとデバッグの鍵であると思います。このフォーラムで、MetaTraderのデバッグ機能の欠如について不平を言っている人たちを見たことがあります。何百万行もの商用コードは、MetaTraderにあるものよりも洗練された機能を使用して、デバッグとテストに成功しています。これらの機能は基本的なものですが、適切に使用する方法を知っていれば、問題なく機能します。
もう一つのポイントは、乱雑で整理されていないコードをデバッグしようとすると、非常に時間がかかり、苛立たしいということです。この点から、よく構造化され、よくコメントされたコードの恩恵を受けることができるようになるのです。もし誰かがあなたのコードで作業する必要があった場合、この点でのあなたの努力にとても感謝することでしょう。
ニック、この旅はまだ道半ばだ。私にとって、テスト、デバッグ、最適化、つまり「すべてを動かすこと」は、この仕事の最も興味深い部分であり、しばしば最も困難な部分でもあります。テストに取りかかるために、コードをあなたにお返しします。そして、あなたが遭遇した問題や質問を私に返してくれるのを待ちます。
参考
Tim
グローバル変数と関数パラメータの違いを示す簡単なコード例
//+------------------------------------------------------------------+
//| Hello Trader.mq4 |
//| Copyright © 2009, Your Name |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Your Name"
#property link ""
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
stringMyGlobalVariable; // This global variable which holds a string i.e text value has been declared
// but as yet has no value in it. It is a 'container' which at this point in time holds
// only an empty or null string.
int init()
{
MyGlobalVariable = "Nick"; // Now we assign i.e put a value in the variable. Our 'container' which is named
// MyGlobalVariable now holds the string value of "Nick"
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
MyFunction(MyGlobalVariable); // This calls the function named MyFunction which is declared below
// This function requires one string parameter.
// In this case we have passed it our global variable as a parameter.
// MyFunction("Fred"); // We could also pass this function the literal string "Fred"
// MyFunction(12.739); // This would not work. The passed value must be a string because that is what we
// have declared the parameter as in the function declaration below.
// MyFunction(DoubleToStr(12.739,3)); // This would work because we have used an inbuilt MT4 function to convert the decimal
// number to a string i.e "12.739").
// We can also pass other functions as parameters as we have shown here, provided the
// function that we are using as a parameter returns the correct data type which in
// this case is a string.
return(0);
}
//+------------------------------------------------------------------+
//| A function with one parameter |
//+------------------------------------------------------------------+
void MyFunction(string MyFunctionParameter) // The function is declared with a parameter in the same way that a varible is declared
// but it is a function parameter not a variable. It can be used just like a variable
// but only inside the function. The big difference is that it can be passed a different value
// from outside the function whenever the function is called. This enables functions to
// be used as general purpose blocks or modules.
// Function parameters are also used in some circumstances to return values from the
// function to the outside world but that is another more complex story for another day!
{
Comment(MyFunctionParameter); // The value passed to 'MyFunctionParameter' will be displayed at the top, left hand
// corner of the screen
}
おい、CB、それは奇妙だ。私はいつもmq4ファイルを新しいものとして保存し、他のファイルを分けるために最新の日付を入れます。
やみくもに中括弧を付けたり外したり するのはやめましょう。以前、完全に余分なセットがあると指摘したことがありましたが、いずれも削除することができました。
以下はその最新版です。次のことを行ってください。
- まずコンパイルして、エラーを修正する - そうすれば、その後のエラーがあなたの行った変更によるものであることがわかります。
- 修正しなければならないエラーがあったかどうか、私に教えてください。
- 試しに使ってみて、必要なことができるかどうか確認する。
- そして、どのような変更が必要なのかを教えてください。
CB
ありがとう、Tim。
あなたが私にこれらのことを説明してくれることに本当に感謝します、とても励みになります。私は、関数に関するドキュメントをもう20回は読んでいるはずなのに、(関数と呼び出しに関して)理解したようなしないような「閃き」があるようです。もっと時間をかけてやってみます。テストとデバッグ」については、以前別のパッケージで行ったことがあります(すべてのトレードを確認し、すべてが適合することを確認する)。私はあなたのコードを進めて、あなたにお知らせします。
ありがとう、CB。ちょっとイライラさせてしまったようで申し訳ない。
ご心配なく。ただ、一歩一歩前進していこうとしているところです。
CB
こんにちは、CBです。
コードのバグをいくつか修正しました。主に括弧の欠落で、コード内でハイライトされています。もう構文エラーはありません。
strategy testerで コードを実行しましたが、買いのみです。ショートトレードは全くありません。ログを見たところ、エラー130(ストップに関係するもの)を出していたので、この問題には何の光明も見いだせません。
私は、エラーがどこにあるか(私はそれがfnSHouldWeTradeまたはfnOrderDuplicateにあると仮定しています)を理解することができるかどうかを確認しようとしました。
最新版のコードを添付します。TopFilterとBotFilterに値を追加して、ストラテジーが取引を行えるようにしました。
ps: なぜ私が以前古いコードを貼り付けたのかがわかりました。
こんにちは、CBです。
コードのいくつかのバグを修正しました。それは主に括弧の欠落で、それはコードで強調表示されています。もう構文エラーはありません。
strategy testerでコードを実行しましたが、買いのみです。ショートトレードは全くありません。ログを見たところ、エラー130(ストップに関係するもの)を出していたので、この問題には何の光明も見いだせません。
私は、エラーがどこにあるか(私はそれがfnSHouldWeTradeまたはfnOrderDuplicateにあると仮定しています)を理解することができるかどうかを確認しようとしました。
最新版のコードを添付します。TopFilter と BotFilter に値を追加して、ストラテジーがトレードを行えるようにしました。
ps: なぜ私が以前古いコードを貼り付けたのかがわかりました。
変更してください。
OrderSend(Symbol(),OP_SELL,Lots,Bid,5,0,Bid+TakeProfit*Point, "Nikos First EA",0,0,Red) に変更します。
にします。
OrderSend(Symbol(),OP_SELL,Lots,Bid,5,0,Ask-TakeProfit*Point, "Nikos First EA",0,0,Red);
CB