MQL4ブック MT4

注文の開始と配置

スポンサードリンク

Contents

注文の開始と配置

 

保留中の注文を開くおよび配置するための取引要求は、OrderSend()関数を使用して形成されます。

 

関数OrderSend()

int OrderSend ( string symbol , int cmd , double volume , double price , int slippage , double stoploss , 
  double takeprofit , string comment = NULL , int magic = 0 , datetime expiration = 0 , color arrow_color = CLR_NONE )

(ここでは関数ヘッダーを参照していますが関数呼び出しをプログラムで使用する例ではありません)。

この機能の詳細について考えてみましょう。

OrderSendは関数名です。 この関数は、取引サーバによって注文に割り当てられたチケット番号(「チケット」は注文の一意の番号)を返します。取引要求がサーバまたはクライアント端末のいずれかによって拒否された場合は-1を返します。 取引要求の拒否理由についての情報を入手するには、関数GetLastError()を使用する必要があります(以下、最も一般的なエラーのいくつかを検討します)。

symbolは、取引される証券の名前です。 各シンボルは文字列変数の値に対応します。 例えば、ユーロ/ドルの通貨ペアの場合、この値は「EURUSD」である。 foregoneシンボルに対して注文が開かれている場合は、このパラメータを明示的に指定することができます:「EURUSD」、「EURGBP」など。ただし、他のシンボルのウィンドウでExpert Advisorを使用する場合は、標準関数Symbol()を使用することができます。 この関数は、EAまたはスクリプトが実行されているウィンドウ内で、シンボルの名前に対応する文字列値を返します。

cmdは操作のタイプです。 操作のタイプは、事前定義された定数またはその値として、また取引のタイプに応じて指定することができます。

ボリュームはロットの量です。 市場の注文については、常に十分な金額をアカウントで確認する必要があります。 保留中の注文の場合、ロットの量は制限されません。

価格はオープンプライスです。 これは、取引を行うために受け入れられる要件および制限に従って指定されます( 注文特性および取引のルールを参照)。 マーケット注文の開設のために要求された価格が価格スレッドに見つからなかったか、またはかなり古くなった場合、取引要求は拒否されます。 しかし、価格が古くても、価格スレッドに存在し、現在の価格からのずれが滑りの値の範囲内にある場合、この取引要求はクライアント端末によって受け入れられ、取引サーバに送られる。

スリッページは、要求された注文オープンプライスとマーケット注文(ポイント)の市場価格との許容最大偏差です。 このパラメータは保留中の注文を処理するために処理されません。

stoplossは、与えられた取引に許される最大損失を決定する要求された終値です。 これは、取引を行うために受け入れられる要件および制限に従って設定されます( 注文特性と取引を行うための取引条件、 要件および制限の 作成に関する規則を参照)。

takeprofitは、与えられた取引の最大利益を決定する要求された終値です。 これは、取引を行うために受け入れられる要件および制限に従って設定されます( 注文特性と取引を行うための取引条件、 要件および制限の 作成に関する規則を参照)。

コメントは注文コメントのテキストです。 コメントの最後の部分は、取引サーバーによって変更することができます。

魔法は魔法の数です。 ユーザー定義の注文IDとして使用できます。 場合によっては、それを開いた1つまたは別のプログラムにそのオーダーが属することを知るのに役立つ唯一の情報です。 パラメータはユーザによって設定されます。 その値は他のオーダのこのパラメータの値と同じでもよいし、異なっていてもよい。

有効期限は、注文が期限切れになる日付です。 この日が来るとすぐに、保留中の注文はサーバー側で自動的に閉じられます。 一部の取引サーバーでは、保留中の注文の有効期限を設定することが禁止されている場合があります。 この場合、パラメータの0以外の値を設定しようとすると、要求は拒否されます。

arrow_colorは、チャート内の開始矢印の色です。 このパラメータがない場合、またはその値がCLR_NONEの場合、開始矢印はチャートにまったく表示されません。

一部の取引サーバーでは、開かれた注文と保留中の注文の合計量に制限が設定されている場合があります。 この限度を超えた場合、市場注文の開始または保留中の注文の挿入を意味する取引要求は、取引サーバーによって拒否されます。

 

マーケットオーダーを開く

関数OrderSend()は、最初はあまりにも複雑すぎるように見えます。 しかし、すべての考慮されたパラメータは非常に簡単で、有用であり、あなたの取引でうまく使用することができます。 これを自ら見てみるために、取引関数OrderSend()がマーケット注文を開くためにどのように使われるかの最も簡単なバリエーションを考えてみましょう。

まず、関数OrderSend()には事前定義されたパラメータがあります( 関数呼び出し関数の説明と演算子 'return'を参照)。 これは、この機能が、必要最小限のパラメータセットを使用して簡略化されたモードで使用できることを意味します。 これらのパラメータは次のとおりです。

symbolは必要なパラメータです。これは、注文をどこで開くかを知る必要があるためです。 スクリプトが任意のシンボルウィンドウで注文を開く可能性を暗示します。 この場合、標準の関数Symbol()をこのパラメータに置き換えます。

cmd - たとえば、Buy orderを開きましょう。 この場合、パラメータOP_BUYを指定します。

volume -ルールで許可されている値を指定できます。 例えば0.1ロットの小さな注文を開きましょう。

価格 - 注文のオープン価格は購入価格です。

スリップは通常0〜3点で指定されます。 2を指定しましょう。

stoploss -ストップオーダーは、最小許容距離よりも近くにない距離、通常は5ポイントで配置することができます(取引を行う上での要件と制限を参照)。 近い価格から15ポイントの距離でストップ注文を出しましょう。つまり、入札 - 15 *ポイント、

takeprofit -近くの価格から15ポイントの距離でストップ注文を出しましょう。すなわち、入札+ 15 *ポイント。

以下は、最も簡単なスクリプトsimpleopen.mq4です。これは購入注文を開くためのものです:

  // ------------------------------------------------ --------------------
 // simpleopen.mq4
 // コードは教育目的でのみ使用する必要があり ます。
 // ------------------------------------------------ --------------------
 int start () //特殊な関数start()
   { //オープニングBUY
    OrderSend ( Symbol () 、 OP_BUY 、 0.1 、 Ask 、 2 、 Bid - 15 * Point 、 Bid + 15 * Point ) ; 
     return ;  // Exit start()
   }
 // ------------------------------------------------ --------------------

