2009/04/17

Mizutoriをカスタマイズ!


ご無沙汰しております。
今回の課題は、『なぜこのEAの取引数が、サーバー(取引業者)によって異なるか?』です。
※この内容は、私の憶測です。

大きく分けると4つの要因が考えられます。
①サーバー(取引業者)によって微妙にデータが違い、それが原因となり注文処理が行われずスルーするのではないか?
②サーバー(取引業者)との接続状況もしくはサーバーの処理状況が悪く、本来1Pips毎に送られてくるデータが数Pipsまとめて送られてくる場合に注文処理がスルーするのではないか?
③こちらからは、注文オーダーを出したにも関わらず、サーバー(取引業者)で受け付けてもらえなかったからではないか?(この要因は、今回対象外としておきます。)
※ちなみに『OFF QUOTES エラーについて by FXDD
④PCの処理途中にpipsの更新があり、対応できない場合に注文処理がスルーするのではないか?(この要因は、今回対象外としておきます。)

2つの要因に対する解決策(?)は?
①に対しては、オリジナルのデータを元に、パラメーターの調整をすることで対応する方法がベターかもしれません。
②を今回のテーマと位置づけて考えてみました。
A)まずこのEAの取引条件の要の2つの条件を考えてみます。
1.『上部の乖離線を売値が越えたら売り!』若しくは、『下部の乖離線を買値が下回ったら買い!』としています。
 2.上記かつ、『RSI【(期間14)終値】が(ある数値を越えたら売りorある数値を下回ったら買い)としています。
※つまり、データがまとめて配信され、その中の一部のデータが、取引条件を超えていても
まとめられたデータの最後の値が、取引条件に達していなければ取引は成立しません。
これが、接続状況及びサーバー処理状況による取引回数が減る要因だと考えました。
B)上記の対策として、以下のように取引条件を変更してみました。
1.『上部の乖離線を現在のバーの高値が越えたら売り!』若しくは、『下部の乖離線を現在のバーの安値が下回ったら買い!』
 2.上記かつ、『RSI【(期間14)終値「ただし、現在のバーのみ高値or安値」】が(ある数値を越えたら売りorある数値を下回ったら買い)
C)上記の内容にしたらどうなるか?
利点:『新しいバーが作成されるか、または、注文オーダーが通るまで注文シグナルを送り続けます。』
欠点:『注文は処理されたが、予定値と実際の注文値に開きが生じる可能性がある。』

では、どの様に実装すればよいか?を以下に掲示しておきます。
①まず、『MQL4からRSIの指標を入手し指標のフォルダーに格納』 iRSIの代わりに使用します。
②次に、EAを開き以下のコードを追加する。
【指標の計算の変更(RSI期間14の場合)】
//RSI = iRSI(NULL,0,14,PRICE_CLOSE,0); 『要らないコードの削除もしくはコメント化』
double Hi_RSI;
double Lw_RSI;
double sump=0,sumn=0,rel=0;
double positive=0;
double negative=0;
double B_positive = iCustom(NULL,0,"RSI",1,1);
double B_negative = iCustom(NULL,0,"RSI",2,1);
//Hi_RSI用
rel=High[0]-Close[1];
if(rel>0) sump=rel;
else sumn=-rel;
positive=(B_positive*13+sump)/14;
negative=(B_negative*13+sumn)/14;
if(negative==0.0) Hi_RSI=0.0;
else Hi_RSI=100.0-100.0/(1+positive/negative);
//Lw_RSI用
sump=0;sumn=0;
rel=Low[0]-Close[1];
if(rel>0) sump=rel;
else sumn=-rel;
positive=(B_positive*13+sump)/14;
negative=(B_negative*13+sumn)/14;
if(negative==0.0) Lw_RSI=0.0;
else Lw_RSI=100.0-100.0/(1+positive/negative);
【条件式記入場所】(参考)
(BUY)
if(
(!OderStop)
&&(pos1<Max_Position)
&&(st>=Xox)
&&(Lw_RSI<=RSILowLimt)【RSIをLw_RSIに変更】
&&(MaLow>=Low[0]) 【AskをLow[0]に変更】
&&(ATR<=ATRLimt)
&&((Ask<=(LastPrice-(PipStep*Point)))||pos1==0)【お好みで、ASKをLow[0]に変更】
)Buy_Flag = true;

(SELL)
if(
(!OderStop)
&&(pos2<Max_Position)
&&(st>=Xox)
&&(Hi_RSI>=RSIHiLimt)【RSIをHi_RSIに変更】
&&(ATR<=ATRLimt)
&&(MaHi<=High[0]) 【BidをHigh[0]に変更】
&&((Bid>=(LastPrice+(PipStep*Point)))||pos2==0)【お好みでBidをHigh[0]に変更】
)Sell_Flag = true;

こんな感じになります。

まとめ
本来は、フォームに掲載するような内容ですが、ブログの更新のために使用させて頂きました。
また、お決まりのように、フォワードテスト等をしておりませんので、ご使用される方は、『人柱覚悟!』でお願いします。
では!

