FX自動売買研究記!

    - 為替相場をメタトレーダーの自作自動売買プログラムで勝ち抜く -

    スポンサーサイト 

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    ( --/--/-- --:-- ) Category スポンサー広告 | トラックバック(-) | コメント(-)

    買い相場と売り相場でEAを分ける 

    勝てるEAを作るちょっとしたコツの様なものです。
    EAを作り始めたものの、バックテストですら勝てないと途方に暮れている方には有益な情報かもしれません。



    僕はEA製作を始めたばかりの頃、どんなに頑張っても好成績のものを作ることが出来ませんでした。
    可能性を感じるEAが出来るようになってきたのは、開発を始めてから2ヶ月程経ってからだったでしょうか。
    MQLに対する知識が増えていった事に加え、ある発見をしたことがきっかけです。

    それは、買い専門EA、売り専門EA、それぞれ別のロジックで制作するべきである。という事です。

    ロング(長期)、ショート(短期)と言われるように、買い相場と売り相場は値動きの特徴が異なっています。(買い相場は緩やかに長期的に上昇し、売り相場はストンと短期的に下降します)。EA制作においても、この点を考慮して取り組む必要があったのです。
    何を今更、と言われてしまいそうですが、これに気がつくまで結構時間がかかってしまいました。
    裁量取引をする際には、ロングとショートの性質の違いを意識して取引をしていたつもりですが、EA制作をするにあたってはその考えをあえて排除していたからです。

    ロジックさえ正しければ、上方向と下方向両方に対応できて然るべきだ。
    美しいロジックならば、力技で最適化する必要すらもなく、優雅にLにもSにも対応したEAが完成するはずだ。
    なんて思っていました。
    そんな神がかった設計は不可能です。
    いえ、可能な人がいたとしても、システム開発をしたことがなく、相場観も人並み以下のこの僕がたどり着ける境地ではありませんでした。
    僕にとって、EA制作はもっと泥仕合だったのです。

    まさに泥仕合です。買と売りのEAを別々に作るのは、単純に手間が二倍ですからね。
    大雑把なロジックを考え、LとSに分けます。(例:Togusa_USDJPY_L_1h、Togusa_USDJPY_S_1h)
    そして、それぞれについて最適化し、コードを修正し、また最適化するを繰り返します。
    修正の過程でLとSは少しづつ異なったEAになってゆくのですが、やはり片方のみしか使い物にならないことが多いです。その場合は泣く泣く切り捨てます。

    そして、その様な苦労の果てに出来たEAは、やはり片方の相場にしか対応していません。
    S専門のEAしか稼働させていない状態でL相場が継続してしまえば、為す術がないのです。
    実際、僕のポートフォリオはドル高に極端に弱くなっています。
    EURUSDはL、AUDUSDもL、USDJPYはSのEA達がメインになっています。
    リスクヘッジの為にドル高に対応したEA開発を目指しているのですが、使い物になるのは何故かドル安方向専門のEAばかりなのです。
    (最近、これは偶然ではなく、僕のEA作りの癖に起因する何らかの必然があるのかもしれないと思う様になってきています。新しい視点で取り組む必要がありそうです。)

    とまぁ、問題が多いようにも思える特定方向に限定したEA作りですが、私はこの作り方が正しいと思っています。
    同一通貨ペアであっても、L方向、S方向であまりにも動き方が違いますから。L、Sを単一のロジックで乗り切ろうというのは無茶だと感じています。
    経験上、ロジックがシンプルであれば両相場に対応するEAの制作も可能ですが(現在検証中の窓埋めEAのBorma君は両相場対応です)、複雑なロジックになればなるほど、LとSで成績が変わってきます。

    両相場対応を謳う市販のEAも、内部では買いと売りで別々のフィルタが掛かっていることが多いのではないでしょうか。
    スポンサーサイト

    ( 2011/01/16 13:31 ) Category その他 | TB(0) | CM(0)

    OrdersTotal()の落とし穴 

    最近、僕の主要EAの一つが、エントリーフラグを満たしているにもかかわらず全く取引を行わなくなりました。

    色々調べてみた結果、どうやら『OrdersTotal()の落とし穴』にハマっていた事が分かりました。

    そのEAはポジションを過剰に保有してしまうことが無いように、最大ポジション数を限定しています。
    例えばMaxPositionsという変数名を用意して、これが現在保有しているポジション数以下の時のみエントリーを許可しているわけです。

    if( 今のポジション保有数 < MaxPositions)
    {
      エントリーオーダー;
    }
    という感じ。

    御存知の通り、ポジション保有数を調べるにはOrdersTotal()を使います。
    しかし、このOrdersTotal()は
    買い建玉、売り建玉、指値買い、指値売り、逆指値買い、逆指値売り
    そして、同時に運用しているその他のEAによって注文したオーダーについても見境なく、
    MT4のターミナルに行事されている全てのオーダーをカウントし、値を返してしまいます。

    そのため、対象EAが
    if( OrdersTotal() < MaxPositions )
    {
    }
    という条件文でポジション数の判断をしていた場合、別EAで大量のポジションを保有してしまっていると、
    その時点でこのif文はスルーされ、対象EAのエントリー判断ロジックに無関係に全てのエントリーを見送ることになってしまいます。


    今回僕のEAエントリーフラグをスルーし続けていたのはこのためでした。


    さて解決策ですが、この様な関数を使えば良いと思います。

    int Check_Positions_Type(int orderstype)
    {
    int r = 0;
    for(int i=0; i<=OrdersTotal()-1; i++)
    {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false) break;
    if(OrderMagicNumber() != MAGIC || OrderSymbol() !=Symbol()) continue;
    if(OrderType() == orderstype)
    {
    r++;
    }
    }
    return(r);
    }


    if(OrderMagicNumber() != MAGIC || OrderSymbol() !=Symbol()) continue;
    の一文は、マジックナンバーと取引通貨ペアからこのEAで注文を出したオーダーのみをカウントさせるための条件文で、
    if(OrderType() == orderstype)
    は、特定注文についてのみカウントさせる条件文です。
    引数に以下の数値を設定でき、返り値として任意のオーダー種の数を取得できます。

    0 = 成行買い
    1 = 成行売り
    2 = 指値買い
    3 = 指値売り
    4 = 逆指値買い
    5 = 逆指値売り


    これらはほとんどが“FXメタトレーダー実践プログラミング”からの引用です。
    FXメタトレーダー実践プログラミング (現代の錬金術師シリーズ)
    FXメタトレーダー入門―最先端システムトレードソフト使いこなし術
    ↑(amazonへのリンクです。僕はこの2冊のみでMQLを習得することができました。超良書ですよ。)
     



    さて、この関数を使えば、問題の箇所である
    if( OrdersTotal() < MaxPositions ){
    }
    で条件処理を行なっている部分を、

    if( Check_Positions_Type(int orderstype) < MaxPositions ){
    }

    と書き換えることで、このEAによって約定したポジション数のみを調べることができ、冒頭の問題はクリアできます。




    バックテストではバッチリ動作するのに、
    なんでライブトレードではトレードしてくれないんだ!!!!
    とか、
    あれ、バックテストとフォワードテストの取引回数が違うぞ??

    って場合はこの辺の可能性を疑ってみてもよいかもしれません。


    ( 2011/02/28 20:41 ) Category コード的なこと | TB(0) | CM(3)

    Trade context is busy対策 

    真剣に約定拒否対策に乗り出すにあたり、
    ERR_TRADE_CONTEXT_BUSY 146 Trade context is busy.
    について調べました。

    ■発生理由
    複数EAを同時に運用する場合、EAのオーダー処理の競合が大きな問題になってきます。
    MT4では、複数のオーダーを同時に発注することができないからです。
    そして、その時にエラーメッセージとして表示されるのが
    ERR_TRADE_CONTEXT_BUSY 146 Trade context is busy.
    です。

    MT4上で運用される複数のEAはまるで同時処理されている様に見えますが、
    実際のところ、それぞれのプログラムがきっちり順番に処理されています。
    もし前の順番のEAの処理が残っていれば、次のEAに障害が出るわけです。
    それが最も顕著なのが、注文処理です。
    一つのEAによって発生した注文処理は、メタトレーダーを通してブローカーとのやりとりを行いますが、
    その間に別のEAからオーダーが入ると、後から発注されたオーダーは処理されず、エラーとなってしまうのです。

    それを踏まえて対応を考える必要があります。


    ■対処
    ERR_TRADE_CONTEXT_BUSY 146 Trade context is busy.
    こいつが出ている以上、オーダーは通っていません。
    なぜなら、別のEAの注文によってメタトレーダーとブローカーがやりとりを行っている最中だからですね。
    ゆえに、これを避けるには注文処理が終わるのを待つ以外ありません。

    まずは競合の有無を調べましょう。

    今現在 ERR_TRADE_CONTEXT_BUSY 146 Trade context is busy. が発生するような状態なのか、
    注文の競合が起こる状態なのか。という事を事前にチェックした上で、競合するようならば
    しばらく待機してから発注をかける必要があります。

    このチェックを行う関数が、

    IsTradeAllowed()


    です。
    こいつは、返り値がbool型の関数で、
    今はどんな注文も入ってないからチャンスだよ!って時は、
    IsTradeAllowed()=true
    今は前のオーダーの注文処理中だからエラーんなるよ!って時は、
    IsTradeAllowed()=false
    を返します。

    ここで競合が発生していた場合、待ちをかける必要があります。
    方法は2つ。
    ①EAの処理の中でwaitを入れる方法
    ②オーダが通らなかった場合は再度EAを呼び出す方法
    です。

    対処① EAの処理の中でwaitを入れる方法
    注文が約定するまで、ひたすらwhileループでオーダーをかけ続ける方法です。
    延々と146 Trade context is busy.が出続けるでしょうが、そんなもの何回出ようが知ったことではありません。
    とにかく約定するまで繰り返し続けます。
    注意点は2つ。再注文を出すまで何秒間待機させるかきちんと設定しておくことと、
    無限ループに陥らないよう、ループの脱出に気を使うことです。
    これは
    ERR_OFF_QUOTES 136 Off quotes.
    ERR_BROKER_BUSY 137 Broker is busy.
    ERR_REQUOTE 138 Requote.
    らの約定拒否対策にも使えますので、詳しくは近いうちに書きたいと思います。


    対処② 次のtickまで待たせる方法
    ①に比べると効果は限定的ですが、コード自体はこっちの方が簡単です。

    int start()
    {
    if(IsTradeAllowed() == false) return(0);

    .....
    }

    という感じでメイン関数を呼び出した直後に注文可能であるか判断し、
    このEAの注文を受ける準備ができていなければ、 return(0)によってメイン関数(start())を終了します。
    これだけです。
    MT4の仕様上、次回start()が呼び出されるのは次のtickが更新されたときになるので、
    その時には恐らく注文処理は終了していることでしょう。




    詳しくはこちら。
    http://articles.mql4.com/141
    英語なので大変ですが、
    このエラーの発生理由から様々なケースの対処法とそのコードまでとても詳しく書かれています。

    あ、例によって愛読書にもキッチリ書かれていますよ。
    FXメタトレーダー実践プログラミング (現代の錬金術師シリーズ)
    FXメタトレーダー入門―最先端システムトレードソフト使いこなし術

    ( 2011/08/06 19:01 ) Category コード的なこと | TB(0) | CM(0)

    約定拒否対策 

    最近約定拒否が多発しています。
    オープンのタイミングを逃すのはまぁ良いとして、イグジットタイミングを逸するのは致命的です。

    約定拒否原因として考えられるのは、
    ①前回処理(ブローカーとの通信)が終了していないためエラーになるケース
    ②相場が激しく動き、設定した価格で取引ができないケース

    の二つだと思います。
    先日、Trade context is busy対策を書きましたが、
    これは①の問題に対する対処法です。

    ここでのメインは、②。
    週明け、指標など、相場の激動によって発生する約定エラー対策です。

    対象となるエラーメッセージはこいつら。

    ERR_OFF_QUOTES 136 Off quotes.
    (ブローカー側で現在の価格を公示が出来ない相場状態なっている。相場が落ち着くまで待つしか無い??)
    ERR_BROKER_BUSY 137 Broker is busy.
    (ブローカービジー。これもエラー136同様、待つしか方法は無い様な感じ。)
    ERR_REQUOTE 138 Requote.
    (激しい価格変化のため、発注しようとした価格が間に合わず公示価格が既に変ってしまった状態)

    これらのエラーは全て、一定の時間を空けて再注文することで対処可能です。


    即ち・・・下記のようにOrderClose()関数を改良して、
    エラー発生時には時間をおいて再オーダーをかけることで対処可能です。

    改良OrderClose()は、SecureOrderClose()としました。

    int SecureOrderClose()
    {
    for(int i=OrdersTotal()-1; i>=0; i--)
    {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false) break;
    if(OrderMagicNumber() != MAGIC || OrderSymbol() !=Symbol()) continue;

    while(true)
    {
    if(IsTradeAllowed() == true) //----①
    {
    RefreshRates();//----②
    if(OrderClose(OrderTicket(),OrderLots(),closeprice,Slippage*10,Gray)==true)
    {
    break;//----③
    }
    }
    Sleep(100); //----④
    }
    }
    }


    ① ここでブローカーとの通信が可能か判定
    ② 実は重要。waitを掛けると価格が過去のものとなるため、ここで再度通貨の価格を取得。
    ③ 正しくクローズが通れば(trueが返れば)、whileを抜ける
    ④ 正しくクローズ出来なければ(falseが返れば)、100ミリ秒待ってやり直し。


    これは例によって市販の解説書を参考としたものですので、詳細に書くのは控えたいと思います。ご了承下さい。

    ( 2011/08/06 19:17 ) Category コード的なこと | TB(0) | CM(0)

    販売しようと思います 

    実はリスクをとった複利運用をして、口座が破綻しました。

    そのころちょうど本業が忙しくなりすぎて管理がままならなくなってしまったので、
    もはやmt4を立ち上げることすらしなくなっていました。

    でも、作ったEA達が勿体ないなぁと思い始めましたので、公開して販売してみようかと思います。
    トレードしなくなって3年くらいのブランクがあるのでその間のデータで検証してみて、
    使えるやつを吟味してみるつもりです。

    全滅してたらどうしよう。

    ( 2016/06/02 22:13 ) Category その他 | TB(0) | CM(1)

    販売しました。 

    テラスFXさんで、週明けの窓埋システムを販売することとなりました。
    これです。
    「Gaptrading窓埋」
    http://www.openterrace.jp/detail.html?id=1030
    リアルタイムの成績が閲覧できますのでご覧ください。

    このEAはGBPUSD、EURUSD、USDJPYのペアを同時に運用して不調を補い合うシステムとなっていて、
    私が運用していた自作EAの中で突出して安定しているEAです。

    ただ、今テラスさんのページではUSDJPYが不調です。
    USDJPYは成績公開に使用しているパラメータの設定が誤っている可能性があります。
    ファイルを何度か誤ってアップロードしていましたので、そのせいかと思っています。
    この点テラスさんにパラメータの確認中です(H29.2.17現在)。


    追記
    恥ずかしながら、USDJPY不調原因は運用時のスプレッドによるものでした。
    GBPUSD、EURUSDではスプレッドに対し獲得pipsが大きいためスプレッドの影響が殆ど無いのですが、
    USDJPYでは獲得pips設定を浅めにしていたため、スプレッドの大きさが無視できなくなり、
    成績不良に繫がったようです。
    スプレッド2pips未満のブローカーであればUSDJPYでも十分に戦力になるのですが、
    テラスさんの運用環境(FXDD)は3pipsであったため、意図した成績になりませんでした。
    よってテラスさんのページでは販売対象外としました。
    とはいえ、GBPUSD版の購入によりEURUSD、USDJPYが同時ダウンロード可能となっておりますので、
    USDJPYについても別ブローカーで試していただいたり、別パラメータを検討していただくなど
    活用は可能であると思います。

    ( 2017/02/17 22:57 ) Category その他 | TB(0) | CM(0)
    プロフィール

    asahi_fx

    Author:asahi_fx
    日々のEA開発記録を綴っています。

    忙しい時は全然更新できませんが、
    進展がある度に少しづつ書いていこうと思います。



    運用中のEA


    Batou_EURUSD_1h_L
    Batou_AUDUSD_1h_L
    Batou_Counter_EURUSD_1h_L
    Batou_Counter_EURUSD_30min_L
    Ishikawa_EURUSD_1h_L
    Ishikawa_AUDUSD_1h_L
    Ishikawa_EURGBP_30min_L
    Ishikawa_USDJPY_1h_S
    Ishikawa_USDJPY_30min_S
    Togusa_USDJPY_1h_L
    Togusa_USDJPY_1h_S
    Togusa_USDJPY_5min_S
    Togusa_EURCHF_1h_S
    Togusa_EURCHF_5min_S
    Borma_USDJPY_15min
    Borma_EURUSD_15min
    Borma_GBPUSD_15min
    Paz_WPR_gradient_USDJPY_15min
    Pza_heikin_EURUSD_1h



    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。