実行のためにこのスクリプトを起動すると、ほとんどの場合、このスクリプトが機能します。 スクリプトは、受注関数OrderSend()と演算子 'return'を含む1つの特殊関数で構成されています。 プログラムラインとそれに関連するイベントの実行アルゴリズムについて説明しましょう。

ユーザは、「ナビゲータ」メニューからマウスボタンを用いてスクリプト名をドラッグすることにより、記号ウィンドウにスクリプトを添付している。 マーケットの注文を開こうとしているシンボルのウインドウにクライアント端末のウィンドウを表示する。市場価格から15ポイントの距離にある0.1ロットの買い注文およびストップ注文を伴う。

2.シンボルウィンドウにスクリプトを付加する瞬間、クライアント端末は特別な関数start()を制御に渡します(ここでは、スクリプトのstart()が起動されたことを簡単に思い出さなければなりません)シンボルウインドウにスクリプトを添付する瞬間に、一方、EAのstart()は、最も近いティックがシンボルに収入する瞬間に開始されます)。

3.特殊関数start()の実行の枠組みの中で、コントロールは注文開始関数を呼び出す行に渡されます。

  OrderSend ( Symbol(), OP_BUY, 0.1, Ask, 2, Bid - 15 * Point, Bid + 15 * Point);

この関数を実行する前に、プログラムはすべての仮パラメータの値を計算します。

3.1。 スクリプトをEur / USdのウィンドウに添付しました。この場合、標準関数Symbol()は文字列値EURUSDを返します。

3.2。 この関数を呼び出した時点でAsk = 1.2852、Bid = 1.2850としましょう。

3.3。 この場合のStopLossの値は、1.2850-15 * 0.0001 = 1.2835、TakeProfit = 1.2865となります。

4. OrderSend()関数の実行:

4.1。 ファンクションは、注文を開くための取引要求を形成し、この要求をクライアント端末に渡した。

4.2。 この機能は、取引要求の受け渡しと同時にクライアント端末に制御を渡したので、プログラムの実行は停止された。

4.3。 クライアント端末は、受け取った取引要求をチェックした。 それは間違ったパラメータを検出しなかったので、サーバにリクエストを送りました。

4.4。 サーバーは取引要求を受け取り、チェックし、間違ったパラメーターを検出しなかったので、要求を実行することにしました。

4.5。 サーバは、データベース内のトランザクションを作成することによって要求を実行し、その実行された要求に関する情報をクライアント端末に送信した。

4.6。 クライアント端末は、最後の取引要求が実行されたという情報を受信し、このイベントを端末ウィンドウおよびシンボルウィンドウに表示し、制御をプログラムに戻した。

4.7。 コントロールを受信すると、プログラムは、コントロールが以前にクライアント端末に渡された場所から作業を続けました(そして、後で返されました)。

プログラムがステップ4.2からステップ4.7から開始して実行されていないことに注意してください。プログラムはサーバーの応答を待機するモードになっています。

5.プログラムの制御が次の演算子、つまり演算子 'return'に渡されます。

6.演算子 'return'を実行すると、関数start()が終了し、プログラムの実行が終了します(スクリプトは実行された後にスクリプトが完了することを覚えておく必要があります)。クライアント端末。

したがって、スクリプトは意図された目的を達成しました。 スクリプトの使用は、小さな1回限りの操作を実行する必要がある場合は非常に便利です。 この場合、スクリプトの使用はかなり妥当です。 ステップ4.6。に従って、業者は画面内の注文を見ることができる。

イチジク。 81.スクリプトsimpleopen.mq4による注文

イベントは必ずしも上記のように順序付けられているわけではありません。 取引要求がクライアント端末またはサーバによって拒否される可能性があります。 たとえば、シンボル名を変更するなど、いくつかの実験を試してみましょう。「GBPUSD」を指定します。 明示的に(これはかなり許容可能です)。 限られた使用分野のプログラムを入手します。

  int start () // 特別な関数の 開始
   { //オープニングBUY
    OrderSend ( "GBPUSD", OP_BUY, 0.1, Ask, 3, Bid - 15 * Point, Bid + 15 * Point ); 
     return ;  // Exit start()
   }

Eur / Usdというシンボルの同じウィンドウでスクリプトを起動しましょう。 スクリプトは、Gbp / Usdのウィンドウで注文を開くことを意図していました。 しかし、それがEur / Usdのウィンドウに接続された後、Gbp / Usdのウィンドウでは何の順序も開かれませんでした。

そのようなプログラムの欠点は、その機能上の制限です。 この場合、シンボルウィンドウにスクリプトを添付すると、ユーザーは注文の開封を待っているだけです。 ただし、注文は開かれません。 ユーザは、その理由を認識していない。なぜなら、それは、プログラムコード中のアルゴリズムエラーによって引き起こされるか、または取引要求が「失われた」ことである。 途中でサーバにアクセスしたり、取引要求が長時間前にクライアント端末によって拒否されたり(ユーザがまだ待っていると思われる)、または別の理由があります。

ユーザに取引要求の実行に関連する事象に関する情報を提供するためには、エラーを処理する必要がある。

エラー処理

クライアント端末の非常に重要な特性は、アプリケーションの実行中にエラーが発生した場合、クライアント端末はプログラムの実行を停止しないことである。 エラーは、通常、アプリケーションで使用されているアルゴリズムの不完全さによって引き起こされます。 場合によっては、エラーはいくつかの外部要因(プログラムに関連する要因)によって引き起こされます。 エラーの内部原因は、無効な価格を使用するなど、MQL4要件または取引ルールの違反です。 外部要因は、アプリケーションプログラムに関連しない原因、例えば、接続の中断などです。

プログラムの実行時にエラーが発生すると、プログラムは実行を継続し、クライアント端末はGetLastError()関数を介してプログラムで使用可能なエラーコード値を生成します。

