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

このサイトでは、FXで完全自動売買を行うために必要な情報を書いていこうと思っています。システムを自分で作りたい方、システムトレードをやってみたい方は御覧になっていって下さい。
お花見
こんばんわ。小松です。

先週の日曜日に京都の方へ花見に行ってきました。



残念ながら、まだ桜自体はほとんど蕾だったのですが、天気がよく風が気持ちよくて、良いピクニック日和でした(笑)

場所にも依りますが、今週末のほうが花見をするにはいいかもしれません。

花より団子みたいな花見になりましたが、一緒に行った人たちと談笑し、とても楽しい一日でした。

ただ、来年の花見は桜が満開だといいな(笑)
JUGEMテーマ:日記・一般


| zikund01 | 雑記 | 16:36 | comments(0) | - |
iPhoneにメールを送る場合の文字化けについて
 こんにちは。更新が遅れてすみません。

 オーダーシステム経由でこのブログを見てくれている方から、メールをよく頂きますので、紛らわしいのでこれからはHNをやめて本名の小松と名乗らせて頂きます。

 あと、これからは出来るだけ更新を頻繁にして行きたいと思います。MT4に関係ない記事も書くこともあると思いますがご了承ください。

 メルマガはMT4関連の記事の時だけ送らせて頂きます。

 これからも宜しくお願いします。


 それでは今回の記事です。
iPhoneにメールを送る場合の文字化けについて」という内容で書かせて頂きます。

 最近よくメール機能でフリーメールなどに送った場合は正常に表示されるのに、iPhoneにメールを送った場合だけ文字化けする。


といった内容のお問い合わせを受けます。

 結論から言いますと、これはメールの内容に日本語が含まれているからです。(正しくは2バイト文字)

 ですので、メール内容を全部半角英数にすれば問題は解決します。


 例えば、iPhoneに下記のようなコードでメールを送った場合、


※事前にオーダーセレクトをしておきます。

SendMail("Mail",
"時間 : "+TimeToStr(TimeLocal())+
"¥n通貨ペア : "+OrderSymbol()+
"¥nシグナル : 買い"+
"¥n取得レート : "+DoubleToStr(OrderOpenPrice() ,Digits)+
"¥nロット : "+DoubleToStr(OrderLots(),2)+
"¥n¥n¥n"+"口座残高 : "+DoubleToStr(AccountBalance(),0)+"円"+
"¥n"+"有効証拠金 : "+DoubleToStr(AccountEquity(),0)+"円"+
"¥n"+"余剰証拠金 : "+DoubleToStr(AccountFreeMargin(),0)+"円");



 iPhoneでは、下記のように文字化けして表示されます。

: 2012.03.27 17:16
y A : USDJPY
V O i :
[ g : 82.825
b g : 0.1


c : 4992750 ~
L : 4992590 ~
] : 4984308 ~



 これを全部半角英数の下記のようなコードにすると、


SendMail("Mail",
"Time : "+TimeToStr(TimeLocal())+
"¥nSymbol : "+OrderSymbol()+
"¥nSignal : New Buy"+
"¥nOpen Price : "+DoubleToStr(OrderOpenPrice() ,Digits)+
"¥nLots : "+DoubleToStr(OrderLots(),2)+
"¥n¥n¥n"+"Balance : "+DoubleToStr(AccountBalance(),0)+" Yen"+
"¥n"+"Equity : "+DoubleToStr(AccountEquity(),0)+" Yen"+
"¥n"+"FreeMargin : "+DoubleToStr(AccountFreeMargin(),0)+" Yen");



文字化けせずに下記のように正常に表示されます。


Time : 2012.03.27 17:19
Symbol : USDJPY
Signal : New Buy
Open Price : 82.830
Lots : 0.1


Balance : 4992620 Yen
Equity : 4992460 Yen
FreeMargin : 4984177 Yen



 iPhoneにメールを送る時は、全部半角英数にするようにしましょう。


 今回はこれで終了です。

 SendMail関数と、メール機能の設定の解説は次回させて頂きます。


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

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


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



JUGEMテーマ:ビジネス


| zikund01 | システムトレード実践編 | 14:52 | comments(0) | - |
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テーマ:ビジネス
| zikund01 | 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でオリジナルのシステムトレード

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

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


| zikund01 | MetaTrader4 プログラム中級編 | 16:07 | comments(2) | - |
色々な決済の仕方
こんばんは、DCです。今回は「色々な決済の仕方」についてお話したいと思います。



 皆さんは決済をどのようにお考えでしょうか。FXで勝つためにはエントリー位置も重要ですがそれと同様に決済の仕方が重要だと私は考えています。今回は決済について一つの方法をご紹介します。





 買いポジションを取得した後、レートが逆行してしまい含み損を抱えてしまった場合、おとなしく損切りをするかレートが持ち直すのを待つのかという選択を迫られる場合があります。
そんな時、ナンピンをしてみるという選択肢があります。


 今回は説明のため、スプレッド抜きで説明させて頂きますが、例えば90.00で買いポジションを立て、レートが逆行して89.50になった場合。この位置で更に買いポジションを立てます。
そうすれば、90.00で立てた買いポジションと89.50で立てた買いポジションの損益の合計が0になるのは89.75となります。ナンピンをしなかった場合、レートが90.00まで戻らなければ
損失を出すはずだったポジションが、89.75までレートが戻れば±0で切り抜けることができるということになります。




 分かりやすく書くと下記の通りになります。


 (説明のため、スプレッドは考慮していません。)

 ポジションA=90.00で取得したポジション。

 ポジションB=89.50で取得したポジション。



 レートが89.75の位置の場合のポジションAの損益=-0.25

 レートが89.75の位置の場合のポジションBの損益=0.25



 合計損益=0



 更にレートが下がった場合、ナンピンを重ねることも可能なので、どんどん相殺レートは下がっていきます。



 デメリットとしては、レートが反転せずに下降し続けた場合、ナンピンした数だけ損益が大きくなるという危険な一面もあります。



 この方法は、ナンピンポジションのlot数を減らしたり増やしたり、ナンピンする幅を広げたり狭めたりとバランスのとり方も色々考えることができます。
その為デメリットもあるものの、バランスの比較的とり易い方法といえます。リスク管理がしっかりしているのであれば、有効な方法かもしれません。



他にもやり方としては、以下のような方法もあります。



 (説明のため、スプレッドは考慮していません。)

 ポジションA=90.00で取得したポジション、ロット数は1。

 ポジションB=89.50で取得したポジション。ロット数は2



 レートが89.75の位置でポジションAの1ロットとポジションBの半分にあたる1ロットを決済して相殺。
残りのポジションBの1ロットを引き続き保有して利益を狙うといった方法もあります。



 実際にはスプレッドの影響などがありますので上記の説明ほど単純には行きませんが、考え方は上記の通りになります。


 今回はこれで終了です。決済方法はすごく奥の深い要素を持っているので、皆さんもぜひ研究してみてください。





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


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


| zikund01 | システムトレード実践編 | 17:17 | comments(6) | - |
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< May 2012 >>

このページの先頭へ