より少ないコード、より多くのアクション...EAを書く

 

Expert Advisorのフレームワークを作ってみようと思います(興味がある人がいれば、私たちもやってみます)。単純なもので、応用プログラマーの知識を必要としないものであれば、可能な限り適しています。

現地で通用している方法とは異なり、上から下へと設計を進めていきます。つまり、まずエンドユーザー向けにEAのメイン(かつ唯一の)ファイルを書き、明らかに不要なものはすべて削除し、これを動作させるためのライブラリを書く。 そして、新しいユースケースを追加してライブラリをアップグレードする、というものである。

https://www.mql5.com/ru/articles/5654 とカルプトフ氏のアドバイザーとの対極、極論として

もちろん、その前に「党是」と「目標-共産主義」を設定する必要があるのですが......。

- ユーザーが戦略を実行するには、100行もあれば十分です。(コメントや入力などの#プロパティは別)。

- 新しい「実体」(関数/クラス/メソッド/定数)の数は最小限に抑えるべきである。

- ライブラリには、カウント可能な数のファイルが含まれている必要があります。

- GUIに適している可能性

- プラグインで拡張可能

達成可能な目標か? 難しいが、原則的にはYESである。そのための方法とアイデアがあります。しかし、まだ解決策はありません :-)

現在のステップは、専門家によるデータの取得を整理することです。ユーザーが簡単に記述できるような形で、同時にメタデータやさらなる拡張のための「手がかり」が残されているのです。(今後 - GUI部分、少なくともデバッグ部分は、さらなるコードで実装されるべきです)


私は、2つのMAが交差したときに取引を行うというシンプルなケースを作成しました。

これに対応して、入力部分は次のようになります。

/** ------- ПАРАМЕТРЫ СОВЕТНИКА ------
**/
input ENUM_APPLIED_PRICE FAST_MA_PRICE=PRICE_CLOSE;
input ENUM_MA_METHOD FAST_MA_METHOD=MODE_EMA;
input int FAST_MA_PERIOD=14;
input int FAST_MA_SHIFT=0;

input ENUM_APPLIED_PRICE SLOW_MA_PRICE=PRICE_CLOSE;
input ENUM_MA_METHOD SLOW_MA_METHOD=MODE_SMA;
input int SLOW_MA_PERIOD=54;
input int SLOW_MA_SHIFT=0;

次にユーザーがしなければならないことは、入力からどのようなデータを受け取るかを記述することです。せめてリストアップしてください。

// просто перечисляем идентификаторы данных
// всех которые нужны для принятия решений
enum ENUM_SERIES {
   FAST_MA,       // id. значений FAST_MA
   SLOW_MA,       // id. значений SLOW_MA
   TOTAL_SERIES   // последний элемент перечисления = кол-во элементов
};

と、このデータをどのように計算/受信しているのかを説明してください(長くなりますが、両端末に適用されます)。

/// вычисление данных
/// эксперт будет обращаться к функции каждый раз когда ему необходимы данные
/// управление кешированием и очерёдность(взаимозависимость) вычислений лежит на верхнем уровне
/// @arg ea - эксперт
/// @arg id - ид.серии данных
/// @arg shift - сдвиг в серии
/// @arg data[] - кешированные результаты
/// @return double - конкретное значение для [id][shift] или EMPTY_VALUE если не может быть вычилено
/// если данные могут быть кешированы, они должны быть сохраненны в массиве data
double GetData(EA *ea,int id,int shift,double &data[])
{
#ifdef __MQL4__
   // для 4-ки всё просто - по идентификаторам серии и бара получить данные
   switch ((ENUM_SERIES)id) {
      case FAST_MA:
         return data[shift]=iMA(ea.Symbol,ea.Period,FAST_MA_PERIOD,0,FAST_MA_METHOD,FAST_MA_PRICE,shift);
      case SLOW_MA:
         return data[shift]=iMA(ea.Symbol,ea.Period,SLOW_MA_PERIOD,0,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);
   }
   return EMPTY_VALUE;
#else
   // для 5-ки несколко сложнее (и кстати не проверено) - надо ещё заводить хендлы стандартных индикаторов
   // и проводить (возможно)лишнее копирование
   static d_fast_ma=0;
   static d_slow_ma=0;
   if (d_fast_ma==0) d_fast_ma=iMA(ea.Symbol,ea.Period,FAST_MA_PERIOD,0,FAST_MA_METHOD,FAST_MA_PRICE,shift);
   if (d_slow_ma==0) d_slow_ma=iMA(ea.Symbol,ea.Period,SLOW_MA_PERIOD,0,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);  
   double tmp[1];
   switch((ENUM_SERIES)id) {
      case FAST_MA: CopyBuffer(d_fast_ma,0,shift,1,tmp); return data[shift]=tmp[0];
      case SLOW_MA: CopyBuffer(d_slow_ma,0,shift,1,tmp); return data[shift]=tmp[0];
   }
   return EMPTY_VALUE;
#endif
}

