OrderSendの書式だけ調べてコピペしたら、損切りが設定されないまま発注されていた——Order系関数はEA開発で必ず使う分、こうした見落としがそのまま実運用の事故につながります。
この記事では、EA(エキスパートアドバイザー)で頻繁に使うOrder系関数を1つずつ解説したうえで、最後に実際にMetaEditorでコンパイルできる、注文・決済を組み合わせた完結したサンプルコードを紹介します。
Order系関数
Order系関数は主にEA(エキスパートアドバイザー)で使用する関数です。
今回はOrder系関数の中で良く活用される関数をご紹介したいと思います。
OrderSend関数
OrderSend関数は売買注文を送信する関数です。
OrderSend(Symbol(), CMD,Volume,Price,Slippage,SL,TP,Comment,Magic,Expiration,Color); OrderSend(オーダーを送信する通貨ペアは?,注文方式は?,ロットは?,レートは?,スリッページは?,損切り価格は?,利確価格は?,オーダーにメモをつける?,マジックナンバーは?,オーダーの有効期限は?,チャート上に何色で表示する?);
cmdの注文は
- OP_SELL
- OP_BUY
のみ使用します。
また、priceには
- Bid(売値)
- Ask(買値)
のみ使用します。
例えば以下のように記述します。
OrderSend("USDJPY", OP_BUY, 0.1, Ask, 3, Ask-200*Point, Ask+200*Point, "EA", 1234, 0, Red);
SL(損切り価格)・TP(利確価格)を0のまま発注しないでください。0を指定すると損切り・利確のどちらも設定されず、ポジションが逆行しても決済されないまま含み損が膨らみ続けます。上の例のように、エントリー価格から一定のPoint幅を引く/足す形で必ず値を入れましょう。
OrderClose関数
OrderClose関数は、ポジションを決済することができる関数です。
OrderCloseは以下のように記述します。
OrderClose(ticket,lots,price,slippage,color); OrderClose(チケットナンバー、ロット、価格、スリッページ、チャート上の色);
チケットナンバーとは、オーダーごとの固有の識別番号のようなものです。
OrderSend関数が成功するとOrderSend関数はチケットナンバーを返します。
int TicketNumber = OrderSend("USDJPY", OP_BUY, 0.1, Ask, 3, Ask-200*Point, Ask+200*Point, "EA", 1234, 0, Red);
OrderClose(TicketNumber,0.1,Bid,3,Yellow);
これでポジションの決済を行います。買いポジションを決済するときはBid、売りポジションを決済するときはAskを使う点に注意してください(発注時とは反対の価格になります)。
OrderSelect関数
OrderSelect関数は、オーダーの詳細情報を取得できる関数です。
ポジションの情報を取得するには、どのポジションに対して情報を要求するのか宣言する必要があります。
オーダーの識別はOrderSelect関数で行います。
OrderSelect(ポジション番号,選択モード,プール);
ポジション番号とは、チケットナンバーとは異なる識別番号で、
現在持っているポジション数-1が最大となる数のことです。
例えば、ポジションを3つ持っている場合は、それぞれのポジションに0,1,2という番号が割り振られています。
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
選択モードは、ポジション番号(SELECT_BY_POS)かチケットナンバー(SELECT_BY_TICKET)のどちらで選択するかを指定します。
3番目のプール(省略可、既定値はMODE_TRADES)は、有効中のポジション・待機注文から探すか(MODE_TRADES)、決済済み・キャンセル済みの履歴から探すか(MODE_HISTORY)を指定します。省略するとMODE_TRADESとして扱われます。
この宣言をすることで、以下のような関数が活用することができます。
- OrderOpenPrice関数:そのオーダーの約定価格
- OrderOpenTime:そのオーダーの約定時間
- OrderTicket関数:そのオーダーのチケット番号
- OrderLots関数:そのオーダーのロット
- OrderSymbol関数:そのオーダーの通貨ペア
- OrderMagicNumber関数:そのオーダーのマジックナンバー
- OrderType関数:そのオーダーの取引種別
詳しくは以下の記事を参照してください。
【MQL】OrderSelect関数で活用できる関数についてわかりやすく説明してみた
OrdersTotal関数(ポジションの総数)
現在の待機注文と保有中のポジションの合計を取得します。
エントリー中の注文と保留中注文の総数を返します。
例えば、エントリー中のポジション数が1、保留中の指値数が1あったとすると戻り値は2になります。
int OrdersTotal();
OrderTakeProfit関数(利益価格)
選択したポジションの利益確定価格を返します。
double OrderTakeProfit();
OrderStopLoss関数(損切り価格)
選択したポジションの損切り価格を返します。
double OrderStopLoss();
関数を組み合わせて動かす
ここまでの関数を組み合わせて、自分(マジックナンバー12345)のポジションを持っていなければ成行で買い、既に持っていれば決済する、という最小限のEAを作ってみましょう。
//+------------------------------------------------------------------+
//| OrderFunctionsDemo.mq4|
//+------------------------------------------------------------------+
#property strict
input double Lots = 0.1;
input int StopLoss = 200;//損切り(pips)
input int TakeProfit = 200;//利確(pips)
input int MagicNumber = 12345;
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
void OnTick()
{
int myTicket = -1;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
myTicket = OrderTicket();
break;
}
}
if(myTicket < 0)
{
//ポジションを持っていなければ新規に買う
int ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3,
Ask - StopLoss * Point,
Ask + TakeProfit * Point,
"EA", MagicNumber, 0, Red);
if(ticket < 0)
Print("発注に失敗しました。エラーコード=", GetLastError());
}
else
{
//既にポジションを持っていれば決済する
if(OrderSelect(myTicket, SELECT_BY_TICKET))
{
bool result = OrderClose(myTicket, OrderLots(), Bid, 3, Yellow);
if(!result)
Print("決済に失敗しました。エラーコード=", GetLastError());
}
}
}
//+------------------------------------------------------------------+
OrderSelect()でポジションの有無を確認し、無ければOrderSendで発注、あればOrderCloseで決済する、というOrder系関数の基本的な組み合わせ方です。実運用のEAを作る際は、この土台にエントリーロジック(移動平均線のクロス等)を追加していく形になります。
まとめ
今回はOrder系関数について紹介しました。
Order系関数はEAを作成する際に非常に重要になってきますので、しっかりと理解しておきましょう。
コメント