取引環境に対応する際の典型的な間違いとその対処法

 
このスレッドでは、いくつかのアルゴリズムで端末の取引環境を操作するときに発生する一般的なミス、その排除と将来的に回避するための方法について説明します。
 
OKです。
あくまでも導入として。
エキスパートアドバイザーは、最後に決済された注文の方向性(または利益、...)を分析します。最後の注文は2日前に締め切られました。
トレーダーはヒストリーの深さを1日に設定した。
OrdersHistoryTotal() には、その注文は表示されません。
解決策は?
 
Andrei Fandeev:
オッケーです。
あくまでも導入として。
Expert Advisorは、最後に決済された注文の方向性(または利益、...)を分析します。最後の注文は2日前に締め切られました。
そして、トレーダーはヒストリーの深さを1日に設定した。
OrdersHistoryTotal() には、その注文は表示されません。
解決策?

MT4の場合 - 私見ですが、曖昧にせず、EA起動時に必要な履歴の深さを使用するように警告を出すようにします。

MT5では、必要な深さまで履歴を読み込むことができます。

 
Artyom Trishkin:

MT4の場合 - 私見ですが、曖昧にせず、EA起動時に必要な履歴の深さを使用するように警告を出すようにします。

ユーザーに依存するのは良くないことです。チェックが必要です。
Artemさん、MT4では、設定した履歴の深さの値を取得するためのGetが見つからなかったのですが。
本当にプログラムで取得することは不可能なのでしょうか?

 
Andrei Fandeev:

ユーザーに依存するのは良くないことです。チェックが必要です。
Artemさん、MT4では、設定した履歴の深さの値を取得するためのGetが見つかりませんでした。
本当にプログラムで取得することは不可能なのでしょうか?

確かに。

 

取引環境の操作とEAの作成には、2つのパラダイムがあります。

  1. イベント入力(OnTick、OnTimerなど)は、互いに依存しあっています。イベントとイベントの間には、(キャッシュのようなスピードのためではなく、ユーザビリティのために)必ず持っていなければならない情報があるのです。例えば、OrderSendAsyncの結果を保存し、OnTradeTransactionで 使用する必要があります。キャッシュは必須情報ではなく、高速化のためにのみ使用されます。だから、すぐには検討しないのです。
  2. イベント入力(OnTick、OnTimerなど)は、互いに依存しません。各入力はゼロからです。大雑把に言うと、イベントごとに自分で実行するスクリプトのようなものです。
MT4では、おそらく2番目のオプションですべてを解決することができます。MT5はそれほど明確なものではありません。


第一の選択肢に対する第二の選択肢の優位性

  • 任意の場所(正常・異常)でアルゴリズムを終了させることができます。
  • 任意の場所でアルゴリズムを開始/継続することができます。
  • 高い信頼性


デメリット

  • In Testerは、性能面で最初のバリエーションに劣ることになります。
  • ゼロからのロジックなので、どこか「非論理的」なコードを書くことになり、最初の段階では慣れが必要です。

 

取引環境APIを比較するには?多種多様なTSを紹介する。そして、理想の仮想APIを想像してみよう。それは、最小限の労力でTSを信頼性の高いコードに具現化することができる。

このように非常に理想的な仮想APIを現実のAPIからラッパーとして作ることができれば、元のAPIが優れていることになる。ラッパーを作るのに、どんなに手間と時間がかかっても。


MT4とMT5は、この基準では優れたAPIです。ソースAPIだけが難しいが、優れたラッパーを書くことができる(アーキテクチャや技術的な制約がない)ので、良いのである。

つまり、MT5がMT4よりも複雑だというのは、彼らが使っているMT4のラッパーと同じくらい使いやすいMT5のラッパーにまだ出会っていない(たぶんまだ書かれていない)ことを意味しているのです。


一般的に、どちらのプラットフォームでも、低レベルのAPIから単一の高レベルのAPI(ラッパー)を作成することができます。つまり、彼らの取引環境APIの複雑さは同等なのです

 

MT4はかなりハイレベルなAPIを持っているので、普遍的により使いやすいラッパーを書こうとする人はほとんどいません。しかし、MT5ではそうではありません。オリジナルの低レベルAPIは、何らかのラッパーを書くことを要求しているだけなのです。ですから、このスレッドで各ラッパーの特徴を議論してもあまり意味がありません。むしろ、それでもラッパーが必要であることを示すことが重要です。低レベルAPIのどのような機能が、高レベルAPIを書く際に考慮される必要があるのでしょうか。

В общем, обе платформы позволяют из низкоуровневых API создать единый высокоуровневый API (обертка). Так что сложности API торговых окружений у них равны!

この発言に基づき、MT4のコードに劣らない使い勝手の良いMT5コードの書き方を学ぶ必要があります。APIラッパーは異なるかもしれませんが(通常は構文)、アーキテクチャ的にMT5はMT4より劣ってはならず、そうでなければ強調された文は失われます。したがって、MT5のコードがより煩雑であることは、批判する理由ではなく、MT4に劣らない使いやすいラッパーに縫い込むための手助けであると考えるべきでしょう。

 
簡単なMT4-template TSを例にとって説明します。

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

