Bibliotecas: MultiTester - página 3

 
Edgar:

Se você quer saber como ver os resultados da otimização, eu estava falando sobre ler os resultados do cache programaticamente.

Não foi isso que eu quis dizer. Mas a leitura do cache é possível. Você só precisa escrevê-la.

[Excluído]  

Muito legal!!!

Também usei o Cycles e era exatamente o que eu estava perdendo )))))

#include <fxsaber\MultiTester\MultiTester.mqh> // Várias execuções/otimizações no Tester.

enum CyclNum
{
   n01   = 1,     // 1
   n02,           // 2
   n03,           // 3
   n04,           // 4
   n05,           // 5
   n06,           // 6
   n07,           // 7
   n08,           // 8
   n09,           // 9
   n10,           // 0
};
sinput bool Period_M1 = false;         // Ligar M1
sinput bool Period_M5 = false;         // Ligar o M5
sinput bool Period_M15 = false;        // Ligar o M15
sinput bool OnlyCustomSymbols = false; // Somente caracteres personalizados
sinput CyclNum number_cycles  = n06;   // Número de ciclos

// Essa função é responsável por gerar a lista de tarefas.
void SetTesterSettings()
{
   for(int n = 0; n < number_cycles; n++)
   {
      // Pesquisar todos os símbolos do Market Watch.
      for (int i = SymbolsTotal(true) - 1; i >= 0; i--)
      {

Obrigado!

 
Сергей Таболин:

Adicionei o Cycles a ele e era exatamente o que eu precisava ))))

Preciso de funções de acionamento de botões no testador. Assim, a automação seria de um nível diferente.

 

Adicionei algumas funções para os controles de que preciso (Depo, Currency, Leverage, OptimisationType, BarsType, Criteria). Mas ainda não o testei. Posso publicá-lo depois.

Eu queria implementar o gerenciamento de agentes. Por exemplo, você pode clicar na lista de agentes, pressionar HOME e selecionar cada agente com VK_DOWN. Mas não sei como chamar o menu de contexto para a linha selecionada. E seria necessário pressionar 'd'/'e' para desativar/ativar.

Alguém pode me dar uma dica?

É ainda mais difícil ativar/desativar a nuvem (desativar antes do tique ou da otimização cruzada). Se você chegar até o menu de contexto, não poderá ativar/desativar explicitamente, só poderá inverter. Não é possível descobrir o estado atual programaticamente. Você pode ler no registro do terminal "2019.07.31 19:27:35.664 Tester Cloud servers using switch off". Parece que também não é possível ler o log programaticamente, é preciso procurar no arquivo de log.

Ainda há uma chance de haver comandos WinAPI não documentados. Talvez alguns programadores de C++ saibam como encontrá-los?

[Excluído]  

Diante do problema de falta de energia. Agora não sei o quanto de otimização foi feito ((((

Quando tiver tempo, tentarei adicionar uma verificação da porcentagem de otimização total e dos caracteres trabalhados. Espero que o autor não se importe. ))) Ou será que ele mesmo vai querer fazer isso?

 
Сергей Таболин:

Enfrentei o problema de falta de energia. Agora não sei o quanto de otimização foi feito ((((

O MultiTester reflete suas etapas nos registros. Se o terminal tiver salvo os registros, você verá tudo lá.

Além disso, os caches de otimização são 100% salvos. Assim, você pode ver o que foi executado.

 
Edgar:

Adicionei algumas funções para os controles de que preciso (Depo, Currency, Leverage, OptimisationType, BarsType, Criteria). Mas ainda não o testei. Posso publicá-lo depois.

Antes de resolver problemas particulares, seria bom descrever cenários de uso de suas soluções.

 
fxsaber:

Antes de resolver problemas particulares, é uma boa ideia prescrever cenários para o uso de suas soluções.

Descrevi meu cenário na página anterior.

O Clicker não é um substituto para tudo, é uma das várias ferramentas necessárias para automatizar a otimização. Ele permite que você faça tudo em um único terminal sem abrir um terminal adicional. Eu acrescentaria quadros para analisar os resultados (sua nova biblioteca para ler o cache de otimização é boa para a mesma finalidade), funções para gerenciar variáveis de entrada, SQLITE para armazenar estados e estatísticas. E você pode escrever scripts de otimização inteligentes. Não é possível alcançar a universalidade, pois cada Expert Advisor tem seu próprio script. E você precisa criá-lo manualmente e só então aplicá-lo repetidamente.

Os quadros já foram adicionados. Eu tinha experiência com o SQLITE.

Apenas estendi sua biblioteca para atender às minhas necessidades. Tenho certeza de que você mesmo estava planejando isso, mas eu não esperei. Essa é a única tecnologia das mencionadas acima para a qual eu não tinha uma solução pronta. A propósito, verifiquei meus add-ons e eles funcionam. Os problemas de gerenciamento de agentes ainda são relevantes. O Spy++ pode ajudar na captura de mensagens para um engenheiro de sistemas experiente, mas eu tive pouca ajuda, preciso saber o que filtrar. Espero que as pessoas se informem. O tópico está sendo abordado desde 2008.

 
Edgar:

Veja como eu gostaria de aprimorá-lo. Meu cenário típico de otimização:

Executar N execuções genéticas para OHLC. Obter o melhor resultado de cada uma delas de acordo com um critério personalizado.

Executar otimização lenta em cada grupo de parâmetros (cada grupo tem de 2 a 3 parâmetros interdependentes).

Repita iterativamente as otimizações lentas para cada grupo até que o ideal seja alcançado (os parâmetros param de flutuar).

Mude para ticks reais e execute as mesmas otimizações lentas.

Mudar para outro símbolo, repetir tudo.

Não tenho essa tarefa diante de mim. É claro que seria bom se a automação permitisse isso.

Eu mesmo estou me esforçando para desenvolver um critério para a robustez do TS por meio de indicadores de otimização automática. Isso faz muita falta para uma maior objetividade na pesquisa.

O esquema do otimizador automático foi totalmente planejado e não há obstáculos técnicos para sua implementação.

Definitivamente, o Bibla precisa ser complementado com funcionalidade. Portanto, sugira suas realizações.

 
enum eOptType   { eOptOff, eOptSlow, eOptGen, eOptAllSym };
enum eBars      { eBarsEvery, eBarsReal, eBarsOHLC, eBarsOpen, eBarsMath };
enum eCriteria  { eCritBal, eCritPF, eCritEPO, eCritDD, eCritRF, eCritSR, eCritCust };



class MTTESTER {
public:

        static bool 
        SetOptType(eOptType opt) {
                const bool rc = MTTESTER::IsReady();
                if (rc) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x28FB };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_HOME, 0);
                        for (int i = 0; i < opt; i++)
                                user32::SendMessageW(Handle, WM_KEYDOWN, VK_DOWN, 0);
                }
                return rc;
        }



        static bool 
        SetBars(eBars type) {
                const bool rc = MTTESTER::IsReady();
                if (rc) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x2913 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_HOME, 0);
                        for (int i = 0; i < type; i++)
                                user32::SendMessageW(Handle, WM_KEYDOWN, VK_DOWN, 0);
                }
                return rc;
        }



        static bool 
        SetCriteria(eCriteria type) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x290B };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_HOME, 0);
                        for (int i = 0; i < type; i++)
                                user32::SendMessageW(Handle, WM_KEYDOWN, VK_DOWN, 0);
                }
                return Res;
        }



        static bool 
        SetCurrency(const string name) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x293F, 0x03E9 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_LBUTTONDOWN, 0, 0);
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_DELETE, 0);
                        char Chars[];
                        const int Size = ::StringToCharArray(name, Chars);
                        for (int i = 0; i < Size; i++)
                                user32::SendMessageW(Handle, WM_CHAR, Chars[i], 0);
                }
                return Res;
        }



        static bool 
        SetDepo(const long depo) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x28F9, 0x03E9 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_LBUTTONDOWN, 0, 0);
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_DELETE, 0);
                        string s = IntegerToString(depo);
                        char Chars[];
                        const int Size = ::StringToCharArray(s, Chars);
                        for (int i = 0; i < Size; i++)
                                user32::SendMessageW(Handle, WM_CHAR, Chars[i], 0);
                }
                return Res;
        }



        static bool 
        SetLeverage(const long leverage) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x28E9, 0x03E9 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_LBUTTONDOWN, 0, 0);
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_DELETE, 0);
                        string s = "1:" + IntegerToString(leverage);
                        char Chars[];
                        const int Size = ::StringToCharArray(s, Chars);
                        for (int i = 0; i < Size; i++)
                                user32::SendMessageW(Handle, WM_CHAR, Chars[i], 0);
                }
                return Res;
        }