システムトレード研究所 〜FXで完全自動売買〜

このサイトでは、FXで完全自動売買を行うために必要な情報を書いていこうと思っています。システムを自分で作りたい方、システムトレードをやってみたい方は御覧になっていって下さい。
特定の時間の別の時間足のバーの取得
 こんばんは、システムトレード研究所の小松です。

 今回の記事は、「特定の時間の別の時間足のバーの取得」です。

 例えば、1時間足のチャートで10本前のバーの21日移動平均線と同じ時間の30分足のチャートの21日移動平均線を取得したいとします。

 30分足のチャート場合は10本前は10時間前ではなく5時間前なので、10時間前の20本前の21日移動平均線を取得しなければなりません。

 今回は簡単に計算で出せましたが色んな時間足を使う場合ややこしくなると思います。

 そこでもっと簡単に出来るようにiBarShift関数を使います。

int iBarShift( string symbol, int timeframe, datetime time, bool exact=false)

 引数は通貨ペア、時間足、調べる時間をいれます。最後のexactはtrueなら調べる時間にバーが存在しなければ一番近いバーの数値を、falseなら-1が入ります。バーが存在する場合はどちらも変わりありません。


 この関数は指定した通貨ペア、時間足のチャートで指定した時間のバーが何処にあるかを出してくれます。

 例えば、戻り値が20なら20個前のバーになります。


 では、実際の使い方です。

datetime a_time;
int b_bars_shift;
double b_ma_Rate;

a_time = iTime(NULL,60,10);

b_bars_shift = iBarShift(NULL,30,a_time,true);

b_ma_Rate = iMA(NULL,30,21,0,MODE_SMA,PRICE_CLOSE,b_bars_shift);


 上記の説明をしていきます。

 まず、a_timeに1時間足のチャートの10本前のバーの時間を入れます。

 次にb_bars_shiftにiBarShift関数を使用してa_timeの時の30分足のチャートのバーの数値を入れます。

 最後にb_ma_Rateに30分足のチャートのb_bars_shift分前のバーの21日移動平均線を入れます。


 これで今回の内容は終了です。

 今回のiBarShift関数を使用すればマルチタイム型のインジケーターの作成も出来ます。

 興味がある方は応用して制作して見てください。





システムトレード研究所〜FXで完全自動売買〜INDEXへ
MT4用オリジナルEAの制作・作成『オーダーシステム』 


--------------注意----------------


内容には注意を払っていますが、保障は出来ません。
実際に運用する場合は、自己責任でお願いします。


JUGEMテーマ:ビジネス


| 小松 | MetaTrader4 プログラム中級編 | 16:03 | comments(0) | - |
マーケット情報の取得について
 こんばんは、システムトレード研究所の小松です。

 今回の記事は、「マーケット情報の取得について」です。

 まずマーケット情報についてですが、これは各通貨ペアのAsk、Bid、スプレッド、スワップなど、その通貨ペアに関する情報です。マーケット情報を引き出す関数はMarketInfo関数になります。

double MarketInfo( string symbol, int type)

 戻り値はdouble型で戻り、引数は通貨ペア(symbol)、何の情報か(type)になります。

 通貨ペアは証券会社によっては通貨ペア名の後にproなどが付いている場合がありますが、その場合はそれも入力してください。

 typeはかなりの数がありますので、詳しくはMQL4でMarketInfoと入力して、それにカーソルを合わせてキーボードのF1キーを押してください。MarketInfoのヘルプが出てきますので、そこからtypeのリンクを選択してください。

 下記に例を書かせて頂きます。

MarketInfo("EURUSD",MODE_BID);

 ユーロドルのBidを取得します、


MarketInfo("USDJPY",MODE_ASK);

 ドル円のAskを取得します。


MarketInfo("EURJPY",MODE_POINT);

 ユーロ円の1Pipsの通貨単位を取得します。レートの少数点が2桁なら0.1、小数点が3桁なら0.01などです。


MarketInfo("GBPUSD",MODE_DIGITS);
 ポンドドルの有効桁数を取得します。レートの少数点が4桁なら4、小数点が5桁なら5などです。



MarketInfo("EURGBP",MODE_SPREAD);
 ユーロポンドのスプレッドを取得します。単位はPipsになります。


 MarketInfo関数は主にAの通貨ペアのチャートでEAを動かしている時にBの通貨ペアの情報を取得したい時に取得します。Aの通貨ペアのチャートでEAを動かしていてもBの通貨ペアのポジションを取得可能ですので、この関数を使用すれば一つのEAで複数の通貨ペアの売買が行えます。

 また、同じチャートの情報でもMarketInfo関数でしか取得出来ない情報もありますので、色々と調べて見てください。




システムトレード研究所〜FXで完全自動売買〜INDEXへ
MT4用オリジナルEAの制作・作成『オーダーシステム』 


--------------注意----------------


内容には注意を払っていますが、保障は出来ません。
実際に運用する場合は、自己責任でお願いします。


JUGEMテーマ:ビジネス


| 小松 | MetaTrader4 プログラム中級編 | 14:25 | comments(0) | - |
口座資金の参照
 こんばんは、小松です。そろそろ気温も暖かくなってきて春になってきましたね。ただ、ここ数日の花粉はかなり厳しいらしいですのでご注意下さい。

 さて、今回の記事は、「口座資金の参照」という内容で書かせて頂きます。

 口座内の全体の資金を参照する関数になります。

 double AccountBalance()

 口座の残高を参照出来ます。
 この関数で参照出来るのは、保有中のポジションの損益を含めない金額になります。
 
 
 double AccountEquity()

 口座の有効証拠金を参照出来ます。
 この関数で参照出来るのは、保有中のポジションの損益を含めた金額になります。


 下記は使用例になります。

double balance = NULL;
double equity = NULL;

balance = AccountBalance();
equity = AccountEquity();

 上記のコードで変数balanceには残高が、変数equityには有効証拠金が入りました。

 また有効証拠金から残高を引けば、口座内の損益を出すことも可能です。
 以前紹介したAccountProfit()関数でも同じ事が可能ですが、他の方法も覚えておけば何か役に立つ時が来る子もしれません。

 口座資金が分かれば、口座資金の変化に応じてロット数を変更するという処理も可能です。

 色々と試してみてください。



システムトレード研究所〜FXで完全自動売買〜INDEXへ
自動売買システム制作のオーダーシステム|FXでオリジナルのシステムトレード

--------------注意----------------

 内容には注意を払っていますが、保障は出来ません。
 実際に運用する場合は、自己責任でお願いします。
JUGEMテーマ:ビジネス




| 小松 | MetaTrader4 プログラム中級編 | 11:44 | comments(0) | - |
損益の取得方法について
 こんばんは、小松です。台風が過ぎて、かなり涼しくなってきましたね。季節の変わり目ですので、体調を崩さないように注意してください。

 今回の記事は、「損益の取得方法について」という内容で書かせて頂きます。

 ポジションの損益を取得した場合、利益(損失)が◯◯を超えれば決済、利益(損失)が◯◯を超えればトレイル開始など、損益の内容によって柔軟にルールを変えることが可能です。

 まずは個別のポジションの損益の取得方法です。

 最初にOrderSelect()を行い、調べるポジションを指定します。OrderSelect()についてはこちらを御覧ください。

 次にOrderProfit()で損益を取得します。損益はPipsではなく、円口座なら◯◯◯円、ドル口座なら◯◯◯ドルで取得されます。

 コードを書くと下記になります。(最初のポジションをセレクトしています)

double aaa = NULL;

OrderSelect(0,SELECT_BY_POS);

aaa = OrderProfit();

 これで変数aaaに最初のポジションの損益を取得出来ます。



 システムを起動している通貨ペアのポジションの損益をまとめて取得する場合は下記のようなコードを書いてください。


double aaa = NULL;
int cnt = NULL;

for(cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS);


if(OrderSymbol() == Symbol())
{

if( OrderType() == OP_BUY || OrderType() == OP_SELL )
{

aaa = aaa + OrderProfit();

}
}


}


 これで変数aaaに損益をまとめて取得出来ます。




 次に、口座の全ポジションの損益を取得する方法です。こちらはOrderSelect()を事前にする必要がなく、AccountProfit()関数を使えばすぐに取得出来ます。

 口座の全ポジションの損益が10000円以上になったら決済する場合、

if( AccountProfit() >= 10000 )
{
決済の処理;
}

とすれば決済出来ます。





システムトレード研究所〜FXで完全自動売買〜INDEXへ
自動売買システム制作のオーダーシステム|FXでオリジナルのシステムトレード

--------------注意----------------


内容には注意を払っていますが、保障は出来ません。
実際に運用する場合は、自己責任でお願いします。





JUGEMテーマ:ビジネス
| 小松 | MetaTrader4 プログラム中級編 | 11:45 | comments(0) | - |
メールの設定の仕方
 こんばんは、小松です。

 最近、マイコプラズマという病原体に感染する人が多いらしく、私の身近な人もかかっております。

 軽い風邪と症状が似ていて放っておくと肺炎になるそうなので気をつけて下さい。予防法は風邪と同じくうがい手洗いをしっかりすることだそうです。


 さて、今回の記事は「メールの設定の仕方」です。

 オーダーシステムの方では記載しておりましたが、こちらでは説明させて頂いていませんでしたので改めて説明させて頂きます。


 メール機能とは、特定のタイミングでメールを送信する機能です。
 例えば、自動売買システムでポジションを取得したとき、出先でも自分の携帯電話にポジション取得のメールが届き、外に居ながら自動売買システムの間接的な監視が可能となります。
 もちろん決済した時にメールを出すこともなども可能です。

 魅力的なメール機能ですが、その為には先にメールの設定を行わないといけません。

 以下にメール機能を使う為の設定方法をご紹介します。



 まず、MetaTreder4の上部にある[ツール]から、[オプション]を選んでください。

メール01

 オプション設定するウィンドが表示されますので、そこから[E-メール]タブを選択します。

メール02

 1.有効にするのチェックボックスにチェックを入れます。

 2.SMTPサーバーの欄には、ご自身の契約しているプロバイダーのSMTPサーバーのアドレスを入力します。

 3.SMTPログインIDの欄には、ご自身の契約しているプロバイダーのメールのIDを入力します。(メールアドレスではなく、IDですのでご注意下さい)

 4.有SMTPパスワードの欄には、ご自身のメールのパスワードを入力します。

 5.発信元には、送信メールアドレスを入力します。この場合、ご自身のアドレスになります。

 6.送信先には、受け取り側のメールアドレスを入力します。(携帯電話に転送が出来ない場合も御座いますが、その場合は他へメールを送り、転送機能で携帯電話に送ります)

 最後に、Testボタンをクリックしてください。 送信先に送信者「Client terminal」から「This is a test message.」という内容のメールが届けば成功です。

 ※プロバイダーのIDやパスワードなどは、ご契約されているプロバイダーにお問い合わせ下さい。


 以上が設定例になります。

 メール機能は非常に便利です。 長時間家を空ける時など、自動売買システムがしっかり働いているか心配になる場合にも確認が取れるだけでストレスが減る場合もあります。
 
 ぜひ活用してみてください。


 今回はこれで終了です。

 次回のMT4関連の記事はSendMail関数について書かせて頂きます。