とし、最後にトレードシグナルを記述する。

/// генерация(вычисление) сигнала при открытии бара
/// @arg ea - эксперт
/// @arg shift - номер бара в таймсерии. Типично будет 0
/// @return int - сигнал OP_BUY или OP_SELL или -1 если сигнала нет 
int SignalOfCross(EA *ea,int shift)
{
   if (FAST_MA_PRICE!=PRICE_OPEN || SLOW_MA_PRICE!=PRICE_OPEN) shift++;
   if (ea.CrossedUp(FAST_MA,SLOW_MA,shift)) {
      return OP_BUY;
   }
   if (ea.CrossedDn(FAST_MA,SLOW_MA,shift)) {
      return OP_SELL;
   }
   return -1;
}

基本的にそれだけです。これだけあればEAを実装するのに十分ですし、ユーザーが大量のドキュメントを読む必要がないのは明らかです。ユーザーは、MQLの基本的な知識さえあればよいのです。あとはすべて、ライブラリ(ここでは気の利いた言葉として、エンジン)がやってくれるはずだ。それはユーザーのために作られるべきで、ユーザーが別の多量のAPIを学ぶためのものではありません。

ちなみに、ここではOnInit :

int OnInit()
{
   ea = new EA();
   // настраиваем таймфрейм "по умолчанию"
   //   символ и период - текущие
   //   TOTAL_SERIES наборов данных и кешируем по 30 в каждом
   //   для получения данных служит GetData
   ea.SetupTimeframe(_Symbol,_Period,TOTAL_SERIES,30,GetData);
   // настраиваем сигнал "по умолчанию"
   ea.SetupSignal(SignalOfCross);
   // ------ настройки завершены ------
   // остальная часть одинакова для всех советников
   int ret;
   if ((ret=ea.OnInit())!=INIT_SUCCEEDED) {
      return ret;
   }
   EventSetTimer(60);

   return(INIT_SUCCEEDED);
}
  

..

Библиотека для простого и быстрого создания программ для MetaTrader (Часть I). Концепция, организация данных, первые результаты
Библиотека для простого и быстрого создания программ для MetaTrader (Часть I). Концепция, организация данных, первые результаты
  • www.mql5.com
Разбирая огромное количество торговых стратегий, множество заказов на изготовление программ для терминалов MT5 и MT4, просматривая огромное разнообразие различных сайтов по тематике скриптов, индикаторов и роботов для MetaTrader, я пришёл к выводу, что всё это многообразие в подавляющем своём большинстве строится на фактически одних и тех же...
 
すべてのコードを正しく挿入してください:この灰色がかったくすみを見ることは不可能です。エディターでボタンをクリックし、表示されるフィールドにコードを 挿入する、という明確な行動計画があります。しかし、頑なにテキストのキャンバスを挿入し、このキャンバスに「コード」スタイルを適用しようとすると
 
Vladimir Karputov:
すべてのコードを正しく挿入してください:この灰色の暗がりを見ることは不可能です。エディターでボタンをクリックし、表示されるフィールドにコードを 挿入する、という明確な行動計画があります。頑固にテキストのキャンバスを挿入し、このキャンバスに「コード」スタイルを適用しようとすると

コードが)正しく挿入されていません。 1つの断片ならまだ対処できますが、もう少し増えるともう大変です...。

つまり、私が決めることではなく、ウェブマスターが決めることなのです。2019年、豊富な資金で、どうやって実現したのか-謎です :-)

ただ、今後はより楽しくするために、まずwikiに多少なりとも大きな書き込みをして、それをここにコピーペーストして、公開コードのボリュームを減らしていこうと思っています。

 
Maxim Kuznetsov:

コードが)正しく挿入されていません。 1つの断片ならまだ対処できますが、もう少し増えるともう大変です...。

つまり、私が決めることではなく、ウェブマスターが決めることなのです。2019年、豊富な資金で、どうやって、実現したのか......謎です :-)

しかし、今後もっと楽しむために、多かれ少なかれ大きな記事はまずwikiに書き、コピーペーストでこちらに転送し、公開コードのボリュームを減らすことにします。

どうやら、コードのブロックをコピーして、メモ帳に貼り付ける必要があるようです。

次に、メモ帳からコピーして貼り付けますが、その前に「新しい」コード用に新しいブロックを作成します。

 

EAの基本的なテンプレートを作成し、ストラテジーファイルは別に作りました。

ユーザーにとって使いやすいと思いますか?

それでも最低限のプログラミングの知識は必要です

そして、「ヘルプ」の指示も、ビデオも、何もあなたを救ってはくれません。

その際、ユーザーには無料でペダルストラテジーを使ってもらう必要があります。

そして、彼らはヘルプを読まないでしょう。

 
Vitaly Muzichenko:

