2024/07/09

リピートトレードEA 永遠の?デバック中

 EAデバッグ、壁にぶつかる

一覧表設定読み込み版のリピートトレードをする自作のEAを起動!…のはずが、思わぬエラーがポツポツと・・・とほほ。


一覧表の作成と確認がネックでした。1マスでもずれると取り返しがつきません。しかも、どう変数に取り込まれて、おかしなことをしているのか、追い込むのが面倒でした。動作をさせるプログラムコードより、設定そのもののミスにたどり着くのはかなり時間がかかりました。何度修正しても、エラーが消えない。まるで、同じパズルを何度も組み立てるような作業に、頭がクラクラしてきました。


トレードの条件設定をする一覧表は時により頻繁に更新するので、間違いがないようにしなければなりません。


そこで、私は2つの対策を講じました。

  1. 一覧表の確認を強化: 表の見落としを防ぐために、二重三重にチェックするシステムを構築しました。
  2. 間違いの内容をPrintでメッセージ出力: エラーが発生した箇所を明確にするために、メッセージを出力するようにしました。まるで、犯人の手掛かりを掴みやすくなります。


さらなる難関、発注無限ループ

あるとき、エラーの警告音が聞こえました。今度は発注無限ループという新たな壁が現れました。まるで、終わりが見えないトンネルに迷い込んだような状況です。しかも、「時々発生する」いやなもの。

条件を少しずつ変えて、デモトレードに投げ込んで状況を再現させ、原因を追い込んでいきました。


そこで、私は2つの対策を講じました。

  1. 区間判定の後端を次の行の始め端を参照していた: 次の業の始め端の値は、その区間の後ろ端とほぼ同じなので、普通はエラーが出ませんでしたが、最後の行(区間)になってしまうと「次の行」はありません。それで、発注できない価格の組み合わせで発注を続けるということを繰り返していました。これは、原因がわかれば簡単な修正です。
  2. 買いの場合の全体範囲の上側、売りの場合の全体範囲の下側のときに処理を別処理: 上に書いたとき以外でも、なぜか発注無限ループになるきがあります。これを防ぐために、処理を分けることにしました。


努力の末、ついに成功!

これらの対策を講じた結果、ようやくEAが安定稼働するようになりました。もう少し様子を見て、安定したところで、参考プログラムを公開しようとか思っています。


その後 (2025/03/09追記)

このEAは今日も使用しています。単純なことしかしていないEAなので、デバッグはもうないかなと思うのですが、発注していなかったり、注文の取り消しをしなかったりと、動作が不安定なときがあります。

メタトレーダーそのものを再起動すると、解消することが多い(注文し忘れは発注してくれるけど、注文の取り消し忘れはそのまま放置されます)。メモリは24GB積んでいるパソコンを使っている、メタトレーダーがメモリ不足で不安定というわけではないでしょう。

といわけで、メタトレーダーか取引サーバーのバグなのかなぁと思いつつ、どうしようもないので、状態を監視しながら使用しています。

うーん、こんな不安定なもの、公開とかするわけにいかないですからね。








2024/06/18

リピートトレードプログラム(EA)を作ろう(4)買いトレードの部分

 メタトレーダーを使ってリピートトレードをするには、それようのプログラム(エキスパートアドバイザー(EA))が必要ですね。

これから数回シリーズで、多段リピートトレードプログラム(EA)を作っていきます。

トレード本体部分

今回は、トレード本体部分を解説します。

全体のフローでは、「今の値(Ask)を取得」から全部です。
買いのトレードと売りのトレードは、発注が買いか売りかの違いと、表を参照していく順番が下から上か、上から下の違いだけです。
とりあえず、今回は、買いの方だけでいきますね。

画像
多段リピートトレードのフローチャート

概略の処理です

やるべきことは簡単です。

  • 現在値が表のどの段になるかを順番に確認していって、表のどの行かを求めます

  • その場所の注文か建玉があれば何もせず、なければ発注

  • すぐ下にも表に行があれば、そこにも同じことをする。

  • さらに2つ下にも行があれば、そこに注文があれば注文取り消し

  • さらに、表の最後まで注文があれば注文取り消し

こんな感じです。

今の値が表の最下限より下の場合

まずは、今の値が表の最下限より下の場合、このときは何もせずに戻るだけです。

画像
今の値が表の最下限より下の場合の処理

一番上のif文は、買いの処理と売りの処理を分けるためのもの
Askで現在の買値を取得して、これが最低価格(スプレッドマージンを加えたもの)より低ければ、何もすることはないのでそのままリターンです。

