Помогите объединить несколько массивов в один. - страница 3

 
Вот, кстати, давно интересно, есть ли смысл класть ArraySize в отдельную переменную, чтобы каждый раз в цикле не вызывать, или компилятор соображает сделать это при оптимизации?
 
Alexey Viktorov #:

Вот такой вариант не нравится?

результат

Нравится)

Да, как и писали вначале, это самый простой способ. 

К нему и пришёл в итоге.  Хотелось бы пооптимальнее, но что то у меня пошло не так, в итоге остановился на таком же варианте как написали вы, только я не стал перераспределять массив ArrayRemove, а копировал из массива в него же, как писал  Aliaksandr Hryshyn

Надо бы проверить, какой способ быстрее.

Спасибо за участие.

А то что я писал, что массивов много и сумма элементов  всех массивов, может оказаться больше максимального числа элементов массива  2147483647, в общем до этого числа мне далеко.

 
JRandomTrader #:
Вот, кстати, давно интересно, есть ли смысл класть ArraySize в отдельную переменную, чтобы каждый раз в цикле не вызывать, или компилятор соображает сделать это при оптимизации?

Значит нужно проверить)


Я проверял как ведёт себя компилятор с PositionsTotal().  Получилось, что запрашивает количество позиций при каждой итерации.

for(int i = PositionsTotal() - 1; i >= 0; i--)  и   for(int i = 0; i < PositionsTotal(); i++) 

дают абсолютно разные результаты при закрытии позиций )))

 
JRandomTrader #:

Типа того.

Не пойдёт. У вас решение конкретного примера, а не поставленной задачи.

А в задаче указанно, что количество массивов заранее не известно. Известно только, что их много)

 
Aleksandr Slavskii #:

Не пойдёт. У вас решение конкретного примера, а не поставленной задачи.

А в задаче указанно, что количество массивов заранее не известно. Известно только, что их много)

Тогда как-то так:

class cA
  {
private:
   int        a[];
   int        i;
public:
              cA(const int &array[]){i=0;ArrayResize(a,ArraySize(array)); ArrayCopy(a,array);};
             ~cA(void){};
   int        cur(void){return a[i];};
   int        size(void){return ArraySize(a);};
   bool       EOA(void){return i>=ArraySize(a);};
   void       next(void){i++;};
  };

void OnStart()
  {
   cA *A[];
   int result[];
   int a,i,s;
   bool done;

//--------Init----------
   ArrayResize(A,3);
   int aaa[] = {0, 2, 3, 12, 13, 25};
   int sss[] = {14, 15, 26, 32};
   int ddd[] = {0, 1, 2, 3, 12, 15, 16, 25, 48};
   A[0]=new cA(aaa);
   A[1]=new cA(sss);
   A[2]=new cA(ddd);
//-------/Init----------

   for(a=0, s=0; a<ArraySize(A); a++)
     {
      s+=A[a].size();
     }
   ArrayResize(result,s);

   for(i=0; i<ArraySize(result); i++)
     {
      done=true;
      for(a=0; a<ArraySize(A); a++)
        {
         if( !A[a].EOA() && ( A[a].cur()<result[i] || done ) )
           {
            result[i]=A[a].cur();
            done=false;
           }
        }
      if(done) break;
      for(a=0; a<ArraySize(A); a++)
         if( !A[a].EOA() && A[a].cur()==result[i] ) A[a].next();
     }
   ArrayResize(result,i);
   ArrayPrint(result);
   for(a=0; a<ArraySize(A); a++) delete A[a];
  }
 
Aleksandr Slavskii #:

Не пойдёт. У вас решение конкретного примера, а не поставленной задачи.

А в задаче указанно, что количество массивов заранее не известно. Известно только, что их много)

Массивов много, а как определяется количество и как они именуются? Ведь как-то в любом случае надо брать имя массива который надо копировать… Я что-то не помню функцию возвращающую количество массивов…

 
JRandomTrader #:

Тогда как-то так:

Возможно это хорошее решение, но как я писал чуть выше, ООП я так и не освоил.  Увы :(

 
Alexey Viktorov #:

Массивов много, а как определяется количество и как они именуются? Ведь как-то в любом случае надо брать имя массива который надо копировать… Я что-то не помню функцию возвращающую количество массивов…

В вашем решении можно использовать цикл для перебора массивов. Поэтому ваше решение мне подошло, немного его сделал по другому, но принцип тот же.


Эх, вроде старался максимально подробно описать задачу, но даже с этим не справился. 

Видимо мой пример всех сбил с толку.  Я его привёл для наглядности, чтоб было понятно какой результат в итоге нужен.

В условии к задаче указано, что есть много массивов, в каком они виде и как именуются не важно, выше в комменте, здесь уже описывал, где и как и что используется.


В советник встраиваю код, который во время одиночного прохода, в тестере, записывает баланс, эквити и время. В OnDeinit() скидываю это в файл.

struct Deal
  {
   datetime          time;
   double            balans;
   double            equity;
  };
Deal m_Deal[];
//----------------------------------------------------
void OnDeinit(const int reason)
  {
    FileSave(FileName, m_Deal, FILE_COMMON);
  }

Таких проходов много.

Затем скрипт,  читает эти сохранённые файлы в массив структур.

 struct Data
  {
   struct Deal
     {
      datetime          time;
      double            balans;
      double            equity;
     };
   Deal              m_Deal[];
  };
Data m_Data[]; 

 FileSelectDialog("Выберите файлы данных", "Files", NULL, FSD_ALLOW_MULTISELECT | FSD_COMMON_FOLDER, FileName);
   int total = ArraySize(FileName);
   if(total <= 0)
      return;

   ArrayResize(m_Data, total);
   ArrayResize(sizeLoad, total);
   for(int i = 0; i < total; i++)
      sizeLoad[i] = (int)FileLoad(FileName[i], m_Data[i].m_Deal, FILE_COMMON);


Так как позиции открываются как разное время,так  и в одно и то же, нужно все значения времени, всех массивов, собрать в один массив.

Я сделал так:

   double timeG[];
  int sizeLine = ArrayMergeSort2(m_Data, timeG);

//-------------------------------------------------------------
int ArrayMergeSort(Data & n_Data[], double & result[])
  {
   int sizeRes = 0;
   int total = ArraySize(n_Data);
   for(int i = 0; i < total; i++)
     {
      int size = ArraySize(n_Data[i].m_Deal);
      ArrayResize(result, ArraySize(result) + size);
      for(int j = 0; j < size; j++)
        {
         result[sizeRes] = (double)n_Data[i].m_Deal[j].time;
         sizeRes++;
        }
     }

   sizeRes = 0;
   ArraySort(result);
   for(int i = 1; i < ArraySize(result); i++)
      if(result[sizeRes] < result[i])
        {
         sizeRes++;
         result[sizeRes] = result[i];
        }

   ArrayResize(result, sizeRes + 1);
   return sizeRes + 1;
  }

Дальше просто суммирую поминутно все балансы и эвити и рисую общий график.

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

 
Aleksandr Slavskii #:

Возможно это хорошее решение, но как я писал чуть выше, ООП я так и не освоил.  Увы :(

Можете использовать как простой пример, чтобы освоить ) Если надо что объяснить - прошу в личку.

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

 

Получаются вот такие картинки

Тестер   ADAUSDT


   ALGOUSDT


BTCUSDT


FTMUSDT


И в итоге когда соединяю все в одну, такой результат.


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

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