システムトレード研究所〜FXで完全自動売買〜INDEXへ
自動売買システム制作のオーダーシステム|FXでオリジナルのシステムトレード

--------------注意----------------


内容には注意を払っていますが、保障は出来ません。
実際に運用する場合は、自己責任でお願いします。
| 小松 | MetaTrader4 プログラム中級編 | 14:31 | comments(2) | - |
OrderSelectについて
こんばんはDCです。



今回は「OrderSelectについて」という内容で記事を書かせて頂きます。


 OrderSelect関数は、ポジションのデータを取得する関数ですが、使い方が複数あり、実際に使いこなすとなれば難しいので、今回は詳しく説明させて頂きます。

 まずは、OrderSelect関数の引数について説明します。



OrderSelect( int index, int select, int pool)


日本語にすると下記のようになります。

オーダーセレクト(番号、番号の種類、取得中か決済後か)

最初の番号(int index)はポジション番号かチケットナンバーを入力します。どちらを入力するかは次の番号の種類の引数で選びます。

ポジション番号は、現在取得しているポジションに対して0から割り振られたナンバーです。例えば、ポジションが3つあれば、先に取得した順に0、1、2とナンバーが付けられます。



for(cnt=0;cnt<OrdersTotal();cnt++)
 {
  OrderSelect(cnt,SELECT_BY_POS);


いつも使っている上記のようなコードの場合は、このポジション番号を取得しています。
OrdersTotal()は現在の取得中のポジション数を調べる関数です。

この番号はポジション数の増減により、番号も変化します。例えば、0番のポジションが決済された場合は、1番が0番に、2番が1番に変更されます。


次にチケットナンバーですが、これはそのポジションに割り振られた固定のナンバーで変わることはありません。ポジションを保有していても、決済していもこのナンバーはずっと同じ番号になります。


チケットナンバーの調べ方は、一度ポジション番号でオーダーセレクトをしてから、OrderTicket()で取得出来ます。


次に番号の種類(int select)ですが、SELECT_BY_POS でポジション番号、SELECT_BY_TICKET でチケットナンバーを選択出来ます。


最後に取得中か決済後か (int pool)ですが、これは現在取得中のポジションか、すでに決済されているポジションかの選択です。

MODE_TRADESで取得中のポジション、MODE_HISTORY で決済されているポジションになります。ただし、番号の種類がチケットナンバーの時はここは必要ありません。チケットナンバーは取得中でも決済後でもナンバーが変わらないためです。

また、ここに何も書かない場合は、自動的にMODE_TRADESになります。


決済したポジション数を調べる関数はOrdersHistoryTotal()です。この関数で取得した数値−1が最後に決済、もしくは取り消されたポジションになります。


実際の使用例です。


OrderSelect(0,SELECT_BY_POS,MODE_TRADES);


現在取得中のポジション番号0番のデータを取得してます。



OrderSelect(1,SELECT_BY_TICKET);


チケットナンバー1番のデータを取得してます。



OrderSelect(5,SELECT_BY_POS,MODE_HISTORY);


決済したポジションの番号5番のデータを取得してます。



for(cnt=OrdersHistoryTotal()-1;cnt>=0;cnt--)
 {
  OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY);


上記の処理で過去に決済したポジションを調べることが出来ます。最新の決済されたポジションから順にループするごとに過去に決済されたポジションになります。


過去に決済したポジションは数が多くなります。その分処理も重くなりますので、必要なデータを見つけたら、そこでループを止める処理をしておいたほうがいいと思います。


今回はこれで終了です。



システムトレード研究所〜FXで完全自動売買〜INDEXへ
自動売買システム制作のオーダーシステム|FXでオリジナルのシステムトレード

---------------------------------------注意---------------------------------------

 内容には注意を払っていますが、保障は出来ません。
 実際に運用する場合は、自己責任でお願いします。

JUGEMテーマ:ビジネス
| 小松 | MetaTrader4 プログラム中級編 | 11:23 | comments(2) | - |
リミットとストップロスを計算で設定する
こんばんはDCです。


今回は「リミットとストップロスを計算で設定する」についてお話したいと思います。

 よくあるシステムはリミットとストップロスを最初に設定しておけば、ポジションを取得した後に毎回同じリミットとストップロスを設定してくれます。今回は、そのリミットとストップロスを毎回違う値で設定するような方法を紹介します。
毎回同じリミットとストップロスにするのではなく、違った値で設定することが可能になります。



サンプルプログラムはこちらです。

http://jidoubaibai.com/Samples/Sample%20TPSL2.mq4

サンプルプログラムの使い方は、こちらで説明しています。

http://jidoubaibai.com/burogu11.html






 今回はレートとボリンジャーバンドの中央線のクロスでポジションを取得し、TPSLはボリンジャーバンドの±2σの位置に設定してみます。
ボリンジャーバンドの中央線は移動平均線なので、ソース内の関数ではMAとのクロスで処理していますので注意してください。






 では、MetaEditorを起動して下さい。
 NameはTPSL2などにして下さい。
 では、まとめてコードを書きますので、同じようにコードを半角英数で書いていってください。




int start()
{
 //変数の宣言
 int cnt, CurrentPosition;
 int Ticket;

 double BuyTP,BuySL;
 double SellTP,SellSL;


 // オーダーチェック(ポジションなどのデータ)
 CurrentPosition=-1;
 for(cnt=0;cnt < OrdersTotal();cnt++)
 {
  OrderSelect(cnt,SELECT_BY_POS);

  if(OrderSymbol() == Symbol())
  {
   CurrentPosition=cnt;
  }
 }




 // ポジションチェック ポジション無し
 if(CurrentPosition == -1)
 {
  //もし終値がMAを上に抜けたら
  if( CrossMA(20) == 1 )
  {
   //買いポジションを取る
   Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Red);
  }

  //もし終値がMAを下に抜けたら
  if( CrossMA(20) == 2)
  {
   //売りポジションを取る
   Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Blue);
  }



 }
 // ポジション有り
 else
 {

  //ポジションの選択
  OrderSelect(CurrentPosition,SELECT_BY_POS);

  //通貨ペアの確認
  if(Symbol() == OrderSymbol())
  {
   //もし買いポジションだったら
   if(OrderType()==OP_BUY)
   {
    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
    {

     //TPSLの値を算出
     BuyTP = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0),Digits);
     BuySL = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,0),Digits);

     //ストップロス更新
     OrderModify(OrderTicket(), OrderOpenPrice(), BuySL,BuyTP, 0, MediumSeaGreen);

    }
   }
   //もし売りポジションだったら
   else if(OrderType()==OP_SELL)
   {
    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
    {

     //TPSLの値を算出
     SellTP = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,0),Digits);
     SellSL = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0),Digits);

     //ストップロス更新
     OrderModify(OrderTicket(), OrderOpenPrice(), SellSL,SellTP, 0, MediumSeaGreen);

    }
   }
  }
 }
 return(0);
}