現在の値がある行を求める処理

次に、現在の値がある行を求めましょう。

画像
現在値が表のどの行に当たるかを求める処理

5行目のforループで、表を下から準備にif文に当てて探していきます。
Gyoは、表の総行数です。
条件にあったら、その時のループカウンタiが求めたい行番号なので、変数n
にカウンタiの値をコピーしてbreakでループを抜けます。

現在値のある行の処理

まずは、現在の値ある行の処理をしましょう。
やるべきことは、
「その場所の注文か建玉があれば何もせず、なければ発注」
だけです。
2行目のMyCurrentOrders関数は、参考文献についているライブラリ関数 MyLib.mq4 に膨れるているもので、第1引数にMY_ALLPOSを指定すると、第2引数のMagic番号に合致する注文の発注済み注文と建玉の合計数を返してくれます。ma[n]は処理する行のMagic番号が格納されています。

MyCurrentOrders(MY_ALLPOS, ma[n]) == 0
は、「マジックナンバーma[n]を満たす注文の、発注済み注文と建玉はないよ。」ということ。なので、このときは注文を発注しましょう。MyOrderSend関数は、エラー処理を組み込んだ発注関数です。同じく参考文献のライブラリの関数です。

画像
現在値のすぐ下の段の発注処理

現在値のある行の1つ下の段の処理

次は、現在値のある行から1つ下の段の処理をしましょう。n-1の段を同じようにすればよいですね。
でも、下に段がなければ変になっちゃうので、n>1のときに限定するのが2行目のif文です。
あとは、nをn-1に変えただけですね。

画像
現在値のすもう1つ下の段の発注処理

3段より下の注文を全部取り消す処理

注文の残したままにしているとそれだけで発注証拠金が必要になるので、現在の値から遠くなった注文を取り消しましょう。発注している注文のすぐ下の段で取り消すと、発注-取消を繰り返すので、1段か2段空けて、それより下の段を全て確認して注文を取り消していく処理です。
2行目のif文は、今の値が表の下から4段目以上にあるときだけこの処理をするということ。それより下だと取り消しをする注文自体がないので。
4行目のforループで3段したより、表の一番下(i=1)まで順に確認していきます。

MyCurrentOrders(MY_ALLPOS, ma[i]) != 0
で、発注済みの注文と建玉(ポジション)の合計が0でなければ、(建玉は決済されているはずなので、発注済みの注文が残っているかどうかの判断)
MyOrdersDelete(ma[i])
でMagic番号を指定して注文を取り消します。

画像
現在値より3段下以降の注文を取り消す処理

参考文献

使用している

  • MyCurrentOrders

  • MyOrderSend

  • MyOrdersDelete

の独自定義関数は、

FXメタトレーダー実践プログラミング (現代の錬金術師シリーズ) (現代の錬金術師シリーズ 83)

に出てくる、MyLib.mq4 というライブラリ関数に出てくるものを利用させて頂いています。

2024/06/07

リピートトレードプログラム(EA)を作ろう(3)一覧読み込みを改良

 メタトレーダーを使ってリピートトレードをするには、それようのプログラム(エキスパートアドバイザー(EA))が必要ですね。

これから数回シリーズで、多段リピートトレードプログラム(EA)を作っていきます。

リピートの価格一覧を読み込むところを改良

価格一覧表の改良

前回は、価格一覧をファイルから読み込むところを作りました。

前回の設定用価格リストのCSVファイルはこんな感じでした。

画像
前回の設定用価格リスト

いくらなんでも使いにくいし、間違いも発生しやすいので、項目とか行数とかを一緒にこのCSVファイルに書き込むようにしました。

こんな感じです。

画像
項目名などを加えた設定用価格リスト

1行目は取引価格をする価格リストの総行数
2行目は売り買いの別を1なら買い、2なら売り
3行目のスプレッドのマージンは、スプレッドの間のときに注文が出せないのでこれを回避するためのマージンです。
4行目はコメントで、どの取引かの通知かが判るようになるので無便利では、私は通貨名と売り買いの別を半角で入れています。
5行目は項目名
6行目以降は注文する価格設定です。

設定値と項目読み込み部分のコード

設定値と項目読み込みはこんな感じ

画像
設定値と項目部分を読み込むブログラム

Gyo,URIKAI,Su_margin,COMMENTが必要な変数。Mojiは必要のない文字部分を読み飛ばすための変数。読み込みますが、使うことはないので、次に上書きされます。

注文する価格一覧を読み込む部分は同じなので省略

設定用価格リストの確認項目を追加

前回、確認については、発注価格に対して、決済価格の上下関係と発注価格が価格順に並んでいることを確認しました。、

今回は、加えて、スプレッドのマージンが1pips~10pipsに有るときに正常と判定するようにしました。下のコードを加えます。
価格が1.0に近いGBP/USDとかEUR/USDと、クロス円との区別は簡易的に価格が40より大きいかどうかで区別しています。

画像
スプレッドのマージンが1pips~10pipsに有るときに正常

2024/06/01

リピートトレードプログラム(EA)を作ろう(2)一覧読み込み

 メタトレーダーを使ってリピートトレードをするには、それようのプログラム(エキスパートアドバイザー(EA))が必要ですね。

これから数回シリーズで、多段リピートトレードプログラム(EA)を作っていきます。

リピートの価格一覧を読み込むところ

前回は、リピートトレードの全体概要(下図)までを考えました。
いよいよ、エキスパートアドバイザー(EA)を書いていきます。

画像
フローチャート 多段リピートトレード全体の概略

仕掛けのための設定リストを作ろう

リストはCSVファイルで下図のようにシンプルなもの。
ただ、マジックナンバー、指値価格、利食い指値価格、損切り逆指値、ロット数をタブ区切りで並べています。リストの項目名すらありません。

サンプルはテキストエディタで表示していますが、実際はエクセルで作って、テキストエディタにコピへして、タブをコンマに一括置換すると楽で間違いがないと思います。
サンプルのリストは、仕掛けの値幅を等間隔で作っていますが、両端を広くしたり、ロット数を増減したりと自由に設定ができます。

画像
リピートトレード発注リスト

リストをファイルから配列変数に読み込もう

リストができたので、これを配列変数に読み込ましょう。
メタトレーダーでCSVファイルを読み込むには、 FileOpen関数を使用します。

書式は
int handle = FileOpen(ファイル名, FILE_CSV,区切り記号をシングルコーテーションで挟む)
です。

メタトレーダーでは、関数を使用するときに、左側の変数に関数を代入するという感じで使うことが多いですね。変数には処理結果の状態が格納させて、それだけでなくて、ちゃんと関数としての作業もやってくれます。

このときは、ファイルがちゃんとオープンされれば、正の整数*1が入ります。ファイルオーブンに失敗したときには、-1が入ります。この値を確認して、ファイルが正常にオープンできたときと、できなかったときを区別して処理できます。
サンプルプログラムは下のような感じです。

*1 複数のファイルをオープンしたときには、それぞれ別の番号が割り当てられるので、区別して読み出したりできます。もちろん、複数のファイルをオープンするときには変数名も変えて区別できるようにしなきゃです。

画像
メタトレーダーでファイルを配列変数に読み込むサンプルプログラム

このサンプルプログラムでは、handleに-1が入っているとき(ファイルのオープンに失敗したとき)には、あとの処理に引き継ぐためにFile_Err 変数(自分の都合で勝手に作ったものだよ)を1にして、あとは何もせず。
handleに正の数字が入ってて、ファイルがオープンできたときには、forループで配列変数に1行ずつデータを読み込みます。
データの読み込みはFileReadNumber関数を使用します。変数のGyoはCSVファイルの行数を格納しています。

読み込みができたら確認しよう

読み込みができたら確認したいですね。お金に直結するものだから。
なので簡単なチェックプログラムを追加しました。
こんな感じ・・

画像
メタトレーダー 入力した一覧のチェックプログラム

これは買いのトレードの場合ですけど、1つ目のforループで、「仕掛けの買い注文より利食いの注文が高い、損切の逆指値が安い」ことを確認しています。
2つ目のforループでは、「仕掛けの買い注文が価格順に並んでいる」ことを確認しています。

一覧ファイルの置き場に注意

リストのCSVファイルなのですがEAと同じフォルダにおいても反応しません。メタトレーダーで専用のフォルダに置かなければだめなようです。最初はこれで結構悩みました。
EAをおいているExpertsのとなり(兄弟姉妹)のところにFilesというフォルダがあるので、ここに一覧のCSVファイルを置いてください。

画像
メタトレーダー 読み込ませるファイルの置き場

2024/05/26

リピートトレードプログラム(EA)を作ろう(1)全体構想を考えよう

 メタトレーダーを使ってリピートトレードをするには、それようのプログラム(エキスパートアドバイザー(EA))が必要ですね。

これから数回シリーズで、多段リピートトレードプログラム(EA)を作っていきます。

リピートするところの動作を考える

リピートの基本部分

まず、リピートするところの動作を考えましょう。
動作は以下のような感じですね。

  1. 買値と売値を決める。

  2. その注文のポジション(建玉)があれば、放置

  3. ポジションがなければ、注文が発注されいるか確認して、発注されてなければ、注文を発注。発注されていれば放置

1.から初めて、あとは2.と3.のプロセスを延々と繰り返す。基本はただこれだけです。

画像
フローチャート リピート注文の基本

今の値の近くに発注しよう

ただ、上のままだと、買値の設定が今の値より高いと指値注文がエラーになりますね。今の値を求めてその近くに発注するように考えてみましょう。

  1. トレードする全体の範囲を考える。例えば100円から150円とか。

  2. リピートの間隔を考える。例えば1円(100pips)とか。

これを考えると、多段のステップができますね。
例えば
100から101
101から102
 ・
 ・
 ・
149から150
というふうに。

今の値から、このステップの1つ下に買値、その上の売値を発注するようにしましょう。

  1. 今の値を取得

  2. 今の値のすぐ下の「買値」の設定値を求める

  3. 「買値」に対応する「売値」を求める。(「買値」+「リピート間隔」ですね)

  4. その注文のポジション(建玉)があれば、放置

  5. ポジションがなければ、注文が発注されいるか確認して、発注されてなければ、注文を発注。発注されていれば放置

という感じ。「今の値」が毎回変わる可能性があるので、1.から5.を延々と繰り返せばオッケーです。
フローチャートはこんな感じですかね。

画像
フローチャート 今の値の近くでリピート

でも、これではうまくいきません。フローチャートに「注意」と書いているところ。
指値買い注文というのは今の値より安い金額の注文を発注するもの。なので、例えば、今の値が120.00ジャストだったとしましょう。120.00円で買いの注文は発注できません。スプレッドがあるので、たぶん今の値が120.01円でもできないでしょう。

なので、例えば、マージンを2pipsおいたら、120.02円以上~121.02円未満なら買値にするすぐ下の値は120.00円などとする必要があります。

ここまで作れば、今の値に対してすぐ下に買い注文とその決済の売り注文を出して(下図の左)、値が下がればその下の段について買い注文と売り注文を出して(下図の真ん中)、値が上がれば、中段の売り決済注文を執行して、上の段の買い注文と売り注文を出して(少しでもさがれば、中段のところに注文も出してしまいます)・・・・

画像
リピートトレード注文の動作

これで、一応、リピートトレードのプログラムができます。
ただ、これだと下の段の未約定の注文を放置していくことになりますので、少し実用性に欠けますね。

実用的に改良

改良点は以下のようなこと

  1. 注文の間隔、ポジションサイズを変化させたい。

  2. 相場の急変動のときにも取り逃しがないように、買いの指値注文は2段発注しておきたい。

  3. それより下の注文は、残しておくと余分に発注証拠金が掛かるので、削除したい。

1.は全体幅と間隔から計算するのではなくて、設定用の表を読み込むようにします。

2.はもう一段下まで確認するようにすればよいですね。

3.がちょっと面倒。
すぐ下とその下の段に買いを発注して、さらのその下の段(3段目と呼びます)より下の段の発注を確認して消したとします。

今の値が、下図の一番上の買い注文(第1買い注文と呼びます)より下がれば、破線で囲った3段目の注文は残したい注文なので発注します。今の値が第一買い注文より上がれば、3段目の注文は取り消さなくてはいけません。

なので、今の値が第1買い注文前後(下図の上下太矢印)辺りでウロウロされると、すごく頻繁に発注取消の繰り返しになります。いくらなんでも取引サーバーの負担にもなるし、メタトレーダーのログもとんでもないことになます。

これを避けるために、1段目、2段目は発注します。3段目は無視します。注文があってもなくてもそのまま。4段目より下は確認して注文を取り消します。

こうすれば、下図の左の状態で買い注文を2つ発注して、今の値が下がって下図の右の状態になったときには、3段目の買い注文が発注されます。また、今の値が上がって左の状態になっても、3段目の注文はあってもなくても無視されるのでそのままになります。これで発注取消ループはさけられます。

画像
注文の取り消し方

全体の流れ

これまでに考えたことを、全体のフローチャートは下のような感じです。最終行の確認は注文取り消しループにだけ書いていますが、本当は全コマで必要だったりします。とりあえず処理の概略の流れはこんな感じと。

画像
フローチャート 多段リピートトレード全体の概略