KimIVの便利な機能 - ページ 2

 
次のようにするとどうでしょう。
if (err==146)
{
while (IsTradeContextBusy())
{
if (IsTradeAllowed()) break;
else
Sleep(1000*1,1);
}}.
この方が解決は早いと思います。ご意見をお聞かせください。
ありがとうございます。
 
Red.Line писал (а): 焦げパイくらいですが、それでももしかしたら誰かが大量データセットからμlで備蓄・サンプリングする問題に直面したことがあるのかもしれませんね、有益なトピックをありがとうございます。µlとデータベース?その方向で考えた人はいますか?
確かにシンプルな解決策ですが、何か。 https://forum.mql4.com/ru/9377
 
zhuki:
このバリエーションはいかがでしょうか。
if (err==146)
{
  while (IsTradeContextBusy())
  {
    if (IsTradeAllowed()) break;
    else 
    Sleep(1000*1,1);
  }
}
この方が早く解決できるように思います。私はこの方法で仕事をしています。コメント
ありがとうございます。

私はそれでいいんです。理解しながら間が持たない、動作が速い...。しかし、あなたのバージョンには、不当な冗長性があります。

IsTradeContextBusy 関数は、取引スレッドの占有フラグを返します。195回目のビルド以前は、そのような機能は全くありませんでした。そこで、EAがトレードを許可されているサインを返すIsTradeAllowed 関数を使い、トレードの流れを自由にしました。

EAのプロパティダイアログボックス(F7キー)で「EAを取引可能にする」ボックスにチェックを入れて、EAの取引を許可しています。

エラー146(Trade Stream is busy)はExpert Advisorの取引を許可することとは関係ありません。そこで、IsTradeAllowed 関数のプロパティについて、取引スレッドにのみ関係するものを見てみましょ う。

そのため、トレードスレッドはフリーとなり、IsTradeAllowed 関数はTrue を返します。取引スレッドがビジー状態であるため、IsTradeAllowed 関数はFalse を返します。では、IsTradeContextBusy 関数が返す値を見てみましょう。取引スレッドが空いている場合、IsTradeContextBusy 関数はFalse を返します。取引スレッドがビジー状態である場合、IsTradeContextBusy 関数はTrue を返します。同じ貿易フローの状態でも、IsTradeAllowed 関数とIsTradeContextBusy 関数の値は逆になっていることが分かります。さらに、これらの関数は、貿易の流れの状態に関して、互いに補完し合うというよりは、重複している。したがって、そのうちの1つを除外することができる。どれだ?IsTradeAllowed 関数は、すでに述べたように、トレードフローの状態フラグとは別に、この状況、すなわち、エラー146(トレードフローがビジー状態)を処理するときに、EAにトレードを許可するフラグも返すので、私たちにとっては必要ないものである。したがって、IsTradeContextBusy 関数は 1 つだけ使用すれば十分である。以上の省略を実行すれば、あなたのコードは私のものになる。

if (err==146) while (IsTradeContextBusy()) Sleep(1000*1,1);
間合いの大きさが違うだけです。しかし、これは好み、個人的な好み、取引スタイルなどの問題である。0.1秒の間を置くことができる。主義主張の問題ではないのですが......。ただ、11秒がいいんです。
 
しかし、私は正確さを期すために、あらゆる種類の取引操作の 間に、5秒からスレッドのリリースまでの間を作る方が良いと考えています。ありがとうございます。
 

SetOrder 関数に2つのエラーが見つかりました。

  1. MarketInfo 関数の使用方法が間違っている。これは、sy パラメータをチェックする前ではなく、後に呼ばれるべきものでした。
  2. 注文設定レベルの誤動作を修正。さらに、ストップ高やテイクオーバーの価格水準も修正されていない。現在は修正され、完全に動作しています。この後少し紹介するテストスクリプトを使って、ずっとテストしています。

注目!オ ンライントレードのSetOrder 機能付きポストを修正しました。機能は少し長めです。ポスト全体に入りきらなかったので、トレーラーに移動することになりました。

 

今回は、SetOrder 関数の動作のポイントを説明することにしました。私自身は注文を受ける仕事をしていませんので、ここは他人の領域です。おそらく、SetOrder 関数の動作を知っている人が、改善点を提案したり、エラーを見つけたりするのでしょう。

1.コードの最初の行では、ローカル変数が宣言され、その一部が初期化されています。例えば、lsCommには、EA名とGetNameTF 関数が返すタイムフレーム名が書き込まれています。ちなみに、GetNameOPGetNameTFMessageなどの 関数については、質問がある人がいる場合だけ、くどくど説明するつもりはない。

string   lsComm=WindowExpertName()+" "+GetNameTF(Period());

2.受信したパラメータを確認する。syが 空の場合、現在のツール名で初期化される。チャート上のアイコンの色に関する変数は、操作の種類によって初期化されます。ゼロでない注文の有効期限が現在時刻より短い場合、ゼロにリセットされます。

if (sy=="" || sy=="0") sy=Symbol();
msl=MarketInfo(sy, MODE_STOPLEVEL);
if (op==OP_BUYLIMIT || op==OP_BUYSTOP) clOpen=clOpenBuy; else clOpen=clOpenSell;
if (ex>0 && ex<TimeCurrent()) ex=0;

3. 取引の試行回数の本体で、その回数はグローバル変数 NumberOfTryの 値で制限されます。SetOrder 関数のメインループの中で行われる操作は、さらにその上を行く。

for (it=1; it<=NumberOfTry; it++)

4.テスターでSetOrder 関数が実行されない場合、その動作を終了させる機会がある。トレードフロー解放サイクルの待機はここで行う。市場環境変数が更新され、現在時刻が記録されます。

if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
  Print("SetOrder(): Остановка работы функции");
  break;
}
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
ot=TimeCurrent();

5.取引サーバーにリクエストを送信すること。チケットが正であれば、SetOrder 関数を終了する。

ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, ex, clOpen);
if (ticket>0) {
  if (UseSound) PlaySound(NameFileSound); break;
 

6.チケットが否定された場合、実行エラー処理を 行います。
7.128(取引実行の待ち時間が終了しました)、142(注文がキューに入りました)、143(注文がディーラーによって実行されました)のエラーの場合、66秒間中断します。一時停止後、ExistOrders関数(後述)を使って、サーバーからの要求から現在の時点までの時間間隔に、すでに注文が設定されているかどうかを確認する。順番が決まっている場合は、機能を終了します。

err=GetLastError();
if (err==128 || err==142 || err==143) {
  Sleep(1000*66);
  if (ExistOrders(sy, op, mn, ot)) {
    if (UseSound) PlaySound(NameFileSound); break;
  }
  Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
  continue;
}

8.ローカル変数には、アイテムサイズとBid価格、Ask価格が格納されます。

mp=MarketInfo(sy, MODE_POINT);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);

9.エラー130(不正確なストップ)の場合、注文、ストップ、テイクアウトの価格水準は可能な限り修正されます。

// Неправильные стопы
if (err==130) {
  switch (op) {
    case OP_BUYLIMIT:
      if (pp>pa-msl*mp) pp=pa-msl*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_BUYSTOP:
      if (pp<pa+(msl+1)*mp) pp=pa+(msl+1)*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_SELLLIMIT:
      if (pp<pb+msl*mp) pp=pb+msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
    case OP_SELLSTOP:
      if (pp>pb-msl*mp) pp=pb-msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
  }
  Print("SetOrder(): Скорректированы ценовые уровни");
}

10.問題解決やエラーの発見に役立つ情報をレポートに表示します。

Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa,"  Bid=",pb,"  sy=",sy,"  ll=",ll,"  op=",GetNameOP(op),
      "  pp=",pp,"  sl=",sl,"  tp=",tp,"  mn=",mn);
if (pa==0 && pb==0) Message("SetOrder(): Проверьте в обзоре рынка наличие символа "+sy);

最後に他のエラーを処理します。あるものは長い休止時間(5分)を表示し、あるものはExpert Advisorをブロックし、あるものはさらに取引を試みることを許可する等です。

それだ!説明終了

 

ExistOrders()関数を使用します。

注文の有無を示すフラグを返す。オーダーが設定されているか否かの質問に答える。この機能を使って、任意の注文だけでなく、より具体的な注文も依頼することができます。リクエストフィルターは、機能パラメーターを用いて設定する。

  • sy- 楽器の名称に制限を加える。デフォルトのパラメータは""で、制限なし、つまりどんな楽器でもOKです。NULLを渡した場合、注文の選択は現在のシンボルによって制限されます。
  • op- オーダータイプに制限を設けます。デフォルトでは制約なし、つまりどのような注文タイプでもチェックされます。有効な値は-1、OP_BUYLIMIT、OP_BUYSTOP、OP_SELLLIMIT、OP_SELLSTOPです。
  • mn- 注文の識別番号 (「マジック」) に制限を設けます。デフォルトでは制約なし、つまり任意のマジックナンバーを持つオーダーがチェックされます。
  • ot- オーダーの設定時間に制限を設けます。このパラメータ値より後に設定されたオーダーであることを確認する。デフォルトでは、制限なし、つまり、任意の設定時間の注文がチェックされます。
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 12.03.2008                                                     |
//|  Описание : Возвращает флаг существования ордеров.                         |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любой ордер)                    |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время установки)          |
//+----------------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal(), ty;
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ty=OrderType();
      if (ty>1 && ty<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (ot<=OrderOpenTime()) return(True);
          }
        }
      }
    }
  }
  return(False);
}
 

ExistOrders() 関数の使用例です。

1.注文の可否を確認する

ExistOrders();

2.現在のチャート上で、任意の商品の注文の可否を確認することができます。

ExistOrders(NULL);

3.任意の商品のBuyLimit注文の有無を確認する。

ExistOrders("", OP_BUYLIMIT);

4.EURUSDにマジックナンバー123456のSellStop注文があるか確認する

ExistOrders("EURUSD", OP_SELLSTOP, 123456);

5.セットアップ時間2時間以内の注文の可否を確認する。

ExistOrders("", -1, -1, TimeCurrent()-2*60*60);
トレイラーには、ExistOrders 関数をテストするスクリプトがあります。スクリプトの最初の4つの例は、コメントアウトされています。

ファイル:
 

警告!2 008.03.12 07:24 の投稿で、SetOrder.mq4 の添付ファイルを差し替えました。