/*------------------------------------------------------
関数名 CrossMA
内容  MAとレートのクロスを判断する関数

引数  int Kikan MAの期間設定

戻り値 0:何も出来ていない 1:上抜け
     2:下抜け
-------------------------------------------------------*/
int CrossMA(int Kikan)
{
 double kakoa,gennzaia;
 double kakob,gennzaib;


 //一つ前の終値
 kakoa = iClose(NULL,0,1);
 //一つ前のMAの値
 kakob = iMA(NULL,0,Kikan,0,0,PRICE_CLOSE,1);

 //現在の終値
 gennzaia = iClose(NULL,0,0);
 //現在のMAの値
 gennzaib = iMA(NULL,0,Kikan,0,0,PRICE_CLOSE,0);



 //もし終値がMAを上に抜けたら
 if( kakoa < kakob && gennzaia >= gennzaib)
 {
  return(1);
 }

 //もし終値がMAを下に抜けたら
 if( kakoa > kakob && gennzaia <= gennzaib)
 {
  return(2);
 }


 return(0);
}



 書けましたか?

 今回は以前こちら
で説明したオリジナル関数を使い、レートの終値とMAのゴールデンクロスとデッドクロスでポジションをとり、
その後にポジションを持っていて、リミットとストップロスが設定されていない場合に、
ボリンジャーバンドの位置を算出してリミットとストップロスを入れるプログラムになっています。

先ず下記のポジションを取るプログラムの説明です。

 // ポジションチェック ポジション無し
 if(CurrentPosition == -1)
 {
  //もし終値がMAを上に抜けたら
  if( CrossMA(20) == 1 )
  {
   //買いポジションを取る
   Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Red);
  }

  //もし終値がMAを下に抜けたら
  if( CrossMA(20) == 2)
  {
   //売りポジションを取る
   Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Blue);
  }



 ここでは、ポジションを持っていないとき、関数内で計算された内容で終値とMAがゴールデンクロス、
またはデッドクロスと判定された時にポジションを取るようになっています。

今回もポジション取得時にリミットとストップロスを入れていると注文がキャンセルされる仕様のブローカーに合わせて、
リミットとストップロスは0でポジションを取得しています。

次に、取得しているポジションのリミットとストップロスが0の場合にボリンジャーバンドの±2σを算出し、
その位置にリミットとストップロスを新たに設定する為のプログラムです。




 // ポジション有り
 else
 {

  //ポジションの選択
  OrderSelect(CurrentPosition,SELECT_BY_POS);

  //通貨ペアの確認
  if(Symbol() == OrderSymbol())
  {
   //もし買いポジションだったら
   if(OrderType()==OP_BUY)
   {
    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
    {

     //TPSLの値を算出
     BuyTP = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0),Digits);
     BuySL = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,0),Digits);

     //ストップロス更新
     OrderModify(OrderTicket(), OrderOpenPrice(), BuySL,BuyTP, 0, MediumSeaGreen);

    }
   }
   //もし売りポジションだったら
   else if(OrderType()==OP_SELL)
   {
    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
    {

     //TPSLの値を算出
     SellTP = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,0),Digits);
     SellSL = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0),Digits);

     //ストップロス更新
     OrderModify(OrderTicket(), OrderOpenPrice(), SellSL,SellTP, 0, MediumSeaGreen);

    }
   }
  }
 }
 return(0);
}




 今回ここで初めて登場するのはiBands関数
NormalizeDouble関数です。

iBands関数(通貨ペア,タイムフレーム(時間足),期間,偏差,バンドのシフト,値を取る時間(始値、終値など),モード,シフト)

ボリンジャーバンドの数値を出す関数です。他のインディケーターで使われる関数に似ている部分が多いので簡単に説明していきます。

 通貨ペア

 どの通過ペアなのかを表すシンボルです。
 基本的に選択された通過ペアで行うNULLを入れておけば問題ありません。

 タイムフレーム(時間足)

 時間足等のタイムフレームです。
 基本的に0を入れておけば問題ないです。
 選択されたタイムフレームで行ってくれます。

 期間

 ボリンジャーバンドの期間です。
 20期間のボリンジャーバンドにしたい場合は20と入力します。

 偏差

 ボリンジャーバンドの偏差です。
 2σのボリンジャーバンドにしたい場合は2と入力します。

 バンドのシフト

 ボリンジャーバンドをシフトする値を入れます
 ここに入力した数字の数だけ右側にシフトします。
 よく分からない場合は0と入力しておけば問題ないです。

  値を取る時間(始値、終値など)

 始値、高値、安値、終値など、どのデータを使用してボリンジャーバンドを作るかです。
 PRICE_CLOSE
 PRICE_OPEN
 PRICE_HIGH
 PRICE_LOW
 PRICE_MEDIAN
 PRICE_TYPICAL
 PRICE_WEIGHTEDの7種類あります。

 モード

 ボリンジャーバンドの上下のラインのうちどれを使うかの設定です。
 MODE_UPPER
 MODE_LOWERの2種類があります。
 MODE_UPPERが上のライン、MODE_LOWERが下のラインになります。

  シフト

 ボリンジャーバンドの時間をシフトする数値です。
 0なら現在のボリンジャーバンド、1なら一つ前の足のボリンジャーバンドのデータが入ります。
 1時間足なら、一時間前の移動平均のデータが入ります。


NormalizeDouble関数(値,位)

この関数は数字の小数点以下を第何位までにするかを制御する関数です。
この関数でボリンジャーバンドの値を通貨ペアで使用されている小数点の位に合わせています。

 

 ここに入力された値を処理します。
 今回はここでボリンジャーバンドの値を処理しています。

 

 ここに入力された数字分、小数点以下を使用します。
 2と入力すると、小数第二位までという形になります。
 今回はチャートの位と合わせるので、Digitsと入力しています。
 これにより自動的にチャートの位に合います



 プログラムの内容は、ポジションを持っている時で尚且つストップロスかリミットに0が入っていた場合、
ボリンジャーバンドの±2σの値を算出してその値にストップロスとリミットの値を変更するという内容です。
基本的な動き方は以前にこちらで説明したとおりです。




//TPSLの値を算出
BuyTP = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0),Digits);
BuySL = NormalizeDouble(iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,0),Digits);

//ストップロス更新
OrderModify(OrderTicket(), OrderOpenPrice(), BuySL,BuyTP, 0, MediumSeaGreen);



こちらが今回追加、または修正された内容です。

NormalizeDoubleの場所にiBands関数
が入っています。つまり、iBands関数で算出した値をチャートの小数点にあわせている形になります。それを変数に入れています

後は、OrderModify関数で、リミットとストップロスの値を先ほど算出した値で設定しています。




/*------------------------------------------------------
関数名 CrossMA
内容  MAとレートのクロスを判断する関数

引数  int Kikan MAの期間設定

戻り値 0:何も出来ていない 1:上抜け
     2:下抜け
-------------------------------------------------------*/
int CrossMA(int Kikan)
{
 double kakoa,gennzaia;
 double kakob,gennzaib;


 //一つ前の終値
 kakoa = iClose(NULL,0,1);
 //一つ前のMAの値
 kakob = iMA(NULL,0,Kikan,0,0,PRICE_CLOSE,1);

 //現在の終値
 gennzaia = iClose(NULL,0,0);
 //現在のMAの値
 gennzaib = iMA(NULL,0,Kikan,0,0,PRICE_CLOSE,0);



 //もし終値がMAを上に抜けたら
 if( kakoa < kakob && gennzaia >= gennzaib)
 {
  return(1);
 }

 //もし終値がMAを下に抜けたら
 if( kakoa > kakob && gennzaia <= gennzaib)
 {
  return(2);
 }


 return(0);
}



 上記の内容はMAのオリジナル関数です。
ここでレートの終値とMAのクロスの判定を行っています。
詳しくは、オリジナル関数の作り方で説明しています。

 今回はこれで終了ですが、一点だけ注意点があります。
TPSLを計算により算出した時、稀に現在のレートに近すぎるため指値を入れることが出来ない場合がありますので注意してください。

今回のような方法で、リミットとストップロスを毎回違う値で設定することが可能になります。
いろいろと応用が出来る方法ですので、ぜひマスターしてください。



システムトレード研究所〜FXで完全自動売買〜INDEXへ
自動売買システム制作のオーダーシステム|FXでオリジナルのシステムトレード

---------------------------注意------------------------------

 内容には注意を払っていますが、保障は出来ません。 実際に運用する場合は、自己責任でお願いします。


| 小松 | MetaTrader4 プログラム中級編 | 16:07 | comments(2) | - |
MetaTrader4 Proactiveへの対応
こんにちは、DCです。今回は「MetaTrader4 Proactiveへの対応」について説明します。



 MetaTrader4 Proactiveが発表され、暫く時間がたちました。従来のMetaTrader4からMetaTrader4 Proactive対応の証券会社に変えたことで、「今までのEAが突然動かなくなった。」などのお便りが多数寄せられています。どうしたらEAが動くのかというご質問に、今回は答えさせて頂こうと思います。





 サンプルプログラムはこちらです。


 http://jidoubaibai.com/Sample%20TPSL.mq4


 サンプルプログラムの使い方は、こちらで説明しています。 


 http://jidoubaibai.com/burogu11.html







 なぜ突然EAが動かなくなったのでしょうか。それはMetaTrader4 Proactiveの仕様に原因があります。決してMetaTrader4 Proactiveの性能の問題ではなく、「ポジション取得時にリミットとストップを設定できない。」という仕様に引っかかっていたのです。




 MetaTrader4 Proactiveでは、ポジションを取得すると同時にリミットとストップを設定していると、エラーが発生し、注文がキャンセルされる仕様となっています。以前のEAでは、ポジション取得と同時にリミットとストップの設定がされているものがほとんどです。その為にEAが突如ポジションを取得しなくなる現象が起っています。つまりポジションを取得する時には、ストップとリミットを設定していてはいけません。




 動かなくなったほとんどのEAはリミットとストップロスを無くせば、また動くようになるでしょう。ストップとリミットを設定する場合は、ポジションを取得した後に設定することになります。




 今回はMACDのゴールデンクロスで買い、デッドクロスで売るシステムのリミットとストップを後からつけるプログラムを紹介します。決済はリミットとストップのみで行い、MACDの判定は以前こちらで紹介したオリジナル関数を使ってみましょう。


 では、MetaEditorを起動して下さい。

 NameはTPSLなどにして下さい。

 では、まとめてコードを書きますので、同じようにコードを半角英数で書いていってください。





int start()

{

 //変数の宣言

 int cnt, CurrentPosition;

 int Ticket;





  // オーダーチェック(ポジションなどのデータ)

 CurrentPosition=-1;

 for(cnt=0;cnt < OrdersTotal();cnt++){

 OrderSelect(cnt,SELECT_BY_POS);

 if(OrderSymbol() == Symbol()) CurrentPosition=cnt;

 }





 // ポジションチェック ポジション無し

 if(CurrentPosition == -1)

 {

  //もしメインがシグナルを下から上にクロスしたら

  if( CrossMACD(12,26,9) == 1 )

  {

   //買いポジションを取る

   Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Red);

  }



  //もしメインがシグナルを上から下にクロスしたら

  if( CrossMACD(12,26,9) == 2)

  {

   //売りポジションを取る

   Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Blue);

  }



 }

 // ポジション有り

 else

 {



  //ポジションの選択

  OrderSelect(CurrentPosition,SELECT_BY_POS);



  //通貨ペアの確認

  if(Symbol() == OrderSymbol())

  {

   //もし買いポジションだったら

   if(OrderType()==OP_BUY)

   {

    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)

    {

     //ストップロス更新

     OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-(200*Point),OrderOpenPrice()+(200*Point), 0, MediumSeaGreen);

    }

   }

   //もし売りポジションだったら

   else if(OrderType()==OP_SELL)

   {

    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)

    {

     //ストップロス更新

     OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+(200*Point),OrderOpenPrice()-(200*Point), 0, MediumSeaGreen);

    }

   }

  }

 }

 return(0);

}



/*------------------------------------------------------

関数名 CrossMACD

内容  MACDのゴールデンクロスとデッドクロスを判断する関数

引数 int fast  短期EMA

    int slow  長期EMA

    int signal シグナル

戻り値  0:何も出来ていない  1:ゴールデンクロス

      2:デッドクロス

-------------------------------------------------------*/

int CrossMACD(int fast,int slow,int signal)

{

 double kakoa,gennzaia;

 double kakob,gennzaib;



 //一つ前のMACDのメイン

 kakoa = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,1);

 //一つ前のMACDのシグナル

 kakob = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,1);



 //現在のMACDのメイン

 gennzaia = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,0);

 //現在のMACDのシグナル

 gennzaib = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,0);



 //もしメインがシグナルを下から上にクロスしたら

 if( kakoa < kakob && gennzaia >= gennzaib)

 {

  return(1);

 }



 //もしメインがシグナルを上から下にクロスしたら

 if( kakoa > kakob && gennzaia <= gennzaib)

 {

  return(2);

 }

return(0);

}





 書けましたか?




 今回は以前こちらで説明したオリジナル関数を使い、MACDのゴールデンクロスとデッドクロスでポジションをとり、その後にポジションを持っていて、リミットとストップロスが設定されていない場合に、リミットとストップロスを入れるプログラムになっています。




先ず下記のポジションを取るプログラムの説明です。


 // ポジションチェック ポジション無し

 if(CurrentPosition == -1)

 {

  //もしメインがシグナルを下から上にクロスしたら

  if( CrossMACD(12,26,9) == 1 )

  {

   //買いポジションを取る

   Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Red);

  }



  //もしメインがシグナルを上から下にクロスしたら

  if( CrossMACD(12,26,9) == 2)

  {

   //売りポジションを取る

   Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Blue);

  }





 ここでは、ポジションを持っていないとき、関数内で計算された内容でMACDがゴールデンクロス、またはデッドクロスと判定された時にポジションを取るようになっています。普段と違うのは、ストップロスとリミットが0になっていることです。


 次に、ポジションを持っている場合にリミットとストップロスが0の場合に新たに設定する為のプログラムです。





 // ポジション有り

 else

 {



  //ポジションの選択

  OrderSelect(CurrentPosition,SELECT_BY_POS);



  //通貨ペアの確認

  if(Symbol() == OrderSymbol())

  {

   //もし買いポジションだったら

   if(OrderType()==OP_BUY)

   {

    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)

    {

     //ストップロス更新

     OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-(200*Point),OrderOpenPrice()+(200*Point), 0, MediumSeaGreen);

    }

   }

   //もし売りポジションだったら

   else if(OrderType()==OP_SELL)

   {

    if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)

    {

     //ストップロス更新

     OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+(200*Point),OrderOpenPrice()-(200*Point), 0, MediumSeaGreen);

    }

   }

  }

 }

 return(0);

}






 今回初めて登場するのはOrderModify関数
OrderOpenPrice関数OrderStopLoss関数
OrderTakeProfit関数OrderTicket関数です。


 プログラムの内容は、ポジションを持っている時で尚且つストップロスかリミットに0が入っていた場合、ストップロスとリミットの値を変更するという内容です。


OrderOpenPrice関数は、ポジションのオープンレートを調べる関数です。

OrderStopLoss関数は、ポジションのストップロス値を調べる関数です。

OrderTakeProfit関数は、ポジションのリミット値を調べる関数です。

OrderTicket関数は、ポジションのチケット番号を調べる関数です。






 OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-(200*Point),OrderOpenPrice()+(200*Point), 0, MediumSeaGreen);





 上記がOrderModify関数です。注文の内容を変更するのに使われる関数となっています。サイズの関係上2行に分けて表記しましたが、皆さんは1行で書いても大丈夫です。


OrderModify関数(チケット番号, 指値, ストップロス値,リミット値, 有効期限, 表示される色)


個別に説明していきます。

チケット番号は変更する注文のチケット番号を選択します。

指値は指値を変更するときなどに使います。今回はオープンレートが入っています

ストップロス値はここに入力された数値をストップロスにします。

リミット値はここに入力された数値をリミットにします。

有効期限は指値などの未約定の注文の有効期限を指定します。

表示される色は色の設定です。


 今回はストップロスとリミットを変更しています。

 買いの場合、ストップロスに「OrderOpenPrice()-(200*Point)」、リミットに「OrderOpenPrice()+(200*Point)」を入力していますので、ストップロスはオープンレートから200pips下で、リミットはオープンレートから200pips上になるようにしています。



/*------------------------------------------------------

関数名 CrossMACD

内容  MACDのゴールデンクロスとデッドクロスを判断する関数



引数 int fast  短期EMA

    int slow  長期EMA

    int signal シグナル



戻り値  0:何も出来ていない  1:ゴールデンクロス

      2:デッドクロス

-------------------------------------------------------*/

int CrossMACD(int fast,int slow,int signal)

{

 double kakoa,gennzaia;

 double kakob,gennzaib;



 //一つ前のMACDのメイン

 kakoa = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,1);

 //一つ前のMACDのシグナル

 kakob = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,1);



 //現在のMACDのメイン

 gennzaia = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,0);

 //現在のMACDのシグナル

 gennzaib = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,0);



 //もしメインがシグナルを下から上にクロスしたら

 if( kakoa < kakob && gennzaia >= gennzaib)

 {

  return(1);

 }



 //もしメインがシグナルを上から下にクロスしたら

 if( kakoa > kakob && gennzaia <= gennzaib)

 {

  return(2);

 }

return(0);

}





 上記の内容はMACDのオリジナル関数です。ここでMACDのクロスの判定を行っています。詳しくは、オリジナル関数の作り方で説明しています。


 余談ですが、MetaTrader4 Proactiveがリリースされた後にオーダーシステムでご注文頂いたシステムには、全て上記の対処がされていますので、正常に稼動します。

 今回はこれで終了です。OrderModify関数は出来ることがたくさんありますので、是非マスターしてください。
 





システムトレード研究所〜FXで完全自動売買〜INDEXへ

自動売買システム制作のオーダーシステム|FXでオリジナルのシステムトレード



----------------------------------注意--------------------------------


 内容には注意を払っていますが、保障は出来ません。
 実際に運用する場合は、自己責任でお願いします。


| 小松 | MetaTrader4 プログラム中級編 | 18:34 | comments(0) | - |
レートを取得する関数
こんばんは、DCです。今日のブログは、「レートを取得する関数」という内容です。


サンプルプログラムはこちらです。
http://jidoubaibai.com/Sample%20Rate.mq4


サンプルプログラムの使い方は、こちらで説明しています。 
http://jidoubaibai.com/burogu11.html



今回もMetaTrader4のプログラムの記事です。最近のプログラムの記事が好評でしたので、しばらくはプログラムの記事を書こうと思っています。今回紹介するのはレートを取得する関数です。一番簡単なレートを取得する方法はAskとBidですが、これら以外にも色々とレートを取得する関数があります。


今回紹介するのは、iOpen関数iHigh関数iLow関数iClose関数の四つです。これらの関数はそれぞれ始値、高値、安値、終値のレートを取得することが出来ます。使用方法は全て同じです。iOpenを例に出すと下記のようになります。

iOpen( string symbol, int timeframe, int shift)


関数の上にカーソルを置いてキーボードのF1キーを押すと、関数の詳細と引数などの入力方法が出てきます。(ただ、全部英語で出てきますので、少々分かり辛いですが……)iOpenの詳細を出すと上記にように出てきます。これを分かりやすくすると下記のようになります。

iOpen( 通貨ペア,タイムフレーム,シフト)


