Planos de desenvolvimento para o MetaTrader 5 Strategy Tester - página 8

 
Aliaksandr Hryshyn:
Eu me pergunto, quantas pessoas usam comentários para funções (classes, estruturas...) usando exatamente este desenho à esquerda?

Uso-o com muita freqüência e densamente (É verdade, não o formato como "quadrados", escrevo-o "exatamente assim".

Aqui está meu arquivo de interface do histórico de licitações atual. E esse não é o número máximo de comentários.

// С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;
};


Em geral, quanto mais específica for a classe - mais comentários deve ter.

Bem, a menos que você tenha mega-memória, como Peter Konov, você pode fazer sem comentários.


 
Nikolai Semko:

Sim, quem gosta do que gosta. Pessoalmente, não consigo ver o código tão bem formatado que não consiga ver o código em si.

Talvez dominar oVisual Studio Code fosse uma boa solução.

Heh heh heh heh... Fico confuso quando "você não consegue ver a floresta para as árvores".

Só neste fragmento - tudo parece estar correto, mas sem um único comentário, e como este "empilhamento", sem omissões, cara, como é difícil entender...

 
Roman:

Eu apago este tipo de comentário de uma só vez, pois obstrui os olhos e escrevo assim

Pronto! Sim.

Para funções curtas e simples, o estilo de comentário mais normal, na minha opinião.

 

Vou colocar meus cinco centavos.

Quanto à formatação. Você precisa entrar em vários estilos. Uma é a da MQ. Eu proponho este:

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

Vou colocar meus cinco centavos.

Quanto à formatação. Você precisa entrar em vários estilos. Uma é a da MQ. Eu proponho este:

Não gosto de todos os parênteses encaracolados do estilo atual. Não entendo porque eles os mudaram de lugar. Eu sempre alinho todos os aparelhos a Tab, como em seu exemplo.

 
Georgiy Merts:

Uso-o com muita freqüência e densamente (É verdade, não o formato como "quadrados", escrevo-o "exatamente assim".

Aqui está meu arquivo de interface do histórico de licitações atual. E esse não é o número máximo de comentários.


Em geral, quanto mais específica é uma classe, mais comentários ela deve ter.

Bem, a menos que você tenha uma mega-memória como Peter Konov - você pode fazer sem comentários lá.


O meu é semelhante, apenas menos comentários :).

//Использование модели
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);

Comentários "manchando" em toda a lista, como é suposto para mim, não é do meu agrado.

Seria bom se houvesse uma opção para desligar isto:

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

Você pode me dizer exatamente como você coloca comentários neles? Você o edita manualmente? Existe uma combinação secreta?

 

A situação é a seguinte:

Eu otimizo em um testador de estratégia, ao concluir, OnTesterDeinit() é executado para analisar resultados, ou apenas para coletar dados. Neste momento, o testador de estratégia muda para o estado como se tudo estivesse terminado, mas neste momento, o processamento final dos dados ainda pode ocorrer em segundo plano por um longo tempo. Quando a janela com o gráfico de símbolos for fechada, o Expert Advisor será fechado à força.

Vamos também descrever a situação quando OnTesterDeinit() está escrevendo em um arquivo pensando que a otimização atual acabou, começamos o próximo com intervalos mínimos de parâmetros que são rapidamente calculados. Como resultado, a execução anterior não está completa e a nova está no mesmo estágio, em nosso exemplo isso leva a um erro de acesso de escrita aos arquivos, ou apenas a um erro no arquivo, e visualmente não é rastreável, apenas através do gerenciador de carga ou arquivo.... Eu gostaria de poder ver no testador que esta operação ainda não está completa.

 
Aliaksandr Hryshyn:

A situação é a seguinte:

Eu otimizo em um testador de estratégia, ao concluir, OnTesterDeinit() é executado para analisar resultados, ou apenas para coletar dados. Neste momento, o testador de estratégia muda para o estado como se tudo estivesse terminado, mas neste momento, o processamento final dos dados ainda pode ocorrer em segundo plano por um longo tempo. Quando a janela com o gráfico de símbolos for fechada, o Expert Advisor será fechado à força.

Vamos também descrever a situação quando OnTesterDeinit() está escrevendo em um arquivo pensando que a otimização atual acabou, começamos o próximo com intervalos mínimos de parâmetros que são rapidamente calculados. Como resultado, a execução anterior não está completa e a nova está no mesmo estágio, em nosso exemplo isso leva a um erro de acesso de escrita aos arquivos, ou apenas a um erro no arquivo, e visualmente não é rastreável, apenas através do gerenciador de carga ou arquivo.... Eu gostaria de poder ver no testador que esta operação ainda não está completa.

Ao otimizar uma nova janela de gráficos - podemos usar a identificação do gráfico para descobrir o fim da operação? Parece que existe uma opção de fechar o gráfico, então após o final dos cálculos no OnTesterDeinit() a janela pode ser fechada e eventualmente só precisamos monitorar a presença do gráfico aberto no início da otimização, assim que ele desaparecer - o testador está pronto para uma nova otimização.

 
Aleksey Vyazmikin:

Quando a otimização abre uma nova janela gráfica - há alguma maneira de descobrir o fim do trabalho por identificação gráfica? Parece que existe uma opção de fechar o gráfico, então após o final dos cálculos no OnTesterDeinit() a janela pode ser fechada, e no final só precisamos monitorar a presença do gráfico aberto no início da otimização, quando ele tiver desaparecido - o testador está pronto para uma nova otimização.

Então, este código deve ser alterado, mas e se não houver tal possibilidade?

 
Aliaksandr Hryshyn:

Então você tem que mudar o código, mas e se você não puder?

Então não há como. Esta é uma situação controversa, por um lado o otimizador está livre e pronto para continuar o trabalho, mas por outro lado pode haver uma sobreposição - a decisão depende da situação.

Razão: