たかはしです。

先日をしていたインジケータのパラメータを最適化するひな形のEAを作ってみました。

最適化したいインジケータの内容に沿っておもいっきりカスタマイズする必要がありますが、一応最適化自体は可能です(・_・;)

使い方が少々ややこしいので、下記に説明していきます。

ダウンロード

とりあえずダウンロードして下さい。

ParameterOptimization.mq4

設置方法

環境によって複雑な場所にフォルダがあるので、この方法でダウンロードしたファイルを設置してください。
※最適化したいインジケーターはIndicatorフォルダに入っている事を前提とします。

MetaEditorを開く

スクリーンショット 2015-05-05 23.10.31

赤枠で囲んでいるボタンをクリックします。

Expertsフォルダを開く

スクリーンショット 2015-05-05 23.10.05

赤枠で囲んでいる「OpenFolder」をクリックします。

EAファイルの設置

ダウンロードしたファイルをExpertsフォルダに設置します。

カスタマイズ方法

コード全体

お粗末なコードで申し訳ないけど、一応目的は果たせますw

<br />
//+------------------------------------------------------------------+<br />
//|                                        ParameterOptimization.mq4 |<br />
//|       Copyright (C)2015 FX取引に関するあれこれ All Rights Reserved. |<br />
//|                                              http://www.mql4.com |<br />
//+------------------------------------------------------------------+<br />
#property copyright   &quot;Copyright (C) 2015 FX取引に関するあれこれ All Rights Reserved.&quot;<br />
#property link        &quot;http://fxtrading.greeds.net&quot;</p>
<p>/*▼EAのパラメータ▼*/<br />
input double TP    =5000;<br />
input double SL    =5000;<br />
input double Lots  =0.1;<br />
/*▲EAのパラメータ▲*/</p>
<p>/*▼インジケーターのパラメータ▼*/<br />
input bool AlertsEnabled=false;<br />
input double Step = 0.009;//was .01<br />
input double Maximum = 0.2;<br />
input int Precision = 7;<br />
input int TimeFrame=0;<br />
/*▲インジケーターのパラメータ▲*/</p>
<p>//+------------------------------------------------------------------+<br />
//|メイン                                                              |<br />
//+------------------------------------------------------------------+<br />
void OnTick(void)<br />
{<br />
int cnt,total;<br />
if(Bars&amp;lt;100)<br />
{<br />
Print(&quot;bars less than 100&quot;);<br />
return;<br />
}</p>
<p>if(TP&amp;lt;10)<br />
{<br />
Print(&quot;TakeProfit less than 10&quot;);<br />
return;<br />
}</p>
<p>/*▼最適化したいインジケータからデータを取得▼*/<br />
double out0_0 = iCustom(NULL,0,&quot;Parabolic_trendchaser&quot;,AlertsEnabled,Step,Maximum,Precision,TimeFrame,0,1);<br />
double out0_1 = iCustom(NULL,0,&quot;Parabolic_trendchaser&quot;,AlertsEnabled,Step,Maximum,Precision,TimeFrame,0,2);<br />
double out1_0 = iCustom(NULL,0,&quot;Parabolic_trendchaser&quot;,AlertsEnabled,Step,Maximum,Precision,TimeFrame,1,1);<br />
double out1_1 = iCustom(NULL,0,&quot;Parabolic_trendchaser&quot;,AlertsEnabled,Step,Maximum,Precision,TimeFrame,1,2);<br />
/*▲最適化したいインジケータからデータを取得▲*/</p>
<p>total=OrdersTotal();</p>
<p>if(total&amp;lt;1)<br />
{<br />
if(AccountFreeMargin()&amp;lt;(1000*Lots))<br />
{<br />
Print(&quot;We have no money. Free Margin = &quot;,AccountFreeMargin());<br />
return;<br />
}</p>
<p>/*買いエントリー*/<br />
if(out1_0&amp;gt;0 &amp;amp;&amp;amp; out0_1&amp;gt;0)<br />
{<br />
EntryL();<br />
}</p>
<p>/*売りエントリー*/<br />
if(out0_0&amp;gt;0 &amp;amp;&amp;amp; out1_1&amp;gt;0)<br />
{<br />
EntryS();<br />
}<br />
}</p>
<p>for(cnt=0;cnt&amp;lt;total;cnt++)<br />
{<br />
if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))<br />
continue;<br />
if(OrderType()&amp;lt;=OP_SELL &amp;amp;&amp;amp;   // check for opened position<br />
OrderSymbol()==Symbol())  // check for symbol<br />
{<br />
if(OrderType()==OP_BUY)<br />
{<br />
/*買い決済*/<br />
if(out0_0&amp;gt;0 &amp;amp;&amp;amp; out1_1&amp;gt;0)<br />
{<br />
SettlementL();<br />
return;<br />
}<br />
}<br />
else // go to short position<br />
{<br />
/*売り決済*/<br />
if(out1_0&amp;gt;0 &amp;amp;&amp;amp; out0_1&amp;gt;0)<br />
{<br />
SettlementS();<br />
return;<br />
}<br />
}<br />
}<br />
}<br />
}<br />
void EntryL()<br />
{<br />
int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask-TP*Point,Ask+TP*Point,&quot;macd sample&quot;,16384,0,Green);<br />
if(ticket&amp;gt;0)<br />
{<br />
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))<br />
Print(&quot;BUY order opened : &quot;,OrderOpenPrice());<br />
}<br />
else<br />
{<br />
Print(&quot;Error opening BUY order : &quot;,GetLastError());<br />
}<br />
return;<br />
}<br />
void EntryS()<br />
{<br />
int ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Bid+TP*Point,Bid-TP*Point,&quot;macd sample&quot;,16384,0,Red);<br />
if(ticket&amp;gt;0)<br />
{<br />
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))<br />
Print(&quot;SELL order opened : &quot;,OrderOpenPrice());<br />
}<br />
else<br />
{<br />
Print(&quot;Error opening SELL order : &quot;,GetLastError());<br />
}<br />
return;<br />
}<br />
void SettlementL()<br />
{<br />
if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))<br />
{<br />
Print(&quot;OrderClose error &quot;,GetLastError());<br />
}<br />
return;<br />
}<br />
void SettlementS()<br />
{<br />
if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet))<br />
{<br />
Print(&quot;OrderClose error &quot;,GetLastError());<br />
}<br />
return;<br />
}</p>
<p>

最適化するインジケータの取得

最適化するインジケーターからデータを拾う準備をします。
コードの15行目「▼インジケーターのパラメータ▼」にインジケータの入力項目をコピペします。
このパラメータで最適化を行います。

だいたい「input」「extern」って書いてあるやつがインジケータのパラメータです。

コードの41行目「▼最適化したいインジケータからデータを取得▼」でデータを取得します。

ちょっとややこしいけど、頑張って理解してください。

double out0_0 = iCustom(NULL,0,”Parabolic_trendchaser”,AlertsEnabled,Step,Maximum,Precision,TimeFrame,0,1);

double out0_0ってのはdouble型という小数点を扱える変数です。

out0_0にインジケータの値が入ります。

iCustom(NULL,0,”Parabolic_trendchaser”,AlertsEnabled,Step,Maximum,Precision,TimeFrame,0,1);

iCustomという関数を利用して最適化したいインジケータの値を取得します。

前から順番に説明します。

NULLの場所には通貨ペアを指定できますが、NULLで現在表示している画面の通貨ペアが自動的に設定されます。

0はタイムフレームで時間軸で、5分足なら5、1時間足なら60といった具合になりまして、0の場合は現在表示している時間軸が自動的に設定されます。

“Parabolic_trendchaser”は最適化したいインジケータの名前を設定します。

.ex4や.mq4は省略してください。

その後ろにはそのインジケータの入力パラメータをすべて設定します。

Parabolic_trendchaserの場合は「AlertsEnabled,Step,Maximum,Precision,TimeFrame」の5項目があるので、その通り設定しています。

スクリーンショット 2015-05-05 23.36.12

最後から2番目の0は出力項目の順番です。
出力項目は画像やり方で確認できます。

データウィンドウの下部に赤枠で表示されているのがインジケータの出力項目です。
上から0番目、1番目という風に数えます。

最後の1は最新の足からさかのぼる数です。
0は現在の足で、1は一つ前の足です。

0だとデータが変動するため、判定ロジックがぶれてしまうので、変更のない確定した直近のデータを用いるために一つ前の足のデータを利用します。

リアルタイム性を持たすなら0を使ってみても良いです。

安定性を持たすなら1とかが無難ですね。

上記コードではこの様になっています。
double out0_0 = iCustom(NULL,0,”Parabolic_trendchaser”,AlertsEnabled,Step,Maximum,Precision,TimeFrame,0,1);
double out0_1 = iCustom(NULL,0,”Parabolic_trendchaser”,AlertsEnabled,Step,Maximum,Precision,TimeFrame,0,2);
double out1_0 = iCustom(NULL,0,”Parabolic_trendchaser”,AlertsEnabled,Step,Maximum,Precision,TimeFrame,1,1);
double out1_1 = iCustom(NULL,0,”Parabolic_trendchaser”,AlertsEnabled,Step,Maximum,Precision,TimeFrame,1,2);

out0_0は1つ前の出力0番目の値を取得しています。
out0_1は2つ前の出力0番目の値を取得しています。
out1_0は1つ前の出力1番目の値を取得しています。
out1_1は2つ前の出力1番目の値を取得しています。

ちなみに出力0は売りのラインで出力1は買いのラインです。

エントリー判定箇所

コードの58行目「/*買いエントリー*/」で買い判定を行っています。

if(out1_0>0 && out0_1>0)
1つ前に買いラインが点灯し、2つ前は売りラインが点灯している状態ということは、転換したというふうにみなします。

if(out0_0>0 && out1_1>0)
売りも同じで1つ前に売りラインが点灯し、2つ前は買いラインが点灯していた状態です。

決済判定箇所

コードの80行目「/*買い決済*/」で決済判定を行っています。
基本的に売買サインの逆転で決済するように書いています。
内容的にはエントリー判定箇所に考え方と同じなので説明は省略します。

まとめ

コードの説明を言葉で説明するのって難しい(;´Д`)

ある程度わかっている人ならわかってくれるんだろうけど、コード自体見たことない人にとっては異世界の話のように感じると思いますw

ガリガリ書くまでは行かないけど、とりあえずコードの買い替えは必須ということなので、使える人はガンガン使ってください。

使えない人は勉強してもらうか、問い合わせから質問くれればサポートします。

では、みんなの最適値を願って今日はこのへんで失礼します(´∀`*)ノシ