MetaTrader 4のバージョンアップにより仕様が変わってきた部分がありますので、 記事を新しい仕様で書き直しております。この注意書きが書かれていないページは 旧仕様の記事になります。旧仕様の記事でも一部を除き基本的にはシステムの制作に問題はありません。
今回は、ドテン売買のシステムの説明です。
サンプルプログラムはこちらです。Zip圧縮していますので解凍してご利用ください。
サンプルプログラムの使い方は、以下の記事で説明しています。
ドテン売買のプログラム
では、MetaEditorを起動して下さい。
NameはiMA3にして置いて下さい。
内容はほとんど前回と同じです。
少し処理が追加されています。
では、まとめて書きますね。
void OnTick() { //--- //変数の宣言 int cnt; int CurrentPosition = -1; double old_fast_ma,old_slow_ma; double now_fast_ma,now_slow_ma; int ticket; int order_select; bool order_close; // オーダーチェック(ポジションなどのデータ) for(cnt=0;cnt= now_slow_ma) { //買いポジションを持つ ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 30, 0,0 , "Buy", 0, 0, clrBlue); } else //もし21日線が90日線を上から下にクロスしたら if( old_fast_ma > old_slow_ma && now_fast_ma <= now_slow_ma) { //売りポジションを持つ ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 30, 0,0 , "Sell", 0, 0, clrRed); } } // ポジション有り else { //ポジションの選択 order_select = OrderSelect(CurrentPosition,SELECT_BY_POS); //ポジションの確認 if(OrderSymbol() == Symbol()) { //もし買いポジションだったら if(OrderType()==OP_BUY) { //もし21日線が90日線を上から下にクロスしたら if( old_fast_ma > old_slow_ma && now_fast_ma <= now_slow_ma) { //手仕舞い order_close = OrderClose(OrderTicket(),OrderLots(),Bid,30,Green); if( order_close == true ) { //売りポジションを持つ ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 30, 0,0 , "Sell", 0, 0, clrRed); } } } else //もし売りポジションだったら if(OrderType()==OP_SELL) { //もし21日線が90日線を下から上にクロスしたら if( old_fast_ma < old_slow_ma && now_fast_ma >= now_slow_ma) { //手仕舞い order_close = OrderClose(OrderTicket(),OrderLots(),Ask,30,Green); if( order_close == true ) { //買いポジションを持つ ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 30, 0,0 , "Buy", 0, 0, clrBlue); } } } } } }
書けましたか?
今回は、前回の応用みたいな感じなので、細かい説明は省きます。
変更点は、まず仕掛けに売りを追加しました。
//もし21日線が90日線を上から下にクロスしたら if( old_fast_ma > old_slow_ma && now_fast_ma <= now_slow_ma) { //売りポジションを持つ ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 30, 0,0 , "Sell", 0, 0, clrRed); }
売りにする場合は、 OP_BUYを OP_SELLにして、AskをBidにして下さい。
そして売りの手仕舞いを追加して、手仕舞いの後に、手仕舞いが売りなら買い、手仕舞いが買いなら売りのオーダーを追加しました。
こうすることによってドテン売買をすることが出来ます。
//ポジションの選択 order_select = OrderSelect(CurrentPosition,SELECT_BY_POS); //ポジションの確認 if(OrderSymbol() == Symbol()) { //もし買いポジションだったら if(OrderType()==OP_BUY) { //もし21日線が90日線を上から下にクロスしたら if( old_fast_ma > old_slow_ma && now_fast_ma <= now_slow_ma) { //手仕舞い order_close = OrderClose(OrderTicket(),OrderLots(),Bid,30,Green); if( order_close == true ) { //売りポジションを持つ ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 30, 0,0 , "Sell", 0, 0, clrRed); } } } else //もし売りポジションだったら if(OrderType()==OP_SELL) { //もし21日線が90日線を下から上にクロスしたら if( old_fast_ma < old_slow_ma && now_fast_ma >= now_slow_ma) { //手仕舞い order_close = OrderClose(OrderTicket(),OrderLots(),Ask,30,Green); if( order_close == true ) { //買いポジションを持つ ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 30, 0,0 , "Buy", 0, 0, clrBlue); } } } }
if( order_close == true )ですが、これはorder_close にOrderCloseの戻り値を入れています。
戻り値がtrueなら正常に決済が行われたということになりますので、決済が正常に行われた場合のみエントリーの処理をしています。
このような処理を行わない場合、決済でエラーが出て決済が行われないのに次のエントリーが行われるということが起こります。
仕掛けに買いと売りの両方のオーダーが書いてあるから、いちいち手仕舞いの後に書かなくてもよいのでは?という疑問が浮かぶ人もいるかもしれませんが、手仕舞いのところに書かない場合処理がズレることになります。
それは何故かというと、プログラムは基本的に上から下に命令を実行して行きますので、手仕舞いのところを通過すると、仕掛けのコードの方が上にありますので、仕掛けの命令は実行しません。
今回のEAのようにレートが動くたびにエントリーのチェックをしているEAならそれほどズレませんが、足が確定時のみにエントリーチェックをするようなEAの場合、次の時間足までエントリーチェックを待つことになります。
そして、次の時間足になった場合は、売買ルールの条件を満たしていませんので、オーダーが実行されないことになります。
例えば、買いの条件は移動平均の21日線が一つ前の足では90日線の下で、現在では90日線の上になっていることですが、次の時間足になった場合は、前回も現在も21日線のほうが上にありますので、オーダーが実行されません。
プログラムはこういう細かいところを間違えるとシステムの内容が異なってきますので気をつけて下さい。
これで、今回のプログラムは終了です。
今回のシステムは移動平均の21日線と90日線のゴールデンクロスで買い、デッドクロスで売り、手仕舞いは仕掛けの逆のルールで行い、手仕舞いの後にドテン売買するというものです。
では、コードを全て書けたらコンパイルのボタンを押してください。
エラーが出てきた場合は、半角になっているか、;を付け忘れていないか、{}を付け忘れていないか、{}の数は合っているかを確認して下さい。
どうしてもエラーが分からない場合は、サンプルプログラムを参照して下さい。
エラーが出なかったら、MetaTrader 4のバックテストでiMA3を選んで、スタートして下さい。
終わったら、結果、グラフ、レポートを見てください。
今回はこれで終了です。
内容には注意を払っていますが、保障は出来ません。
実際に運用する場合は、自己責任でお願いします。