MetaTrader 5 Strategy Testerの開発計画について - ページ 8

 
Aliaksandr Hryshyn:
この左のデザインで、関数(クラス、構造体など)にコメントをつけている人はどのくらいいるのだろうか。

非常によく、濃密に使っています(本当は、「四角」のような書式ではなく、「ちょうどいい」書き方をしています。

これが私の現在の入札履歴のインターフェースファイルです。 しかも、コメント数の上限がありません。

// СTradeHistoryI переносимый интерфейс торговой истории 

// История состоит из компонент-наследников интерфейса CHistoryPosComponentI
// 
// Реально для МТ4 имплементацией интерфейса является объект CMT4TradeHistory, для МТ5 - объект CMT5TradeHistory
// CMT4TradeHistory представляет из себя массив объектов CMT4HistoryOrderInfo, наследников интерфейса CHistoryPosComponentI.
// Фактически это массив исторических МТ4-ордеров.
// CMT5TradeHistory представляет из себя массив объектов CMT5HistoryPositionInfoCore, наследников интерфейса CHistoryPosComponentI.
// Объект CMT5HistoryPositionInfoCore не имеет прямого аналога в МТ5-терминах, это два массива ордеров и сделок, а также структура данных,
// имеющуая идентификатор позиции (m_lPosID или POSITION_IDENTIFIER), тикет магик, вид позиции, и так далее, по аналогии с МТ4-ордером,
// фактически, массивы ордеров и сделок - это аналоги ордеров и сделок обычной неттинговой МТ5-позиции, а структура данных - относится
// к хеджевой позиции, и имеет аналог МТ4-ордера. 
//
// Реально при запросе у позиции компоненты CHistoryPosComponentI в МТ4 мы получаем указатель на ордер (класс CMT4HistoryOrderInfo),
// а в МТ5 - на ядро позиции (класс CMT5HistoryPositionInfoCore) 

#include <MyLib\DebugOrRelease\DebugSupport.mqh>
#include <MyLib\Common\MyObject.mqh>
#include <MyLib\Common\CurSymEnum.mq5>
#include <MyLib\Common\TrendEnums.mqh>
#include <MyLib\Trade\TradePosComponentI.mqh>
#include <MyLib\Trade\SortTradePosComponentT.mqh>

class CTSContainerI;

class CROTradeHistoryI: public CMyObject
{
public:

   void CROTradeHistoryI() {    SetMyObjectType(MOT_TRADE_READONLY_HISTORY_I); };
   virtual void ~CROTradeHistoryI() {};
   
   virtual uint GetTotalComponents() const = 0;  // Получение общего числа компонент
   virtual CHistoryPosComponentI* GetComponent(uint uiComponentIdx) const = 0;
   virtual CHistoryPosComponentI* GetOldestOpenComponent() const = 0; // Может вернуть NULL !!!
   virtual CHistoryPosComponentI* GetNewestCloseComponent() const = 0; // Может вернуть NULL !!!
   
   // Функция ищет внутри истории компоненту с указанным тикетом. 
   // В случае, если ее нет - возвращается false.
   // Если компонента найдена - возвращается true, и uiComponentIdx устанавливается на индекс компоненты внутри позиции.
   virtual bool FindComponentByTicket(long lTicket,uint &uiComponentIdx) const = 0;
   
   // Функция анализирует историю и возвращает символ, по которому совершены сделки.
   // Если все выбранные сделки имеют один и тот же символ - возвращается этот символ.
   // Если сделки имеют разные символы или сделок нет - возвращается CS_CURRENT.
   // Если хотя бы один символ CS_UNKNOWN  - возвращается CS_UNKNOWN
   virtual ECurrencySymbol GetSymbols() const = 0;
};


class CTradeHistoryI: public CROTradeHistoryI
{
public:
   void CTradeHistoryI() {    SetMyObjectType(MOT_TRADE_HISTORY_I); };
   virtual void ~CTradeHistoryI() {};
   
   // Выбор существующей истории. 
   // Указывается магик и символ, по которому выбираются исторические ордера, а также промежуток времени, в котором необходимо искать их.
   // Если ulMagic = 0 - выбираются все позиции по всем магикам.
   // Если ECurrencySymbol = CS_UNKNOWN - выбираются все позиции по всем символам
   // Если ECurrencySymbol = CS_CURRENT - запрашивается функция Symbol(), и выбираются все позиции по этому символу
   // ptcTSContainer - указатель на контейнер таймсерий, по которому можно определять просад для каждой позиции. Может быть NULL, в этом случае просад устанавливается нулевым.
   // Возвращает число компонент позиции внутри истории (может быть нулевым если ничего не найдено) или WRONG_VALUE в случае ошибок
   // NOTE !!! 
   // При выборе - отложенные ордера не учитываются.
   virtual int Select(ulong ulMagic = 0,ECurrencySymbol csSymbol = CS_CURRENT,datetime dtFrom = MIN_DATETIME,datetime dtTill = NEVER_EXPIRES,CTSContainerI* ptcTSContainer = NULL) = 0;

   
   // Расширенный интерфейс
   virtual void Sort(ESortTPCMode stmMode = STM_BY_OPEN_TIME_A) = 0;
};


一般に、より具体的なクラスであればあるほど、より多くのコメントが必要です。

まあ、Peter Konovのようにメガメモリを持っている人以外は、コメントはなくても大丈夫でしょう。


 
Nikolai Semko:

そう、好きなものは好きなんです。個人的には、コードそのものが見えないほど整形されているのはいただけません。

Visual Studio Codeを マスターすれば、解決できるかもしれませんね。

へっへっへっへ...。木を見て森を見ず」だと混乱します。

この断片だけで、すべてが正しいように見えるが、一つのコメントもなく、この「積み上げ」のように、漏れもなく、やれやれ、なんとわかりにくいことか......。

 
Roman:

この手のコメントは目が詰まるので一旦削除し、こんな風に書いています。

そこだ!はい。

短時間でシンプルな機能であれば、最もノーマルなコメントスタイルだと思います。

 

私の5セントを入れておきます。

フォーマットについてはいくつかのスタイルを入力する必要があります。ひとつは、MQのものです。これを提案します。

if(.....)
{
   ..............
}
else
if(.........)
{
   ......
   for(.....)
   {
      .....
   }
)
else   ......
 
Сергей Таболин:

私の5セントを入れておきます。

フォーマットについてはいくつかのスタイルを入力する必要があります。ひとつは、MQのものです。これを提案します。

今のスタイルでは、中括弧がほとんど好きじゃないんです。なぜ移動させたのか、その理由がわからない。私はいつも、あなたの例のように、すべての中括弧をTabに合わせます。

 
Georgiy Merts:

非常によく、濃密に使っています(本当は、「四角」のような書式ではなく、「ちょうどいい」書き方をしています。

これが私の現在の入札履歴のインターフェースファイルです。 しかも、コメント数の上限がありません。


一般に、クラスが具体的であればあるほど、より多くのコメントを付ける必要があります。

まあ、Peter Konovのようなメガメモリを持っている人以外は、コメントはなくても大丈夫でしょう。


私のも似たようなもので、コメントが少ないだけです :)。

//Использование модели
class Catboost
  {
private:
   static int        lng_id;//
public:
   //Правило сплита: предиктор больше указанного значения(true/false)
   struct sSplit_rule
     {
      uint              predictor_id;  //Индекс предиктора
      double            border;        //С чем сравнивается он
     };
   //Набор правил, при соответствии которым получим результат листа leaf
   struct sLeaf
     {
      double            leaf;          //Значение листа
      sSplit_rule       split_rules[]; //Набор правил
     };
   uint              TreeDepth[];      //Глубины деревьев, глубина означает колчиство правил. В каждом правиле используется один бинарный признак.
   uint              TreeSplits[];     //Какие бинарные признаки использует каждое дерево
   uint              BorderCounts[];   //На сколько бинарных признаков будет разбит каждый предиктор
   float             Borders[];        //Пороговые значения для всех предикторов, они определяют значения бинарных признаков(0/1). Если предиктор выше значения в массиве, будет 1, иначе 0.
   double            LeafValues[];     //Результаты деревьев для каждого сочетания используемых бинарных признаков
   uint              features_pos[];   //Откуда взялась бинарная фича.Указывается индекс.

                    ~Catboost(void);
                     Catboost();
   //Создание экземпляра класса (инициализация конкретной модели)
                     Catboost(uint &TreeDepth_[],uint &TreeSplits_[],uint &BorderCounts_[],float &Borders_[],double &LeafValues_[]);
   //Приеменение модели
   //features     -предикторы
   double            ApplyCatboostModel(const double &features[]);
   //Приеменение модели.Модель передаётся через массивы
   static double     ApplyCatboostModel(const double &features[],uint &TreeDepth_[],uint &TreeSplits_[],uint &BorderCounts_[],float &Borders_[],double &LeafValues_[]);
   //Применение модели с сохранением данных о влиянии предикторов на результат
   double            ApplyCatboostModel_data(const double &features[],datetime time);

   long              data_counter;           //Счётчик выполнения функции ApplyCatboostModel_data
   CSV               *csv_tree_rules;        //Сюда сохраняются все сработанные правила, результаты деревьев
   CSV               *csv_model_rules;       //Сюда сохраняются правила, которые сработали во всей модели.перекрывающиеся правила будут удаляться
   //Перобразование модели CatBoost с исходников C++ в MQL
   static bool       CatBoost_model_to_MQL(string input_file_cpp,string output_file_mql);
   //Чтение модели с файла исходника C++
   bool              Model_read_from_file(string input_file_cpp);
   //Получение полного списка правил для каждого листа leaf_rules_out
   void              Get_leaf_rules(sLeaf &leaf_rules_out[]);
  };
int Catboost::lng_id=cLng::Set_users_errors_messages("Catboost",Catboost_lngs,Catboost_strings);

このような、掲載されているもの全てに "中傷 "するようなコメントは、私の好みではありません。

これをオフにするオプションがあればいいと思います。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

どのようにコメントを入れているのか、具体的に教えてください。手動で編集しているのでしょうか?秘密の組み合わせがあるのでしょうか?

 

こんな状況です。

ストラテジーテスターで 最適化し、終了時にOnTesterDeinit()を実行し、結果を分析したり、データを集めたりしています。このとき、ストラテジーテスターはすべてが終了したかのような状態に切り替わりますが、このとき、バックグラウンドではまだ最終的なデータ処理が長い時間行われることがあります。シンボルチャートが表示されているウィンドウを閉じると、Expert Advisorも強制的に閉じられます。

また、OnTesterDeinit()が現在の最適化が終了したと思ってファイルに書き込んでいるときに、すぐに計算される最小限の範囲のパラメータで次の最適化を開始する状況を説明しましょう。その結果、前の実行が完了せず、新しい実行が同じステージにあることになります。この例では、ファイルへの書き込みアクセスのエラーになったり、ファイル内で単なるミッシュマッシュになったり、視覚的にはロードマネージャやファイルを通じてのみ追跡可能です...。この操作はまだ完了していないことをテスターで確認できるようにしてほしい。

 
Aliaksandr Hryshyn:

こんな状況です。

ストラテジーテスターで 最適化し、終了時にOnTesterDeinit()を実行し、結果を分析したり、データを集めたりしています。 このとき、ストラテジーテスターはすべてが終了したかのような状態に切り替わりますが、このとき、バックグラウンドではまだ最終的なデータ処理が長い時間行われることがあります。シンボルチャートが表示されているウィンドウを閉じると、Expert Advisorも強制的に閉じられます。

また、OnTesterDeinit()が現在の最適化が終了したと思ってファイルに書き込んでいるときに、すぐに計算される最小限の範囲のパラメータで次の最適化を開始する状況を説明しましょう。その結果、前の実行が完了せず、新しい実行が同じステージにあることになります。この例では、ファイルへの書き込みアクセスのエラーになったり、ファイル内で単なるミッシュマッシュになったり、視覚的にはロードマネージャやファイルを通じてのみ追跡可能です...。この操作はまだ完了していないことをテスターで確認できるようにしてほしい。

最適化の際、新しいチャートウィンドウが開きますが、チャートIDで操作の終了を把握することは可能ですか?チャートを閉じるオプションがあるようですが、その後、OnTesterDeinit()で計算の終了後にウィンドウを閉じ、最終的には最適化の開始時に開いているチャートの存在を監視し、それが消えたらすぐに - テスターは新しい最適化の準備ができている、ということができます。

 
Aleksey Vyazmikin:

最適化すると新しいチャートウィンドウが開きますが、チャートIDで作業終了時刻を調べる方法はありますか?チャートを閉じるオプションがあるようですが、その後、OnTesterDeinit()で計算の終了後にウィンドウを閉じ、最終的には最適化の開始時に開いているチャートの存在を監視し、それが消えたらすぐに - テスターは新しい最適化の準備ができています。

では、このコードを変更しなければならないが、そのような可能性がない場合はどうするか。

 
Aliaksandr Hryshyn:

では、コードを変えなければならないが、変えられない場合はどうすればいいのか?

では、仕方がない。一方では、オプティマイザーは自由であり、さらなる作業の準備が整っているが、他方ではオーバーラップする可能性がある。この判断は状況によって異なる。