Multi_Lot_Scalperの解読4

Multi_Lot_Scalperの解読4


今回はMulti_Lot_Scalperの解読の続きを見ていきましょうね!


続きはここから

Profit = 0;
LastTicket = 0;
LastType = 0;
LastClosePrice = 0;
LastLots = 0;


あれれ?
start関数の中で初めて出てきましたね。

ここで、0を代入するってことは特に記憶用ではなさそうですね^^;


つぎを見てみましょう。

//----
for(cnt = 0; cnt < OrdersTotal(); cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
//----
if(OrderSymbol() == Symbol())
{

です。
何回も出てきているお決まりのパターンなので、もうわかりますよね?

インデックス0のものから順に実行していくやつですね。


でわ次。


LastTicket = OrderTicket();
//----
if(OrderType() == OP_BUY)
LastType = OP_BUY;
//----
if(OrderType() == OP_SELL)
LastType = OP_SELL;
LastClosePrice = OrderClosePrice();
LastLots = OrderLots();


です。内容は

LastTicketに選択したポジションの注文番号を代入。
もし、ポジションが買いなら、LastType に OP_BUY を代入。
もし、ポジションがうりなら、LastType に OP_SELL を代入。
LastClosePrice に今ポジションを手仕舞いする場合の値を代入。
LastLots にポジションのロット数を代入。

です。
for文を閉じた後には、最後に代入されたものが残るわけですね。


次見てみましょうか。


//----
if(LastType == OP_BUY)
{
if(OrderClosePrice() < OrderOpenPrice())
Profit = Profit - (OrderOpenPrice() - OrderClosePrice())*OrderLots() / Point;
//----
if(OrderClosePrice() > OrderOpenPrice())
Profit = Profit + (OrderClosePrice() - OrderOpenPrice())*OrderLots() / Point;
}
//----
if(LastType==OP_SELL)
{
if(OrderClosePrice() > OrderOpenPrice())
Profit = Profit - (OrderClosePrice() - OrderOpenPrice())*OrderLots() / Point;
//----
if(OrderClosePrice() < OrderOpenPrice())
Profit = Profit + (OrderOpenPrice() - OrderClosePrice())*OrderLots() / Point;
}
 }
}

です。
内容は、

もし、LastType が OP_BUY の場合、
もし、現在の売値がエントリー値より小さいとき、
Profit に 「Profit - (エントリー値 - 現在の売値)* ロット数のピプス表示」を代入。
もし、現在の売値がエントリー値より大きいとき、
Profit に 「Profit + (現在の売値 - エントリー値)* ロット数のピプス表示」を代入。

もし、LastType が OP_SELL の場合、
もし、現在の買値がエントリー値より大きいとき、
Profit に 「Profit - (現在の買値 - エントリー値)* ロット数のピプス表示」を代入。
もし、現在の売値がエントリー値より大きいとき、
Profit に 「Profit +(エントリー値 - 現在の買値) * ロット数のピプス表示」を代入。

です。

なんだか、遠回りしてるような気がしますが^^;
Profit には、合計損益が代入されていることになります。


でわ、次です。

Profit = Profit*PipValue;
text2 = "Profit: $" + DoubleToStr(Profit,2) + " +/-";

です。内容は

Profit に Profit * PipValue を代入する。
text2 に 「Profit: $ 」と Profit の小数点以下2ケタまでを文字列にしたものと「 +/-」を
並べたものを代入する。

といった感じです。

ここで、DoubleToStrは小数を文字列に変換するときに使います。この場合は、小数点以下3桁目を
四捨五入した数字を文字列にしてあります。

パラメータのPipValueは損益をドルに換算するときに使うみたいですね。
これは、パラメータでそのつど変更するよりもプログラムのなかで計算した方が
よさそうな気がしますが^^;


でわ、次見てみましょう。

//----
if(OpenOrders >= (MaxTrades - OrderstoProtect) && AccountProtection == 1)
if(Profit >= SecureProfit)
{
OrderClose(LastTicket, LastLots, LastClosePrice, slippage, Yellow);
ContinueOpening = False;
return(0);
}


です。内容は

もし、OpenOrders がMaxTrades - OrderstoProtect 以上で AccountProtection が1の場合
もし、Profit が SecureProfit以上の時
取引番号LastTicketのものを手仕舞いにして、
ContinueOpening を False にする。
そして、終了。

といった感じです。

MaxTrades,OrderstoProtect,AccountProtection,SecureProfitの4つはパラメータ用の変数ですね。

条件が満たされて、合計利益がSecureProfit以上になったら、手仕舞いにする感じですね。
ここで一つ手仕舞いされると、前に出てきたコードで全てのポジションを手仕舞いにするという
ところにたどり着くわけですね。


でわ、次です。

//----
if(!IsTesting())
{
if(myOrderType == 3)
text="No conditions to open trades";
else
text=" ";
Comment("LastPrice=", LastPrice, " Previous open orders=", PreviousOpenOrders,
"\nContinue opening=", ContinueOpening, " OrderType=", myOrderType, "\n",
text2, "\nLots=", lotsi, "\n", text);
}

です。内容は

もし、テストではない場合、
もしmyOrderType が3ならば、textに「No conditions to open trades」を代入。
その他ならば、textに「 」を代入。
チャートに
「LastPrice=」 LastPriceの数値 「 Previous open orders=」 PreviousOpenOrdersの数値 改行
「Continue opening=」 ContinueOpeningの真偽 「OrderType=」 myOrderTypeの数値 改行
text2の文字列 改行
「Lots=」 lotsiの数値 改行
textの文字列
を表示させる。

といった感じです。

知りたい情報をチャートに表示させるときは、Commentを使いますね。


でわ、次です。


//----
if(myOrderType == 1 && ContinueOpening)
{
if((Bid - LastPrice) >= Pips*Point || OpenOrders < 1)
{
SellPrice = Bid;
LastPrice = 0;
//----
if(TakeProfit == 0)
tp = 0;
else
tp = SellPrice - TakeProfit*Point;
//----
if(InitialStop == 0)
sl = 0;
else
sl = SellPrice + InitialStop*Point;


です。内容は

もし、myOrderType が1で ContinueOpening がtrueの場合
もし、現在の売値 - LastPrice が Pipsピプス以上、または OpenOrders が1より小さい(0の)時、
SellPrice に現在の売値を代入。
LastPrice に0を代入。
もし、TakeProfit が0のとき、tp に0を代入。
その他の時は、tp に SellPrice から TakeProfitピプス引いた値を代入。
もし、InitialStop が0のとき、 sl に0を代入。
その他の時は、 sl に SellPrice と InitialStopピプスを足した値を代入。

といった感じです。

前回のエントリー値よりPipsピプス以上値上がりした時か、ポジションが無いときに
売りポジションを持つときの利食い値、損切り値を計算する感じですね。


そして、

//----
if(OpenOrders != 0)
{
mylotsi = lotsi;
//----
for(cnt = 1; cnt <= OpenOrders; cnt++)
if(MaxTrades > 12)
mylotsi = NormalizeDouble(mylotsi*1.5, 1);
else
mylotsi = NormalizeDouble(mylotsi*2, 1);
   }
   else
   mylotsi=lotsi;


です。内容は

もし、OpenOrders が0じゃない場合
mylotsi に lotsiを代入。
cntが1から OpenOrders の値の数値以下の間、次のことを実行して
cntに1を足すというのを繰り返す。
もし、MaxTrades が12より大きいときは mylotsi に mylotsi の1.5倍を小数点以下1桁にしたものを
代入。その他のときは、 mylotsi に mylotsi の1.5倍を小数点以下1桁にしたものを代入。

その他(OpenOrders が0)の場合
mylotsi に lotsi の値を代入。

という感じです。

ここは、ポジションサイジングですね。
MaxTrades が 12以下を見てみると
ポジションが1つある場合は、ロット数が2倍、
ポジションが2つある場合は、ロット数が2*2の4倍、
ポジションが3つある場合は、ロット数が4*2の8倍。
という感じです。

で、ポジションが無いときは、lotsiをそのまま代入といった感じですね。


でわ次。


  //----
if(mylotsi > 100)
mylotsi = 100;
OrderSend(Symbol(), OP_SELL, mylotsi, SellPrice, slippage, sl, tp, NULL, 0, 0,
Red);
return(0);
}
}

です。内容は

もし、mylotsi が100より大きい時はmylotsi に100を代入。
設定した内容で売り注文を出す。
で、終了。

といった感じです。

ロット数の制限を付け加えてますね。
OrderSend のカッコ内の項目も変数に代入されている値を使っています。


そして、最後


if(myOrderType == 2 && ContinueOpening)
{
if((LastPrice-Ask) >= Pips*Point || OpenOrders < 1)
{
BuyPrice = Ask;
LastPrice = 0;
//----
if(TakeProfit == 0)
tp = 0;
else
tp = BuyPrice + TakeProfit*Point;
//----
if(InitialStop==0)
sl = 0;
else
sl = BuyPrice - InitialStop*Point;
//----
if(OpenOrders != 0)
{
mylotsi = lotsi;
for(cnt = 1; cnt <= OpenOrders; cnt++)
if(MaxTrades > 12)
mylotsi = NormalizeDouble(mylotsi*1.5, 1);
else
mylotsi = NormalizeDouble(mylotsi*2, 1);
}
else
mylotsi = lotsi;
//----
if(mylotsi > 100)
mylotsi = 100;
OrderSend(Symbol(), OP_BUY, mylotsi, BuyPrice, slippage, sl, tp, NULL, 0, 0,
Blue);
return(0);
}
}
//----
return(0);
}

です。今度は買いの注文です。
内容は、売り注文の時と同じですね。

そして、start関数も終了っと。


これで全部です。なかなか分かりづらいですよね^^;

そこで、余分な情報などを削除して、取引部分を再構築してみました!

変数名やコード配置などの変更はありますが、まったく同じ取引をするものを作りました。
ブロックごとに内容をメモしてあるので参考にしてください。

しかし、このままではマネーマネジメントの部分や
損失を抱え込んでしまうなどの難ありなので、
今後改良していきたいと思います。

でわ、ダウンロード

その前に
応援よろしくお願いいたしますm(..)m
→FXシステムトレード派
→rank応援クリック
→人気ブログランキング


MetatoreLotScalper.zip(mq4ファイル)

タグ

2008年1月21日|コメント (13)

カテゴリー:EAの作成方法

コメント (13)

こんばんは。
大変参考になっています。
修正された方のトレイリング注文のマジックナンバーは800のままなのですか?

投稿者:あ |2008年1月22日 01:12

あ、激しく勘違い?

投稿者:あ |2008年1月22日 01:13

あさん、おはようございます。

トレイリング注文のカッコ内の意味について、勘違いしておりまして、記事を修正しました。スイマセン^^;
800はマジックナンバーではなくて、有効期限だったんですね^^;

また何かありましたら、聞いてくださいね!

投稿者:慶次 |2008年1月22日 08:06

こんばんは。
MQL初めて2日目なもんで自分もすっかりマジックナンバーだと思ってました。
これからも勉強させてください!

投稿者:あ |2008年1月22日 18:03

あさん、こんばんわ。

プログラムについてアドバイスとか
よろしくお願いいたします。

投稿者:慶次 |2008年1月22日 19:36