オーダーループの整理

fxsaber さん 2018.02.15 23:19

// Шаблон большинства ТС

#property strict // обязательно

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит ордер соответствующего типа
bool OrdersScan( const string Symb, const int Type )
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() == Type) && (OrderSymbol() == Symb))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const int Type, const double Lots = 1 )
{
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((OrdersScan(Symb, 1 - Type)) && (Res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100)));

  // Открыли позицию по сигналу
  return(Res && !OrdersScan(Symb, Type) && OrderSend(Symb, Type, Lots, SymbolInfoDouble(Symb, Type ? SYMBOL_BID : SYMBOL_ASK), 100, 0, 0));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, OP_BUY);
  else if (SellSignal(Symb))
    Action(Symb, OP_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

MT4の利便性を示すものでは少しもなく、あくまで比較の基準点となるものです。MT5のラッパーが持つべきは、その低い使い勝手のハードルなのです。テンプレートは、2番目のパラダイムに基づいて 書かれています。


MT5でも同じことを書いているようです

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

オーダオーバーフローサイクルの構築

fxsaber さん 2018.02.15 22:30

// Шаблон большинства ТС

#include <Trade/Trade.mqh>

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит позицию соответствующего типа
bool PositionsScan( const string Symb, const ENUM_POSITION_TYPE Type )
{
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if ((PositionGetSymbol(i) == Symb) && (PositionGetInteger(POSITION_TYPE) == Type))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const ENUM_POSITION_TYPE Type, const double Lots = 1 )
{
  static CTrade Trade;    
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((PositionsScan(Symb, (ENUM_POSITION_TYPE)(1 - Type))) && (Res = Trade.PositionClose(PositionGetInteger(POSITION_TICKET))));

  // Открыли позицию по сигналу
  return(Res && !PositionsScan(Symb, Type) && (Type ? Trade.Sell(Lots, Symb) : Trade.Buy(Lots, Symb)));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, POSITION_TYPE_BUY);
  else if (SellSignal(Symb))
    Action(Symb, POSITION_TYPE_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

同じTSでも、なぜかより多くのコードを書く人がいます。しかし、実はこのコードも同じようにうまくいく。ほとんどのTCはBuySignalとSellSignalを書くだけでいいのです。他に必要なものはありません。

テンプレート例は、特にSBで書かれています。MT5の専門家に質問ですが、コードは正しいのでしょうか?


ラッパーの必要性を示す機能を赤色で表示しました。その問題点については、こちらで 解説しています。これは、古くはOrderSendの後にポジションが開くのを待ち、Sleepを使って解決していたポジションの再オープンの問題を思い出す人がいることでしょう。しかし、実はこの問題はOrderSendとは関係がない。取引環境を正しく読み取る方法を知る必要があります。

 
fxsaber:

取引環境を正しく読み取ることが必要です。

簡単な例で正しく理解する

// Возвращает количество позиций по символу
int GetAmountPositions( const string Symb )
{
  int Res = 0;
  
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if (PositionGetSymbol(i) == Symb)
      Res++;
      
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderGetTicket(i) && (OrderGetInteger(ORDER_TYPE) <= ORDER_TYPE_SELL) &&
        !OrderGetInteger(ORDER_POSITION_ID) && (OrderGetString(ORDER_SYMBOL) == Symb))
      Res++;  

/*
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
      Res++;
*/      
  return(Res);
}

一言で言えば、「成行注文があれば、それも『ポジション』と考えよ」ということです。包み込むようなポジションなので、引用符で囲んでいます。ハイライトされたコードは通常、どこにも表示されません。しかし、ポジションの再オープンを 回避することができます。ここで最も興味深いのは、赤で示した部分です。このチップの必要性はすぐにわかるものではありません。

いわゆる寄り付き成行注文があることです。同じSL/TPです。もちろん、このような成行注文を「ポジション」と見なすのは好ましくありません。そして、せっかく出した注文も閉まってしまうのは避けたい。つまり、ハイライトされた状態が適切なフィルターということになる。


ZZZはこのコードをここに 貼り付けて、デモサーバーで 結果を確認してください。

 
fxsaber:

簡単な例で見る正しい選択

簡単に説明すると、成行注文がある場合は、それも「ポジション」と考えてください、ということです。包み込むようなポジションなので、引用符で囲んでいます。ハイライトされたコードは通常、どこにも表示されません。しかし、ポジションの再オープンを 回避することができます。ここで最も興味深いのは、赤で示した部分です。このチップの必要性はすぐにわかるものではありません。

いわゆる寄り付き成行注文があることです。同じSL/TPです。もちろん、このような成行注文を「ポジション」と見なすのは好ましくありません。そして、せっかく出した注文も閉まってしまうのは避けたい。つまり、ハイライトされた状態が適切なフィルターということになる。


HZのコードをここに 貼り付けて、デモサーバーで 結果を確認してください。

質問:取引注文を送信してから次のティックまで、サーバーによって成行注文が発注されない場合はどうなりますか?

理由: