MQL4の記事一覧

バックテストをしてみる2

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

前回、EAを作ってみるでつくったEA(自動売買)、MA_EAをバックテストしてみました。

結果は、あまりよくありませんでしたね。

 

でも、EAを作ったときにパラメータをいくつか外出しにしたと思います。

覚えていますか?

 

もしかしたら、このパラメータをいじるといい感じの結果が出そうな予感がしませんか?

思わなくてもしたことにしてください。

話が進まないので。。。

 

で、パラメータのパターンをテストしていけばいいだけです。

たとえば、1つのパラメータで5パターンするとします。

 

1つで5パターン。

  楽勝!!

2つで25パターン。

  ちょっといやになってきますね。

3つで、125パターン。

  やる気でないですね。

4つで、625パターン。

  もう無理です。

 

やっぱり無理でした。。。

っていうことになりそうですが、メタトレーダーには、便利な機能があります。

 

スタート、ステップ、ストップの値をパターン分析したいパラメータにセットすると、すべての組み合わせを行ってくれる機能があるんです。

テスターに「Optimization」というチェックがあったのに気がつきませんでしたか?

このチェックが、パターン分析を行うチェックなんです。

 

では、チェックを入れてスタート!

と行く前に、

先ほどの説明のスタート、ステップ、ストップを設定して、どのパラメータを変更して解析させるかを指定する必要があります。

 

では、「Expert properties」ボタンを押して、プロパティウィンドウを開いてください。

次に、「パラメータの入力」タブを押してください。

では、設定していきます。

 

BuyLots:変更しません。

LossEntry:変更しません。

残りは、すべてチェックします。

MaPerirod:スタート(7)、ステップ(7)、ストップ(35)

TakeMa:スタート(5)、ステップ(5)、ストップ(25)

LossMa:スタート(5)、ステップ(5)、ストップ(20)

TakeEntry:スタート(25)、ステップ(5)、ストップ(50)

 

では、早速スタートを押してみましょう!

 

以下のタグに利益が出ているものだけ表示されます。

Optimization Results:損益やトレード回数、ドローダウンと利用したパラメータ

Optimization Graph:損益のグラフ

 

すべての解析が終了するまで、待ってください。

 

Optimization Resultsの損益をクリックしたください。

利益の多い順や少ない順にソートされます。

他の項目も同様です。

 

利益の多い順に並べます。

 

では、一番利益の多い行をダブルクリックしてください。

セッティングタブに戻ると思います。

「Optimization」のチェックが外れていることを確認してください。

 

先ほどのダブルクリックで、「Expert properties」のパラメータに選択行のパラメータが自動的にセットされました。

 

では、このパラメータでバックテストをとしてみましょう。

スタートボタンを押してください。

 

今度は、利益が出ましたね。

100pipsぐらいは増えたと思います。

 

サンプル用に適当に作ったEAとしては、まずますですかね。

 

バックテストは、こんな感じで行います。

 

ちなみに、一番利益が上がっているからいいパラメータではありません。

ドローダウンが大きく損失も大きいかもしれません。

 

たまたまその月はよかったと思いますが、未来もよいとは限りません。

また、テストの期間などもどのぐらいがいいのか?というのもEAの特性で変わってくるでしょう。

 

この辺はやってみないと分かりませんね。

 

とりあえず、これというパラメータが決まったあとは、フォワードテストというのを行います。

次回は、フォワードテストについて書きたいと思います。

タグ

EAを作ってみる2

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

前回のEAを作ってみるで説明不足のところを説明します。

 

まず、スリップについてです。

成行でオーダーするときに、メタトレーダーではAskかBidの金額を指定してオーダーします。

しかし、為替は動いていますので、この金額からずれていることがあります。

ですが、注文をなるべく成功させたいと考えたときに、ズレの許容値を指定することができます。

これが、スリップです。

 

スリップは、オーダーするときもクローズするときも指定可能です。

OrderSend(Symbol(),OP_SELL,BuyLots,Bid,3,Bid+LossEntry*Point,Bid-TakeEntry*Point,”MA_EA Sell”,MagicNo,0,Blue);

OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);

の3がスリップの値になります。

 

ですから、Bidから+-3pipsのズレまで、許可するということになります。

このズレ以上の場合は、オーダーされないことになります。

 

クローズの方が失敗するのがいやな人は、多めを指定した方がいいでしょう。

 

次は、自分でオーダーした注文かどうかを判断する方法です。

前回は、マジックナンバーというのを利用しました。

他にもオーダーしたときにもらえるチケットナンバー、コメントなどをキーに探すことが可能です。

ただし、チケット番号は再起動したときに分からなくなってしまうので、マジックナンバーを利用するのがいいでしょう。

※グローバル変数を使うことで、2週間覚えておく方法もあります。

 

なぜ、このようなことを行うかというと、利用中の口座のオーダーはすべて見ることができてしまうからです。

別の通貨ペアでも、別のEAでも、手動オーダーでもなんでも見ることができます。

ですから、自分のEAが注文したものかどうかを判断する必要があるんです。

 

初めてのEAなので、こうしたことをやならくてもよかったのですが、今後EAを作る場合、こうした仕組みで作ることになると思い、初めからちゃんとした機能を持たせました。

そのため、少し難しくなっています。

 

ちなみに、すべて見えることの応用ですが、たとえば週末にすべてのオーダーをクローズするEAなんていうのも作ることができます。

週末の持ち越しはしたくない!って方で、販売されているEAを利用している方は、こうしたEAを作れると便利かもしれませんね。

タグ

EAを作ってみる

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

今回は、EA(自動売買)のプログラムを作ってみたいと思います。 今回は、単純移動平均のラインをブレイクしたときに順張りするEAを作成します。  

単純移動平均をブレイクしたときに、成行でオーダーし、テイク(利益確定)ポイントとロスカットポイントを指定します。

これは、通信できなかったときの保険で、実際の利益確定やロスカットはEAが値を確認して行います。  

 

注意事項ですが、ここで作成したプログラムを実運用で利用してもかまいませんが、利益を保証するものではありません。

ご自分の判断で、利用してください。

損害等は、一切保証しません。

 

では、プログラムの作成を行いましょう。  

MetaEditorを開き、Expert Advisor Wizardを開きます。  

Expert Advisor作成

Expert Advisor作成

Expert Advisorを選択し、次へを押します。

 

EAの名前を決める

EAの名前を決める

NAMEに「MA_EA」と入力します。

パラメータを指定できますが、今回はコード上で指定しますので、そのまま完了を押してください。

スケルトンが作成されます。

 

前半の設定を行います。

 

//オーダーするときのロット数をパラメータとして指定します。

//0.1ロットが1万通貨となります。

extern double BuyLots=0.1;

//単純移動平均のサンプリングする足の数をパラメータとして指定します。

extern int MAPeriod=21;

//EAが利益確定するポイント数をパラメータとして指定します。

extern int TakeMA=20;

//EAがロスカットするポイント数をパラメータとして指定します。

extern int LossMA=10;

//オーダー時に保険として設定する利益確定ポイントを指定します。

extern int TakeEntry=25;

//オーダー時に保険として設定するロスカットポイントを指定します。

extern int LossEntry=25;

 

//オーダー番号を格納する変数を設定します。

int ticket=0;

//このEAのオーダーを判断するための番号を設定します。

int MagicNo=1;

 

今回は、初期処理と終了処理ではなにも行いません。

実行処理を指定します。

 

int start()

  {

//ポジションを持っているか判断するフラグを設定します。

//0がポジションなし、1がポジションを持っていることにします。

    int KeepPosition=0;

//現在持っているオーダー数を取得します。

    int total=OrdersTotal();

    int i;

//現在持っているオーダーの中からこのEAがポジションを持ったオーダーを探します。

    for(i=0;i < total;i++){

//オーダーを選択します。

        if(OrderSelect(i, SELECT_BY_POS)==true)

        {

//オーダーの通貨ペアが同じで、このEAが指定したマジックNoが同じものを探します。

            if(Symbol() == OrderSymbol() && OrderMagicNumber() == MagicNo)

            {

//このEAがオーダーしたものが見つかったときはオーダーを持っていることにします。

                KeepPosition = 1;

//チケット番号をセットします。

                ticket=OrderTicket();

//ループを抜けます。

                break;

            }

        }

    }

 

//現在から過去の単純移動平均を5本分取得します。

    double Ma0=iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,0);

    double Ma1=iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,1);

    double Ma2=iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,2);

    double Ma3=iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,3);

    double Ma4=iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,4);

 

//ポジションを持っている場合、クローズするか確認します。

    if(KeepPosition == 1)

    {

//オーダーから何本足を描画したかを求めます。

//オーダーから最小値、最大値を求めるために利用します。

        int ChkAshi = (OrderOpenTime()-TimeCurrent())/(Period()*60);

//売りポジションの場合

        if(OrderType() == OP_SELL)

        {

//オーダーしてから、TakeMAの2倍の値を出して、TakeMAまで戻ってきたときにクローズします。

//利益確定は、戻ってきたときとオーダー時に設定したポイントの2つが利益確定ポイントです。

            if(OrderOpenPrice()-TakeMA*Point >= Ask && OrderOpenPrice()-TakeMA*2*Point >= Low[iLowest(NULL,0,MODE_LOW,0,ChkAshi)])

            {

                OrderClose(OrderTicket(),OrderLots(),Ask,3,Green);

            }

//LossMAで指定したポイントを割ってしまったときにロスカットします。

            if(OrderOpenPrice()+LossMA*Point <= Ask)

            {

                OrderClose(OrderTicket(),OrderLots(),Ask,3,Green);

            }

        }

//買いポジションの場合

//売りポジションと同じことを行います。

//符号の向きが逆なのとAskではなくBidを利用しているところが違います。

        else if(OrderType() == OP_BUY)

        {

            if(OrderOpenPrice()+TakeMA*Point <= Bid && OrderOpenPrice()+TakeMA*2*Point <= High[iHighest(NULL,0,MODE_HIGH,0,ChkAshi)])

            {

                OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);

            }

            if(OrderOpenPrice()-LossMA*Point >= Bid)

            {

                OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);

            }

        }

    }

 

//ポジションを持っていない場合、ポジションを持つかどうか確認します。

    else if(KeepPosition == 0)

    {

//下降トレンドの場合

        if(Ma4 > Ma3 && Ma3 > Ma2 && Ma2 > Ma1 && Ma1 > Ma0)

        {

//Ma4、Ma3、Ma2のクローズが大きくて、Ma1と現在値(Bid)が小さい場合売りポジションを持ちます。

            if(Ma4 < Close[4] && Ma3 < Close[3] && Ma2 < Close[2] && Ma1 > Close[1] && Ma0 > Bid)

            {

                ticket=OrderSend(Symbol(),OP_SELL,BuyLots,Bid,3,Bid+LossEntry*Point,Bid-TakeEntry*Point,”MA_EA Sell”,MagicNo,0,Blue);

                if(ticket==0) Print(”Error opening SellChk order : “,GetLastError());

            }

        }

//上昇トレンドの場合

        else if(Ma4 < Ma3 && Ma3 < Ma2 && Ma2 < Ma1 && Ma1 < Ma0)

        {

//Ma4、Ma3、Ma2のクローズが小さくて、Ma1と現在値(Bid)が小さい場合買いポジションを持ちます。

            if(Ma4 > Close[4] && Ma3 > Close[3] && Ma2 > Close[2] && Ma1 < Close[1] && Ma0 < Ask)

            {

                ticket=OrderSend(Symbol(),OP_BUY,BuyLots,Ask,3,Ask-LossEntry*Point,Ask+TakeEntry*Point,”MA_EA Buy”,MagicNo,0,Red);

                if(ticket==0) Print(”Error opening BuyChk order : “,GetLastError());

            }

        } 

    }

 

   return(0);

  }

 

OrderSelectで、選択しているオーダーはOrder???関数で値を取得することができます。

Low[iLowest(NULL,0,MODE_LOW,0,ChkAshi)、High[iHighest(NULL,0,MODE_HIGH,0,ChkAshi)]は、オーダーしてからの最安値、最高値を求めています。

OrderSendは売買注文を行う関数で、成行、IFD、OCOなどのオーダーを組み合わせて注文することができます。

今回の例では、成行+OCO注文を行っています。

また、ticketが0の場合は注文失敗で、GetLastErrorを利用してエラー番号を取得しています。

Printは、操作履歴に結果を出力する関数です。

操作を残したいときに利用すると便利です。

次は、バックテストのやり方を説明したいと思います。

 

 

今回のプログラムは、以下からダウンロードできます。

ここから、ダウンロード

 

EA(自動売買)は、

インストールパス\MetaTrader\experts

に入れてください。

 

タグ

トレンドラインを書いてみる3

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

さて、前回と前々回で、トレンドラインを書くプログラムの基本とプログラムを書くときに気をつけたほうがいいことを書きました。

 

今回は、トレンドラインの総仕上げとして、ループ回数を最小にして、好きな本数のトレンドラインを書くインジケータを作成します。

少々、難易度が上がりますが、がんばってついてきてください。

 

トレンドラインを書いてみるを参考にインジケータのスケルトンを作成してください。

前回のソースにそのまま上書きでもかまいません。

 

まず、前半の定義部分です。

#property indicator_chart_window
extern int nPeriod=9;
extern int Limit=350;
extern int nLine=3;

nLineを追加しました。

これは、トレンドラインの数です。

デフォルトでは、3本ずつ書きます。

 

初期化部分です。

int init()
{
    int i;
    for(i=0;i<nLine;i++)
    {
        ObjectCreate(”Trend DN-”+i,OBJ_TREND,0,0,0,0,0);
        ObjectSet(”Trend DN-”+i,OBJPROP_COLOR,Maroon);
        ObjectSet(”Trend DN-”+i,OBJPROP_WIDTH,3);

        ObjectCreate(”Trend UP-”+i,OBJ_TREND,0,0,0,0,0);
        ObjectSet(”Trend UP-”+i,OBJPROP_COLOR,Green);
        ObjectSet(”Trend UP-”+i,OBJPROP_WIDTH,3);
    }

   return(0);
}

 

オブジェクトの作成ですが、前回と違って指定した数だけ作る必要があるため、ループをまわして指定した数のトレンドラインを書くためのオブジェクトを作成します。

名前が、「Trend UP-0″」など固定でしたが、数にあわせて名前を変更したいので、「Trend UP-”+i」としてループの値を名前に追加するように変更しました。

また、線が細くて見にくかったので、今回は少し太く描画させて見ます。

ObjectSet(”Trend DN-”+i,OBJPROP_WIDTH,3);

の部分で、線の幅をデフォルトの1ポイントから3ポイントに広げます。

 

次は、終了処理です。

int deinit()
{
    int i;
    for(i=0;i<nLine;i++)
    {
        ObjectDelete(”Trend UP-”+i);
        ObjectDelete(”Trend DN-”+i);
    }
   return(0);
}

初期処理と同じく、指定された数分だけ削除するようにループしています。

 

次は、本題のメイン処理です。

int start()
{

//今回は、線の数が分からないので、配列を使います。
//まず、空の配列を用意します。
//固定で指定する場合は、double r[10];の様に数字を指定します。
    double r[];
    int rt[];
    double s[];
    int st[];

//配列に必要な入れ物を指定した数だけ用意します。
//はじめと終わりの入れ物が必要なので、実際の線の数より1つ多い数を指定します。
    ArrayResize(r,nLine+1);
    ArrayResize(rt,nLine+1);
    ArrayResize(s,nLine+1);
    ArrayResize(st,nLine+1);

    int nCurBar;
    int ChkRLine=0;
    int ChkSLine=0;

    if(Bars<Limit) Limit=Bars-nPeriod;

//前回とは逆に最新のものから指定本数までループをまわします。
    for(nCurBar=0; nCurBar<Limit; nCurBar++)
    {

//一番低い谷を見つけます。
        if(Low[nCurBar+(nPeriod-1)/2] == Low[iLowest(NULL,0,MODE_LOW,nPeriod,nCurBar)])
        {
//値が1つだけでは線を引けないので、配列に代入だけします。
            if(ChkSLine==0)
            {
                s[ChkSLine]=Low[nCurBar+(nPeriod-1)/2];
                st[ChkSLine]=nCurBar+(nPeriod-1)/2;
                ChkSLine++;
            }
//2本目の値で、1つ目の値より小さい場合描画します。
            else if(s[ChkSLine-1] < Low[nCurBar+(nPeriod-1)/2] && ChkSLine <= nLine)
            {
//値の代入を行い
                s[ChkSLine]=Low[nCurBar+(nPeriod-1)/2];
                st[ChkSLine]=nCurBar+(nPeriod-1)/2;
//描画させます。
                ObjectMove(”Trend DN-”+(ChkSLine-1),1,Time[st[ChkSLine-1]],s[ChkSLine-1]);
                ObjectMove(”Trend DN-”+(ChkSLine-1),0,Time[st[ChkSLine]],s[ChkSLine]);
//ラインを1つ進めます。
                ChkSLine++;
            }
//もし、1つ前より小さい値が見つかったときに値を入れ替えます。
            else if(s[ChkSLine-1] > Low[nCurBar+(nPeriod-1)/2] && ChkSLine <= nLine)
            {
                s[ChkSLine-1]=Low[nCurBar+(nPeriod-1)/2];
                st[ChkSLine-1]=nCurBar+(nPeriod-1)/2;
            }
        }


//谷と同様に山を見つけます。
        if(High[nCurBar+(nPeriod-1)/2] == High[iHighest(NULL,0,MODE_HIGH,nPeriod,nCurBar)])
        {
            if(ChkRLine==0)
            {
                r[ChkRLine]=High[nCurBar+(nPeriod-1)/2];
                rt[ChkRLine]=nCurBar+(nPeriod-1)/2;
                ChkRLine++;
            }
            else if(r[ChkRLine-1] > High[nCurBar+(nPeriod-1)/2] && ChkRLine <= nLine)
            {
                r[ChkRLine]=High[nCurBar+(nPeriod-1)/2];
                rt[ChkRLine]=nCurBar+(nPeriod-1)/2;
                ObjectMove(”Trend UP-”+(ChkRLine-1),1,Time[rt[ChkRLine-1]],r[ChkRLine-1]);
                ObjectMove(”Trend UP-”+(ChkRLine-1),0,Time[rt[ChkRLine]],r[ChkRLine]);
                ChkRLine++;
            }
            else if(r[ChkRLine-1] < High[nCurBar+(nPeriod-1)/2] && ChkRLine <= nLine)
            {
                r[ChkRLine-1]=High[nCurBar+(nPeriod-1)/2];
                rt[ChkRLine-1]=nCurBar+(nPeriod-1)/2;
            }
        }

//上昇・下降ともに指定本数見つかった場合、ループを抜けます。
        if(ChkSLine > nLine && ChkRLine > nLine)break;
    }

   return(0);
}

 

メイン処理は、ループの中に納まっていて、必要な本数が見つかった後、breakで抜けいていることが分かると思います。

必要な数だけ、ループをまわすようにして負荷を抑えています。

値は、配列に格納しています。

本当は、配列に代入しなくても描画だけなら可能です。

ですが、今後の拡張のために値を残しておくようにしました。

値を残しておくことで、いろいろ拡張できると思います。

 

値の格納も1つ目の変数への格納と、条件を満たした場合に次の配列へ格納すること、一度格納した配列より大きい・小さい値の場合入れ替える処理を追加してあります。

 

少々複雑になりましたが、コンパクトにまとまっていると思います。

 

今回のプログラムは、以下からダウンロードできます。

 

インジケータは、

インストールパス\MetaTrader\experts\indicators

に入れてください。

タグ

かるく文法(省略記号編)

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

質問があったので、MQL4で有効な四則演算での省略記号の説明を追加します。

 

省略記号編

 

符号(+-)を2回繰り返すことで、1足したり、引いたりすることと同じになります。

i++;

→ i=i+1;

i–;

→ i=i-1;

 

複数の足し引きをしたい場合

i+=2;

→ i=1+2;

i-=3;

→ i=i-3;

 

このように同じ数の足し引きには、便利ですので覚えておくといいでしょう。

また、サンプルでもよく使われますので、意味を覚えておいてください。

 

ちなみに

i-;

では、通常の引き算としてあつかわれるので、iから右辺のものを引こうとしますが右辺が無いためエラーになります。

また、

i-1;

では、計算結果が左辺に出力されますが、結果を受け取ることができません。

 

省略記号以外は、

代入先の変数=計算式;

と記述してください。

 

if文などは、()内の変数を利用するため、代入先の変数を用意する必要はありません。

if(a==1)

は、

a==1の計算結果が、trueかfalseになり、その値が引数としてif文にわたされるので、代入先の変数は必要ありません。

関数の説明は、後ほど行います。

タグ

トレンドラインを書いてみる2

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

前回紹介した、トレンドラインを書いてみるはご覧になりましたか?

MT4でも手動で書くことができますが、やっぱり自動が楽ですよね。

 

でも、ちゃんと動くと思いますが、実はあまりいいプログラムではありません。

ちゃんと動く=いいプログラム

ではないということです。

 

では、何が悪いか。。。

 

ソースを見た時点で、だめだめジャン!!

って思った人は、プロかセミプロレベルの人ですね。

 

では、どこがダメなんでしょうか?

 

まず、for文でループを回している部分がありますよね。

ここが、ダメです。

for文じゃなくて、while文を使うってわけじゃありません。

基本的にループをまわすには、どちらを使ってもかまいません。

使いやすい方を使ってください。

 

では、ダメな部分。

調査する足の最大数からカウントダウンしてますよね。

古い方から新しい方へ調査しています。

 

別に古い方から新しい方へループをまわすことが悪いんじゃないんですが、今回はダメです。

実際に動かすと、トレンドラインを引く山や谷を見つけるのに、新しい方から数十本の足ですんでいますよね。

ということは、無駄なループをたくさん回しているということになります。

 

ループは、結構PCに負担なんです。

為替は、生き物ですから1秒でも無駄にしたくありませんよね。

だから、無駄を省く必要があります。

 

ですから、正解は新しい方から古い方にループを回して、必要な山や谷を見つけたらループを抜けるように組めばいいんです。

「break」という命令で、ループを抜けることができます。

 

もう一つあります。

ループの中で余分な変数に代入して、ループを抜けた後に上昇・下降か判断している部分があります。

ループ内で、判断すれば無駄が省けますよね。

 

プログラムは、動くことも大事ですがこうした無駄を省くように心がけると結果的に高速に動いたり、見やすいソースになります。

ぜひ、自分で組むときは心がけてください。

 

次は、もう一度トレンドラインを引くインジケーターを作ります。

上記で説明した、ダメな部分の修正ともう一つ。

表示してみると分かりますが、最新の1本だけだとトレードに使えません。

少なくても3本ぐらいないと、トレードの参考にならないはずです。

ですから、1本のトレンドラインから3本に増やします。

 

次回をお楽しみに!

タグ

トレンドラインを書いてみる

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

前回は、インジケーターを作ってみるで足に対応したバッファに代入することで、メタトレーダーの機能を使いグラフを自動的に描画方法を試してみました。

今回は、オブジェクトという機能を使い好きな場所に線や文字などを描画する方法を試してみます。

 

で、単純に線を書いてもおもしろくないのでトレンドラインを書いてみたいと思います。

 

トレンドとは、上下に動きながら移動している為替も平均してみると上昇していたり、下降しているときがあります。

こうした状態をトレンド相場と呼びます。

平均した線が横ばいの場合は、レンジ相場と呼びます。

 

為替は、上昇トレンド、下降トレンド、レンジ相場の3種類のどれかの状態になっています。

 

このトレンドを表す線をトレンドラインと呼びます。

上昇トレンドラインは、上下に動いている山の高値と高値を結んだ線。

下降トレンドラインは、谷の安値と安値を結んだ線のことをいいます。

 

このトレンドラインをインジケーターの機能を使って、描画したいと思います。

 

インジケーターを作ってみるを参考にスケルトンを作ります。

Nameを「TrendLine」。

その他は、何も入力しません。

 

まずは、TrendLineのスケルトンを作成してください。

 

まず、前半の宣言部分を作成します。

//メインウィンドウに描画します。

#property indicator_chart_window

//山と谷を見つける幅をパラメータとして指定します。

extern int nPeriod=9;

//先頭から何本まで山、谷を見つけるかパラメータとして指定します。

extern int Limit=350;

 

次は、初期化処理です。

int init()

{

//下降トレンドライン0番目のオブジェクトを作ります。

    ObjectCreate(”Trend DN-0″,OBJ_TREND,0,0,0,0,0);

//下降トレンドライン0番目のオブジェクトの色を指定します。

    ObjectSet(”Trend DN-0″,OBJPROP_COLOR,Maroon);

 

//上昇トレンド0番目のラインオブジェクトを作成します。

    ObjectCreate(”Trend UP-0″,OBJ_TREND,0,0,0,0,0);

    ObjectSet(”Trend UP-0″,OBJPROP_COLOR,Green);

 

   return(0);

}

上昇、下降用のトレンドラインを引くためのオブジェクトを用意しました。

次は、終了処理です。

int deinit()
{
//オブジェクトを削除します。
    ObjectDelete(”Trend UP-0″);
    ObjectDelete(”Trend DN-0″);
   return(0);
}

 

インジケータを削除したときに、オブジェクトが残ってしまいます。

そのために、インジケータ終了時に自分が作ったオブジェクトを削除する処理を追加します。

次は、トレンドラインを描画するための山、谷を見つけラインを引く処理です。

 

int start()
{

//山、谷の値と足番号を格納する変数と描画する値を格納する変数を宣言します。

    double r1,r2,r3,r_1,r_2;
    int rt1,rt2,rt3,rt_1,rt_2;
    double s1,s2,s3,s_1,s_2;
    int st1,st2,st3,st_1,st_2;
    int nCurBar=0;

 

//表示されている足の数が、Limitより小さい場合、nPeriod引いた値をセットします。
//検査用の領域を確保するためです。
    if(Bars<Limit) Limit=Bars-nPeriod;

 

//検査する足を古い方からセットしていきます。
    for(nCurBar=Limit; nCurBar>0; nCurBar–)
    {

 

//検査する足の数の中心の安値が、検査する足の範囲で最小の安値の場合
//最新の安値をs1に代入します。
//S1を代入する前に過去の安値をS3、S2と古い変数へスライドさせて格納します。
        if(Low[nCurBar+(nPeriod-1)/2] == Low[iLowest(NULL,0,MODE_LOW,nPeriod,nCurBar)])
        {
            s3=s2; s2=s1; s1=Low[nCurBar+(nPeriod-1)/2];
            st3=st2; st2=st1; st1=nCurBar+(nPeriod-1)/2;
        }

 

//安値と同様に高値を変数へ代入します。
        if(High[nCurBar+(nPeriod-1)/2] == High[iHighest(NULL,0,MODE_HIGH,nPeriod,nCurBar)])
        {
            r3=r2; r2=r1; r1=High[nCurBar+(nPeriod-1)/2];
            rt3=rt2; rt2=rt1; rt1=nCurBar+(nPeriod-1)/2;
        }
    }

 

//2つの安値を比べたときに最新の安値が下降している場合のみ描画します。
//そのために各谷の安値を比較して、下降している隣接している谷を見つけます。
//もし、存在しない場合はデフォルトでEMPTY_VALUEがセットされているため、描画されません。
    if(s1 < s2){
        s_1=s1;
        s_2=s2;
        st_1=st1;
        st_2=st2;
    }
    else if(s2 < s3){
        s_1=s2;
        s_2=s3;
        st_1=st2;
        st_2=st3;
    }

 

//描画開始位置と次の点を設定します。
    ObjectMove(”Trend DN-0″,1,Time[st_1],s_1);
    ObjectMove(”Trend DN-0″,0,Time[st_2],s_2);
//上昇トレンドラインも下降トレンドラインと同様にセットします。
    if(r1 > r2){
        r_1=r1;
        r_2=r2;
        rt_1=rt1;
        rt_2=rt2;
    }
    else if(r2 > r3){
        r_1=r2;
        r_2=r3;
        rt_1=rt2;
        rt_2=rt3;
    }
    ObjectMove(”Trend UP-0″,1,Time[rt_1],r_1);
    ObjectMove(”Trend UP-0″,0,Time[rt_2],r_2);
   return(0);
}

 

これで、終了です。

コンパイルして、インジケータを表示させてみてください。

以下のようにトレンドラインが表示されれば成功です。

TrendLineインジケーター

TrendLineインジケーター

ちょっとは、らしいものができたのではないでしょうか?

少しずつレベルをアップしていきますね。

 

今回のプログラムは、以下からダウンロードできます。

ここから、ダウンロード

 

インジケータは、

インストールパス\MetaTrader\experts\indicators

に入れてください。

 

→この記事の続きを読む

タグ

Expert Advisor Wizard

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

Expert Advisor Wizardは、インジケーターを作ってみるでも紹介していますが、MetaEditorでEAやインジケーターを作るときのウィザードです。

 

一応、注意事項というか便利かもという情報を

 

 

Expert Advisor Wizard インジケータ作成

Expert Advisor Wizard インジケータ作成

ここでは、まあ書いてある内容のものが作れます。

よく使うのは、

Expert AdvisorとCustom Indicatorでしょう。

 

Expert Advisorは、EAとか自動売買とかいわれるものを作成します。

インストールパス\MetaTrader\experts

にソースと実行ファイルができあがります。

ソースの拡張子は、mq4

実行ファイルの拡張子は、ex4

です。

 

Custom Indicatorはインジケーターというグラフを各プログラムを作成します。

ソースと実行ファイルは、

インストールパス\MetaTrader\experts\indicators

に格納されています。

拡張子は、EAと同様です。

 

EA、インジケーターの違いは、

EAは、売買ができる。

インジケータは、足に合わせたバッファと描画指示ができる。

で、逆はできません。

 

で、Expert Advisor Wizardは何を作るか決めた後、名前やパラメータなどの情報をセットするとスケルトンができあがるわけです。

決まった部分などは、自動的に作成してくれるわけですね。

 

でも、たとえば、私が書いたソースを試したい!

そんなとき、パラメータをいちいち入力するのが面倒じゃないですか。

そういうときは、どうするか。

 

Nameに名前を入れます。

これは、ファイル名なので入れないわけにはいきません。

その他は、入力する必要はありません。

 

たとえば、インジケーターを作るときの前半にあるこんな命令。

#property indicator_chart_window

#property indicator_buffers 1

#property indicator_color1 Red

自分で書けば、ウィザードで入力しなくても大丈夫です。

 

サンプルを使いたいときは、ファイル名だけでファイルを作って、ソースはコピーするやり方もあるっていうことですね。

自分で作ったものをベースに作りたいときも同じです。

 

ソースファイルも配っているから、そんな面倒なこともしたくない!!

って人は、もっと簡単な方法があります。

 

EAは、

インストールパス\MetaTrader\experts

インジケーターは、

インストールパス\MetaTrader\experts\indicators

にソースファイルや実行ファイルをコピーしてください。
それで、MetaEditorを再起動してください。

 

再起動しないといけないところが、煩わしいところですね。
ファイル名だけ作る方法だと再起動がいりません。

 

EAなどを動かしていて、止めたくない!!
ってときは、ファイル名方式
どうでもいいときは、コピー&再起動方式
と使い分けが必要かな。

 

どちらの方法でも結果は同じなので、いい方法をお使いください。

タグ

かるく文法(まとめ)

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

メタトレーダーのMQL4は、CやC#と同じような書式で、

関数は、{}の中が有効で、計算や条件は()でくくります。

if(a==0)

{

//処理

}

上記のように条件は()でくくります。

a==0は最終的に、true、falseのどちらかとしてあつかわれ、条件があっている場合は、true、

間違っている場合は、falseになります。

{}の間は、関数(上記の例ではif)の処理が有効な範囲として表します。

 

また、計算も()でくくることができて

a=(10/(2+3));

の様に表すことができて、

a=10/5;

となり

a=2;

と同じ意味になります。

 

四則演算は、かるく文法(四則演算編)を参照してください。

条件判断は、かるく文法(if文編)を参照してください。

ループ(繰り返す処理)は、かるく文法(for文編)かるく文法(while文編)を参照してください。

タグ

かるく文法(while文編)

4XP => メタトレーダー対応、固定スプレッド、最小1000通貨
50種類以上の通貨ペア、各種CFD(金、株など)対応

かるく文法(for文編)と同じようにぐるぐる回す系です。

メタトレーダーのMQL4でもそうですが、文法的にはCやC#と同じなので、この辺のプログラムを使っている方は、おなじみの文法です。

 

while編

while(条件)

{

}

の様に使います。

条件を満たしている間は、ぐるぐる{}の間を回り続けます。

 

int i=10;

whie(i>=0)

{

//処理

i–;

}

このように記述するとiが10から0の間、処理を続け-1になったときに抜けます。

このような記述の場合は、for文を利用してもかまいません。

 

int flg=1;

int a=0;

while(flg==1)

{

//処理

a++;

if(a==10) flg=0;

}

 

上記のようにaが10になったときにflgへ0を代入して、ループを抜けるような使い方も行います。

 

while文の場合は、下の例のような使い方が一般的かもしれません。

タグ