コードのブロックをコピーして、メモ帳に貼り付ける必要があるようです。

次に、メモ帳からコピーして貼り付けますが、その前に「新しい」コード用に新しいブロックを作成します。

少し手間取ったが、なんとなく「色」がついた。:-)

上記のウェブマスターに小石を(というか、小石を):内蔵エディタでペーストするとき、というか明らかに最初の「色付け」のときに、エディタは気に入らないコードの一部を排出するのです。特に、「if ((ret=ea.OnInit())!=INIT_SECEED) {...}」を任意に編集している。どうやらハイライトアルゴリズムはOnInitが唯一のもので、クラス内でオーバーロードすることはできないと信じているようです。

 
これは疑似コードなのでしょうか、それともすでにアプリケーション用なのでしょうか?GetData 関数は、インジケータ「ハンドル」(d_fast_ma、d_slow_ma)に「静的」を使用できません。なぜなら、ユーザはフィルタリングや別のパラメータ(例えば、別のシンボル)を持つ何か別の「ハンドル」のカップルを取得することになるからです。ハンドル」を何らかのオブジェクトにキャッシュしておくか、(効率を考えなければ)「ハンドル」を毎回取得し直すべきでしょう - パラメータが等しい場合は、端末自身がキャッシュすべきです。
 
Maxim Kuznetsov:

もちろん、その前に「党是」と「目標共産主義」を確立しておく必要があるのですが。

1) ユーザーは100行でストラテジーを実行することができる。(コメントや入力などの#プロパティは別)。

2) そのための新しい「実体」(関数/クラス/メソッド/定数)の数を最小限にすること。

3) ライブラリには、カウント可能な数のファイルが含まれていること。

4)GUIに適している可能性がある

5)プラグインによる拡張性


3) ライブラリに含まれるファイルの数にどんな違いがあるのでしょうか?1, 10, 100, 1000?すべては開発者の都合で作られているはずです。もし、彼がすべてを小さなファイルに入れることに抵抗がなければ、ご自由にどうぞ。1つのファイルですべてをコーディングすることに慣れている場合は、ご自由にお使いください。自動化されたバラバラの手段からメガファイルを組み立てるのは、概して難しいことではありません。だから、この点にはこだわらない。

4)GUIの使い勝手-どうなのかよくわからない。ライブラリは、成熟した方法でビジネスロジックを分離したレイヤーです。このレイヤーは、外部のGUIに一切依存してはいけません。GUIはこのレイヤーに依存するはずです。

 
Maxim Kuznetsov:
if (d_fast_ma==0) d_fast_ma=iMA(ea.Symbol,ea.Period,FAST_MA_PERIOD,0,FAST_MA_METHOD,FAST_MA_PRICE,shift);
if (d_slow_ma==0) d_slow_ma=iMA(ea.Symbol,ea.Period,SLOW_MA_PERIOD,0,SLOW_MA_METHOD,SLOW_MA_PRICE,shift);  


あなたのアプローチは、最初から純粋に手続き的なもので、見たままを伝えるものです。平均を価格ではなく、例えば出来高や他の指標で計算しなければならない場合はどうでしょうか。またユーザーを書き直さなければならないのか?平均値の算出はアルゴリズムである。アルゴリズムを適用したいのは、データです。この疑似コードのように)すぐに分離するのではなく、アルゴリズムとデータを混ぜているんですね。

int period_ma = 12;
int shift = 3;
double fast_ma = SMA(Close, period, shift);

あ、シリーズインデックスを忘れてました。- 本当はないはずなんです。アルゴリズムをパイプラインに組み合わせて、リングバッファで すべてを計算する必要があるのです。

 
Maxim Kuznetsov:

https://www.mql5.com/ru/articles/5654 とカルプトフ氏のアドバイザーへの対抗策、極論として

私のは、不当に忘れ去られて いる。そして、むなしく、そこにあるもの。

 
Vasiliy Sokolov:

あなたのアプローチは、最初から純粋に手続き的なもので、見たままを伝えるものです。 平均を価格ではなく、例えば出来高や他の指標で計算しなければならない場合はどうでしょうか。ま たユーザーを書き直さなければならないのか?平均値の算出はアルゴリズムである。アルゴリズムを適用したいのは、データです。この疑似コードのように)すぐに分離するのではなく、アルゴリズムとデータを混ぜているんですね。

あ、シリーズインデックスを忘れてました。- 本当にあってはならないことです。アルゴリズムをパイプラインに組み合わせて、リングバッファですべてを計算する必要があるのです。

何事も、そのためにやっている部分が大きい。そうすれば、あなたがすべてを計算し、Expert Advisorが配列と相互関係を自ら把握することができます。以前、MT4でmicro-excelのような表計算ソフトを作ったことがありますが、計算の構成はこのモデルがベースになっています。

ユースケース型は、基本的に手続き型である。潜在的なユーザー(初級プログラマー)は、このように書きます。


理由: