快適なスキャルピング
はじめに
本稿では、スキャルピングをより快適にするトレードオープンのアルゴリズムについて説明します。このアルゴリズムはその他の取引方法にも適用することができます。実際に、本稿はトレーダーがそのようなスピードの速い取引を行うのに役立つ方法を提供します。
一般的に、スキャルピングはひじょうに神経をつかうタイプの取引と考えられています。ここでひじょうに重要なのは、ロット、テイクプロフィットおよびストップロスレベルを毎回指示する必要があることで、そのためチャートから注意が反れることとなります。
本稿は『「市場の勘」を養う手段としてのベットモデル』の続編です。本稿を学習する前に、その前稿の一読をお薦めします。
スキャルピングとは何か思い出していただきたいのです。スキャルピングは、素早い取引方法を言います。通常、そのような取引では利益は1~10pip(ポイント)に固定されます。スキャルピングはその複雑性、緊張性、高い注意力が要求されることで知られています。それは本格的なものではないと思う人もいれば、完璧な専門的技能であると考える人もいます。私としては、この取引タイプを評価するつもりはありません。それは広く論じられ、だれもが個人的な意見を持っているものです。
コンセプト
おそらく、トレーダーはだれもスキャルピング戦略を試したことあるでしょう。スキャルピングがもっとも都合のよい取引タイプであるトレーダーもいれば、その逆というトレーダーもいます。スキャルピングはをもっとも興味深い取引であると思う人もいれば、ただの時間の無駄だと思う人もいます。しかしだれもが、市場やこの取引タイプでオープンしているトレードに対して、強い関心を持つ必要があることには気づいています。
多くのトレーダーが、より労力と神経を使わないといけないという理由だけでスキャルピングを拒むものです。ですが、スキャルピングをする人に役立つ方法があります。
トレーダーが固定ロットおよび各トレードでテイクプロフィットを設定してスキャルピングを行おうとしている、と仮定します。明らかにトレードのたびに毎回こういったパラメータを指示する必要性を排除することは合理的です。なぜなら、それにより余分な時間が取られ、トレーダーの注意がチャートから反れるからです。
それは、トレーダーの命令の固定ロットと TP/SL レベルでトレードをオープンするツールが必要である、ということです。ツールの操作は最大限シンプルな必要があります。そのうえ、チャートからトレーダーの注意をそらすのは最小限に抑えるものでなければなりません。
そのようなツールは MQL4 手段を使えば簡単に実装できるのです。
実装
基本として、記事 『「市場の勘」を養う手段としてのベットモデル』で述べられているゲームを取り入れます。ツールを作成しますが、それはこのゲームとトレードを同時に行うことに役立つものです。
ゲームの概要上向きと下向きの2種類の矢印がチャートに描かれます。トレーダーは不要な矢印を削除します。それで、ある銘柄が上がるか下がるか、の選択がトレーダーの意見を表わします。新規のろうそく足の始めで、EA はトレーダーの予測が正しいか誤っているかチェックします。予測が正しければ、ゲームのスコアに反映されます。また、トレーダーは限られた期間内で選択を行います。それは変更可能です(トレーダーがそれを設定するかしないか判断します)。
実装には、現行バーの1本前にもう2つの矢印を描きます。現行バーはまだベッティングに使用されます。前バーの矢印を削除することで、それが EA に対して必要な方向でトレードをオープンする合図となります。そのうえ、トレード方向を選択する期間の制限は取引に対して無効になります。以下、変更可能なパラメータがあります。それは、テイクプロフィットおよびストップレベル、ロット、許容スリッページ、マジックナンバーです。また、取引は外部の bool 変数によって無効になり、そのため EA はベッティングのためだけに使用されます。
トレードのオープ時、『売り』または『買い』という名前のついた矢印がチャート上に描画されます。それはそのときのトレードオープンで決まります。これは EA がこのろうそく足に新規トレードをオープンするのを妨げるために行われます。この矢印はバーの開始価格から300ポイント離れて描かれるため、ユーザーはおそらくそのことを関知しません。
EA 自体は2つのブロックに分けられます。ゲームとトレードオープンです。それでみなさんは何がコードに追加されるか確認できます。
よって以下のプログラムコードを取得します。
//+------------------------------------------------------------------+ //| trener.mq4 | //| Copyright © 2008, FXRaider | //| | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, FXRaider" extern int gap=2; extern bool Trading=true; extern int TP=2; extern int SL=20; extern double Lots=0.02; extern int slippage=1; extern int MagicNumber=777; extern int time_limit=30; int start() { //---- //################################################################################# //####################################### GAME #################################### //------------------------------ string solution="none"; int point, point_neg, point_pos; //------------------------------ //+---------------------------------------------------------------+ //| "up" choice searching | if( ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1 &&ObjectFind("down") != 0 &&ObjectFind("up") == 0 ) { solution="up"; } //| "up" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| "down" choice searching | if( ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1 &&ObjectFind("up") != 0 &&ObjectFind("down") == 0 ) { solution="down"; } //| "down" choice searching | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a positive answer | if((solution=="up"&&Open[1]<Close[1]) ||(solution=="down"&&Open[1]>Close[1])) { point=1; point_pos=1; point_neg=0; } //| counting points at a positive answer | //+---------------------------------------------------------------+ //+---------------------------------------------------------------+ //| counting points at a negative answer | if((solution=="up"&&Open[1]>Close[1]) ||(solution=="down"&&Open[1]<Close[1])) { point=-1; point_pos=0; point_neg=1; } //| counting points at a negative answer | //+---------------------------------------------------------------+ //+----------------------------------------------------------------------------------+ //| working with an external file | int handle; double points, //total score points_pos, //score of positive answers points_neg; //score of negative answers handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); if(handle>0) //if there is a file, read it { points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); FileClose(handle); } if(solution!="none") //if a choice has been made made { handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv", FILE_CSV|FILE_WRITE|FILE_READ,";"); FileWrite(handle ,points+point); //write the total score FileWrite(handle ,points_pos+point_pos); //write the score of positive answers FileWrite(handle ,points_neg+point_neg); //write the score of negative answers FileClose(handle); } //| working with an external file | //+----------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| working with objects | if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0 ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) { ObjectDelete("down"); } if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0 ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point) { ObjectDelete("up"); } int sec_lim; if(!time_limit) { sec_lim=0; } else { sec_lim=TimeCurrent()-time_limit; } if(sec_lim>ObjectGet("up",OBJPROP_TIME1) &&sec_lim>ObjectGet("down",OBJPROP_TIME1) &&ObjectFind("down") == 0&&ObjectFind("up") == 0 &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0 &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0) { ObjectDelete("up"); ObjectDelete("down"); } if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no object &&sec_lim<Time[0]) { ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow ObjectSet("down", OBJPROP_STYLE, STYLE_DOT); ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN); ObjectSet("down", OBJPROP_COLOR, Red); ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow ObjectSet("up", OBJPROP_STYLE, STYLE_DOT); ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP); ObjectSet("up", OBJPROP_COLOR, Blue); } //| working with objects | //+------------------------------------------------------------------------------------+ //####################################### GAME #################################### //################################################################################# //################################################################################# //#################################### TRADING #################################### //+------------------------------------------------------------------------------------+ //| working with objects I | if(iBarShift(NULL,0,ObjectGet("down_1",OBJPROP_TIME1))>1 ||ObjectGet("down_1",OBJPROP_PRICE1)!=Open[0]-gap*Point ||!Trading) { ObjectDelete("down_1"); } if(iBarShift(NULL,0,ObjectGet("up_1",OBJPROP_TIME1))>1 ||ObjectGet("up_1",OBJPROP_PRICE1)!=Open[0]+gap*Point ||!Trading) { ObjectDelete("up_1"); } if(iBarShift(NULL,0,ObjectGet("sell",OBJPROP_TIME1))>0 ||ObjectGet("sell",OBJPROP_PRICE1)!=Open[0]-300*Point ||!Trading) { ObjectDelete("sell"); } if(iBarShift(NULL,0,ObjectGet("buy",OBJPROP_TIME1))>0 ||ObjectGet("buy",OBJPROP_PRICE1)!=Open[0]+300*Point ||!Trading) { ObjectDelete("buy"); } if(ObjectFind("down_1") != 0&&ObjectFind("up_1") != 0 && Trading) { ObjectCreate("down_1", OBJ_ARROW, 0, Time[1], Open[0]-gap*Point); ObjectSet("down_1", OBJPROP_STYLE, STYLE_DOT); ObjectSet("down_1", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN); ObjectSet("down_1", OBJPROP_COLOR, Red); ObjectCreate("up_1", OBJ_ARROW, 0, Time[1], Open[0]+gap*Point); ObjectSet("up_1", OBJPROP_STYLE, STYLE_DOT); ObjectSet("up_1", OBJPROP_ARROWCODE, SYMBOL_ARROWUP); ObjectSet("up_1", OBJPROP_COLOR, Blue); } //| working with objects I | //+------------------------------------------------------------------------------------+ if(Trading) { //+----------------------------------------------------------------------------------------------+ //| searching open orders for a security | int pos_sell=0, bar_op_buy, bar_op_sell; for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--) { if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break; if (Symbol()==OrderSymbol() &&(OrderType()==OP_SELLSTOP||OrderType()==OP_SELL) &&(OrderMagicNumber()==MagicNumber) &&iBarShift(NULL,0,OrderOpenTime())==0) { pos_sell=1; break; } } int pos_buy=0; for (int i_op_buy=OrdersTotal()-1; i_op_buy>=0; i_op_buy--) { if (!OrderSelect(i_op_buy,SELECT_BY_POS,MODE_TRADES)) break; if (Symbol()==OrderSymbol() &&(OrderType()==OP_BUYSTOP||OrderType()==OP_BUY) &&(OrderMagicNumber()==MagicNumber) &&iBarShift(NULL,0,OrderOpenTime())==0) { pos_buy=1; break; } } //| searching open orders for a security | //+----------------------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| working with objects II | if(pos_buy==1) { ObjectCreate("buy", OBJ_ARROW, 0, Time[0], Open[0]+300*Point); ObjectSet("buy", OBJPROP_STYLE, STYLE_DOT); ObjectSet("buy", OBJPROP_ARROWCODE, SYMBOL_ARROWUP); ObjectSet("buy", OBJPROP_COLOR, Red); } if(pos_sell==1) { ObjectCreate("sell", OBJ_ARROW, 0, Time[0], Open[0]-300*Point); ObjectSet("sell", OBJPROP_STYLE, STYLE_DOT); ObjectSet("sell", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN); ObjectSet("sell", OBJPROP_COLOR, Red); } //| working with objects II | //+------------------------------------------------------------------------------------+ //+------------------------------------------------------------------------------------+ //| opening trades | double sl_buy, sl_sell; if(!SL) { sl_buy=0; sl_sell=0; } else { sl_buy=Ask-SL*Point; sl_sell=Bid+SL*Point; } if( ObjectGet("up_1", OBJPROP_PRICE1)==Open[0]+gap*Point &&iBarShift(NULL,0,ObjectGet("up_1",OBJPROP_TIME1))==1 &&ObjectFind("down_1") != 0 &&ObjectFind("up_1") == 0 &&!pos_buy &&ObjectFind("buy") != 0 ) { OrderSend(Symbol(),OP_BUY, Lots,Ask,slippage,sl_buy,Ask+TP*Point,"trener",MagicNumber,0,Blue); } if( ObjectGet("down_1", OBJPROP_PRICE1)==Open[0]-gap*Point &&iBarShift(NULL,0,ObjectGet("down_1",OBJPROP_TIME1))==1 &&ObjectFind("up_1") != 0 &&ObjectFind("down_1") == 0 &&!pos_sell &&ObjectFind("sell") != 0 ) { OrderSend(Symbol(),OP_SELL, Lots,Bid,slippage,sl_sell,Bid-TP*Point,"trener",MagicNumber,0,Red); } //| opening trades | //+------------------------------------------------------------------------------------+ } //#################################### TRADING #################################### //################################################################################# Comment("Score: ", points," (",points_pos,"/",points_neg, //displaying score ") | Time: ", Hour(),":", Minute(),":", Seconds()); //displaying time (for convenience) return(0); } //+------------------------------------------------------------------+
コードには必要なコマンドがすべて入っています。
Expert Advisor がチャートにアタッチされると、以下を取得します。
ここでは、最後の2本の矢印がゲーム、その前の2本がオーダーのオープンに使用されます。
前のろうそく足で矢印を削除すると、OrderSend() 関数が実行され、対応するオーダーがオープンします。
以下は入力パラメータを変更するタブです。
"gap" 変数は矢印とろうそく足の開始価格の距離に等しいポイント数です。変数 "Trading" は取引関数を、 "TP" はテイクプロフィットをポイントで、"SL" はストップロスをポイントで示します。変数 "Lots" はオープンしているポジションのボリュームを、"slippage" は受け入れ準備のできている許容スリッページをポイントで示します。"MagicNumber" はオープンしたポジションに対し EA が割り当てるマジックナンバーを示します(EA が『自分の』オーダーを追跡するのに必要です)。"time_limit" limit 変数はユーザーが選択を行う制限の秒数を設定します。"0" が指定されると、時間は無制限、すなわちろうそく足が形成されている間中選択は可能ということになります。
おわりに
結果、標準パラメータ(TP、SL、 スリッページ、ロット)を持つオーダーによる快適な取引のための銘柄を手にします。このツールはすべての取引で利用可能です。ただし、短期間で大きな数のトレードがオープンしている場合に最も効率よく利用されます。たとえば、スキャルピングです。
このプログラムによって、トレーダーは毎回オープンしているオーダーに対してパラメータを設定する必要はありません。よって、トレーダーの注意は最大限チャートに集中するのです。明らかに、これは取引の効率を高めるのに役立つものです。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1509
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索