zyx40さんのルール検証2
前回の記事(zyx40さんのルール検証)で、zyx40さんの使用したEAと紹介しましたが、ご指摘があり訂正しました。正しくは、zyx40さんのEAのベースのようです。申し訳ございません。
このEAにzyx40さんの考えをプラスしたそうです。
さあ!
前回の続きを見ていきましょう!
int start(){}の中身ですね。
if((TimeHour(TimeCurrent())>TradeTime)) cantrade=true;
となってます。
ここで、TimeHour(TimeCurrent())は現在の時間ということです。
例えば、現在 19:25 だとすると、TimeHour(TimeCurrent())は19という数字になります。
もっと、分解してみていきましょうか。
TimeHour() のカッコ内に、1970年1月1日0時0分0秒から何秒経った時の事かを入れてあげるとその時の時間を計算してくれます。
TimeCurrent() は、現在、1970年1月1日0時0分0秒から TimeCurrent() 秒経ってますよっと言った感じで秒数を計算してくれます。
それで、TimeHour(TimeCurrent())は現在の時間ということになります。
TradeTime はパラメータ用の変数、 cantrade は記憶用の変数でしたね。
なので、「もし現在の時間が TradeTime より大きかったら cantrade を true にしてください」といった意味になります。
次に、
// проверяем есть ли открытые ордера ...
total=OrdersTotal();
としています。
//オープンオーダーがあるかどうかをチェック
というメモと、
OrdersTotal()で調べたポジションの数を total という変数に代入してくださいという文ですね。
次、
if(total<Orders)
{
もし、total がパラメータで指定した Orders より小さい場合はという意味ですね。
// ... если нет ни одного открытого ордера, то идем дальше
// проверяем настало ли время для торговли
if((TimeHour(TimeCurrent())==TradeTime)&&(cantrade))
{
// ... если настало время, то
//もし取引権利がない場合、飛ばします
//時間をチェックします
もし、現在の時間がTradeTime でかつcantradeがtrueの場合。
//もしその時間の場合
といった感じです。
次に
if (((Open[t1]-Open[t2])>delta_S*Point)) //Если цена уменьшилась на величину delta
{
もしt1の始値からt2の始値を引いたものがdelta_S*Pointより大きい場合といった意味ですね。
//もし価格がデルタ量より減少してたら
という具合です。ここの部分がこのEAの心臓部分のような感じですね!
次に
//условие выполнено значит входим в короткую позицию:
// проверяем есть ли свободные деньги для открытия короткой позиции
if(AccountFreeMarginCheck(Symbol(),OP_SELL,lot)<=0 || GetLastError()==134)
{
Print("Not enough money");
return(0);
}
となってます。
//条件が満たされたら売り注文を出す
//売り注文を出す余剰証拠金があるかどうかをチェック
ここで、AccountFreeMarginCheck() という関数を使っています。
これは、仮にカッコ内の指定(通貨、売りor買い、ロット数)通りオーダーした場合、余剰証拠金はいくらになるかを教えてくれる関数です。もし、指定したオーダーが出来ないときはエラー番号134というエラーを出します。(エラー134は資金不足というエラーです)
なので、
もしこの通貨をlotロット売った時の余剰証拠金が0以下、または最後に生じたエラーが134ならば
Not enough money と表示させて
実行終了してください
という意味になります。
そして
OpenShort(lot);
cantrade=false; //запрещаем торговать повторно до следующего бара
return(0);
}
ここで出てきましたね!自作の関数OpenShort。
カッコ内のlot(初期設定では0.1)という数字を引き連れて、
OpenShortという関数を宣言したところに一旦移ります。宣言した所のカッコ内はvolumeとなっていますので、この場合は、volumeにlotを代入。そして一通りOpenShort関数の内容を実行したらまた戻ってきます。
OpenShort関数の中で、売り注文を出してますね。
その後、「cantradeをfalseにしてください」としています。
メモは、//次のバー(時間)まで再売り禁止
という感じです。
そして、実行終了ですね。
次に
if (((Open[t2]-Open[t1])>delta_L*Point))
として、今度はdelta_L*Pointより大きく値が上がった場合の時の処理です。買い注文のプログラムですね。
内容は、売りの時と同じ感じです。説明は省略^^;
そして、if((TimeHour(TimeCurrent())==TradeTime)&&(cantrade))とif(total<Orders)のカッコを閉じてます。
次に
// блок проверки времени жизни сделки, если MaxOpenTime=0, то проверку не проводим.
として、
//保持ポジションの残り時間をチェックする部分です。もし、MaxOpenTimeが0なら、この確認プロセスはおこないません。
という感じです。
では、見ていきましょう。
if(MaxOpenTime>0)
{
MaxOpenTime が0より大きい場合、ですね。
なので、MaxOpenTime が0以下ならこの確認プロセスは実行されないことになります。
次に、
for(cnt=0;cnt<total;cnt++)
{
として、繰り返しのfor文が使ってありますね。
cntが0からtotalより小さいうちはcntに1を足しつつ繰り返してくださいといった感じです。
なので、例えばtotalが3の場合は、cntが0、1、2の3回繰り返されるということです。
そして、
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
{
として、そのcntが使われてます。
「もしインデックスcntのポジションを選択したときtrueになったら」
といった意味ですね。
次にここで
tmp = (TimeCurrent()-OrderOpenTime())/3600.0;
としてtmpに現在と選択されたポジションのオープン時の秒差を3600で割ったものを代入しています。
これは、選択されたポジションを何時間保持してるかを計算しtmpに入れているわけですね。
次に
if (((NormalizeDouble(tmp,8)-MaxOpenTime)>=0))
{
としています。経過時間 - MaxOpenTimeが0以上の場合という意味です。
ここで、NormalizeDouble(小数値,0~8)という関数は、小数値の第何位(0~8)の後ろで四捨五入するといった関数です。
例えば、
NormalizeDouble(3.1415,3)
とすれば、
3.142
というように小数点以下第3位の後ろで四捨五入した値になります。
この場合、私が調べたところNormalizeDoubleを使っても使わなくても値は変わりませんでした。
次に
RefreshRates();
としてます。
これは、EAの計算時間が長くて Ask や Bid といったあらかじめ作ってある変数の値をもう一度取得する必要があるときに使います。
文字通りレートのリフレッシュですね。
そして、
if (OrderType()==OP_BUY)
closeprice=Bid;
else
closeprice=Ask;
として選択されたポジションが買いの場合、closeprice に現在の売値を代入。その他(ポジションが売り)の場合、closeprice に現在の買値を代入。
といった感じです。
次に
if (OrderClose(OrderTicket(),OrderLots(),closeprice,10,Green))
として、そのポジションを手仕舞いしてます。
と同時にOrderCloseはbool型の関数というのを利用して
「この手仕舞いが無事に取引された(OrderClose関数がTrueになった)場合」
というif文にしています。
{
Print("Принудительное закрытие сделки - №",OrderTicket());
OrderPrint();
}
else
Print("OrderClose() в блоке проверки времени жизни сделки вернул ошибку - ",GetLastError());
として、
「強制手仕舞い-No」という文字と選択されたポジションのチケットナンバーをつなげたものを表示してください。
選択されたポジションの情報を表示してください。
そうでない場合(OrderClose関数がfalseの場合)は
「 保持ポジションの残り時間をチェックする部分のOrderClose()でエラーが返されました - 」という文字とエラーナンバーをつなげたものを表示してください。
といった感じです。
ここでOrderPrint()は、
チケットナンバー、エントリーの時間、売りor買い、ロット数、通貨、エントリーの値、損切り値、利食い値、手仕舞いの値、手数料、スワップ、売買差益、コメント、マジックナンバー
といった感じで表示されます。
そして、
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))の終わりカッコのあとの
else
Print("OrderSelect() в блоке проверки времени жизни сделки вернул ошибку - ",GetLastError());
}
として、ポジション選択できなかった場合の処理を書いてます。
保持ポジションの残り時間をチェックする部分のOrderSelect()でエラーが返されました - エラーナンバー
を表示してください。といった意味です。
次の閉じカッコはfor文の閉じカッコです。ここまできたらcntに1を足してまたfor文以下を繰り返します。
最後に
}
return(0);
}
として、保持ポジションの残り時間をチェックする部分の始のif文のカッコを閉じて、実行終了、int start終了。
です。
エントリー時間を決めて、その時の過去数時間の始値の差で売りor買いを決める。ポジションには寿命がある。
といった売買ルールですね。
今回はこのへんで。
次回は、zyx40さんはどのようにしたのか。パラメータをどう変えたらいいのかなどを書きたいと思います。
応援ありがとうございます!
→FXシステムトレード派
→rank応援クリック
タグ
コメント (4)
以外と単純なシステムなんですね。
あと、ランキング増えましたね。3つポチってしました!
次回の記事とプレゼント企画楽しみにしてます。
投稿者:saki |2007年12月28日 22:36
sakiさん、おはようございます。
>以外と単純なシステムなんですね。
そうですね。でも、実際に利益が出せているので有効な戦略だと思います。
応援クリックありがとうございます!
投稿者:慶次 |2007年12月29日 07:56
リンクありがとうございます。
こちらもリンク設置完了しました。
ブログに記事を書いていただけるなんて
光栄です。
是非ともよろしくお願いします!!
投稿者:「FXの泉」管理人akira |2007年12月29日 08:41
akiraさん、ありがとうございます。
投稿者:慶次 |2007年12月29日 08:44


