Дмитрий здравствуйте. У вас написано что Вы использовали 5 агентов и собрали ими 100 проходов. Те Вы запускали сбор 20 раз? Просто иначе 5 агентами будет собрано только 5 проходов. К тому же если запустить советник с одними и теме же параметрами, то он не расчитывается повторно, а подтягивает результат с кэша. Или Вы сдвигали эти 5 агентов при каждом последующем сборе? Объясните пожалуйста этот момент.
Я запускал 20 раз, но перед запуском очищал кэш. Смещать агентов нельзя, так как к номеру агента привязан файл модели. Следовательно, при смещении агентов каждый раз будет создаваться новая случайная модель и мы не получим требуемого эффекта.
I ran it 20 times, but cleared the cache before starting. You can't shift agents because the model file is linked to the agent number. Therefore, if the agents are shifted, a new random model will be created each time and we will not get the desired effect.
then set agent to 5 and Optimization to 20
Total of 100...
I don't know how MetaTrader Tester select inputs for every core. Main idea in online study use pretrained model from one pass to other. But if Tester run Optimithation 1..4 to Agent 1 at one pass the they all use random (not pretrained) model.
I don't know how MetaTrader Tester select inputs for every core. Main idea in online study use pretrained model from one pass to other. But if Tester run Optimithation 1..4 to Agent 1 at one pass the they all use random (not pretrained) model.
I also added some indicators and Parameters, total 27 BarDescr... Momentum, Bands & Ichimoku Kinko Hyo =)
int OnInit()
{
Set symbol and refresh
if(! Symb.Name(_Symbol))
return 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;
Initialize the Ichimoku Kinko Hyo indicator
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()
{
//---
if(! 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();
Refresh Ichimoku values for the current bar
Ichimoku.Refresh();
--- History Data
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 the calculated value
float kijun = (float)Ichimoku.KijunSen(1); Use the calculated value
float senkasa = (float)Ichimoku.SenkouSpanA(2); Use the calculated value
float senkb = (float)Ichimoku.SenkouSpanB(3); Use the calculated value
Check for EMPTY_VALUE and division by 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 ||
bandzlo == EMPTY_VALUE || tenkan == EMPTY_VALUE || kijun == EMPTY_VALUE || senkasa == EMPTY_VALUE ||
senkb == EMPTY_VALUE || kijun == 0.0 || senkb == 0.0)
{
continue;
}
Ensure buffers are not resized within the 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();
// Refresh Ichimoku values for the current bar
Ichimoku.Refresh();
//---
Print("State 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);
I also added some indicators and Parameters, total 27 BarDescr... Momentum, Bands & Ichimoku Kinko Hyo =)
int OnInit()
{
Set symbol and refresh
if(! Symb.Name(_Symbol))
return 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;
Initialize the Ichimoku Kinko Hyo indicator
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()
{
//---
if(! 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();
Refresh Ichimoku values for the current bar
Ichimoku.Refresh();
--- History Data
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 the calculated value
float kijun = (float)Ichimoku.KijunSen(1); Use the calculated value
float senkasa = (float)Ichimoku.SenkouSpanA(2); Use the calculated value
float senkb = (float)Ichimoku.SenkouSpanB(3); Use the calculated value
Check for EMPTY_VALUE and division by 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 ||
bandzlo == EMPTY_VALUE || tenkan == EMPTY_VALUE || kijun == EMPTY_VALUE || senkasa == EMPTY_VALUE ||
senkb == EMPTY_VALUE || kijun == 0.0 || senkb == 0.0)
{
continue;
}
Ensure buffers are not resized within the 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();
// Refresh Ichimoku values for the current bar
Ichimoku.Refresh();
//---
Print("State 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 - How many cycles did you study your version before getting the result in your picture? (data collection - training). And how long did it take?
What is your computer configuration (processor, video card, RAM)?
Thank you
затем устанавливаем агента на 5 и оптимизацию на 20
Итого 100...
Я вижу в коде ссылку на агента, но не вижу оптимизацию. Было ли дополнительное дополнение к коду, которое вы сделали, чтобы использовать этот новый параметр?
Спасибо
Пол
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Опубликована статья Нейросети — это просто (Часть 66): Проблематика исследования в офлайн обучении:
Обучение моделей в офлайн режиме осуществляется на данных ранее подготовленной обучающей выборки. Это дает нам ряд преимуществ, но при этом информация об окружающей среде сильно сжимается до размеров обучающей выборки. Что, в свою очередь, ограничивает возможности исследования. В данной статье хочу предложить познакомиться с методом, позволяющем наполнить обучающую выборку максимально разнообразными данными.
Метод ExORL можно разделить на 3 основных этапа. Первый этап — сбор неразмеченных исследовательских данных. Для этого возможно использование различных алгоритмов обучения без учителя. Авторы метода не ограничивают круг используемых алгоритмов. При этом в процессе взаимодействия с окружающей средой на каждом эпизоде используем политику π, зависящую от истории предыдущих взаимодействий. Каждый эпизод сохраняется в наборе данных в виде последовательности состояния St, дейcтвия At и последующего состояния St+1. Сбор обучающих данных осуществляется до полного заполнения обучающей выборки, размер которой органичен техническим заданием или доступными ресурсами.
После сбора набора данных о состояниях и действиях, осуществляется их переоценка с использованием заданной функции вознаграждения. На этом этапе просто необходимо оценить вознаграждение для каждого кортежа в наборе данных.
Практический опыт показывает о возможности параллельного использования в одном буфере воспроизведения собранных различными методами. Я использовал как траектории собранных ранее рассмотренным советником "Research.mq5", так и советником "ResearchExORL.mq5". Первый указывает на преимущества и недостатки выученной политики Актера. Второй позволяет максимально исследовать окружающую среду и оценить неучтенные возможности.
В процессе итерационного обучения модели мне удалось повысить её результативность.
При общем снижении количества сделок за тестовый период в 3 раза (56 против 176) прибыль увеличилась практически в 3 раза. Сумма максимальной прибыльной сделки увеличилась более чем в 2 раза. А средняя прибыльная сделка увеличилась в 5 раз. При этом мы наблюдаем рост баланса на протяжении всего периода тестирования. В итоге профит фактор модели увеличился с 1.3 до 2.96.
Автор: Dmitriy Gizlyk