関数GetLastError()

  int GetLastError ( )

関数は新しく発生したエラーのコードを返します。最後のエラーのコードを格納する特殊変数last_errorの値はゼロになります。 その後のGetLastError()呼び出しは0を返します。

以下では、発生したすべてのエラーをこのコードで識別します。 プログラムの実行中にいくつかのエラーが発生する可能性があります。 関数GetLastError()は、それらのうちの1つのみのコード値を取得できるようにします。最新のエラーです。これは、この情報が必要なたびにGetLastError()関数をプログラム行の直後に使用することが推奨されます。エラーが発生することがあります。

エラー130:無効な停止指示

最後に考えられたスクリプトはエラーを分析しないので、ユーザーは注文開封機能の実行結果について無知なままです。 関数GetLastError()を使用する単純なバリエーションでは、プログラムはエラーを分析し、そのことについてユーザーに知らせるだけです。 Eur / Usdのウィンドウでconfined.mq4スクリプトを実行すると、エラーが発生します。

  // ------------------------------------------------ --------------------------
 // confined.mq4
 // コードは教育目的のみに使用する必要があります  
 // ------------------------------------------------ --------------------------
 int start () //特別な関数の開始
   { // オープニング BUY
    OrderSend ( "GBPUSD", OP_BUY, 0.1, Ask, 2, Bid - 15 * Point, Bid + 15 * Point ); 
     Alert ( GetLastError() );  // エラーメッセージ
    return ;  // Exit start()
   }
 // ------------------------------------------------ --------------------------

このスクリプトには1つしか追加されていませんが、非常に有益な行が追加されました。

  Alert ( GetLastError() ) ;  // エラーメッセージ

関数GetLastError() は最後のエラーのコードを返しますが、Alert()はこの値を画面に表示するために使用されます。 スクリプトconfined.mq4がシンボルEur / Usdのウィンドウに添付された後、スクリプトが実行され、その結果、次のメッセージが表示されます。


イチジク。 82. eur / usdウィンドウのconfined.mq4スクリプト実行に取得されたエラーコード。

プログラムの実行時に発生する可能性のあるエラーコードについては、付録の付録を参照してください。 この場合、エラー130(無効なストップオーダー)が発生しました。 これは、関数OrderSend()で使用される仮パラメータの値が、取引を行う上での要件と制限に指定されている制限に準拠していないことを意味します。 より詳細に見ると、エラーを引き起こした理由を見ることができます。市場価格BidとAskの現在の値は、スクリプトが添付されているシンボルウィンドウ、つまりEur / Usdのウィンドウから取得されます。 ただし、これらの値はGbp / Usdの取引要求を形成するために使用されます。 その結果、Gbp / Usdの現在の価格Ask = 1.9655で、新しく開かれた市場注文のTakeProfitの価値は(Eur / Usd Bid = 1.2930)1.2930 + 15 * 0.0001 = 1に等しくなることが判明した。 2945であり、これは最小許容値よりかなり低い、すなわち無効である。

この場合、アルゴリズム上のエラーが発生しました。 それを修正するには、シンボル価格の正しい値を使用する必要があります。 これらの値は、MarketInfo()関数を使用して取得できます。 Gbp / Usdのマーケットオーダーを開くスクリプトmodified.mq4は、任意のシンボルウィンドウで起動できます:

  // ------------------------------------------------ ------------------------------
 //改善された.mq4
 // コードは教育目的でのみ使用する必要があり ます。
 // ------------------------------------------------ ------------------------------
 int start () //特別な関数の開始
   {
    ダブル ビッド = MarketInfo ( " GBPUSD " 、 MODE_BID ) ;  //入札単価のリクエスト
    ダブル ask = MarketInfo ( " GBPUSD " 、 MODE_ASK ) ;  // Askの値を要求する
    ダブル ポイント = MarketInfo ( " GBPUSD " 、 MODE_POINT ) ;  // Pointのリクエスト
    //オープニングBUY
    OrderSend ( "GBPUSD", OP_BUY, 0.1, ask, 2, bid - 15 * Point, bid + 15 * Point ); 
    Alert ( GetLastError() );  // エラーメッセージ
    return ;  // Exit start()
   }
 // ------------------------------------------------ ------------------------------

上記のエラーは、このスクリプトの実行時には発生しないため、実行すると対応するメッセージが表示されます。0(ゼロ)。 これは、関数GetLastError() が値0を返したことを意味します。つまり、クライアント端末による取引要求の実行中にエラーが検出されませんでした。

他の一般的なエラーも考えてみましょう。 ここでは、スクリプトが添付された同じウィンドウ内のスクリプトを使用して注文を開くという考えに戻りましょう。

 

エラー129。無効な価格

場合によっては、単純なエラーが発生します。双方向見積りの間違った値が公開価格として指定されます。 マーケットオーダーの購入は、Ask価格で開かれることが知られています( 取引行う際の要件と制限を参照)。 以下は、間違ってスクリプトmisid.mq4の入札価格を指定するとどうなるでしょうか?

  // ------------------------------------------------ -------------------------
 // mistaken.mq4
 // コードは教育目的のみに使用する必要があります  
 // ------------------------------------------------ -------------------------
 int start () //特別な関数の開始
   { //オープニングBUY
    OrderSend ( Symbol(), OP_BUY, 0.1, Bid, 2, Bid - 15 * Point, Bid + 15 * Point ); 
    Alert ( GetLastError() );  // エラーメッセージ
    return ;  // Exit start()
   }
 // ------------------------------------------------ -------------------------

取引要求をサーバに送信する前に、クライアント端末は、要求された価格および注文の注文が許容値に適合するかどうかを分析する。 このチェックでは、要求された発注金額が無効として検出されるため、クライアント端末は取引要求をサーバーに送信してGetLastError()関数は129の値を返します( エラーコードを参照)。 スクリプトを実行すると、対応するエラーメッセージが表示されます。

イチジク。 エラーmistake.mq4の実行時のエラー129(無効な価格)。

エラー134.取引のための十分な金額

注文を開くために十分な金額がアカウントにない場合、同様の結果(エラー134)が得られます。 関数MarketInfo(symbol_name、MODE_MARGINREQUIRED)を使用して、各シンボルを購入するために1ロットを開くために必要なフリーマネーの金額を知ることができます。

同じシンボルの標準ロットのサイズは、ディーリングセンターごとに異なる場合があります。

1ロット発注に必要な自由資産の量は、提供されるレバレッジの量に反比例します。 同時に、シンボルの預金通貨の1ポイントのコストは、提供されたレバレッジには関係しません。

表3. 1ロットのコストと1ポイントのコストの組み合わせ(預金通貨は米ドル)。

ディーリングセンター1 ディーリングセンター2 ディーリングセンター3
購入 売る 1pt 購入 売る 1pt 購入 売る 1pt
EUR / USD 1296.40 1296.20 10.00 1296.50 1296.20 10.00 1000.00 1000.00 10.00
GBP / USD 1966.20 1966.00 10.00 1376.48 1376.20 7.50 1000.00 1000.00 10.00
AUD / USD 784.40 784.20 10.00 1569.20 1568.40 20.00 1000.00 1000.00 10.00
USD / JPY 1000.00 1000.00 8.29 1000.00 1000.00 8.29 1000.00 1000.00 8.29
USD / CHF 1000.00 1000.00 8.02 1000.00 1000.00 8.02 1000.00 1000.00 8.02
EUR / CHF 1296.40 1296.20 8.02 1296.35 1296. 35 8.02 1000.00 1000.00 8.02

価格は、2007年12月16日現在の価格です。

1ロットと1ポイントのコストを計算する一般的な方法を簡単に考えてみましょう。

ディーリングセンター1(最も一般的)

USDを相互に有するシンボルの場合、1ロットのコストは、対応する双方向見積りの現在の価格に1000を掛けたものに等しいが、1ポイントのコストは$ 10に等しい。

分子をUSDとしたシンボルの場合、1ロットのコストは$ 1000.00になりますが、1ポイントのコストは現在の見積に反比例し、1 /(入札)に等しくなります。 たとえば、USD / CHFの場合、入札額= 1.2466の場合、1ポイントの費用は1/1です。 2466 = 8.02。

クロスレートの場合、1ロットのコストは分子通貨と同じ方法で計算されますが、1ポイントのコストは分母通貨のコストと同じ方法で計算されます。 たとえば、EUR / CHFの場合、1ロットのコストは129.40(EUR / USDの場合)ですが、1ロットのコストは8.02(USD / CHFの場合)です。

ディーリングセンター2

一部のディーリングセンターでは、コスト計算の同じルールを考慮して、一部のシンボルではコストの値が異なる場合があります。 例えば、1ロットのコストと1ポイントのコストは比例して増減することができる。 たとえば、GBP / USDの場合は0.75、AUD / USDの場合は2.0です。 そのようなコスト値の表現は経済的な変化をもたらさない。 そのような場合は、注文のコストを計算する際にこの特別な機能を考慮する必要があります。 また、クロスレートで資産を売買するための1ロットのコストが同じであるという事実にも注意する必要があります。

ディーリングセンター3

1つのロットのコストを任意のシンボルに対して$ 1000.00と設定する取引センターもあります。 同時に、1ポイントのコストは現在の価格に比例しています。 これは、各シンボルに対して特別なレバレッジを設定することを意味します。

米ドルに関連して引用されていないすべてのシンボルの1ポイントのコストは、常に、相互に指定されたシンボルのコストに比例して変化します。

一般に、コスト値を構築する他の原則が存在する可能性があります。 言うまでもなく、実際の取引を開始する前に、特定のディーリングセンターの計算方法について調べ、コーディングでこの方法を検討する必要があります。

無料マージン

コーディングでは、フリーアセットを形成する原則を検討することが非常に重要です。 フリーマージン(資産)は、取引を行うために利用可能な金額です。

例を考えてみましょう。 残高を5000.00とすると、端末に未発注の注文はありません。 ディーリングセンター3で1ロットの購入注文を開きましょう。以下のルールはディーリングセンター3に記載されています:

1つのシンボルに対して異なる指向のマーケットオーダーが開かれた場合、一方向注文の統合コストがより小さくなり、トレーディングのために解放されます(このルールはすべてのディーリングセンターに適用されるわけではありません)。

ターミナルウィンドウには、開かれたオーダーに関する情報が表示されます。 マージンは1000.00、注文利益は-30.00であるため、フリーアセット(フリーマージン)は5000-1000-30 = 3970.00となります。

イチジク。 ターミナルウィンドウで注文する。

同じ価値の売り注文が開かれた後、フリーマージンが増加します。 一方向市場受注の統合コストが小さくなると1000.00となるため、フリーマージンは1000.00増加します。 Fig。 85では、指図の異なる指図が同じ価値を持つ状況を見ることができるため、指図コストの合計は取引のためにリリースされます。

イチジク。 注文。端末ウィンドウで購入し、売る。

より少ないコストの売り注文が開かれた後、フリーマージンも増加するでしょう。 この場合、一方向市場受注の統合コストが小さいほど700.00となるため、フリーマージンは700.00増加し、マージンは指図別指数の統合コストの差になります(図86)。

イチジク。 注文は、ターミナルウィンドウで購入し、売る。

0.1ロットのもう1つの注文販売が開かれた場合(コスト100.00)、一方向市場受注の統合コストが小さいほど、700.00 + 100.00 = 800.00となります。 したがって、マージンは(1注文のみが開かれる状況と比較して)800.00だけ減少する。 図2に示す状況と比較して、 図86では、マージンは減少し、資本は100.00増加する(図87参照)。

イチジク。 注文。端末ウィンドウで購入して売る。

フリーマージンは図3に示す。 図86および図79を参照されたい。 87は、現在の価格の変更に伴い、未処理受注の統合利益が変更されているため、100.00を超えて相互に異なります(差異は8.00となります)。

別のディーリング・センターで同様の操作を行うと、上記の余裕金額の順序が維持されていないことがわかります。 一部のディーリングセンターでは、次のルールが有効です。

市場受注を開始しても資本が解放されたり、フリーマージンが増加することはありません。 市場受注を開始すると、シンボルに対する異なる指向の市場受注の統合コストを上回る金額まで資本が増加します(ルールはすべての取引センターに適用されません)。

たとえば、ディーリングセンター2でUSD / JPYの注文を4ロット前に注文した場合、4ロットの売り注文を開くと、株式およびフリーマージンの金額は変更されません。

イチジク。 88.指図の順序が異なると資本が解放されない。

現在の株式が注文を開くのに十分であるかどうかを計算することができます。 AccountFreeMarginCheck()関数を使用して、特定のシンボルのロット数を指定したマーケットオーダーを開いた後に残る余白の値を返すこともできます。 戻り値が0以上の場合は、アカウントに十分な金額があります。 値が0より小さい場合、このボリュームの順序とこのシンボルの順序は開けません。クライアント端末はエラー134を返します。

ディーリングセンターが提供する条件と、1ロットの数量で注文を開くために必要なフリーマージンの量を知るためには、単純なスクリプトconditions.mq4を使用することができます。

  // ------------------------------------------------ --------------------------
 // conditions.mq4
 // コードは教育目的でのみ使用する必要があり ます。
 // ------------------------------------------------ --------------------------
 int start () //特別な関数の開始
   {
     Alert ( Symbol(), " Sell = ", AccountFreeMargin()   //販売時 
           - AccountFreeMarginCheck ( Symbol(), OP_SELL, 1 ) ) ; 
    Alert ( Symbol(), " Buy = ", AccountFreeMargin()    //購入時 
           - AccountFreeMarginCheck ( Symbol(), OP_BUY, 1 ) ); 
     return ;  // Exit start()
   }
 // ------------------------------------------------ --------------------------

ここで、

 AccountFreeMargin () - AccountFreeMarginCheck ( Symbol(), OP_SELL, 1)

利用可能なフリーマージンと、注文後に残るフリーマージンとの差額を計算することができます。

このスクリプトを実行すると、端末に市場注文がないときに、現在入手可能な資本金額を取得することができ、購入および売却のための1ロットの注文の開設に十分な金額を得ることができます。

イチジク。 1 - 条件記号を使用して得られた異なるシンボルのロット・コスト。

マーケット条件が公開されているシンボルのウィンドウで実行するスクリプトconditions.mq4を起動すると、他の値を取得することができます。これは、別のディーリング・センターで受け入れられた計算方法に依存します。

 

その他のエラーとMarketInfo()関数

関数OrderSend()のパラメータの値の決定に関連する他の制限があります。 これは、最大および最小注文価格ステップ、最大および最小注文価格値などである。関数MarketInfo()を使用すると、ウィンドウに表示されるシンボルに関する様々な情報を得ることができる。

 

MarketInfo()関数

double MarketInfo ( string symbol , int type ) 

この関数は、ウインドウ「Market Watch」にリストされたシンボルに関する様々な情報を返す。 現在のシンボルに関する情報の一部は、事前定義された変数に格納されます。

パラメーター:

symbol - シンボルの名前。

type - 返される情報のタイプを決定する要求識別子。 要求識別子の値のいずれかになります( 関数MarketInfo識別子を参照)。

サーバー側の理由により、いくつかのエラーが発生することがあります。 たとえば、一時的な価格の条件では、ブローカーは保留中の注文の配置を制限し、注文を停止する最小距離を増やすことがあります。 さらに、穏やかな市場では、ブローカーはこの距離を再び短くすることができます。 したがって、いくつかのパラメータの値は、いつでも変更することができます。

最小限の拒否された要求でプログラムが安定して動作するためには、関数OrderSend()を実行する前に、MarketInfo()関数とRefreshRates()関数を使用してプログラムで使用される情報環境のパラメータを更新する必要があります。

フリーオーダーの35%を要する注文を発注し、いくつかのプリペアドストップオーダー値( openbuy.mq4 )を持つ簡単なスクリプトの例。

 

  // ------------------------------------------------ -------------------------------
 // openbuy.mq4
 // コードは教育目的のみに使用する必要があります  
 // ------------------------------------------------ ---------------------- 1  - 
 int start () //特別な関数の開始
   {
    int Dist_SL = 10 ;  //プリセットSL(pt)
    int Dist_TP = 3 ;  //プリセットTP(pt)
    ダブル プロット = 0.35 ;  //フリーマージンのパーセンテージ
    文字列 Symb = Symbol () ;  //シンボル
 // ------------------------------------------------ -------------------------- 2  - 
    while ( true ) //注文を開くサイクル
      {
       int Min_Dist = MarketInfo ( シンボル 、 MODE_STOPLEVEL ) ;  // Min。  距離
       double Min_Lot = MarketInfo ( Symb 、 MODE_MINLOT ) ;  // Min。  ボリューム
       double Step = MarketInfo ( Symb 、 MODE_LOTSTEP ) ;  //ロットを変更するステップ
       double Free = AccountFreeMargin () ;  //無料マージン
       double One_Lot = MarketInfo ( シンボル 、 MODE_MARGINREQUIRED ) ;  // 1ロットあたりのコスト
       // ------------------------------------------------ -------------------- 3  - 
       double Lot = MathFloor ( Free * Prots   One_Lot  Step ) * Step;  //たくさん
       if ( Lot < Min_Lot ) //許可されていない場合
         {
           Alert  ( "十分でない金額", Min_Lot, "ロット" ); 
           break ;    // サイクルを終了する 
         }
       // ------------------------------------------------ -------------------- 4  - 
       if ( Dist_SL < Min_Dist ) // 許容されていない場合 
         {
          Dist_SL = Min_Dist ;  //許可を設定する
          Alert ( "SL =距離の増加", Dist_SL, "pt" ); 
          }
            double SL = Bid - Dist_SL * Point ;  // SLの要求価格
       // ------------------------------------------------ -------------------- 5  - 
       if ( Dist_TP < Min_Dist ) // 許容されていない場合 
         {
          Dist_TP = Min_Dist ;  // 許可を設定する 
          Alert ( "TP = ", Dist_TP, "pt の 距離を増加させました 。" ); 
          }
       double TP = Bid + Dist_TP * Point ;  // TPの 要求価格
       // ------------------------------------------------ -------------------- 6  - 
        Alert ( "リクエストはサーバーに送信されました。応答を待っています.. " ) ; 
         int ticket = OrderSend ( Symb , OP_BUY , Lot , Ask , 2 , SL , TP ) ;
        // ------------------------------------------------ -  -  -  -  -  -  -  -  -  -  7  - 
       if ( ticket > 0 ) //見つけた!:)
         {
           Alert ( "注文発注", ticket);
          breake;  // サイクルを終了する 
         }
       // ------------------------------------------------ -------------------- 8  - 
       int Error = GetLastError();    //失敗しました:(
       switch ( Error )   //オーバーフロー可能なエラー
         {
          case 135: Alert ( "価格が変更されました 。再試行します.. " ); 
              RefreshRates () ;  //データを更新する
             続ける ;  //次の繰り返しで
          case 136: Alert ( "価格がない。新しいチックを待っている.. " ); 
              while ( RefreshRates () == false )    //新しいティックまで
                sleep(1);  //サイクル遅延
             continue;  // 次の繰り返しで 
          case 146: Alert ( "取引サブシステムはビジー状態です。再試行します.. " ); 
              sleep (500);  //単純な解
             RefreshRates() ;  //データを更新する
             continue;  // 次の繰り返しで 
         }
       switch ( Error ) //重大エラー
         {
          case 2: Alert ( "一般的なエラー" ); 
              break;    // exit ' switch'
          case 5: Alert ( "クライアント端末の古いバージョン" ); 
              break;    // exit ' switch'
          case 64: Alert ( "アカウントはブロックされてい ます 。");
              break;    // exit ' switch'
          case 133: Alert ( "取引禁止" );
              break;    // exit ' switch'
          default: Alert ("発生エラー", Error );    //その他の選択肢
         }
        break;    // サイクルを終了する 
      }
 // ------------------------------------------------ -------------------------- 9  - 
      Alert ( "スクリプトは操作を完了しました --------------------------- " ); 
     return ;  // Exit start()
   }
 // ------------------------------------------------ -------------------------- 10  - 

スクリプトは1つの特別な関数start()(ブロック1〜10)で構成されています。 ブロック1-2では、順序を開く必要がある値が設定されます。 ブロック2-9は、すべての必要な計算が実行されるサイクル演算子while()を表す。 このサイクルは、プログラムが注文をいくつか開こうとするためのコードに含まれています。 ブロック2-3において、環境変数が更新される。 ブロック3-4-5-6において、ロットの量および停止命令の要求された価格が計算される。 ブロック7-8-9において、エラーが処理される。 ブロック9-10において、スクリプトがその動作を完了したというメッセージが印刷される。

プログラムコードの特別な機能を考えてみましょう。 貿易要求がブロック6-7で形成されていることは容易に分かります。 ブロック3-4において、ロットの量が計算される。 また、利用可能なフリーマージンが最低ロットの注文であっても開くことができない状況も考慮されます。 このため、ブロック3-4では、不十分な金額のメッセージを印刷した後、オペレータ '休憩'を使用してサイクル2-9を終了します。 制御はブロック9-10に渡され、スクリプトはその動作を完了する。 ブロック9のメッセージは不要です。 プログラムの操作が終了したときや、ネットワークやサーバーの遅延による一時停止がいつ発生するのかを、コードのユーザーがスクリプトの末尾や頭を見つけるのを助けるためにここに与えられています。

フリーマージンが注文を開くために十分である場合、制御はブロック4-5に進み、ブロック5-6に進む。 これらのブロックでは、サイクルの終了はありません。 これは、ブローカーによって設定された最小距離に対して、対応する停止レベルが見つかることを意味します。 ブロック1-2において、TPは設計上3点を選択した。 ブローカーの大部分は、最低距離を5ポイントに設定しました。 ブロック5-6において、プログラムは、プリセット値が許容値よりも小さいことを発見する。 プログラムは制限に反しないストップオーダー価格の値を設定します。

制御はブロック6-7に進み、注文を開く。 このブロックの最初の行に、メッセージが印刷されます。 取引要求は2行目にのみ形成されます。 疑問が生じます。なぜ、実際に形成される前にリクエストを作成することを宣言するのですか? 最初に指示を出して、ユーザーに知らせることができます。 この質問に対する答えは、要求をクライアント端末に送信してからサーバーに送信する技術と密接に関連しています(図66参照)。 私たちの場合、取引要求は、代入演算子の右部分で指定された関数OrderSend()で形成されます。 そのような取引要求は作成され、関数内のサーバーに送られるが、割り当て操作は、サーバーが「運命」に関する返信を返した後に代入演算子で実行される。 要求の したがって、要求に関連するイベントの開始についてユーザに知らせる唯一の可能性は、代理演算子の前にメッセージを表示することであり、その右側には取引関数が指定される。

遅かれ早かれ、クライアント端末は、制御をプログラムに戻し、ブロック6-7の割り当てオペレータが実行され、結果として「チケット」変数が値をとり、制御はさらに渡される - エラー分析ブロック7-8-9に進む。

注文がサーバー上で開かれている場合、開いた注文の番号(チケット)が変数 'チケット'に割り当てられます。 この場合、スクリプトがそのタスクを完了し、プログラムが操作を続行する必要はありません。 ブロック7-8では、while()を終了するために演算子 'break'を使用します。 制御はブロック9-10(サイクル外)に渡され、プログラムはその動作を完了する。

しかし、注文を開こうとする試みが失敗した場合、制御はエラー分析のためにブロック8-9に渡される。 2つのタイプのエラーがここで検討されます:注文を正常に開くことを望むものと、プログラムの実行の明白な終了を意味するものの発生。 変数「Error」には、この例では、サーバーまたはクライアント端末がOrderSend()関数の実行時に返したエラーの最後のエラーのコードが割り当てられます。

ブロック8-9の第1の演算子「スイッチ」では、相殺可能な誤差が考慮される。 このグループの各エラーは別々に処理されます。 たとえば、価格が変更された場合(エラー135)、RefreshRates()を使用して環境パラメータを更新し、注文を開こうと試みるだけで十分です。 エラー「価格なし(エラー136)、取引サーバーに要求を再送信する意味がありません。 この場合、新しいダニが収入を待たなければなりません(現時点ではサーバーに価格はありません)。それ以降は注文を再試行してください。 これは、エラー136を処理するブロック内に待機サイクルがある理由です。この待機サイクルは、新しいティックが収入を得たらすぐに中断されます。 演算子 'continue'を使用して演算子switch()を終了し、サイクルの現在の繰り返しを中断し、新しいサイクルを開始します。

重大なエラーは別の方法で処理されます。 このようなエラーが発生した場合、プログラムはユーザーに通知して操作を終了します。 この目的のために、while()を中断する演算子 'break'(ブロック8-9の最後のもの)を使用して、プログラムが終了します。

この例では、例外なく、すべてのエラーを考慮していないことに注意してください。 この場合、私たちは既製のプログラムをユーザーに提供することを目指していません。 プログラマー自身が他のエラーを分析し、エラーやプログラムの処理方法を個別に決定することは非常に重要です。 同時に、いくつかのエラーは処理されてはいけません。プログラムは、エラー129,130​​などのエラーの発生を意味しないように構築されているためです。

上記の例では、コンパイルもクライアント端末もサーバ上にも見つからない小さなアルゴリズムエラーがあります。

任意の権限を無視して、塩の穀物でプログラムコードを取得してください。

ブロック4-5のコードに注意してください。

  // ------------------------------------------------ --------------------------- 4  - 
       if ( Dist_SL &lt; Min_Dist ) // 許されていない場合 。
         {
          Dist_SL = Min_Dist ;  //許可を設定する
          Alert ( "SL = ", Dist_SL, " pt の 距離を増やしました 。 ");
         }
       double SL = Bid - Dist_SL * Point ;  // 要求された価格   SL
 // ------------------------------------------------ --------------------------- 5  - 

演算子if()内の計算の結果、変数Dist_SLは新しい値をとることができます。 通常の最小距離が5ポイントとする。 最初の実行(クイックマーケット)で、この値がサーバー上で20ポイントに設定されているとします。 変数Min_Distは20の値をとります。

 double SL = Bid - Dist_SL * Point ;   //最小距離

また、形成された取引要求がエラー136のために拒否されたと仮定する。ブロック8-9で、プログラムは新しいチックを追跡する。 この期間内に、最小距離の値をサーバー上で変更することができます(たとえば、10ポイントに減らすなど)。 新しいチックが収入する瞬間に、コントロールが新しいサイクルに渡され、10に等しい変数Min_Distの新しい値が計算されます。 しかし、変数Dist_SLの値は変更されずに20に等しい(ブロック4-5はDist_SLの値が増加するようにコード化される)。 このアルゴリズムエラーを除外するには、状況に依存する値だけが変更されるような方法でブロック4-5を書く必要があります(この場合、SLの値です)。Dist_SLの値は、たとえば、次のように変更します。

  // ------------------------------------------------ ------------------------- 4  - 
       double SL = Bid - Dist_SL * Point   // SLの要求価格
       if ( Dist_SL < Min_Dist ) // 許容されていない場合 
         {
          SL = Bid - Min_Dist * Point ;  //   要求された価格   SL
          Alert ("SL = ", Min_Dist, " ptの 距離を増やしました 。");
         }
 // ------------------------------------------------ ------------------------- 5  - 

他の停止命令についてはブロック5-6で同様の変更を行う必要があります。

 

保留中の注文の配置

保留中の注文を置くことと市場の注文を入れることとの間には、プログラミング上の重要な違いはありません。

保留中の注文を市場に変更するために必要な資産は、クライアント端末でもサーバーによっても満たされていないかどうかがチェックされているだけです。 彼らにも制限はありません。 アカウントで利用可能な金額を何回も上回る金額の保留中の注文を行うことができます。 そのような命令は無期限に保つことができます。 市場価格が保留中の注文に対して要求されたオープン価格のレベルに達すると、サーバー上でチェックが行われます。 この注文を開く口座に十分な金額があれば、それは市場のものに変更されます(開かれた)。 そうでない場合は削除されます。

 

関数WindowPriceOnDropped()

MQL4では、シンボルウィンドウで、エキスパートアドバイザーまたはスクリプトが配置された位置の座標を、マウスを使用してプログラムで配置することができます。 たとえば、関数WindowPriceOnDropped()を使用して、スクリプトの添付ファイルの縦座標値を取得できます。

double WindowPriceOnDropped ()

この関数は、EAまたはスクリプトがドロップされたチャートのポイントで価格の値を返します。 EAまたはスクリプトがマウス(「ドラッグアンドドロップ」)を使用して移動された場合、値は真になります。 この値はカスタム指標には定義されていません。

いくつかの既定値の停止注文( openbuystop.mq4 )で、余裕の35%を要するBuyStop注文を開く簡単なスクリプトの例。

 

  // ------------------------------------------------ ------------------------------------
 // openbuystop.mq4
 // コードは教育目的でのみ使用するべきです 。
 // ------------------------------------------------ ------------------------------- 1  - 
 int start () //特別な関数の開始
   {
    int Dist_SL = 10 ;  //プリセットSL(pt)
    int Dist_TP = 3 ;  //プリセットTP(pt)
    double Prots = 0.35 ;  // フリーマージンのパーセンテージ 
    string Symb = Symbol();  // シンボル 
    double Win_Price = WindowPriceOnDropped () ;  //スクリプトはここにドロップされます
    Alert ( "価格はマウスで= ", Win_Price "として設定されています 。");  //マウスで設定
 // ------------------------------------------------ ------------------------------- 2  - 
    while ( true ) // 注文を開くサイクル 
      {
       int Min_Dist = MarketInfo ( Symb, MODE_STOPLEVEL ) ;  // Min。  距離
       double Min_Lot = MarketInfo ( Symb, MODE_MINLOT ) ;  // Min。  ボリューム
       double Free = AccountFreeMargin();  //無料マージン
       double One_Lot = MarketInfo ( Symb, MODE_MARGINREQUIRED );  // 1ロットあたりのコスト 
       double Lot = MathFloor ( Free * Prots One_Lot Min_Lot ) * Min_Lot ;  //たくさん
       // ------------------------------------------------ ------------------------- 3  - 
       double Price = Win_Price ;  //価格はマウスで設定します
       if ( NormalizeDouble ( Price 、 Digits ) <    // // 許可されていない場合 
          NormalizeDouble ( Ask + Min_Dist * Point 、 Digits ) )
         { // BuyStopのみ!
          Price = Ask + Min_Dist * Point ;  //近くにない
          Alert ( "要求 された価格を変更:価格= ", Price ); 
          }
       // ------------------------------------------------ ------------------------- 4  - 
       double SL = Price - Dist_SL * Point ;  // 要求された価格   SL
       if ( Dist_SL < Min_Dist ) // 許容されていない場合 
         {
          SL = Price - Min_Dist * Point ;  // 要求された価格   SL
          Alert ( "距離を増やした SL = ", Min_Dist, " pt " ) ; 
          }
       // ------------------------------------------------ ------------------------- 5  - 
       double TP = Price + Dist_TP * Point ;  // 要求された価格   TP
       if ( Dist_TP < Min_Dist ) // 許容されていない場合 
         {
          TP = Price + Min_Dist * Point ;  // 要求された価格   TP
          Alert ( "距離の増加 TP = ", Min_Dist, " pt " ) ; 
          }
       // ------------------------------------------------ ------------------------- 6  - 
       Alert ( "リクエストはサーバーに送信されました。応答を待ってい ます.. " ) ; 
        int ticket = OrderSend ( Symb, OP_BUYSTOP, Lots, Price, 0, SL, TP ) ; 
        // ------------------------------------------------ -  -  -  -  -  -  -  -  -  -  -  - - 7  - 
       if ( ticket > 0 ) //見つけた!:)
         {
            Alert ( "Order BuyStop", ticket ); 
           break;    // サイクルを 終了 する 
         }
       // ----------------------------------------------------- ------------------------- 8  - 
       int Error = GetLastError () ;  //失敗しました:(
       switch ( Error )    // オーバーフロー可能なエラー 
         {
          case 129: Alert (" 無効な価格。再試行.. " ) ; 
              RefreshRates();  //データを更新する
             continue ;  //次の繰り返しで
          case 135: Alert ( "価格が変更されました 。再試行します.. " ) ; 
              RefreshRates();  // データを更新する 
             continue ;  // 次の繰り返しで 
          case 146: Alert ( "取引サブシステムはビジー状態 です。再試行します.. " ) ; 
              sleep ( 500 ) ;  //単純な解
             RefreshRates () ;  // データを更新する 
             continue ;  // 次の繰り返しで 
         }
       switch ( Error ) //重大エラー
         {
          case 2 : Alert ( "一般的なエラー") ;
              break;  // exit ' switch'
          case 5 : Alert ( "クライアント端末の古いバージョン " ); 
              break;    // exit ' switch'
          case 64 : Alert ( "アカウントがブロックされている" ) ; 
              break;   // exit ' switch'
          case 133 : Alert ( "取引不能" );
              break;    // exit ' switch'
          default : Alert ( "発生エラー", Error  ) ; //その他の選択肢
         }
       break;    // サイクルを終了する 
      }
 // ------------------------------------------------ ------------------------------- 9  - 
      Alert ( "スクリプトの操作が完了しました   ----------------------------- " ) ; 
     return ;  // Exit start()
   }
 // ------------------------------------------------ ------------------------------- 10  - 

スクリプトopenbuystop.mq4の構造は、スクリプトopenbuy.mq4と同じように構築されているので、詳細を記述する必要はありません。 これらのプログラムの基本的な違いのみに注意を向けることにします。

スクリプトがシンボルウィンドウにアタッチされているレベルの価格は、次の行で決定されます。

  double Win_Price = WindowPriceOnDropped () ;  //スクリプトはここにドロップされます

その後、この変数の値は、プログラムの全動作期間中変化しないままである。 これは、スクリプトが複数の注文を開くことができない場合に必要です。 同時に、スクリプトは、ユーザーがスクリプトを添付した場所(価格レベルまで)に近い価格の要求値を計算するたびにスクリプトを実行します。

スクリプトopenbuystop.mq4には、注文を開くための余裕が十分にあるかどうかはチェックされていませんが、注文オープン価格のチェックがあります(ブロック3-4)。 変数Priceの計算された値が、保留中のストップオーダを行う要件(貿易を行うための注文特性およびルール貿易を行う上での要件および制限を参照)に従わない場合、この値は再計算されます。

エラー処理のブロックには、いくつかの小さな変更もあります。いくつかのエラーは考慮されませんが、他のエラーのコードが処理されます。

 

合理的な制限

取引関数の使用に関連して、より一般的な制限に注意を払う必要があります。 たとえば、取引要求を形成する複数のプログラムが1つのシンボルウィンドウで機能する場合にのみ、エラー146が発生します。 私たちの意見では、この慣習は許されていますが、合理的ではありません。

トレーディングのすべての特別な機能を考慮する1つのトレーディングプログラムを作成して使用する方がずっと効率的です。 1つの取引プログラムしか使用しない場合、複数の取引要求を同時に行うことは不可能です。 さらに、アルゴリズム全体が、このようなプログラムではるかに良く構成されています。この確率に従って、成功した取引の確率を考慮し、正確に資金を再配分することができます。

トレードを行うには、フルスケールのエキスパートアドバイザーを使用する方が効率的ですが、スクリプトは1回限りの計算や画面に役立つ情報の表示に適しています。 同時にトレーダが自動取引にエキスパートアドバイザーを使用していない場合は、クライアント端末のコントロールパネルを使用して注文するよりも効率的にスクリプトを使用することができます。

-MQL4ブック, MT4
-,

© 2024 FX・ビットコイン・オプションのシステムトレード開発と取引録 Powered by AFFINGER5