7 件のコメント :

polarB さんのコメント...

面白いです。バックテストでも2%ほどトレード数増えますね。リアルフォワードでこそ効果がわかる改良なのでさっそく人柱になります^^。
また報告しますね。

bighope さんのコメント...

そうなんですよね!
こればかりは、バックテストでは賛否できませんから、使ってみてのお楽しみといったところでしょうか?

それと、現行のMizutoriは、決済処理が軟弱で、一度決済処理にエラーが発生してもカバーするようになっていないので、思わぬ損益が発生する可能性がないか心配しています。特に121で使用される場合は、修正の必要があるかもしれません。
では、また報告してください。

polarB さんのコメント...

検証期間1週間ですが報告します。36.1&40.0をAlpariUK(USサーバVPS)にて検証。
結果は大差なしでした^^;取引回数、勝率(100%)、注文タイミング共に同じです。
ただ、変更後の方が10秒〜90秒早く注文し,そのため約定値が0〜4pips違いました(ほとんど不利な値)。
期待した取引回数増加はなかったです。サーバ環境が良かったということかもしれません。様々な環境で検証しないとなんともいえないですね・・・。

決済処理ですが、121の場合決済失敗してもTPを満たしている限り処理は走りつづけると思うのですが、これだけだと問題が起こるということでしょうか?(一瞬のTPタッチ時決済エラーには対応できないですね)
幸いにも決済エラーに遭遇したことがなくこのへん疎いもので><

bighope さんのコメント...

polarBさんへ
検証報告ありがとうございます。
まず、Buy注文が早く注文されて、そのオーダーが不利な値となるのは、本来ASK値を利用しての取引を想定しているにも関わらず、Lowを使用しているため間接的にBid値で処理しているので、スプレッド分不利なポジションで取得しているのが原因だと思います。
しかし、SELL注文時に上記の内容が発生した場合は、今回の検証対象ヵ所だと思います。(ただし、今回は、再突入があり、その際に注文した可能性があるように思います。)

一瞬のTP時決済エラーへの対応は、決済処理再ループで対応は可能だと思うのですが、ベストの対応なのか疑問が残るところです。(サーバーに負荷をかける原因につながりますし、TPの減につながるかもしれません。)特に問題がなければ、現状維持がベストかもしれませんね。

最近VPSが話題になっていますね!
今後の主流になるんでしょうね!
私のように、夏に向けて、ファンの増設を考えているようでは・・・

では!

t-taka さんのコメント...

いつも参考にさせて頂いています。初心者ですが見真似で作って設定を変えて試してみる楽しみが増えました。お時間御座いましたらお教え頂きたいのですが、RSIの期間、HiLowの数値をEAの設定窓から変更したいと考えています。何とかRSIの期間変更は出来た様に思えるのですがHiLowの設定の方ができません。窓から変更しても反映されて居ないように思いますので何かヒント頂ければあり難いです。

bighope さんのコメント...

t-takaさんへ
どこからわからないかわからないので、とりあえずRSIの期間の変更について書いておきますね!
まず、グローバル領域に・・
extern int RSI_Period = 14;(RSIの期間変数)
それから、
double B_positive = iCustom(NULL,0,"RSI",RSI_Period,1,1);
double B_negative = iCustom(NULL,0,"RSI",RSI_Period,2,1);
//Hi_RSI用
rel=High[0]-Close[1];
if(rel>0) sump=rel;
else sumn=-rel;
positive=(B_positive*(RSI_Period-1)+sump)/RSI_Period;
negative=(B_negative*(RSI_Period-1)+sumn)/RSI_Period;
if(negative==0.0) Hi_RSI=0.0;
else Hi_RSI=100.0-100.0/(1+positive/negative);
//Lw_RSI用
sump=0;sumn=0;
rel=Low[0]-Close[1];
if(rel>0) sump=rel;
else sumn=-rel;
positive=(B_positive*(RSI_Period-1)+sump)/RSI_Period;
negative=(B_negative*(RSI_Period-1)+sumn)/RSI_Period;
if(negative==0.0) Lw_RSI=0.0;
else Lw_RSI=100.0-100.0/(1+positive/negative);
のような形にしてもらえれば、期間の変更が可能になると思います。ご健闘を!


ここからは、記事の追記です。
 ティックがまとめて送られる状況でトレードしている方の対策です。そうでない方は、無意味なものだと思っています。
 ティックがまとめて送られてくる状況をどのように確認するか?
【ティックチャート】で確認するのが一番だと思います。
 ちなみに、【表示】/【気配値表示】/通貨ペアをクリック/【ティックチャート】で見ることができます。

t-taka さんのコメント...

御忙しい所有り難う御座いました。RSIの期間の変更と上下限の設定がEAの設定窓から変更出来る様になりました。
どこでどう間違えたのか窓から数値を変更しても反映されずに頭を悩ませていましたので助かりました。色々にらめっこし、弄る事で勉強にもなりました。
有り難う御座いました。