Discussão do artigo "Redes neurais de maneira fácil (Parte 66): Problemáticas da pesquisa em treinamento off-line"
Olá, Dmitry. O relatório diz que você usou 5 agentes e coletou 100 passes com eles. Você executou a coleta 20 vezes? Caso contrário, apenas 5 passes serão coletados por 5 agentes. Além disso, se você executar o Expert Advisor com os mesmos parâmetros, ele não recalculará, mas extrairá o resultado do cache. Ou você trocou esses 5 agentes a cada coleta subsequente? Por favor, explique esse ponto.
Eu o executei 20 vezes, mas limpei o cache antes de executá-lo. Não é possível deslocar agentes porque o arquivo de modelo está vinculado ao número do agente. Portanto, se você mudar os agentes a cada vez, um novo modelo aleatório será criado e não obteremos o efeito desejado.
Executei-o 20 vezes, mas limpei o cache antes de começar. Não é possível mudar os agentes porque o arquivo de modelo está vinculado ao número do agente. Portanto, se os agentes forem deslocados, um novo modelo aleatório será criado a cada vez e não obteremos o efeito desejado.
em seguida, defina o agente para 5 e a otimização para 20
Total de 100...
em seguida, defina o agente para 5 e a otimização para 20
Total de 100...
Olá,
Quantos núcleos você usou?
Não sei como o MetaTrader Tester seleciona as entradas para cada núcleo. A ideia principal no estudo on-line é usar o modelo pré-treinado de uma passagem para outra. Mas se o testador executar o Optimithation 1..4 para o Agente 1 em uma passagem, todos eles usarão um modelo aleatório (não pré-treinado).
Não sei como o MetaTrader Tester seleciona as entradas para cada núcleo. A ideia principal no estudo on-line é usar o modelo pré-treinado de uma passagem para outra. Mas se o testador executar o Optimithation 1..4 para o Agente 1 em uma passagem, todos eles usarão um modelo aleatório (não pré-treinado).
Também adicionei alguns indicadores e parâmetros, totalizando 27 BarDescr.... Momentum, Bands & Ichimoku Kinko Hyo =)
int OnInit()
{
Definir símbolo e atualizar
if(! Symb.Name(_Symbol))
retorna INIT_FAILED;
Symb.Refresh();
//---
if(! RSI. Create(Symb.Name(), TimeFrame, RSIPeriod, RSIPrice))
return INIT_FAILED;
//---
if(! CCI.Create(Symb.Name(), TimeFrame, CCIPeriod, CCIPrice))
return INIT_FAILED;
//---
if(! ATR. Create(Symb.Name(), TimeFrame, ATRPeriod))
return INIT_FAILED;
//---
if(! MACD. Create(Symb.Name(), TimeFrame, FastPeriod, SlowPeriod, SignalPeriod, MACDPrice)))
return INIT_FAILED;
//---
if (! Momentum.Create(Symb.Name(), TimeFrame, MomentumMaPeriod, MomentumApplied))
return INIT_FAILED;
Inicializar o indicador Ichimoku Kinko Hyo
if (! Ichimoku.Create(Symb.Name(), TimeFrame, Ichimokutenkan_senPeriod, Ichimokukijun_senPeriod, Ichimokusenkou_span_bPeriod)))
return INIT_FAILED;
//---
if (! Bands.Create(Symb.Name(), TimeFrame, BandsMaPeriod, BandsMaShift, BandsDeviation, BandsApplied))
return INIT_FAILED;
//---
if(! RSI. BufferResize(HistoryBars) || ! CCI.BufferResize(HistoryBars) ||
! ATR. BufferResize(HistoryBars) || ! MACD. BufferResize(HistoryBars))
{
PrintFormat("%s -> %d", __FUNCTION__, __LINE__);
return INIT_FAILED;
}
//---
void OnTick()
{
//---
se(! IsNewBar())
return;
//---
int bars = CopyRates(Symb.Name(), TimeFrame, iTime(Symb.Name(), TimeFrame, 1), HistoryBars, Rates);
if(! ArraySetAsSeries(Rates, true))
return;
//---
RSI. Refresh();
CCI.Refresh();
ATR. Refresh();
MACD. Refresh();
Symb.Refresh();
Momentum.Refresh();
Bands.Refresh();
Symb.RefreshRates();
Atualizar os valores de Ichimoku para a barra atual
Ichimoku.Refresh();
--- Dados do histórico
float atr = 0;
for (int b = 0; b < (int)HistoryBars; b++)
{
float open = (float)Rates[b].open;
float close = (float)Rates[b].close;
float rsi = (float)RSI. Main(b);
float cci = (float)CCI.Main(b);
atr = (float)ATR. Main(b);
float macd = (float)MACD. Main(b);
float sign = (float)MACD. Signal(b);
float mome = (float)Momentum.Main(b);
float bandzup = (float)Bands.Upper(b);
float bandzb = (float)Bands.Base(b);
float bandzlo = (float)Bands.Lower(b);
float tenkan = (float)Ichimoku.TenkanSen(0); Use o valor calculado
float kijun = (float)Ichimoku.KijunSen(1); Use o valor calculado
float senkasa = (float)Ichimoku.SenkouSpanA(2); Use o valor calculado
float senkb = (float)Ichimoku.SenkouSpanB(3); Use o valor calculado
Verifique se há EMPTY_VALUE e divisão por zero
if (rsi == EMPTY_VALUE || cci == EMPTY_VALUE || atr == EMPTY_VALUE || macd == EMPTY_VALUE ||
sign == EMPTY_VALUE || mome == EMPTY_VALUE || bandzup == EMPTY_VALUE || bandzb == EMPTY_VALUE || bandzb == EMPTY_VALUE ||
bandzlo == EMPTY_VALUE || tenkan == EMPTY_VALUE || kijun == EMPTY_VALUE || senkasa == EMPTY_VALUE || senkasa == EMPTY_VALUE ||
senkb == EMPTY_VALUE || kijun == 0.0 || senkb == 0.0)
{
continue;
}
Assegurar que os buffers não sejam redimensionados dentro do loop
int shift = b * BarDescr;
sState.state[shift] = (float)(Rates[b].close - open);
sState.state[shift + 1] = ((float)(Rates[b].close - open) + (tenkan - kijun)) / 2.0f;
sState.state[shift + 2] = (float)(Rates[b].high - open);
sState.state[shift + 3] = (float)(Rates[b].low - open);
sState.state[shift + 4] = (float)(Rates[b].high - close);
sState.state[shift + 5] = (float)(Rates[b].low - close);
sState.state[shift + 6] = (tenkan - kijun);
sState.state[shift + 7] = (float)(Rates[b].tick_volume / 1000.0f);
sState.state[shift + 8] = ((float)(Rates[b].high) - (float)(Rates[b].low));
sState.state[shift + 9] = (bandzup - bandzlo);
sState.state[shift + 10] = rsi;
sState.state[shift + 11] = cci;
sState.state[shift + 12] = atr;
sState.state[shift + 13] = macd;
sState.state[shift + 14] = sign;
sState.state[shift + 15] = mome;
sState.state[shift + 16] = (float)(Rates[b].open - tenkan);
sState.state[shift + 17] = (float)(Rates[b].open - kijun);
sState.state[shift + 18] = (float)(Rates[b].open - bandzb);
sState.state[shift + 19] = (float)(Rates[b].open - senkasa);
sState.state[shift + 20] = (float)(Rates[b].open - senkb);
sState.state[shift + 21] = (float)(Rates[b].close - tenkan);
sState.state[shift + 22] = (float)(Rates[b].close - kijun);
sState.state[shift + 23] = (float)(Rates[b].close - bandzb);
sState.state[shift + 24] = (float)(Rates[b].close - senkasa);
sState.state[shift + 25] = (float)(Rates[b].close - senkb);
sState.state[shift + 26] = senkasa - senkb;
//---
RSI.Refresh();
CCI.Refresh();
ATR.Refresh();
MACD.Refresh();
Symb.Refresh();
Momentum.Refresh();
Bands.Refresh();
Symb.RefreshRates();
// Atualizar os valores do Ichimoku para a barra atual
Ichimoku.Refresh();
//---
Imprimir ("Estado 0: ", sState.state[shift]);
Imprimir ("Estado 1: ", sState.state[shift + 1]);
Print("State 2: ", sState.state[shift + 2]);
Print("State 3: ", sState.state[shift + 3]);
Print("State 4: ", sState.state[shift + 4]);
Print("State 5: ", sState.state[shift + 5]);
Print("State 6: ", sState.state[shift + 6]);
Print("State 7: ", sState.state[shift + 7]);
Print("State 8: ", sState.state[shift + 8]);
Print("State 9: ", sState.state[shift + 9]);
Print("State 10: ", sState.state[shift + 10]);
Print("State 11: ", sState.state[shift + 11]);
Print("State 12: ", sState.state[shift + 12]);
Print("State 13: ", sState.state[shift + 13]);
Print("State 14: ", sState.state[shift + 14]);
Print("State 15: ", sState.state[shift + 15]);
Print("State 16: ", sState.state[shift + 16]);
Print("State 17: ", sState.state[shift + 17]);
Print("State 18: ", sState.state[shift + 18]);
Print("State 19: ", sState.state[shift + 19]);
Print("State 20: ", sState.state[shift + 20]);
Print("State 21: ", sState.state[shift + 21]);
Print("State 22: ", sState.state[shift + 22]);
Print("State 23: ", sState.state[shift + 23]);
Print("State 24: ", sState.state[shift + 24]);
Print("State 25: ", sState.state[shift + 25]);
Print("State 26: ", sState.state[shift + 26]);
Print("Tenkan Sen: ", tenkan);
Print("Kijun Sen: ", kijun);
Print("Senkou Span A: ", senkasa);
Print("Senkou Span B: ", senkb);
}
bState.AssignArray(sState.state);
Também adicionei alguns indicadores e parâmetros, totalizando 27 BarDescr.... Momentum, Bandas e Ichimoku Kinko Hyo =)
int OnInit()
{
Definir símbolo e atualizar
se(! Symb.Name(_Symbol))
retorna INIT_FAILED;
Symb.Refresh();
//---
if(! RSI. Create(Symb.Name(), TimeFrame, RSIPeriod, RSIPrice))
return INIT_FAILED;
//---
if(! CCI.Create(Symb.Name(), TimeFrame, CCIPeriod, CCIPrice))
return INIT_FAILED;
//---
if(! ATR. Create(Symb.Name(), TimeFrame, ATRPeriod))
return INIT_FAILED;
//---
if(! MACD. Create(Symb.Name(), TimeFrame, FastPeriod, SlowPeriod, SignalPeriod, MACDPrice))
return INIT_FAILED;
//---
Se (! Momentum.Create(Symb.Name(), TimeFrame, MomentumMaPeriod, MomentumApplied))
return INIT_FAILED;
Inicializar o indicador Ichimoku Kinko Hyo
If (! Ichimoku.Create(Symb.Name(), TimeFrame, Ichimokutenkan_senPeriod, Ichimokukijun_senPeriod, Ichimokusenkou_span_bPeriod))
return INIT_FAILED;
//---
se (! Bands.Create(Symb.Name(), TimeFrame, BandsMaPeriod, BandsMaShift, BandsDeviation, BandsApplied))
return INIT_FAILED;
//---
if(! RSI. BufferResize(HistoryBars) || ! CCI.BufferResize(HistoryBars) ||
! ATR. BufferResize(HistoryBars) || ! MACD. BufferResize(HistoryBars))
{
PrintFormat("%s -> %d", __FUNCTION__, __LINE__);
return INIT_FAILED;
}
//---
void OnTick()
{
//---
se(! IsNewBar())
return;
//---
int bars = CopyRates(Symb.Name(), TimeFrame, iTime(Symb.Name(), TimeFrame, 1), HistoryBars, Rates);
if(! ArraySetAsSeries(Rates, true))
return;
//---
RSI. Refresh();
CCI.Refresh();
ATR. Refresh();
MACD. Refresh();
Symb.Refresh();
Momentum.Refresh();
Bands.Refresh();
Symb.RefreshRates();
Atualizar os valores do Ichimoku para a barra atual
Ichimoku.Refresh();
--- Dados do histórico
float atr = 0;
for (int b = 0; b < (int)HistoryBars; b++)
{
float open = (float)Rates[b].open;
float close = (float)Rates[b].close;
float rsi = (float)RSI. Main(b);
float cci = (float)CCI.Main(b);
atr = (float)ATR. Main(b);
float macd = (float)MACD. Main(b);
float sign = (float)MACD. Signal(b);
float mome = (float)Momentum.Main(b);
float bandzup = (float)Bands.Upper(b);
float bandzb = (float)Bands.Base(b);
float bandzlo = (float)Bands.Lower(b);
float tenkan = (float)Ichimoku.TenkanSen(0); Use o valor calculado
float kijun = (float)Ichimoku.KijunSen(1); Use o valor calculado
float senkasa = (float)Ichimoku.SenkouSpanA(2); Use o valor calculado
float senkb = (float)Ichimoku.SenkouSpanB(3); Use o valor calculado
Verifique se há EMPTY_VALUE e divisão por zero
se (rsi == EMPTY_VALUE || cci == EMPTY_VALUE || atr == EMPTY_VALUE || macd == EMPTY_VALUE ||
sign == EMPTY_VALUE || mome == EMPTY_VALUE || bandzup == EMPTY_VALUE || bandzb == EMPTY_VALUE || bandzb == EMPTY_VALUE ||
bandzlo == EMPTY_VALUE || tenkan == EMPTY_VALUE || kijun == EMPTY_VALUE || senkasa == EMPTY_VALUE || senkasa == EMPTY_VALUE ||
senkb == EMPTY_VALUE || kijun == 0.0 || senkb == 0.0)
{
continue;
}
Assegure-se de que os buffers não sejam redimensionados dentro do loop
int shift = b * BarDescr;
sState.state[shift] = (float)(Rates[b].close - open);
sState.state[shift + 1] = ((float)(Rates[b].close - open) + (tenkan - kijun)) / 2.0f;
sState.state[shift + 2] = (float)(Rates[b].high - open);
sState.state[shift + 3] = (float)(Rates[b].low - open);
sState.state[shift + 4] = (float)(Rates[b].high - close);
sState.state[shift + 5] = (float)(Rates[b].low - close);
sState.state[shift + 6] = (tenkan - kijun);
sState.state[shift + 7] = (float)(Rates[b].tick_volume / 1000.0f);
sState.state[shift + 8] = ((float)(Rates[b].high) - (float)(Rates[b].low));
sState.state[shift + 9] = (bandzup - bandzlo);
sState.state[shift + 10] = rsi;
sState.state[shift + 11] = cci;
sState.state[shift + 12] = atr;
sState.state[shift + 13] = macd;
sState.state[shift + 14] = sign;
sState.state[shift + 15] = mome;
sState.state[shift + 16] = (float)(Rates[b].open - tenkan);
sState.state[shift + 17] = (float)(Rates[b].open - kijun);
sState.state[shift + 18] = (float)(Rates[b].open - bandzb);
sState.state[shift + 19] = (float)(Rates[b].open - senkasa);
sState.state[shift + 20] = (float)(Rates[b].open - senkb);
sState.state[shift + 21] = (float)(Rates[b].close - tenkan);
sState.state[shift + 22] = (float)(Rates[b].close - kijun);
sState.state[shift + 23] = (float)(Rates[b].close - bandzb);
sState.state[shift + 24] = (float)(Rates[b].close - senkasa);
sState.state[shift + 25] = (float)(Rates[b].close - senkb);
sState.state[shift + 26] = senkasa - senkb;
//---
RSI.Refresh();
CCI.Refresh();
ATR.Refresh();
MACD.Refresh();
Symb.Refresh();
Momentum.Refresh();
Bands.Refresh();
Symb.RefreshRates();
// Atualizar os valores de Ichimoku para a barra atual
Ichimoku.Refresh();
//---
Imprimir ("Estado 0: ", sState.state[shift]);
Print("State 1: ", sState.state[shift + 1]);
Print("State 2: ", sState.state[shift + 2]);
Print("State 3: ", sState.state[shift + 3]);
Print("State 4: ", sState.state[shift + 4]);
Print("State 5: ", sState.state[shift + 5]);
Print("State 6: ", sState.state[shift + 6]);
Print("State 7: ", sState.state[shift + 7]);
Print("State 8: ", sState.state[shift + 8]);
Print("State 9: ", sState.state[shift + 9]);
Print("State 10: ", sState.state[shift + 10]);
Print("State 11: ", sState.state[shift + 11]);
Print("State 12: ", sState.state[shift + 12]);
Print("State 13: ", sState.state[shift + 13]);
Print("State 14: ", sState.state[shift + 14]);
Print("State 15: ", sState.state[shift + 15]);
Print("State 16: ", sState.state[shift + 16]);
Print("State 17: ", sState.state[shift + 17]);
Print("State 18: ", sState.state[shift + 18]);
Print("State 19: ", sState.state[shift + 19]);
Print("State 20: ", sState.state[shift + 20]);
Print("State 21: ", sState.state[shift + 21]);
Print("State 22: ", sState.state[shift + 22]);
Print("State 23: ", sState.state[shift + 23]);
Print("State 24: ", sState.state[shift + 24]);
Print("State 25: ", sState.state[shift + 25]);
Print("State 26: ", sState.state[shift + 26]);
Print("Tenkan Sen: ", tenkan);
Print("Kijun Sen: ", kijun);
Print("Senkou Span A: ", senkasa);
Print("Senkou Span B: ", senkb);
}
bState.AssignArray(sState.state);
JimReaper - Quantos ciclos você estudou a sua versão antes de obter o resultado da sua imagem (coleta de dados - treinamento)? E quanto tempo isso levou?
Qual é a configuração do seu computador (processador, placa de vídeo, RAM)?
Obrigado, Jim
em seguida, defina o agente para 5 e a otimização para 20
Total de 100...
Vejo a referência ao Agent no código, mas não vejo a Optimisation. Você fez alguma outra adição ao código para usar esse novo parâmetro?
Obrigado
Paul

- 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 Redes neurais de maneira fácil (Parte 66): Problemáticas da pesquisa em treinamento off-line foi publicado:
O treinamento de modelos em modo off-line é realizado com dados de uma amostra de treinamento previamente preparada. Isso nos oferece várias vantagens, mas também comprime significativamente as informações sobre o ambiente em relação às dimensões da amostra de treinamento. Isso, por sua vez, limita as possibilidades de pesquisa. Neste artigo, quero apresentar um método que permite enriquecer a amostra de treinamento com dados o mais diversificados possível.
O método ExORL pode ser dividido em três etapas principais. A primeira etapa é a coleta de dados exploratórios não rotulados. Para isso, é possível usar diferentes algoritmos de aprendizado não supervisionado. Os autores do método não limitam o conjunto de algoritmos utilizados. Durante a interação com o ambiente, em cada episódio é utilizada uma política π, que depende do histórico de interações anteriores. Cada episódio é salvo no conjunto de dados como uma sequência de estado St, ação At e o estado subsequente St+1. A coleta de dados de treinamento continua até que a amostra de treinamento esteja completamente preenchida, limitada pelo escopo técnico ou recursos disponíveis.
Após a coleta do conjunto de dados sobre estados e ações, é realizada uma reavaliação usando uma função de recompensa definida. Nesta etapa, é essencial avaliar a recompensa para cada tupla no conjunto de dados.
A experiência prática mostra a possibilidade de uso paralelo em um único buffer de reprodução coletado por diferentes métodos. Usei tanto as trajetórias coletadas anteriormente pelo EA "Research.mq5" quanto pelo "ResearchExORL.mq5". O primeiro destaca as vantagens e desvantagens da política aprendida pelo Ator. O segundo permite explorar ao máximo o ambiente e avaliar as oportunidades não contabilizadas.
Durante o processo iterativo de treinamento do modelo, consegui aumentar sua eficácia.
Com uma redução geral no número de negociações durante o período de teste em 3 vezes (56 contra 176), o lucro aumentou quase 3 vezes. O valor da negociação mais lucrativa aumentou mais de duas vezes. E a média de lucro por negociação aumentou cinco vezes. Durante todo o período de teste, observamos um aumento no saldo. Como resultado, o fator de lucro do modelo aumentou de 1.3 para 2.96.
Autor: Dmitriy Gizlyk