お疲れ様です
以前はありがとうございました
大分理解しました。。まだ完璧ではないですけど・・・
またご質問なのですが、N時になったら
実行するといったPGを記載するときに
TimeHour(CurTime()を使うと思うのですが
N時N分N秒と指定したときはバックテスト、実際の取引では時間足を1分足を使わないとずれるように思うのですが・・・ローソク足が変わるのは時間足の周期になるのでしょうか?

要はint start()関数は時間足の周期でイベントが発生する??ということですか??

後、バックテストをするときは期間をしていしても思い通りの期間をテストしてくれません。。本にはチャートを表示して一番左までもっていかないといけないとかかいてあったりするのですがいまいち意味がよくわかりません。

それと過去のデータはどこかからとってこないといけないとも記載があったのですがどこから取ってくるのでしょうか?


本当に質問ばかりですみません。。
分からないことが次から次へとでてきてしまって・・・

本当にすみません。。。

投稿者:xyz__ |2008年1月22日 20:40

xyz__さん

おはようございます。

>ローソク足が変わるのは時間足の周期になるのでしょうか?要はint start()関数は時間足の周期でイベントが発生する??ということですか??

ローソク足が変わるのは時間足の周期なんですが、start関数が実行されるのは1tickごとです。なので、数分間値動きが無かった場合は数分間実行されないということになりますね。(1分足でも)
あと、バックテストはモデルをEvery tickにしても精度は最高90%なので、多少のズレがあると思います。

チャートについてですが、私もよく分かってないのですが、チャートを表示させることによってデータを自動的に取り込む感じだと思います。Homeキーを押すとチャートの左端に行きます。そこの年月日が一番古いデータです。
もっと過去を取り込むには
http://fc888.blog40.fc2.com/blog-entry-394.html

こちらの記事が参考になるかもです。

投稿者:慶次 |2008年1月23日 08:32

お疲れ様です

早速の回答ありがとうございます
非常に勉強になりました。

投稿者:xyz__ |2008年1月23日 20:00

こんばんわ。

新規で約定したらその3バー後の終値で決済するというコードはどのように記述すればいいのでしょうか?

例えば4時間足なら
OrderSend(…);
OrderSelect(…);
int opentime = OrderOpenTime();

if(TimeHour(TimeCurrent()) >= opentime + 240*3*60) OrderClose(…);

こんな感じでいけそうな気もしますが、他の時間足で検証しようとするとコードを書き換えなければならないんですよね。

それに週末が絡むとこのコードじゃ使えないですよね?週明けの寄りで決済になってしまいます。 

TimeDayOfWeek() と TimeHour()を使って条件分岐すれば可能な気もしますが結構複雑になりそうで…

簡単で他の時間足でも使える記述方法はありますか?

ほんとは面倒とか言ってちゃいけないんでけどね。

 

投稿者:red sauce |2008年1月24日 00:57

red sauceさん
おはようございます。

3バー後の終値とするとやはり複雑になりそうですね。
4バー後の始値でよいなら

int bar;

int start()
{
・・・
OrderSend(…);
bar=Bars;
・・・
if(Bars==bar+4) OrderClose(…);
・・・
return(0);
}

でいけると思います。

あと、週末はやはり条件に時間を加える感じだと思います。
その場合余裕を持たせた方がいいと思います。
終わる時間もぴったりならいいんですけど。

投稿者:慶次 |2008年1月24日 08:18

はじめまして、
「インフォ2ちゃんねる」http://info2ch.com
というサイトを運営しているものです。

metatraderの非常に有益なサイト、
非常に参考になります。コメントへの
記載申し訳ありません。

今回、このサイトを立ち上げまして、多くの
方に利用していただきたいと考え、ご連絡を
差し上げております。

情報商材の質の向上のためにも、多くの方に
有益なサイトとしてご利用いただけるように
努めています。

以前より、販売者をレビュー評価するサイトが
ほとんどなく、今回そのような主旨でサイトを
立ち上げました。

 ■■お願い■■
あなたの貴重な購入体験をレビューとして、
「インフォ2ちゃんねる」http://info2ch.com
にご記入・ご協力いただけますと幸いです。

どうぞ、末永くご愛顧のほう
よろしくお願いします!

こんばんわ。

なるほどBarsをそのように使えばどの足でも使えるしすっきりとしますね。

このやり方でいこうと思います。どうもありがとうございました。

投稿者:red sauce |2008年1月24日 22:12

リンクありがとうございました。
よろしくお願いします。

投稿者:forexscalper |2008年1月25日 06:34

コメントを投稿する

(初めてのコメントの時は、コメントが表示されるためにこのブログのオーナーの承認が必要になることがあります。承認されるまでコメントは表示されませんのでしばらくお待ちください)






画像の中に見える文字を入力してください。

Captchaの認証で入力ミスがありますと、コメントが消えてしまいますのでご注意ください。
コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。