Discussão do artigo "Implementado OLAP na negociação (Parte 4): análise quantitativa e visual dos relatórios do testador"
Ao analisar o código do artigo, tive a sensação constante de que não seria capaz de chegar nem perto de um nível tão alto de habilidade. Infelizmente, não consegui entendê-lo devido à minha incompetência.
Peço ao autor que mostre (código pronto), como um exemplo, como adicionar essa funcionalidade ao kit de ferramentas apresentado?
Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação.
Bibliotecas: SingleTesterCache
fxsaber, 2020.01.14 11:42 AM
uchar Bytes2[]; if (MTTESTER::GetLastTstCache(Bytes2) != -1) // Se fosse possível ler o último registro de cache de uma única execução { const SINGLETESTERCACHE SingleTesterCache(Bytes2); // Conduza-o para o objeto correspondente.
Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação
fxsaber, 2019.11.11 04:45 pm.
uchar Bytes[]; MTTESTER::GetLastOptCache(Bytes); // TESTERCACHE<TestCacheSymbolRecord> Cache; // Otimização de símbolos TESTERCACHE<ExpTradeSummary> Cache; // Otimização padrão if (Cache.Load(Bytes)) // Ler o cache de otimização.
Por favor, esclareça a pergunta. O SingleTesterCache e o TesterCache já estão conectados no artigo.
Quero executar o EX5 e ele pegará automaticamente o último arquivo opt/tst (a última tarefa correspondente executada no Tester) para análise.
Quero executar o EX5 e ele pegará automaticamente o último arquivo opt/tst (o último trabalho correspondente executado no Tester) para análise.
Aqui está uma variante para uma execução separada.
//+------------------------------------------------------------------+ //|TSTcube.mqh //|Direitos autorais (c) 2020, Marketeer | //| https://www.mql5.com/en/users/marketeer | //| Processamento analítico on-line de hipercubos de negociação //| https://www.mql5.com/pt/articles/6602 | //| https://www.mql5.com/pt/articles/6603 | //| https://www.mql5.com/pt/articles/7656 | //|rev. 5.03.2020 | //+------------------------------------------------------------------+ #include "ReportCubeBase.mqh" #include <fxsaber/SingleTesterCache/SingleTesterCache.mqh> #include <fxsaber/MultiTester/MTTester.mqh> // + class TesterDeal: public Deal { public: TesterDeal(const TradeDeal &td) { time = (datetime)td.time_create + TimeShift; price = td.price_open; string t = dealType(td.action); type = t == "buy" ? +1 : (t == "sell" ? -1 : 0); t = dealDir(td.entry); direction = 0; if(StringFind(t, "in") > -1) ++direction; if(StringFind(t, "out") > -1) --direction; volume = (double)td.volume; profit = td.profit; deal = (long)td.deal; order = (long)td.order; comment = td.comment[]; symbol = td.symbol[]; commission = td.commission; swap = td.storage; // saldo - SingleTesterCache.Deals[i].reserve } static string dealType(const ENUM_DEAL_TYPE type) { return type == DEAL_TYPE_BUY ? "buy" : (type == DEAL_TYPE_SELL ? "sell" : "balance"); } static string dealDir(const ENUM_DEAL_ENTRY entry) { string result = ""; if(entry == DEAL_ENTRY_IN) result += "in"; else if(entry == DEAL_ENTRY_OUT || entry == DEAL_ENTRY_OUT_BY) result += "out"; else if(entry == DEAL_ENTRY_INOUT) result += "in out"; return result; } }; template<typename T> class TesterReportAdapter: public BaseReportAdapter<T> { protected: SINGLETESTERCACHE *ptrSingleTesterCache; virtual bool fillDealsArray() override { for(int i = 0; i < ArraySize(ptrSingleTesterCache.Deals); i++) { if(TesterDeal::dealType(ptrSingleTesterCache.Deals[i].action) == "balance") { balance += ptrSingleTesterCache.Deals[i].profit; } else { array << new TesterDeal(ptrSingleTesterCache.Deals[i]); } } return true; } public: ~TesterReportAdapter() { if(CheckPointer(ptrSingleTesterCache) == POINTER_DYNAMIC) delete ptrSingleTesterCache; } virtual bool load(const string file) override { if(StringFind(file, ".tst") > 0) { BaseReportAdapter<T>::load(file); if(CheckPointer(ptrSingleTesterCache) == POINTER_DYNAMIC) delete ptrSingleTesterCache; bool loaded = true; // + ptrSingleTesterCache = new SINGLETESTERCACHE(); if(file == "*.tst") // + { // + uchar Bytes2[]; // + // Por que MTTESTER::GetLastTstCacheFileName() é privado? // + // Print("Loading ", MTTESTER::GetLastTstCacheFileName()); // + if(MTTESTER::GetLastTstCache(Bytes2) != -1) // + { // + loaded = ptrSingleTesterCache.Load(Bytes2); // + } // + } else { loaded = ptrSingleTesterCache.Load(file); // * } if(!loaded) // * { delete ptrSingleTesterCache; ptrSingleTesterCache = NULL; return false; } size = generate(); Print("Tester cache import: ", size, " trades from ", ArraySize(ptrSingleTesterCache.Deals), " deals"); } return true; } }; TesterReportAdapter<RECORD_CLASS> _defaultTSTReportAdapter;
Eu queria enviar o nome do último arquivo tst para o registro, mas o método correspondente é privado.
Nas configurações, você precisa selecionar o arquivo "*.tst" (um nome vazio ainda inicia a análise do histórico da conta on-line).
Para obter os resultados da otimização:
#include <fxsaber/MultiTester/MTTester.mqh> // + ... template<typename T> class OptCacheDataAdapter: public DataAdapter { private: TESTERCACHE<ExpTradeSummary> Cache; ... public: OptCacheDataAdapter() { reset(); } void load(const string optName) { bool loaded = true; // + if(optName == "") // + { // + uchar Bytes[]; // + // Por que GetLastOptCacheFileName() é privado? // + // Print("Loading ", MTTESTER::GetLastOptCacheFileName()); // + MTTESTER::GetLastOptCache(Bytes); // + loaded = Cache.Load(Bytes); // + } else { loaded = Cache.Load(optName); // * } if(loaded) // * { customize(); reset(); } else { cursor = -1; } } ...
Gostei do artigo, assim como de todos os artigos sobre a tecnologia OLAP.
Pessoalmente, eu sentia falta do voo do pensamento, - formulações filosóficas da essência, dando uma ideia de toda a abordagem, - do espaço coberto de tarefas e potencial. E o potencial é enorme. Fico triste com os detalhes múltiplos e insignificantes que desperdiçam o tempo do leitor. Dizem que há uma variável lá, e há uma variável aqui..... Entendo que isso é necessário para os iniciantes que estão copiando soluções, mas ainda assim.... Nenhuma tecnologia é estática e, se suas classes e métodos forem usados agora, no futuro, alguém vai querer mudar tudo para si mesmo e, para ele, a utilidade do artigo diminuirá proporcionalmente ao número de entidades privadas. Escreva mais sobre a abordagem como um todo, sobre seu presente e futuro. Você precisa ser mais global com essas abordagens.
Mas essa é minha opinião subjetiva. Obrigado pelo artigo.
Eu queria enviar o nome do último arquivo tst para o registro, mas o método correspondente é privado.
Não me ocorreu que alguém pudesse precisar dele. Se você tiver mais comentários sobre privado->público, diga-me. Farei isso.
Olá, senhor,
Tentei compilar o arquivo 'OLAPGUI_Opts.mq5', mas há 17 erros em alguns arquivos de inclusão.
Atenciosamente,
Ben
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Novo artigo Implementado OLAP na negociação (Parte 4): análise quantitativa e visual dos relatórios do testador foi publicado:
O artigo oferece ferramentas básicas para análise OLAP dos relatórios do testador sobre execuções únicas e resultados de otimização em formatos padrão (tst e opt), bem como uma interface gráfica interativa. Os códigos fonte MQL são anexados ao final artigo.
Para ver a distribuição total dos lucros por níveis em incrementos de 100, selecionamos o campo profit nas estatísticas ao longo do eixo X e no agregador count.
Distribuição dos lucros de todos os passes por intervalos em incrementos de 100 ye
Por fim, o agregador identity permite avaliar o impacto do número de trades no lucro. Em princípio, esse agregador permite ver visualmente muitos outros padrões.
Lucro vs número de transações
Autor: Stanislav Korotky