実際に使用すると下記のようになります。

iOpen(NULL,0,0);


この例では、このシステムを使用しているチャートの通貨ペアと時間足の現在の足の始値のレートを取得しています。通貨ペアはNULL、タイムフレームは0と入力するとこのシステムを使用しているチャートの通貨ペアと時間足を自動的に選択してくれます。


他の関数の実例も書いてみます。

iLow("EURUSD",PERIOD_M15,2);


この例では、ユードルの15分足の二つ前の安値のレートを取得しています。このように、これらの関数を使用すれば、MetaTrader4で選べる全ての通貨ペア、全ての時間足、全てのバーの始値、高値、安値、終値のレートを取得することが可能です。例えば、ドル円の15分足のレートとユーロドルの1時間足のレートを同時に判断する売買ルールのシステムを製作することも可能です。



expert




サンプルプログラムは、現在の始値、一つ前の足の高値、15分足の現在の安値、ユーロドル現在の終値のレートを取得して変数に入れ、Comment関数でチャート上に表示しています。




 

 宜しかったら、応援して下さい



システムトレード研究所〜FXで完全自動売買〜INDEXへ


----------------------注意----------------------
このブログは半角のスペースが認識されない為、コードを見易くするために全角で書いている場合があります。実際にプログラムにコードを書くときは、コピー&ペーストせずに半角で書いて行って下さい。

また、内容には注意を払っていますが、保障は出来ません。実際に運用する場合は、自己責任でお願いします。
| 小松 | MetaTrader4 プログラム中級編 | 22:07 | comments(11) | - |
アラートを鳴らす方法
こんばんは、DCです。今日のブログは、「アラートを鳴らす方法」という内容です。


サンプルプログラムはこちらです。
http://jidoubaibai.com/Sample%20Alert.mq4


サンプルプログラムの使い方は、こちらで説明しています。 
http://jidoubaibai.com/burogu11.html


今回もMetaTrader4プログラムの記事です。前回のComment関数の記事が思いのほか好評でしたので、今回も似たような関数を紹介していきます。今回紹介するのはアラートを鳴らす関数です。この関数を使用することで、特定の場面でアラートを鳴らすことが出来ます。パソコンの近くにはいるが、いちいち画面を見ているのは面倒だという時などに役に立ちます。シグナルが出た時にアラートをなるようにしておくと、シグナルが出た時に音を出してシグナルが出たことを知らせてくれます。


アラートを鳴らすには、Alert関数を使用します。使い方はPrint関数Comment関数などとほとんど同じです。


Alert(“RSIが30以下になりました  RSI = ”,RSI);


このように使用します。ただ、Comment関数などと違う注意点があります。Alert関数は条件が成立している間中ずっと鳴り続けてしまいますので、一度アラートが鳴ったら次の条件成立まで鳴らないようにする処理が必要になります。


方法としては、グローバル変数を使用します。グローバル変数について分からない人は下記のアドレスのページで解説していますので、ご覧下さい。

http://mastertraders.livedoor.biz/archives/50553465.html


まず、int start()の上で変数宣言をしてフラグを作ります。このフラグで、アラートがシグナルが出てから一度もなっていないかどうかを判断します。次に、シグナルの条件の後にこのフラグを使って、一度もなっていなかったらという条件のif文を付けます。これにより二度目以降を鳴らさないようにします。


次に、シグナルが成立してAlert関数で音を鳴らした後に、フラグを立てておきます。最後にシグナルが出なくなったときにフラグを元に戻します。これでシグナルが成立してからアラートが一度しかならないようにすることが可能です。この処理を実際にプログラムのコードに書くと下記のようになります。



//グローバル変数
bool AlertFlag = false;

int start()
{
//変数の宣言
double RSI;

RSI = iRSI(NULL,0,14,PRICE_CLOSE,0);

if( RSI >= 70 )
{
//まだ一度も鳴っていなかったら
if( AlertFlag == false)
{

//アラートを鳴らす
Alert(" RSIが70以上になりました RSI = ",RSI);

//連続でならないようにする処理
AlertFlag = true;

}

}
//それ以外だったら
else
{
//また条件が一致したらアラートを鳴らすようにする
AlertFlag = false;
}

return(0);
}



サンプルプログラムはこのコードにif文を一つ増やして、RSIが70以上の時と30以下の時にアラートが鳴るようにしています。また、現在のRSIの数値が分かるようにComment関数でチャートにRSIの数値を表示しています。


最後に注意点として、Comment関数と同じで、Alert関数を使用する場合はそのシステムが動いていないと駄目です。他のシステムを動かすときみたいにニコマークを出してください。また、ニコマークが出てからレートが動かないとアラートが鳴りませんので、ご注意下さい。


expert



条件が成立して、Alert関数が実行された時は、アラート音と一緒に画像のような新しいウィンドウが出てきます。




 

 宜しかったら、応援して下さい



システムトレード研究所〜FXで完全自動売買〜INDEXへ


----------------------注意----------------------
このブログは半角のスペースが認識されない為、コードを見易くするために全角で書いている場合があります。実際にプログラムにコードを書くときは、コピー&ペーストせずに半角で書いて行って下さい。

また、内容には注意を払っていますが、保障は出来ません。実際に運用する場合は、自己責任でお願いします。
| 小松 | MetaTrader4 プログラム中級編 | 09:17 | comments(2) | - |
   1234
567891011
12131415161718
19202122232425
2627282930  
<< November 2017 >>



このページの先頭へ