本ブログは、MetaTrader を利用して、EA プログラムを自作紹介するサイトです。
決して儲かるシステムを紹介するものではありませんのであしからず・・・
もし、記事中に嘘偽りを発見された方、ご連絡頂けると幸いです。
なお、過去に作成した EA プログラムの作り方はこちらになります。

Loop_Entry : 同じ指値エントリーを繰り返し実行するプログラムです。
estTurn : 高値(安値)で反対売買を実行するプログラムです。

2010年4月26日月曜日

iMA() の使い方

早速、トレンド察知用のプログラムロジックを考えてみたいと思います。

まずは移動平均線の情報を取得する方法を調べてみます。

移動平均線の情報は iMA() を使うことで取得でき、例えば、20 時間分の移動平均値の終値を取得するには次のように記載します。

iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE,0);

NULL:チャート上で表示されている通貨を使う
0:チャート上で表示されているローソク足の時間枠を使う
20:移動平均値を計算するために利用するローソク足数
0:画面にグラフ表示する際のシフト値
MODE_SMA:移動平均値の計算方法で MODE_SMA は単純移動平均で計算
PRICE_CLOSE:移動平均値を出す際に利用する価格で PRICE_CLOSE は終値を指す
0:現在のローソク足から何本前の移動平均値を取得するか指定

今回は「XX 回移動平均値を超えたら」という判断が必要になるため、iMA() の一番最後のパラメーターを順次変更しながら過去 XX 回分の移動平均値を取得することになります。

つまり、最後の 0 の部分を過去 XX 回分指定できるように次のように変数指定にし、必要回数分回すようにします。

y=10;
for(x=0; x<y; x++)
{
iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE,x)
}

上記は、x の値が 0(現在のローソク足)から 10(過去 10 個分)までローソク足の移動平均値を取得します。

2010年4月25日日曜日

トレンド察知ルール

前回からトレンド形成を察知する手段がないか、無い知恵を絞りながら移動平均線をジィーーーーーと眺めていて気づいたのは、「トレンド形成中は平均線より 上か下にローソク足が続けて存在する」という事ぐらいでした。

#誰でも思いつく当たり前のことですが・・・

あと、 ジーーーーーと眺めている時に思ったことは、「せめてトレンドが形成されている期間に1回でもいいから取引して利益が出せれば・・・」くらいです。

今 の私に考え付くことはこれで精一杯です・・・
なので、この2つの思いつきに沿ったプログラムのルールを考えてみることにします。

ま ずトレンド形成を察知する手段として「移動平均線よりローソク足が続けて存在」をもう少し具体的にしたいと思います。

図の赤枠の期間がトレンドが形成されている状態だと思いますが、この期間を見てみると移動平均算出期間が長い平均線ほど、ローソク足が平均線の上下に存在し続けています。

例えば赤枠の期間中、 5 時間線はトレンドの途中でローソク足が平均線をまたがってしまうけど、20 時間線は 1 度もローソク足が平均線をまたぐことはありません。

そのため、

1.安値が移動平均線(20時間)を上回っているローソクが XX 回続いたら買いトレンド発生
2.高値が移動平均線(20時間)を下回っているローソクが XX 回続いたら売りトレンド発生

をルールとしたいと思います。

# XX 回の部分は実際にプログラムを作ってバックテストで調整してみようと思います。

2010年4月14日水曜日

トレンド発生を知るにはどうすれば

今日は昼食に坦々麺を食べたんですが、めっちゃ辛かったです。

メニューに辛いと書いてあったので、分かってて注文したのですが予想以上の辛さで、汗と涙が止まりませんでした。

今、ちょっとお腹痛いです・・・

------------------------------------------------------------------------

さて、前回の EA の事は忘れ、新たな EA でも作ろうかと思います。

とは言っても、前回の EA で課題だった「トレンドを形成した場合」の対処方法として、特にいい方法が思いつかなかったのでボリンジャーバンドを利用しましたが、トレンドが発生して いるかどうかを知る手段は何かないのでしょうか?

もしかしたら何かよい統計手法ロジックやチャット分析ツールがあるのかも知れませんが、知識の無い自分には思いつきません。

パッと思いつくのは「移動平均」くらいしかないので、とりあえずチャートに表示して眺めながら何か良いルールが無いか考えてみます。

ちなみに、MetaTrader のチャート上に「移動平均」を表示するには、ナビゲータウィンドウから<罫線分析ツール>-<Moving Average>を右クリックで選択し<チャートで表示>をクリックすると表示されます。

下の図は、終値について 5時間、10時間、15時間、20時間の移動平均を表示したものです。


何か思いつかないか、じぃーーーーーーっと眺めてみます。

2010年4月13日火曜日

結果は微妙です

estTurnプログラムにボリンジャー値を利用したルールを追加し、前回と同様の条件でバックテストを行ってみました。

結果は、一応利益が出たようですが、予想通り極端に注文回数が減ってしまいました。


もう少し注文回数を増やしたいなと思い、テスト条件を5分足で行ってみたところ、今度は利益がマイナスになってしまいました・・・



どんな局面でも利益をだせる EA ではなさそうです。どうやら、estTurn プログラムはお蔵行きですかね・・・

また、新しいルールを考えて見ます。

2010年4月12日月曜日

ボリンジャールール組込み完了

今日の夕食はチンジャオロースーでした。
私が作れる数少ないレパートリーです。

気が向いた時にたまに作るのですが、子供達には結構評判よいです。

といっても、野菜切ってレトルトのソースと絡めるだけなので、殆ど料理の腕は関係ありませんが・・・

----------------------------------------------------------

さて、バックテストでイマイチの結果だった estTurnプログラムの勝率を上げるためにボリンジャーバンドを使ったルールを追加してみます。

プログラムの書き方は「直近50足分の高値(安値)と比較」する方法と大して変わりません。

次のように現在価格とボリンジャーバンド値を if で比較するだけです。(売り注文するための条件の場合)

if(Bid>iBands(NULL,0,20,3,0,PRICE_HIGH,MODE_UPPER,0))
{
注文する・・・
}

あとは、どこに上記内容を記述するかですが、「直近50足分の高値(安値)と比較」した後に、高値(安値)を指している場合のみにボリンジャー値の比較をする方法で良いかと思います。

結果、次のようになりました。


テスト結果は・・・

2010年4月11日日曜日

追加のルールにボリンジャーを利用

夕べも麻雀ゲームに夢中でした。
気がついたら朝の4時・・・

ハマリ過ぎないように気をつけます。

----------------------------------------------------

テストした estTurnプログラムの結果チャートを眺めていると、"トレンドが形成されている時"に負けが込んでいるみたいです。

例えば下の図のような時です。

トレンドが形成されている時の注文を抑える事ができれば、もう少し勝率も上がるかな。

ということで、"トレンドが形成されている"ということをどのように察知すればよいか考えたのですが、よい案が浮かびません・・・

そこで、以前調べたボリンジャーバンドを利用してみたいと思います。

追加ルールとしては、

・ボリンジャーバンドの20日における高値3σ(安値3σ)を超えていたら注文する

です。

先ほどと同じチャート上でボリンジャーバンド3σを表示してみると次のようになります。

これなら、ダラダラとトレンドが形成されている時に注文をすることはないのではないかと思います。

#ただ、極端に注文数が減る気もしますが・・・

とりあえずプログラムを修正してみます。

2010年4月10日土曜日

テスト結果

夕べは麻雀でした。
といってもオンラインゲームですけど・・・

最近麻雀を覚えたんですが、結構ハマッテしまってます。

細かいルールや点数計算など、まだまだ分からない部分はありますが、それなりに楽しめます。

寝不足が続きそうです。

--------------------------------------------------------------

さて、前回までで一応当初に考えたルール通りのプログラムは完成したと思いますので、コンパイルして早速テストしてみたいと思います。

MetaTrader におけるバックテストの見方は、こちらこちらを参照ください。

とりあえず、ここ3週間分位のデータでテストしてみました。

テストの条件は、こちら。

結果は・・・


残念ながら、世の中そんなにあまくはありません。

期間を長くして再テストしてみましたが、続ければ続けるほど負けが込む感じですね・・・

折角作ったプログラムなので、もう少し結果を調べて対策を考えルールを追加してみたいと思います。

2010年4月9日金曜日

プログラム完成

前回、High と iHight を利用することで、直近50足分の最高値(最安値)は得られるようになりました。

最後の仕上げです。

直近50足分の最高値(最安値)と現在価格を比較し反対売買のタイミングに利用します。

現在価格は Bid で買値が得られます。そのため、if を使って比較し最高値を超えたら売り注文を出すために次のように記述します。

if(Bid>High[iHighest(NULL,0,MODE_HIGH,50,1)])
{
OrderSend(Symbol(),OP_SELL,0.1,Bid,3,・・・
}

逆 に、最安値の場合には、Ask で売値が得られるため次のように記述します。

if(Ask<Low[iLowest(NULL,0,MODE_HIGH,50,1)])
{
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,・・・
}


これで、一応プログラムは完成です。

#ついでに、マジックNoを定数化しました。

次回、テストしてみます。

2010年4月4日日曜日

直近50ローソク足で最高値

今日は朝から子供達の部屋掃除を手伝いました。

新学期を迎えるにあたり、机の中や使わなくなった教科書などの整理、ついでに布団も古くなったので粗大ごみに出す準備など結構腰にきました・・・ 

年ですかね・・・

--------------------------------------------------------------

さてさて、前回までのプログラムで最初に決めたルールのうち次の部分が完成しました。

・注文は成行注文
・注文時に指値決済+35 ポイント、逆指値決済-25ポイントを指定
・チャートは15分足
・取引通貨はAUD/JPY
・決済されるまでは次の注文を入れない

残りは「直近50足分で最高値(最安値)をつけたら、反対売買で注文」の部分になります。

まずは「直近50足分で最高値(最安値)」という部分について調べてみたいと思います。

高値を調べるには、High[0] を使えば分かります。(安値はLow[0])

ただし、High[0] は表示されているチャートの現在のローソク足における高値が分かるだけで、直近50足分で最高値かどうかは分かりません。

High[0] の数字の部分を増やしていき、次のように50足分の高値を調べることは可能です。

High[1]:1個前のローソク足における高値
High[2]:2個前のローソク足における高値
High[3]:3個前のローソク足における高値

High[50]:50個前のローソク足における高値

面倒です・・・

そこで、便利な iHighest() を使いたいと思います。

iHighest() は「最高値をたたき出した足が何本前にあるかを調べてくれる」とっても便利な関数です。

使い方は、iHighest(NULL,0,MODE_HIGH,50,1) となり、それぞれの内容は次の通りです。

NULL:通貨ペアを指定(NULLを指定するとチャートに表示されている通貨)
0:時間足を指定(0はチャートに表示されている時間足)
MODE_HIGH:調べたい値を指定(MODE_HIGHは高値)
50:過去何本の足を調べるかを指定
1:現在の足から数えて何本前の足から調べるかを指定

つまり、次のように High[] と ihighest() を組み合わせて使います。

High[iHighest(NULL,0,MODE_HIGH,50,1)]

同様に、最安値を調べるには次のようになります。

Low[iLowest(NULL,0,MODE_LOW,50,1)]

これで、「直近50足分の最高値(最安値)」が得られました。

2010年4月3日土曜日

同時注文は回避できたと思います

では前回の続きで、同じプログラムで保有中のポジションがあるかどうかを調べる方法を書いてみます。


①でトレードプールにあるポジションの数を取得し、j に保持しておきます。

③でトレードプールにあるポジション情報を取得していますが、OrderSelect()では1回につき1つのポジション情報しか取得できないので、②のfor()を使って①で調べたポジションの数だけ、OrderSelect()を繰り返しながらポジション情報を取得します。

OrderSelest()の使い方については、こちらをご覧ください。

ポジション情報を取得した後に、④の OrdermagicNumber()を使って、マジックNoが"12345"と同じかどうか調べています。
同じであれば、return(0)にてプログラムを終了しています。

これで、同じプログラムで同時に注文を行ってしまう現象は回避できると思います。

2010年4月2日金曜日

ルール追加

さて、注文し続けるのを止めるために「決済されるまでは次の注文を入れない」というルールを追加しようと思います。

決済前のポジションを保有しているかどうかは、OrdersTotal()で判断できます。

ただし、OrdersTotal()はポジションの数を調べるもので、他のプログラムで注文したものまでカウントしてしまいます。

そのため、本プログラムで注文したポジションだけを調べるためにマジックNoを利用します。

前回記載した注文内容に、マジックNo("12345")を追記します。

OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Bid+25*Point,Bid-35*Point,NULL,12345,0,Aqua);
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Ask-25*Point,Ask+35*Point,NULL,12345,0,DeepPink);

これで、注文したポジションに"12345"のマジックNoが付与され、後で識別することができるようになります。

次に現在保有中のポジションを調べます。

保有中のポジションは、トレードプールと呼ばれる場所に保持されていますので、次の手順で保有ポジションのマジックNoを調べます。

1.トレードプールのポジション数を調べます
2.OrderSelect()を使いトレードプールからポジションの情報を順番に取り出します。
3.ポジションの情報を取り出したら、OrderMagicNumber()でマジックNoを確認します。
4.マジックNoが"12345"ならば、注文せずに終わります。

次回、上記手順をプログラミングしてみます。

2010年3月31日水曜日

まずは注文部分を記載

今日の夕食はピザでした。
ピザにはビールがぴったり!!
ついつい、食べすぎちゃいました・・

----------------------------------------------------

さて、簡単ですがルールは決めましたので、早速 EA 作りたいと思います。

まずは、MetaEditor を起動し、メニューより-にて新規に EA を作成します。

EA の名前は・・・、「estTurn」とでもしましょうか。

とりあえず、注文処理部分を記述してみます。

注文ルールは、「成行」で「指値決済+35ポイント」「逆指値決済-25ポイント」でしたので、OrderSend()を使って記述します。

まずは、売り注文から。

OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Bid+25*Point,Bid-35*Point,NULL,0,0,Aqua);

記述内容を解説すると、

Symbol():チャート上の通貨
OP_SELL:売り注文
0.1:取引数量(1000通貨)
Bid:現在の売値(成行)
3:スリッページ
Bid+25*Point:逆指値決済額
Bid-30*Point:指値決済額
NULL:コメントなし
0:マジックNo
0:注文キャンセル時間
Aqua:チャート上の注文矢印色

になります。

あと、買い注文も次のように記述しておきます。

OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Ask-25*Point,Ask+35*Point,NULL,0,0,DeepPink);

これで、売りと買いの注文ができるようになりました。



もちろん、これだけでは”限度額いっぱい注文を繰り返してしまいます”ので、注文数を制御する記述を次回追加します。

2010年3月29日月曜日

単純なルールで作ってみます

さて、久しぶりにブログ再開したものの、何しようかな・・・

リハビリを兼ねて、簡単なルールを考えてEA作ってみます。

まず、 ルールですが、

・直近50足分で最高値(最安値)をつけたら、反対売買で注文
・注文は成行注文
・注文時に指値決済+35 ポイント、逆指値決済-25ポイントを指定
・チャートは15分足
・取引通貨はAUD/JPY

てな感じでいきたいと思いま す。

チャートイメージで表すとこんな感じです。


利益がでるかどうかは作ってからのお楽しみです。

2010年3月28日日曜日

再開しようかな・・・

久しぶりに自分のブログサイトを見たら、最後に投稿してから1年も経過していました・・・

今となっては、なぜ投稿しなくなったのかも思い出せない。

やっぱり長続きしない性格なのか?

まあ、そんなに気にしなくてもいいか。

最近、自分の中でFXトレード熱が再燃してきたので、このブログも再開してみようと思います。

2009年3月1日日曜日

次に作るプログラムのルールを決めました

次に作るプログラムのルールを考えました。

ボリンジャーバンドをベースにしたルールですが、素人が考えることですから
大した物ではありませんが・・・

ルールを説明する前に、まずは次の図を。

上記図は、USD/JPY の 1 分足でボリンジャーバンド 2σ(赤線)と 3σ(水色線)を
表しています。

今回のプログラムでターゲットにするのは、上図のピンク色で囲んだ丸の部分です。

一言で説明すると「3σ を 2 回超えたら逆張りでエントリーする」です。

もう少し具体的に説明すると次のようになります。

1.過去 10 ローソク足のボリンジャーバンド値(20 日間/終値/3σ)を
  それぞれ調べる

2.さらに、同じローソク足期間の最高値を調べる

3.そして、過去 10 ローソク足において、それぞれの高値が 3σを超える
  ローソク足が何本あるか調べる

4.もし、3σ を超えるローソク足が 2 本以上あり、かつ調べた最高値より
  高い市場価格であれば売り注文する

5.画面で入力した利確ポイントまたは損切りポイントを超えたら決済する

これを、買いと売りの 2 本立てでポジション保持できるようにしたいと思います。

本当はトレンドを調べて買いと売りのエントリーを判断したいですが、トレンドを
計るすべがわからないので、とりあえずボリンジャーバンドの上ラインを超えたら
売り、下ラインを超えたら買いで作ってみたいと思います。

名づけて、"Bolli_Entry"です。

2009年2月21日土曜日

ボリンジャーバンドの値を取得する

次に作るプログラムを考えています。

どんなルールにするかまだ決まっていませんが、ボリンジャーバンドを
利用したものを作りたいのだけは決めています。

ボリンジャーバンドは統計学を応用したものらしく、難しいことは
わかりませんが、トレンドの変換点として利用されており、私も
チャートを表示するときはボリンジャーバンドを表示しています。

そのため、プログラムでボリンジャーバンドの情報を扱うには
どうすればよいのか調べてみたいと思います。

なお、MetaTrader のチャート画面でボリンジャーバンドを表示する方法は
こちらをご参考ください。

ボリンジャーバンドは iBands() を使うことで情報が取れるみたいです。

マニュアルを見てみると、次のように記載してあります。

iBands( symbol, timeframe, period, deviation, bands_shift,
applied_price, mode, shift)

symbol:通貨ペアを指定
timeframe:ローソク足の種別( 1 分足、5 分足など)
period:ボリンジャーバンド値を計算するのに利用するローソク足数
deviation:標準偏差
bands_Shift:いくつチャート表示をずらす?
applied_price:ローソク足のどの値(高値、終値など)を取得するか
mode:ボリンジャーバンド上下ラインのどちらの情報を取得するか
shift:何本前のローソク足からボリンジャーバンド情報を取得するか

MetaTrader のチャート画面でボリンジャーバンドを表示する際に設定する
画面で説明すると

period:期間
deviation:偏差
bands_Shift:表示移動
applied_price:適用価格

になります。

実際にプログラムに書く場合には次のようになります。

double boll_price = iBands(NULL,0,20,2,0,PRICE_LOW,MODE_LOWER,0)

symbol:NULL(現在の通貨ペア)
timeframe:0(プログラムが表示されているチャートのローソク足種別)
period:20(20 個分のローソク足でボリンジャーバンド値を計算)
deviation:2(2 シグマ標準偏差)
bands_Shift:0(表示はずらさない?)
applied_price:PRICE_LOW(ボリンジャーバンド情報の終値を取得)
mode:MODE_LOWER(ボリンジャーバンドの下ライン情報を取得)
shift:0(現在のローソク足からボリンジャーバンド情報を取得)

あとは、次のように、取得したボリンジャーバンド値と現在の市場価格と
比較するようなプログラムを作ることになるかと思われます。

if (boll_price < Ask)
{
}

2009年2月14日土曜日

Loop_Entry プログラムを手直ししてみました。

さて、損益 10 ポイント未満で決済できるように Loop_Entry プログラムを手直ししてみました。

手直ししたプログラムはこちら↓にアップしてあります。

http://www1.bbiq.jp/hideho-fx-auto/loop_entry/source/loop_entry.htm

#上記プログラムは十分なテストを行っておりません。もしご利用の際には
#自己責任でお願いします・・・


手直しのポイントは次のとおりです。

・トレードプールに複数のポジションがある場合を見越した対応

・複数の EA 同時実行を見越しマジック番号での識別対応

・注文の仕方を指値注文っぽい成行注文に変更

・画面より入力した利益確定ポイント幅を基準に成行決済

現時点では 1 つのEA ならびに 1 つの注文しかしないため複数ポジション対応の必要はありませんが、将来的に他の EA を同時に動かしたりする場合を見越し、トレードプールに複数のポジションがあっても動作するように対応しました。

また、指値注文についても、指値と相場価格にある一定以上の価格差がないと注文が成立しなかったため、こちらも画面で指定した価格で即注文成立するように変更しました。


手直しの詳しい内容は次のとおりです。

1. トレードプールにあるポジションを順番に調べ、Loop_Entry プログラムによる注文のマジック番号をもつポジションを見つける。

まず、トレードプールにあるポジションを順番に調べる方法として次のような書き方をしています。

---------------------------------------------------------
int MAGIC_NO=1; //Loop_Entryプログラムで注文したことを識別するマジック番号
int Entry_Cnt=0; //トレードプールにLoop_Entryプログラムでのポジションが何個あるか保持する
int i; //トレードプールからポジションを取得するためのオーダー番号を格納する
int j=OrdersTotal(); //トレードプールにある全ポジションの数を取得し保持する

for(i=0; i<j; i++)
{
}
---------------------------------------------------------

これは、i という数値が入る識別子を準備し、かつ、トレードプールの全ポジション数を j という識別子に格納し、i を 0 から一つずつカウントアップしながら j の数より小さい間、for の中括弧の内容を実行するというものです。

このカウントアップしていく i の値をオーダー番号として利用し、OrderSelect() でポジションを取得していきます。

そして、Loop_Entry プログラムによるポジションがみつかったら、見つかったことを識別するための Entry_Cnt 識別子に 1 を加算し、for の処理を中断しています。

Loop_Entry プログラムによるポジションかどうかは、取得したポジションのマジック番号を OrderMagicNumber() で調べ、新規注文の時に指定しているマジック番号(MAGIC_NO)とを比較して判断しています。


2. ポジションが見つからなかったら、新規に注文する

次に、上記1. で調べた結果である Entry_Cnt が 0 のままであれば、Loop_Entry による注文ポジションは存在しないため、新たな注文を実行しています。

注文する際には、注文方法を指値注文ではなく成行注文に変えてあります。

つまり「OrderSend(Symbol(),CHUMON_TYPE,・・・」の CHUMON_TYPE の値を、入力画面で"買"が指定されたら"0"とし、"売"が指定されたら"1"をセットしています。

これで成行注文となりましたが、Loop_Entry はあくまでも「同じ価格で注文を繰り返す」プログラムなので、画面で指定した指値と相場価格が同じ場合のみ成行注文が実行されるようにしました。


3. ポジションが見つかったら、「有効なポジション」なのか「有効な注文」なのかを判断し、有効なポジションであれば、決済注文を出す。

Entry_Cnt が 0 以外なら、最後に取得したポジションは Loop_Entry により注文されたポジションなので、ポジションタイプ(取引種類)を OrderType() で調べ判断しています。


4. 決済注文を出す際には、市場価格と利食い価格と損切り価格から判断し成行決済を行う

最後に、市場価格(Bid/Ask)と、画面で指定した入力パラメータより算出した利食い価格と損切り価格から、決済すべきかどうかを判断し処理しています。


なお、今回は判断の方法として「switch」を利用しています。これは「if」でも書ける内容ですが、一つの判定基準に対して複数の結果がありえる場合に便利な書き方です。

つまり、switch の横に判定される内容(今回はポジションタイプ)を書き、判定基準を case の行に書いて、それぞれの場合に即した処理を書いていきます。


ざっと変更点を書きましたが、公開しているプログラムにもできるだけコメントを書き込んでいますので、参考にしてみてください。

2009年2月11日水曜日

10 ポイント未満利益確定サンプルプログラム

では、実際に 利益確定を 10 ポイント未満で決済するプログラムを作ってみます。

作るプログラムのルールは、次のとおりです。

1. 有効なポジションならびに有効な注文がなければ指値買い注文する
2. 有効なポジションの取得価格より相場の売値が 5 ポイント高ければ決済する

といった感じで、あまり細かい条件をいれずにシンプルなものを作ってみます。

まず、1. についてですが、これは Loop_entry プログラムを作成した際に使ったものを利用し、次のように書きます。

//
//有効なポジションあるいは有効な注文があるかどうかを判定する
//
if (OrdersTotal()==0)
{
//
//有効なポジションならびに有効な注文が一つもないので指値買い注文する。
//
OrderSend(Symbol(),OP_BUYLIMIT,0.1,Bid,3,0,0,NULL,0,0,Green);
}
else
{
//
//ここに、2. の内容に沿ったプログラムを記載する
//
}

次に 2. についてですが、次のような判断をしながら決済することになります。

2.1. トレードプールからポジションを取得する
2.2. 取得したポジションが「有効なポジション」なのか「有効な注文」なのかを判断する
2.3. 有効なポジションであれば取得価格と相場を比較する
2.4. 5 ポイント以上の利益確定なら決済する

で、これをプログラムで書いてみると

//
//トレードポジションプールからポジションを取得する。
//
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);  '--- ①
//
//有効なポジションなのか有効な注文なのかチェックし、
//有効なポジションの場合のみ処理する。
//
if (OrderType()==OP_BUY) '--- ②
{
//
//有効なポジションの取得価格が相場の売値より5ポイント分
//上なのかどうか判断し、上の場合のみ決済する
//
if (OrderOpenPrice()+5*Point '--- ③
{
//
//相場の売値で決済する
//
OrderClose(OrderTicket(),OrderLots(),Ask,3,Red);
'--- ④⑤
}
}

ここでポイントとなるのは次のとおりです。

注文は必ず 1 つしかないので、OderSelect() でオーダー番号を 0 で取得している

有効なポジションの場合、ポジションのタイプ(取引種別)が "buy"(OP_BUY)になっているはずなので、OrderType() で取得したポジションのタイプを調べている

#指値買い注文で有効な注文の状態であれば、取得したポジションのタイプは "buylimit"(OP_BUYLIMIT)になっています。

有効なポジションの取得価格を OrderOpenPrice() で取得し、5 ポイント加算したものと相場の売値(Ask)で比較している

取得したポジションのチケット番号を OrderTicket() で取得し決済している

取得したポジションのロット数(取引数)を OrderLots() で取得し、決済取引数として指定している

これで、指値注文の際にひっかかる決済制限をクリアできました。

次回は、これを応用して、Loop_Entry を手直ししたいと思います。

2009年2月9日月曜日

OrderClose の書き方

OrderSelect() でのポジション取得については大体わかりました。

次に、決済するための OrderClose() について調べてみます。

OrderClose( ticket, lots, price, slippage, color) ;

ticket:チケット番号を指定する
lots:決済するロット数(取引数)を指定する
price:決済価格を指定する
slippage:スリッページを pips で指定する
color:チャート上に表示する決済矢印の色を指定する

で、実際にどのように書くかというと

OrderClose(1234,0.1,90.50,3,Red) ;

となります。

上記内容は大体わかりましたが、一つだけ疑問が・・・

チケット番号はどのようにして調べるのでしょうか?

チケット番号とは、実は MetaTrader 画面で見られる「注文番号」のことです。

とはいっても、サーバーが勝手に割り振る番号なので、どの注文に何番が割り振られるかをプログラムで事前に予測し割り振られた番号を保持するのは面倒です。

そこで、OrderTicket() を利用します。

OrderTicket() は、OrderSelect()によって取得したポジションのチケット番号を返してくれるものです。

使い方としては、

OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
OrderClose(OrderTicket(),0.1,90.50,3,Red) ;

のように、OrderSelect()とセットで利用します。

つまり、OrderSelect() でポジションを取得し、取得したポジションのチケット番号をOrderClose() に指定するということです。

これで、保有ポジションを取得し、決済する方法はわかりました。

次回は実際にプログラムを作ってみたいと思います。

2009年2月8日日曜日

OrderSelect の書き方

さて、損益 10 ポイント未満で決済するためには、OrderSelect() で有効なポジションを取得し、OrderClose()で決済する必要があることがわかりました。

そのため、これらについて調べてみたいと思います。

まず、OrderSelect() についてですが、マニュアルには次のように書いてありました。

OrderSelect( index, select, pool);

index:オーダー番号かチケット番号を指定する

select:オーダー番号とチケット番号のどちらで探すかを次の中から選ぶ
SELECT_BY_POS - オーダー番号で探す場合
SELECT_BY_TICKET - チケット番号で探す場合

pool
:オーダー番号で探すときにどこから探すかを次の中から選ぶ
MODE_TRADES (default)- 有効なポジションか有効な注文から探す
MODE_HISTORY - 決済済みポジションかキャンセルした注文の履歴から探す

有効なポジションと有効な注文を並べた状態をトレードプール( Trading Pool )、決済済みポジションとキャンセルした注文を並べた状態をヒストリプール( History Pool )と呼ぶみたいです。

OrderSelect() の説明には 2 つの番号が出てきました。それぞれの番号の意味は、

オーダー番号:それぞれのプール内の並び順

チケット番号
:注文した際に勝手に割り振られるユニークな番号(同じ番号の注文は他にはない)

になります。

どのような場合に使い分けるのかというと、複数の有効なポジションを保有している場合に、次々と何らかの処理をしたい場合にはオーダー番号を利用し、あらかじめ処理すべきポジションが特定できている場合にチケット番号を使うみたいです。

ついでに、OrderSend() のプロパティに「マジック番号」というものもあります。

これは、例えば複数のプログラムを同時に動かしているときに、どのプログラムで注文されたものなのかを識別する際に使う番号です。

オーダー番号を利用する際に、一つ注意が必要です。

トレードプールはその時々によって対象となるものが変わりますので、例え同じポジションであっても、同じオーダー番号が割り振られるわけではありません。

なお、どのような番号が割り振られるかというと、0,1,2,3,・・・ といった具合になります。

#厳密には番号を割り振るわけではあません。トレードプールとは単に配列のこと
#ですので、ここでいうオーダー番号とは配列の番号になります。

実際の書き方としては、次のとおりです。

OrderSelect(0,SELECT_BY_POS,MODE_TRADES);

これで、トレードプール内の最初の有効なポジション(もしくは有効な注文)を取得することができます。

ポジションを取得する書き方は大体わかりました。

次は OrderClose() を調べてみたいと思います。

参考になりました? よろしければご協力ください。

にほんブログ村 為替ブログへ 人気ブログランキング【ブログの殿堂】