Свои символы и свои датафиды в Метатрейдер 5 - страница 11

 

Добавлю еще тест функции, содержащей два ровных плато максимальных значений:

z = abs(tanh(x) + tanh(y)) 

 z = abs(tanh(x) + tanh(y))

при изменении X,Y от -20 до +20 с шагом 0.1 полный перебор занимает 160801 итераций.

На тесте оба плато видны за 1400 итераций, что менее одного процента от полного перебора.

 

 Кто-нибудь прогонит это на ГА? Интересно сравнить.

 
event:

Добавлю еще тест функции, содержащей два ровных плато максимальных значений:

 

 z = abs(tanh(x) + tanh(y))

при изменении X,Y от -20 до +20 с шагом 0.1 полный перебор занимает 160801 итераций.

На тесте оба плато видны за 1400 итераций, что менее одного процента от полного перебора.

 

 Кто-нибудь прогонит это на ГА? Интересно сравнить.

А разве Вы не с ГА ищете?

Работа с двумя аргументами оптимизируемой функции вообще не показатель. Не только потому, что пространство поиска мало, но ещё потому что могут проявится "нехорошие" свойства самого алгоритма поиска.

Преобразуйте формулу к такому виду, что бы было по меньшей мере 10 аргументов - сразу проявятся все положительные и отрицательные свойства алгоритма.

 
joo:

А разве Вы не с ГА ищете?

Работа с двумя аргументами оптимизируемой функции вообще не показатель. Не только потому, что пространство поиска мало, но ещё потому что могут проявится "нехорошие" свойства самого алгоритма поиска.

Преобразуйте формулу к такому виду, что бы было по меньшей мере 10 аргументов - сразу проявятся все положительные и отрицательные свойства алгоритма.

Это не ГА, в ветке есть ссылка на статью.

Выше выкладывал пример с шестью параметрами. Вся сложность с отображением много параметров.

Если предложите функцию с большим кол-вом параметров - сделаю тест. 

 
event:

Если предложите функцию с большим кол-вом параметров - сделаю тест. 

Y=a+b;

где:

a=Skin(x1, y1)+Skin(x2, y2)+Skin(x3, y3)+Skin(x4, y4)+Skin(x5, y5);

b=Skin(x6, y6)+Skin(x7, y7)+Skin(x8, y8)+Skin(x9, y9)+Skin(x10, y10);

Функцию Skin Вы уже знаете где искать.

И того: 20 переменных, а функцию Y очень просто визуализировать. По такому принципу можно построить функцию с неограниченным количеством аргументов но при этом иметь возможность визуализации.

И соответственно итоговый результат проверяется как Y*2/n в сравнении с известным значением экстремума, где n-общее количество аргументов.

 
Laryx:

А можно привести пример алгоритма, когда в "недостестере" полный перебор -  за десяток часов, а в МТ - месяцы ?

Реальна и ситуация, когда полный перебор быстрее эвристика при оптимизации. Полный перебор в MT представляется как множество независимых друг от друга прогонов. На самом же деле всегда есть возможность рассмотреть оптимизацию, как одну единую вычислительную задачу и применить к ней алгоритмическую оптимизацию.

При таком подходе последовательность проходов имеет огромное значение, т.к кэшируются почти все расчеты. Почти для каждого (для всех независимых) входного параметра ТС в оптимизаторе всегда присутствуют глобальные буффера, которые хранят значения предыдущих проходов.

Например, вы используете МАшку и PriceChannel. Для каждого из этих индикаторов есть свои независимые друг от друга входные параметры. Поэтому для каждого индикатора прописывается (несколько строчек на самом деле, с ООП еще красивее должно быть) функция заполнения своего соответствующего глобального буффера. Далее сравнивается ресурсоемкость каждого из индикаторов (PriceChannel тяжелее МАшки). Входные параметры наиболее тяжелых индикаторов начинают перебираться на внешнем контуре (первый for), простых - внутреннем (во вложенных for).

Вот здесь и получается огромный выигрышь. Плюс C++, целочисленные вычисления и своя без лишних проверок ордерная система. Так и получается результат. В итоге одиночные прогоны быстрее MT на порядок, как минимум. А оптимизация - уже на порядки.

В MT-оптимизаторе не хватает функции OnOptimization, в которой был бы полный доступ к полученной матрице результатов оптимизации. Там у себя делаю различные анализы полученной матрицы: фильтрую, объединяю проходы ТС, которые не пересекаются по времени торговли и т.д. Но что еще полезнее, так это вычисление весовых коэффициентов для каждого из проходов, чтобы составить мета-ТС в виде соответствующего портфеля. Для этого OnOptimization имеет вектор-Equity для каждого из не "безнадежных" проходов.

Но до недотестера руки доходят не на этапе поиска рабочей ТС, а когда она уже найдена, к сожалению. Сам поиск - совсем другой этап: без описания.
 
event:

 Кто-нибудь прогонит это на ГА? Интересно сравнить.

 
joo:

Y=a+b;

где:

a=Skin(x1, y1)+Skin(x2, y2)+Skin(x3, y3)+Skin(x4, y4)+Skin(x5, y5);

b=Skin(x6, y6)+Skin(x7, y7)+Skin(x8, y8)+Skin(x9, y9)+Skin(x10, y10);

Функцию Skin Вы уже знаете где искать.

