記事"MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第21部): 取引クラス - 基本クロスプラットフォーム取引オブジェクト"についてのディスカッション - ページ 3

 
Artyom Trishkin:
取引リクエストとポジションを比較する必要がある場合、最も簡単な方法はポジション識別子を設定することです(マジックではありません)。各リクエストは独自の識別子を持っています。アドバイザーのマジックは、すべてのポジションに対して1つのままにしておくことができます。そうすれば、識別子(ポジションや注文のマジックに書き込まれ、失われることはない)によって、いつでもリクエストとポジションや注文を正確に一致させることができる。

こんな感じでしょうか?

トレード・リクエスト

ulong order_magic = m_engine.SetCompositeMagicNumber(m_magic, 0, 0, m_order_id);
bool submit_ok    = m_engine.PlaceBuyLimit(m_lot_size, m_symbol, m_entry, m_hard_stop, m_ratio_target, order_magic, m_comment, m_expiry);

イベントハンドラ

void CMyRobot::EngineEventHandler(int event_id, const long &lparam, const double &dparam, const string &sparam, bool testing, long chart_id)
{
   if (sparam != m_symbol) return;                                                  //--- シンボルが不一致の場合、イベント処理をスキップする。

   if (event_id > SERIES_EVENTS_NO_EVENT && event_id < SERIES_EVENTS_NEXT_CODE) {   //--- 時系列イベントの処理
      if (event_id == SERIES_EVENTS_NEW_BAR) {                                      // "新しいバー "イベント: lparam = 期間 | dparam = 日時
         this.RefreshAllIndicators(1);
         this.ExecuteFSM(1, chart_id);                                              // 有限ステートマシンを実行する(注:新しいバーのインデックス=1)
      }
   }
   else
   if (event_id > TRADE_EVENT_NO_EVENT && event_id < TRADE_EVENTS_NEXT_CODE) {      //--- 取引イベントの処理
      CArrayObj *event_list = m_engine.GetListAllOrdersEvents();                    // 取引イベントのリストを取得する
      if (event_list == NULL) return;
      
      //--- リストの最後からの相対的なイベントインデックスのシフトを計算する。
      //--- バックテストでは、シフト値はイベントハンドラの'lparam'パラメータに渡される。
      //--- 通常の運用では、取引イベントは1つずつ送信され、OnChartEvent()で処理される。
      int shift = testing ? (int)lparam : 0;
      CEvent *event = event_list.At(event_list.Total() - 1 - shift);
      if (event == NULL || event.GetPendReqID() != m_order_id) return;
      
      switch (event.TypeEvent())
      {
         case TRADE_EVENT_PENDING_ORDER_PLASED:                                     //--- 未決注文の発注
            if (m_state_curr == FSM_PENDING_ORDER && m_ticket == WRONG_VALUE)
                m_ticket = event.TicketOrderEvent();
            break;
      
         // ...
      }
   }
}
 

問題:上記で必要なCEvent::GetPendReqID() メソッドは以下のとおりです。 プロテクトされた!!DoEasyのソースコードを変更することなく、何か良いアイデアはありませんか?私の考えでは、これらのメソッドはpublic であるべきです ;-)

class CEvent : public CObject
  {
//...
protected:
//--- (1)指定されたマジックナンバー、(2)第1グループのID、(3)第2グループのID、(4)マジックナンバーの値から保留中のリクエストを返す。
   ushort            GetMagicID(void)                          const { return ushort(this.Magic() & 0xFFFF);                                 }
   uchar             GetGroupID1(void)                         const { return uchar(this.Magic()>>16) & 0x0F;                                }
   uchar             GetGroupID2(void)                         const { return uchar((this.Magic()>>16) & 0xF0)>>4;                           }
   uchar             GetPendReqID(void)                        const { return uchar(this.Magic()>>24) & 0xFF;                                }
//...
};
 
Dima Diall :

問題:上記で必要なCEvent::GetPendReqID() メソッドは以下のとおりです。 プロテクトされた!!DoEasyのソースコードを変更することなく、何か良いアイデアはありませんか?私の考えでは、これらのメソッドはpublic であるべきです ;-)

CEngineクラスを見てください。CEngineクラスだけがユーザープログラムにライブラリへのアクセスを提供します。

他のすべてのクラスはライブラリのニーズに対応するもので、ユーザ向けではありません。ただし、ライブラリを接続した後にプログラムで利用できるライブラリ・サービス関数は 例外です。

 
Artyom Trishkin:

CEngineクラスを見る必要がある。CEngineクラスだけが、ユーザー・プログラムにライブラリへのアクセスを与える。

他のすべてのクラスはライブラリのニーズに対応するものであり、ライブラリに接続した後にプログラムで利用できるライブラリ・サービス関数を除いて、ユーザー向けではない。

例を挙げていただけますか?CEngine クラスを見ていると、イベントのリストを抽出し、そのタイプなどをチェックすることができるようです。しかし、CEngine オブジェクトから マジック・ナンバー(グループとリクエストID)に含まれる特定のイベントの詳細を読み取る明らかな方法は見当たりません。私の見るところ、上記のイベント・ハンドラの例のように、ロボットのeven-handlerメソッド(CEvent:GetPendReq() )で CEvent オブジェクトのインスタンスから直接この情報を読み取る必要があります。

class CEngine
  {
//...
//...
//--- (1) 注文、取引、ポジションイベントのリスト、(2) インデックスによるベース取引イベントオブジェクト、(3) 新規取引イベントの数を返す。
   CArrayObj           *GetListAllOrdersEvents(void)                    { return this.m_events.GetList();                     }
   CEventBaseObj       *GetTradeEventByIndex(const int index)           { return this.m_events.GetTradeEventByIndex(index);   }
   int                  GetTradeEventsTotal(void)                 const { return this.m_events.GetTradeEventsTotal();         }
//--- 最後の取引イベントをリセットする
   void                 ResetLastTradeEvent(void)                       { this.m_events.ResetLastTradeEvent();                }
//--- (1) 最後の取引イベント、(2) 口座プロパティの最後のイベント、(3) シンボルプロパティの最後のイベントを返す。
   ENUM_TRADE_EVENT     LastTradeEvent(void)                      const { return this.m_last_trade_event;                     }
   int                  LastAccountEvent(void)                    const { return this.m_last_account_event;                   }
   int                  LastSymbolsEvent(void)                    const { return this.m_last_symbol_event;                    }
//--- (1) ヘッジ口座、(2) テスターでの作業、(3) 口座イベント、(4) シンボルイベント、(5) 取引イベントフラグを返す。
   bool                 IsHedge(void)                             const { return this.m_is_hedge;                             }
   bool                 IsTester(void)                            const { return this.m_is_tester;                            }
   bool                 IsAccountsEvent(void)                     const { return this.m_accounts.IsEvent();                   }
   bool                 IsSymbolsEvent(void)                      const { return this.m_symbols.IsEvent();                    }
   bool                 IsTradeEvent(void)                        const { return this.m_events.IsEvent();                     }
//...
//...
  };
 
Dima Diall :

CEngineはどんなエンジンですか?CEngine については、"Я смотрю на классCEngine и вижу, что можно извлечь список событий, проверить их тип и т.Д.,Поэтому я могу получить доступ к каждому событию, но не нахожу очевидного способа прочитать конкретные детали события、 CEngineを 使用することにより、 以下のようなことが可能になります。- CEventは、CEngineを 使用することで、以下の ようなことが可能になります、 この場合、CEventは以下の ようになります:: GetPendReqID ()

少々お待ちください。次のru-segmentの記事はアドバイザーについてで、そこで説明しようと思う。

 
Artyom Trishkin:

ちょっと待ってください。ru-segmentの次の記事はアドバイザーについてで、そこで説明しようと思う。

オーケー、クールだ。