朝チャートを開くと、同じ通貨の買いが5本並んでいる。ロットも同じ、価格もほとんど変わらない。約定した時刻を見ると、5本とも同じ1分のなかに収まっている。入る条件はひとつしか書いていないはずなのに、抱えている量だけが5倍になっている。
積み増していく作りにしたのなら、それでいい。困るのは「1回だけ入るつもりで書いた」のに、気づくと何本も入っている場合だ。しかも3本で済む日と、10本入る日がある。
本数がばらつく原因は、判定を走らせている回数と、いま何本持っているかの数え方、そして注文を出したあとの扱いの三つに、だいたい集約される。どれもコードの奥ではなく入口のあたりにある。順に見ていきます。
値動きの回数だけ、判定は走っている
EAの本体は、値が動くたびに呼び出される。1分のあいだに何十回も呼ばれることもあれば、数分まったく呼ばれないこともある。何回呼ばれるかは、こちらでは決められない。
条件が「移動平均を上に抜けた」だとして、抜けた直後の数分間は、その条件が成立したままになる。成立している間ずっと注文を出す作りなら、その数分に呼ばれた回数だけ注文が出る。静かな時間に1本、動く時間に10本になるのは、勢いの差ではなく値が動いた回数の差でしかない。
条件が真である回数と、入るべき回数は別のものだ。ここを分けていないコードは、値動きが荒い日にだけ本数が増える。検証で見つけにくいのはそのためで、穏やかな期間のデータで回すと1本しか出ない。
増えているのは注文ではなく、判定が走った回数のほうだ。
足が変わった時だけ判定する
いちばん簡単な直し方は、判定する側の回数を減らすことだ。前回判定したときの足の時刻を覚えておき、いまの足の時刻がそれと違うときだけ判定に入る。これで1本の足につき1回になる。
覚えておく値は、その足の開始時刻でよい。時刻が変わっていなければ、その回は何もせずに戻る。判定の中身には手を入れず、入口の手前に門を一枚置くだけの話で、数行で済むわりに効き方は大きい。
ここで一つ決めることがある。足が変わった瞬間に前の足の確定した値で判定するのか、動いている途中の値で判定するのか。後者は同じ足の中で条件が付いたり消えたりする。確定した値だけを見るなら、判定は足が変わった直後の一度きりになり、動きが読みやすくなる。
併せて、時間足を変えたときのことも見ておきたい。1分足に載せれば、それだけで1日1,440回の判定になる。同じEAでも、載せる足を変えれば入る本数は変わる。上限をいくつにするかは、この回数から逆算して考える。
いま何本持っているかの、数え方
判定の回数を絞っても、保有の数え方が甘ければ本数は増える。足が変わった時だけ判定する形にしたところで、その1回で条件が成立していれば注文は出る。止める役目を負っているのは「すでに持っているなら入らない」のほう、その「持っている」の数え方だ。
端末が抱えているポジションの一覧には、そのEAのものも、別のEAのものも、手で入れたものも並んでいる。絞らずに数えれば他人の分まで数に入って入れなくなり、絞りが足りなければ数え落として二重に入る。
絞る条件は二つ。銘柄と、そのEAが注文につける識別番号だ。片方だけでは足りない。銘柄だけで絞れば同じ通貨を触っている別のEAの分が混ざり、識別番号だけで絞れば、別の通貨で持っている分まで数に入る。
もう一つ、やりたくなるが避けたいのが、保有数を変数に持って自分で足し引きすることだ。決済されたとき、手で閉じたとき、端末を再起動したとき、その変数だけが実際とずれていく。数は保存せず、要るときにその場で数え直す。ずれようがない形にしておくと、あとの調査が短く済む。
出した注文が通ったかを見てから、次へ行く
注文を送ったあと、それが通ったかどうかを見ずに抜ける作りがある。通信が混んで応答が遅れると、次に呼ばれた時点ではまだ保有の一覧に出てこない。数え直しても0本のままなので、同じ注文をもう一度出す。
手当ては二つある。一つは戻り値をその場で確かめること。成功したのか、失敗ならどの理由なのかを見て、失敗したなら次の判定に進ませない。もう一つは、直前に送信した時刻を持っておいて、そこから数秒のあいだは新規を出さないこと。応答を待っているあいだに二本目が出るのを防げる。
「送った」と「約定した」は別の出来事である。数え直しが正しい答えを返すのは、約定したあとだ。そこを踏まずに本数だけ制限しても、混み合う時間帯に限ってすり抜ける。
失敗したときに何も残さず黙って戻る作りも、同じ機会に直しておきたい。理由を1行書き出しておけば、あとから「なぜあの日だけ増えたのか」を追える。動きが崩れるのは、たいてい正常に進んだ時ではなく例外が出た時のほうだ。
どこで止めるのかを、先に決める
ここまでの手当ては、どれも「何本までにするか」が決まっていて初めて意味を持つ。決めないまま直すと、一か所ふさいでも別の場所が空く。「増えすぎないように」では条件に落ちない。数と単位まで言葉にできて、はじめてコードの形になる。
形はいくつかある。決済するまで次を出さない。買いと売りを別に数えて、同じ方向だけ1本に絞る。本数ではなく合計ロットで上限を置く。1日の新規回数で切る。積み増すことを前提にした作りなら、本数より合計ロットのほうが実態に合う。
複数を組み合わせるときは、どれが先に効くのかまで決めておく。「同じ方向は1本、ただし合計ロットが上限に届いたら両方向とも止める」のように順番まで文にしておくと、作るときも試すときもぶれない。
1本で止まることを見てから、増やす
直したあとに、いきなり運用の設定へ戻さない。上限を1にして、動きの多い時間帯に、デモ口座か最小の数量で動かす。見るのは三つ。新規が1本で止まるか、決済されたあとにまた入れるか、端末を再起動しても数え方が壊れないか。
三つめは忘れやすい。変数に頼っている作りは、再起動したところでここに出る。その場で数え直す形にしてあれば、再起動しても答えは変わらない。回線が切れて戻った場面でも同じなので、止まって再開する動きはひととおり通しておきたい。
確認が済んでから、2本、3本と一段ずつ上げて、そのつど本数を数える。順番を逆にすると、3本入っているのが決めたとおりなのか、止まっていないだけなのかを区別できない。
入った時に1行だけログを残しておくと、あとが楽になる。何本目か、どの条件で入ったか、その時の保有数はいくつだったか。この三つがあれば、増えた日のログを見るだけで場所が絞れる。誰がいつ何をしたかが残っていないものは、後から誰にも確かめられない。
当方は元金融系のシステムエンジニアで、MT4・MT5のEAの改修と最適化をココナラでお受けしています。意図した本数で止まらない、どこを直せばよいか分からない、というご相談も承ります。いまの動きと、何本で止めたいかを添えて、ココナラのメッセージからご相談ください。なお、お渡しするのはソフトウェアであって、投資助言や運用の代行ではありません。