И того: 20 переменных, а функцию Y очень просто визуализировать. По такому принципу можно построить функцию с неограниченным количеством аргументов но при этом иметь возможность визуализации.

И соответственно итоговый результат проверяется как Y*2/n в сравнении с известным значением экстремума, где n-общее количество аргументов.

страшное дело...)) А можете объяснить как "функцию Y очень просто визуализировать"?
 
Serj_Che:
Сколько проходов и с каким шагом переменных расчет?
 
event:
Сколько проходов и с каким шагом переменных расчет?

Какая разница, не нравится картинка?

64 битный ГА в МТ5 очень хорош, решает любые задачи, главное правильно сформулировать задачу.

И по скорости ему равных нет, не понимаю какой заскок завел разговор в этой теме про ГА.

Проблема вовсе не в ГА, а в том что сам тестер бесполезный, особенно на бирже, из за неправильного хранения истории котировок и невозможности подсунуть свою историю.

Надеюсь эту проблему решат, боюсь только ждать придется 3-5 лет. 

 
zaskok:
 
Например, вы используете МАшку и PriceChannel. Для каждого из этих индикаторов есть свои независимые друг от друга входные параметры. Поэтому для каждого индикатора прописывается (несколько строчек на самом деле, с ООП еще красивее должно быть) функция заполнения своего соответствующего глобального буффера. Далее сравнивается ресурсоемкость каждого из индикаторов (PriceChannel тяжелее МАшки). Входные параметры наиболее тяжелых индикаторов начинают перебираться на внешнем контуре (первый for), простых - внутреннем (во вложенных for).

Что-то мне подсказывает, что такой подход легко можно осуществить и при ГА. Количество работы - приблизительно одно и тоже. "Внутренний контур" перебирается на каждом проходе...

Но, главное - насколько это будет востребовано ? Как я подозреваю, даже просто кастомной функцией OnTester()  - пользуются далеко не все. А ведь это очень мощный инструмент оптимизации.

Вот, например, одна из моих реализаций:

double CDoublePeakBottomAdvisorPartsFactory::MyOnTester(CMyExpertT* pmeExpert)
{
   ulong ulTickedTime = pmeExpert.GetTickedTime();
   uint  uiTotalNumberOfSL = pmeExpert.GetNumOfLosePositions();

   double dDDPercent = TesterStatistics(STAT_EQUITY_DDREL_PERCENT);
   double dStartBalance = TesterStatistics(STAT_INITIAL_DEPOSIT);
   double dProfit = TesterStatistics(STAT_PROFIT);
   double dNumOfTrades = TesterStatistics(STAT_TRADES);
   double dNumOfProfitTrades = TesterStatistics(STAT_PROFIT_TRADES);
   double dMaxNumOfSL = TesterStatistics(STAT_MAX_CONLOSS_TRADES);
   double dRecoveryFactor = TesterStatistics(STAT_RECOVERY_FACTOR);
   double dProfitTradesPerWeek = dNumOfProfitTrades/ulTickedTime*SECS_IN_WEEK;
   double dProfitPerDay = dProfit/ulTickedTime*SECS_IN_DAY;
  

   Print("Ticked time (days): ",DoubleToString(ulTickedTime/SECS_IN_DAY,2));

   Print("Number Of Trades: ",DoubleToString(dNumOfTrades,1));

   if(dNumOfTrades == 0)
      {
      Print("Ни одного трейда !");
      return(-100000);
      };


   if(dMaxNumOfSL > uiIMaxNumOfSeqSL)
      return(-10000 - dMaxNumOfSL*100 + dProfit/1000);
  
   
   double dBarsPerTrade = ((double)ulTickedTime/PeriodSeconds(m_didData.m_etTimeFrame))/dNumOfTrades;

   if((bILongAllow == false) || (bIShortAllow == false))
      dBarsPerTrade /= 2;
   
   if(dBarsPerTrade < MIN_BARS_PER_TRADE)
      return(dBarsPerTrade-MIN_BARS_PER_TRADE + dRecoveryFactor);

   Print("Max number Of SL: ",DoubleToString(dMaxNumOfSL,1));

   if(iIMaxNumOfSeqSLForQualify > 0 && dMaxNumOfSL > iIMaxNumOfSeqSLForQualify)
      {
      Print("Слишком много СЛ подряд !");
      return(dRecoveryFactor - (dMaxNumOfSL-iIMaxNumOfSeqSLForQualify)*1000)-10000;
      };

   Print("Bars Per Trade (half): ",DoubleToString(dBarsPerTrade,1));
        
   if(dBarsPerTrade > MAX_BARS_PER_TRADE)
      {
      Print("Слишком редкие трейды !");
      return(dRecoveryFactor - dBarsPerTrade/100);
      };
     

   Print("Profit: ",DoubleToString(dProfit,3));
   Print("Profit per day: ",DoubleToString(dProfitPerDay,3));
   Print("Число СЛ: ",IntegerToString(uiTotalNumberOfSL));


   Print("Приемлемая торговля.");
   
   return(dRecoveryFactor + (1-(uiTotalNumberOfSL/dNumOfTrades))*100);
};

Здесь основа - фактор восстановления, однако, при этом выделяются прогоны с минимальным количеством СЛ подряд, и с достаточно частыми трейдами.

Однако, как я погляжу - большинство используют стандартные варианты.

Причина обращения: