Как сгенерировать сочетания без повторений с помощью тестера стратегий? - страница 2

 
Igor Makanu:

как писал, думал лишняя инфа будет отвлекать 

если я правильно понимаю, нужна генерация сочетания по его номеру?

Генерация случайных сочетаний. Генерация сочетания по его порядковому номеру
  • rsdn.org
Базовые определения и обозначения Вычисление биномиального коэффициента Генерация случайного сочетания методом случайной перестановки Генерация сочетания по его номеру Использование реализованных функций Сравнение двух...
 

Не пробовал, но... осуждаю :) 

Там, в принципе, Рош написал, детальней наверное должно быть так. 

1. задать переменную глобально 

int counter = 0;
2. создать N индикаторов в OnInit 

int indicators[] = new int[10];
int indicatorsPerTest[] = new int[10];

indicators[0] = MA(...)
indicators[1] = SAR(...)
...
indicators[9] = MACD(...)
3. в OnTester генерить новую комбинацию битовой маской 

int OnTester()
{
  counter = counter < 10 ? counter + 1 : counter;

  for (int i = 0; i < ArraySize(indicators); i++)
  {
      indicatorsPerTest[i] = (counter & i) ? indicators[i] : null;
    }
  }

  return counter;
}

4. в методе отвечающем за торговую логику брать значения indicatorsPerTest, которые не NULL 

bool buy = true; 

for (int i = 0; i < ArraySize(indicatorsPerTest); i++)
  {
      if (indicatorsPerTest[i]) {
        buy = buy && indicatorsPerTest[i][0] > indicatorsPerTest[i][1];
      }
  }
}

if (buy) {
  // OrderSend(buy)
}

Возможно хрень написал, но пусть будет :) 

 
Igor Makanu:

нет, откуда тестер будет знать какой проход сейчас идет? агенты тестера между собой не могут общаться

нужно такую вот таблицу генерировать и прогонять в оптимизации, вот для N=4

что-то теперь ничего не понимаю. Да и что за число 2046, это же не "Число сочетаний без повторений"?

там в формуле M и N д.б. а у вас один пар-р 10.

Может вам надо - объединение множеств сочетаний без повторений m из N, где m =1...M. Так?

 
...:

Возможно хрень написал, но пусть будет :) 

не хрень, Вы, в принципе, изложили вот этот алгоритм https://e-maxx.ru/algo/generating_combinations

//+------------------------------------------------------------------+
void OnStart()
{
   for(int i = 1; i <= 4; i++)
   {
      Print(all_combinations(4, i));
   }
}
//+------------------------------------------------------------------+
int count_bits (int n)
{
   int result = 0;
   for (; n; n >>= 1) result += n & 1;
   return result;
}
//+------------------------------------------------------------------+
string all_combinations (int n, int k)
{
   string s = "";
   for (int i = 0; i < (1 << n); ++i)
   {
      int pos = i ^ (i >> 1);
      if (count_bits (pos) == k)
      {
         s += "{ ";
         for (int j = 0; j < n; ++j)
         {
            if ((pos & (1 << j)) != 0) s += (string)(j + 1) + " ; ";
         }
         s += " }";
      }
   }
   return(s);
}
//+------------------------------------------------------------------+

2020.03.17 00:05:02.465 combinatoric_2 (EURUSD,H1) { 1 ;  }{ 2 ;  }{ 3 ;  }{ 4 ;  }

2020.03.17 00:05:02.465 combinatoric_2 (EURUSD,H1) { 1 ; 2 ;  }{ 2 ; 3 ;  }{ 1 ; 3 ;  }{ 3 ; 4 ;  }{ 2 ; 4 ;  }{ 1 ; 4 ;  }

2020.03.17 00:05:02.465 combinatoric_2 (EURUSD,H1) { 1 ; 2 ; 3 ;  }{ 1 ; 3 ; 4 ;  }{ 2 ; 3 ; 4 ;  }{ 1 ; 2 ; 4 ;  }

2020.03.17 00:05:02.465 combinatoric_2 (EURUSD,H1) { 1 ; 2 ; 3 ; 4 ;  }




алгоритм рабочий, но кажется я понял что нужно.... РЕКУРСИЯ! 

блин.. ненавижу рекурсию!

 
Andrei Trukhanovich:

если я правильно понимаю, нужна генерация сочетания по его номеру?

да правильно, именно это я и ищу, посмотрел бегло статью https://rsdn.org/article/alg/Combine.xml#E5NAC

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

Генерация случайных сочетаний. Генерация сочетания по его порядковому номеру
  • rsdn.org
Базовые определения и обозначения Вычисление биномиального коэффициента Генерация случайного сочетания методом случайной перестановки Генерация сочетания по его номеру Использование реализованных функций Сравнение двух...
 
Igor Makanu:

возможно там есть готовое решение

да, там есть готовое решение, но оно какое-то чрезмерно эээ плюсово-STL-ное

смысл алгоритма в том, что если сочетания упорядочены лексикографически, мы можем вычислить, включается ли данный номер в сочетание по простой рекуррентной формуле:

C(n,m) = C(n-1,m) <не включаетя> + C(n-1, m-1) <включается>

 
TheXpert:

да, там есть готовое решение, но оно какое-то чрезмерно эээ плюсово-STL-ное

угу, в этом то и проблема, я не знаю С++ уже лет 20 как

почти решил свою хотелку - на основе последнего скрипта, задача именно через оптимизируемые параметры тестера работать и получать по очереди различные сочетания цифр

UPD: кажется сделал что хотел - перебор комбинаций всех сочетаний с помощью тестера:

sinput int AllSettingEA     = 4;       
input int CountCombination = 15;       //CountCombination = 1..15

bool isInitOK = true;
string set_combination = "";
//+------------------------------------------------------------------+
int OnInit()
{
   set_combination = GenFileNames(AllSettingEA, CountCombination);
   if(set_combination == "")
   {
      isInitOK = false;
      return(INIT_FAILED);;
   }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
double OnTester()
{
   if(isInitOK)
   {
      int handle = FileOpen("tstEA.txt", FILE_READ | FILE_WRITE | FILE_TXT | FILE_COMMON);
      if(handle > 0)
      {
         FileSeek(handle, 0, SEEK_END);
         FileWriteString(handle, set_combination + "\n");
         FileClose(handle);
      }
   }
   return(AccountInfoDouble(ACCOUNT_BALANCE));
}
//+------------------------------------------------------------------+
void OnTick()
{

}
//+------------------------------------------------------------------+
string GenFileNames(int n, int Ncomb)
{
   int cg, gray_code, num = 0;
   string s = "";
   for(int k = 1; k <= n; k++)
   {
      for (int i = 0; i < (1 << n); ++i)
      {
         cg = gray_code = i ^ (i >> 1);
         int count_bits = 0;
         while(cg)
         {
            count_bits += cg & 1;
            cg >>= 1;
         }
         if (count_bits == k && ++num == Ncomb)
         {
            for (int j = 0; j < n; ++j)
               if ((gray_code & (1 << j)) != 0) s += IntegerToString(j, 2, '0') + ".bin ";
            StringTrimRight(s);
            return(s);
         }
      }
   }
   return("");
}
//+------------------------------------------------------------------+

запустил оптимизацию на одном агенте(чтобы запись в файл корректно происходила) вот файл tstEA.txt

00.bin

01.bin

02.bin

03.bin

00.bin 01.bin

01.bin 02.bin

00.bin 02.bin

02.bin 03.bin

01.bin 03.bin

00.bin 03.bin

00.bin 01.bin 02.bin

00.bin 02.bin 03.bin

01.bin 02.bin 03.bin

00.bin 01.bin 03.bin

00.bin 01.bin 02.bin 03.bin

вроде все перебирает и работает как задумано, есть правда небольшое неудобство в примерном расчете input int CountCombination = 15;  - это количество переборов в тестере, формула то по факториалу, но можно ставить бОльшее значение - пустой проход тестера очень быстрый
 
Задача, которая решается на лету не отходя от кассы и не снимая шубы. Сгенерировать массив и вставить его в эксперта.
 
Dmitry Fedoseev:
Задача, которая решается на лету не отходя от кассы и не снимая шубы. Сгенерировать массив и вставить его в эксперта.

неее, не прокатит, нудная работа, тем более я еще не знаю сколько .set - файлов обьединять в одного ЕА, сейчас вроде 100 файлов будет, значит нужно поставить в настройки последнего кода 

AllSettingEA     = 100;

и... тут то основная проблема, прикинул, ну на сто файлов примерно такое число  CountCombination = 200 000; 

но можно и с запасом брать, хотя нужно формулу нагуглить и сделать скрипт как калькулятор

ЗЫ: потом можно в буквальном смысле слова стопяцот настроек ЕА попробовать в один портфель стратегий обьединить.... в общем потестирую там видно будет

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