Выявления диагонали движущего объекта по спирали, симметрии взаимно вложенных фаз и т.п.

Mikhail Toptunov  

Ищу помощника в реализации идеи.
На базе выявления симметрии взаимно вложенных фаз и т.п.
Готов платить за  толковые идеи.

Изложу, что желаю реализовать уже более 10 лет)))
Что то сделал, что казалась не реальным для меня.
Хочу, что бы было идеально!)

“мазком” для оценки работы над первым модулем.
Смысл первого модуля:

Есть N- кол-во Скользящих Средних МА с заданными параметрами (например 1200 штук МА, HL/2, Simple).
Нужно проявить образуемые скопления этих МА наиболее эффективным способом, с возможностью считывать образовавшиеся Жгуты, на всех ТаймФреймах.

Жгуты имеют особенность прерываться.
Жгут это множества МА. Интересно как реализовать выявление жгута который динамичен , на каждом новом баре являет себя на следующих периодах МА. Он то проявляется то пропадает и являет себя с каждым движением на более старших периодах))) (С долей шутки)

В моём примере я отбираю именно момент перехода жгута из одного положения в другое и прокладываю Фибо от Максимума или Минимума цены и от 50 ур, в зависимости от того с какой тенденции жгут меняет направление.

Думаю желательно осознавать что Жгут это один из параметров для поиска Диагонали движущегося объекта(точнее процесса), а цена это контур этого движения, а движение идёт по спирали (понимаю , что для Профи это не так, но для реализации этой общей задачи , это как допущение для понимания о что мечтаю увидеть)


Скидываю пример как реализован у меня:
не всегда проявляет Скопления.
Вообще я сканирую двумерный массив по диагонали , нахожу фрактал и заношу его в класс, записывая всю какую можно инфу о нём.

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

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTimer()
  {
   int total = list_new_bar.Total();
   for(int i = 0; i < total; i++) // перебор по всем ТФ
     {
      CNewBar* nb = list_new_bar.At(i);   // Класс сбора информации по барам расчётного бара 
      CSMA_Greed *sm = list_new_MA.At(i); // Класс расчёта МА
      if(nb == NULL || sm == NULL)
         continue;
      //--- Новый бар
      if(nb.IsNewBar())
        {
         ObjectsDeleteAll(0,(string)PerioD(i)+" Пер ");  // Чистим график от неактивных ФибУровней
         //--- Расчитываем МА дополняя новым баром
         sm.Solve(nb.m_rt, nb.m_pc, nb.m_pr_hl2);//nb.m_pc
         //--- Расчитываем связку по фракталам
         Svjazka0_1(i);
         //--- Выставляем ФибУровень
         ObjectFibOn(i);
         //--- Загрузка в файл
       //  SaveStats(Symbol(),i);
         //---
         Print(" ObjectsTotal ", ObjectsTotal(0,-1,OBJ_FIBO)," Tf ",nb.m_timeframe);
         //Print("Tf ",nb.m_timeframe," Mb ",nb.m_rt," Mp ",nb.m_pmax," CountCB ",CountCB);
         //--- Обнуляем класс Исходного Сигнала
         ZeroMemory(cand_buff);
         CountCB=0;
        }
     }
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Расчитываем связку волны по фракталам - перебор по диагонали     |
//+------------------------------------------------------------------+
void Svjazka0_1(int tf)
  {
   CNewBar* nb = list_new_bar.At(tf);
   CSMA_Greed *sm = list_new_MA.At(tf);
//--
   for(int pu=2; pu< nb.m_pmax; pu++)
     {
      ZeroMemory(alt);
      for(int p = pu, b = nb.m_rt-1; p >= pu-p-1 && b >= nb.m_rt-nb.m_pmax; p--, b--)
         Svjazka0_2(p,b,pu,tf);
      if(alt.count > 2)
         Svjazka0_3(alt.count,tf);
     }
   for(int pu=nb.m_rt-2, o=nb.m_pmax/2; pu >nb.m_rt-nb.m_pmax; pu--, o++)
     {
      ZeroMemory(alt);
      for(int p = nb.m_pmax-1, b =pu; p >= o; p--, b--)
         Svjazka0_2(p,b,pu,tf,nb.m_pmax-1);
      if(alt.count > 2)
         Svjazka0_3(alt.count,tf);
     }
  }
//+---Записываем если попала в фрактал-------------------------------+
//* Добавить размерность alt[]
void Svjazka0_2(int p, int b, int pu, int tf, int pusum=0)
  {
   CNewBar* nb = list_new_bar.At(tf);
   CSMA_Greed *sm = list_new_MA.At(tf);
//---
   if(sm.d[p-1].f[b] != NULL)
     {
      ArrayResize(alt.indp,alt.count+1);
      ArrayResize(alt.indb,alt.count+1);
      ArrayResize(alt.indx,alt.count+1);
      ArrayResize(alt.pr,alt.count+1);
      //---
      int count= alt.count;
      alt.indp[count]= p;
      alt.indb[count]= b;
      alt.indx[count]= pusum == 0 ? pu : nb.m_pmax + MathAbs(nb.m_rt - pu);
      alt.pr[count]= sm.d[p-1].m[b];
      alt.count++;
     }
//---
  }
//+---Рассчитываем связку волны по фракталам--------------------------+
//* рассчитывать фрактал первого бара
void Svjazka0_3(int count, int tf)
  {
   double arr[];
   int ipor= 10;           // Количество пробелов в связке 10
   ArrayResize(arr,count);
//---
   for(int i= 0; i<count; i++)
      arr[i]= alt.pr[i];
//---
   int imax= ArrayMaximum(arr,1,count-2);
   int imin= ArrayMinimum(arr,1,count-2);
//---
   int ipormax1= alt.indb[imax] - alt.indb[imax+1];
   int ipormax2= alt.indb[imax-1] - alt.indb[imax];
   int ipormin1= alt.indb[imin] - alt.indb[imin+1];
   int ipormin2= alt.indb[imin-1] - alt.indb[imin];
//---
   if(ipormax1 < ipor && ipormax2 < ipor)
      if(alt.pr[imax]>=alt.pr[imax+1] && alt.pr[imax]>=alt.pr[imax-1])
         SignalPO2(imax,0,tf);
   if(ipormin1 < ipor && ipormin2 < ipor)
      if(alt.pr[imin]<=alt.pr[imin+1] && alt.pr[imin]<=alt.pr[imin-1])
         SignalPO2(imin,1,tf);
//---
   ArrayFree(arr);
  }

//+------------------------------------------------------------------+
//| Записываем полный сигнал                                         |
//+------------------------------------------------------------------+
void SignalPO2(int count,int type,int tf)
  {
   CNewBar* nb= list_new_bar.At(tf);
   CSMA_Greed *sm= list_new_MA.At(tf);
   ArrayResize(cand_buff,CountCB+1);
//---
   cand_buff[CountCB].ID= CountCB;
   cand_buff[CountCB].tf= tf; //nb.m_timeframe изменил на текущее, SQL работать не будет т.к. там другой форман числа
   cand_buff[CountCB].PeriodUr50= alt.indp[count];
   cand_buff[CountCB].bar= alt.indb[count];
   cand_buff[CountCB].PraceUr50= alt.pr[count];
   cand_buff[CountCB].type= type;
   cand_buff[CountCB].timeUr50= nb.m_tim_pr_hl2[alt.indb[count]];
   cand_buff[CountCB].timeOt= nb.m_tim_pr_hl2[(alt.indb[count]-alt.indp[count])];
   cand_buff[CountCB].timeDo= nb.m_tim_pr_hl2[alt.indb[count]]+PeriodSeconds(nb.m_timeframe)*alt.indp[count];
   cand_buff[CountCB].CountChain= nb.m_rt - alt.indx[count];  // номер цепи
   cand_buff[CountCB].PriorVH= 0;
   cand_buff[CountCB].Actual= 0;
   cand_buff[CountCB].VHProc= -1;                   // ProcVolumFiltr
   cand_buff[CountCB].High= nb.iHighMax(cand_buff[CountCB].bar-cand_buff[CountCB].PeriodUr50-1,cand_buff[CountCB].PeriodUr50+1);
   cand_buff[CountCB].Low= nb.iLowMin(cand_buff[CountCB].bar-cand_buff[CountCB].PeriodUr50-1,cand_buff[CountCB].PeriodUr50+1);
//--- Фильтр на актуальность
//--- ...будущее   if(cand_buff[CountCB].Actual == 0)
     {
         CountCB++;
     }
  }
//+------------------------------------------------------------------+
//| Выставляем ФибСигнал                                             |
//+------------------------------------------------------------------+
void ObjectFibOn(int tf)
  {
   CNewBar* nb = list_new_bar.At(tf);
   for(int i= 0; i<CountCB; i++)//&&!IsStopped()
    //  if(cand_buff[i].Actual!=-1)
        {
         Fib(cand_buff[i].type,cand_buff[i].timeUr50,cand_buff[i].PraceUr50,cand_buff[i].High,
             cand_buff[i].Low,cand_buff[i].bar,cand_buff[i].PeriodUr50,cand_buff[i].Actual,cand_buff[i].tf,cand_buff[i].CountChain, i);
         Print(" PeriodUr50 ",cand_buff[i].PeriodUr50," bar ",cand_buff[i].bar," time ",cand_buff[i].timeUr50," type ",cand_buff[i].type," VH ",cand_buff[i].VH,
               " PriorVH ",cand_buff[i].PriorVH," CountChain ",cand_buff[i].CountChain,
               " tf ",GetPeriodEnumerator((uchar)tf)," i ",i);
        }
  }
Файлы:
Maxim Kuznetsov  

"Жгут" - группа SMA c близкими значениями и следующими параллельно (какое-то время)

SMA(close) c периодами N<M идут примерно паралелльно пока (варианты определений для незначительных изменение на единичном баре):
1) (Close[N]-Close[0])/N~=(Close[M]-Close[0])/M, прямо по определению SMA

2) пока Close[N]-Close[M]~=const, 

3) имела место быть автокорреляция N,M

3) или SMA c периодом M-N и сдвигом N горизонтальна

4) совсем по простому - для близких N,M пока цена в канале средние почти паралельны

аналогично можно про "схождение/пересечение SMA" (они сближаются после разворотов)

итого, навскидку : жгут - след линейного канала, возникшего после разворота, причём в большинстве случаев - завершённого, сами жгуты - срез в кореллограмме. Сильно-сильно сомневаюсь в практическом применении, то есть ничего в код ненамерян, но в свободное время отчего не поболтать

Mikhail Toptunov  

Есть значения - это фрактал жгута, минимум(Tape1)L  или максимум(Tape0)H.

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

как вариант:

1) По Tape

2) В зависимости от Tape определять к какому High или Low цены относятся.

3) По цене Ур50(самого фрактала, цена самого жгута) - очень не надёжно

...

Ищу вариант! Буду признателен за возможные пути решения!

По каким параметрам связать эти точки? Доступные Параметры

Mikhail Toptunov  

Может кто подскажет , как максимально эффективно определить максимальный бар в зависимости от значения type, в зоне CountC. 

Вроде должно быть просто, а выходит ухожу в дебри.

Пример : У CountC =2  для  type =1  максимальный бар 4227, а  для  type =0  максимальный бар 4226.


Пробовал значению  CountC  присваивать -(минус), если  type =1. Потом сортировать , но чем дальше тем усложняю решение.

//+----------------------------------------------------------------------------+
//| Дублирование класса в массив, фильтруем по тождественности сигнала         |
//+----------------------------------------------------------------------------+
//*** Усовершенствовать по скорости
//*** Создать два разных, распознать цикл подобных
void DuplicateArrayClass(int tf)
  {
//---
   double ArrayIdentity[];
   int ArrayBar[];
   int in= 1,arrin[];
   ArrayResize(arrin,CountCB+1);
   ArrayResize(ArrayIdentity,CountCB+1);
   ArrayResize(ArrayBar,CountCB+1);
//---
   for(int i=0; i<CountCB; i++)
     {
      ArrayIdentity[i]= cand_buff[i].type==0 ? in : -in;//in;//
      arrin[i]= i;
      ArrayBar= cand_buff[i].bar;
      for(int j=i-1; j>=0; j--)
        {
         if(cand_buff[j].High==cand_buff[i].High && cand_buff[j].Low==cand_buff[i].Low)
            if(MathAbs(cand_buff[j].CountChain-cand_buff[i].CountChain)<40)
               break;
         in++;
         ArrayIdentity[i]= cand_buff[i].type==0 ? in : -in;//in;//
         break;
        }
     }
//---
// DuplicateArrayClassType(ArrayIdentity,arrin);
//---
   for(int i=0; i<CountCB; i++)
      cand_buff[i].CountChain= (int)ArrayIdentity[i];
//---
  }
//+----Ищим экстремум по типу---------------------------------------------+
void DuplicateArrayClassType(double &array[],int &arrin,int &arrbr)
  {
 /*  MathQuickSort(array,arrin,0,CountCB-1,1);
//---
   int CC=0, count=0;
   for(int i=0; i<CountCB; i++)
      if(array[i]!=CC)
        {
         ArrayMaximum(arrbr,i,count);
         CC= array[i];
         count= 0;
        }
      else
         count++;*/

//---
  }
Renat Akhtyamov  

---цикл 1 (уменьшение промежутка между текущим и например 100-м баром)

-------цикл 2 (перебор МА)

-----------поиск минимального Abs(дельта значения МА)

---

к тому же сейчас появились матрицы

---

задачу таким образом решите, но платить не надо, все равно бесполезно

Mikhail Toptunov  
Mikhail Toptunov #:

Может кто подскажет , как максимально эффективно определить максимальный бар в зависимости от значения type, в зоне CountC. 

Вроде должно быть просто, а выходит ухожу в дебри.

Пример : У CountC =2  для  type =1  максимальный бар 4227, а  для  type =0  максимальный бар 4226.


Пробовал значению  CountC  присваивать -(минус), если  type =1. Потом сортировать , но чем дальше тем усложняю решение.

Пока такое исполнение.

Хотелось бы конечно по симпатичней исполнить.

//+----Ищим экстремум по типу---------------------------------------------+
void DuplicateArrayClassType(int &array[])
  {
   for(int i=0; i<CountCB; i++)
      if(array[i]!=NULL)
        {
         int bar= 0, _i= 0;
         for(int j=0; j<CountCB; j++)
            if(array[j]!=NULL)
               if(array[i]==array[j])
                 {
                  if(cand_buff[j].bar>=bar)
                    {
                     bar= cand_buff[j].bar;
                     if(_i>0)
                       {
                        cand_buff[_i].Actual= 1;
                       // array[i]=NULL;
                       }
                     _i=j;
                    }
                  if(cand_buff[j].bar<bar)
                    {
                     cand_buff[j].Actual= 1;
                  //   array[j]=NULL;
                    }
                 }
        }

//---
  }
Mikhail Toptunov  

Может кто-нибудь помочь. Есть у меня канал, CCanvas отражает его на графике. 

Как или с помощью канваса или отдельно, отследить текущее положение этого канала . Например текущая цена  аск  1.05 , а нижняя текущая цена канала 1.00. Как мне с считать эту информацию, Какая цена у канала на текущий момент, например по бару 0?

//+------------------------------------------------------------------+
//| Координаты Парабулу                                              |
//+------------------------------------------------------------------+
void CoordinatesParabola(int tf, int type,int bar1,int bar2,int bar3,int bar4,double price1,double price2,double price3,double price4, int count)
  {
   ArrayResize(ParCoo,count+1);
//---
   ParCoo[count].tf= tf;
   ParCoo[count].clorZig= ColorToARGB(clrMediumSpringGreen,50);
   ParCoo[count].clorUpper= type==0 ? ColorToARGB(clrRed,255) : ColorToARGB(clrBlue,255);
   ParCoo[count].clorLower= type==0 ? ColorToARGB(clrBlue,255) : ColorToARGB(clrRed,255);
// переводим координату в барах в пиксельную координату
   ParCoo[count].x1= Canvas.X((datetime)bar1);
   ParCoo[count].x2= Canvas.X((datetime)bar2);
   ParCoo[count].x3= Canvas.X((datetime)bar3);
   ParCoo[count].x4= Canvas.X((datetime)bar4);
// переводим координату "цена" в пиксельную координату
   ParCoo[count].y1= Canvas.Y(price1);
   ParCoo[count].y2= Canvas.Y(price2);
   ParCoo[count].y3= Canvas.Y(price3);
   ParCoo[count].y4= Canvas.Y(price4);
//---
  }
//+---Рисуем Парабулу------------------------------------------------+
void DrawParabola(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4,uint clorUpper,uint clorLower,uint clorZig)
  {
   double a0=(((double)x2*x2-x4*x4)*(x1-x3)-((double)x1*x1-x3*x3)*(x2-x4));
   if(a0==0)
      return;
   double a=((y2-y4)*(x1-x3)-(y1-y3)*(x2-x4))/a0;
   double b=(y2-y4-a*(x2*x2-x4*x4))/(x2-x4);
   double  c=y1-a*x1*x1-b*x1;
   double  c1=y2-a*x2*x2-b*x2;
   double  h=c1-c;

   double step = 10;
   double pre_y = a*x1*x1+b*x1+c;
// рисуем две параболы
   for(double x = x1+step; x < W.Width; x+=step)
     {
      double y = a*x*x+b*x+c;
      Canvas.LineD(x-step, pre_y,x,y,clorUpper);
      Canvas.LineD(x-step, pre_y+h,x,y+h,clorLower);
      pre_y = y;
     }
// рисует линии соединяющие 4 точки
   Canvas.LineD(x1,y1,x2,y2,clorZig);//0xCC98FB98
   Canvas.LineD(x2,y2,x3,y3,clorZig);
   Canvas.LineD(x3,y3,x4,y4,clorZig);
//---
  }
Maxim Kuznetsov  
Mikhail Toptunov #:

Может кто-нибудь помочь. Есть у меня канал, CCanvas отражает его на графике. 

Как или с помощью канваса или отдельно, отследить текущее положение этого канала . Например текущая цена  аск  1.05 , а нижняя текущая цена канала 1.00. Как мне с считать эту информацию, Какая цена у канала на текущий момент, например по бару 0?

за вас ещё раз посчитать y = a*x*x + b*x + c ?

Mikhail Toptunov  
Maxim Kuznetsov #:

за вас ещё раз посчитать y = a*x*x + b*x + c ?


Что получается в место Х подставлять, что бы по последнему бару высчитать положение канала? 


// рисуем две параболы
   for(double x = x1+step; x < W.Width; x+=step)
     {
      double y = a*x*x+b*x+c;
      Canvas.LineD(x-step, pre_y,x,y,clorUpper);
      Canvas.LineD(x-step, pre_y+h,x,y+h,clorLower);
      pre_y = y;
     }
    					НЕ МОГУ ПОНЯТЬ!!!


/////////////Определяем координаты верхней линии канала по 1 бару///////////////     
   CNewBar* nb = list_new_bar.At(0);  
   double bar= Canvas.Bar(1);  
   ParCoo[count].X0= Canvas.X((datetime)nb.m_time);     // текущее время
   ParCoo[count].Y0= Canvas.Y(a*bar*bar+b*bar+c);       // текущее цена
   
   Canvas.PixelSet(ParCoo[count].X0,ParCoo[count].Y0,ColorToARGB(clrBlack,255));
///////////////////////////////////////////////////////////////////////////////
// рисует линии соединяющие 4 точки    Canvas.LineD(x1,y1,x2,y2,clorZig);//0xCC98FB98    Canvas.LineD(x2,y2,x3,y3,clorZig);    Canvas.LineD(x3,y3,x4,y4,clorZig); //---
Nikolai Semko  
Mikhail Toptunov #:


Что получается в место Х подставлять, что бы по последнему бару высчитать положение канала? 


Да, Михаил, тяжело устанавливаются новые нейронные связи в мозгу. Понимаю хорошо. Но это важно для эволюции. ))
Важно понимать, в какой системе координат вычислются коэф. a,b,c.

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

Если есть пиксельные координаты, а нужно получить время или бар и цену, то есть соответствующие функции (в iCanvas):

double  Price(int y_coord);
double  Bar(double x_coord);
datetime  TimePos(double x_coord);

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

double  X(double bar);
double  X(datetime Time);
double  Y(double Price);

Канвас рисует в пикселях. Поэтому, пожалуй, разумнее имеющиеся точки каждый раз пересчитывать в пиксельные координаты. Для пиксельных координат расчитывать a, b, c, а потом сразу строить в пикселей без перевода в другую систему координат.
Можно посчитать конечно коэффициенты a, b, c для баров и цене, но тогда придется при рисовании каждый раз преобразовывать координаты в пиксельные на каждом шаге. 

Для демонстрации 2 простых скрипта. Один рисует параболический канал по 4м точкам (два экстремума вверху, а два внизу), а другой параболу по 3м точкам.

Сначала задаем точки в коордитатах бар-цена, а потом их переводим в пиксельные координаты. После этого получаем коэф. a,b,c

ЗЫ С Максимом согласен. Рыбы здесь нет. Ибо что можно получить от запаздывающих машек кроме как еще более запаздывающий сурогат. 
Но для красоты, я бы тебе порекомендовал реализовать подобную горизонтальную гистограмму, только вместо накапливания цены на предыдущих барах, нужно накапливать машки по текущему бару. Думаю это будет более наглядно. Причем каждую горизонтальную линию этой гистограммы можно окрашивать в два цвета (например сначала зеленый (наклон машек вверх), а потом красный (наклон машек вниз) 
что-то типа такого 

такая гистограмма будет своя для каждого бара. Удобно будет привязать ее к указателю мыши, когда данная гистограмма будет меняться с движением мышки.
Тогда будет красивая динамичная картина Даже в маркете можно такое продать. Тормозов не будет, если все сдалать правильно. 
Maxim Kuznetsov  
Nikolai Semko #:

Да, Михаил, тяжело устанавливаются новые нейронные связи в мозгу. Понимаю хорошо. Но это важно для эволюции. ))
Важно понимать, в какой системе координат вычислются коэф. a,b,c.

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

Если есть пиксельные координаты, а нужно получить время или бар и цену, то есть соответствующие функции (в iCanvas):

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

Канвас рисует в пикселях. Поэтому, пожалуй, разумнее имеющиеся точки каждый раз пересчитывать в пиксельные координаты. Для пиксельных координат расчитывать a, b, c, а потом сразу строить в пикселей без перевода в другую систему координат.
Можно посчитать конечно коэффициенты a, b, c для баров и цене, но тогда придется при рисовании каждый раз преобразовывать координаты в пиксельные на каждом шаге. 

Для демонстрации 2 простых скрипта. Один рисует параболический канал по 4м точкам (два экстремума вверху, а два внизу), а другой параболу по 3м точкам.

Сначала задаем точки в коордитатах бар-цена, а потом их переводим в пиксельные координаты. После этого получаем коэф. a,b,c

ЗЫ С Максимом согласен. Рыбы здесь нет. Ибо что можно получить от запаздывающих машек кроме как еще более запаздывающий сурогат
Но для красоты, я бы тебе порекомендовал реализовать подобную горизонтальную гистограмму, только вместо накапливания цены на предыдущих барах, нужно накапливать машки по текущему бару. Думаю это будет более наглядно. Причем каждую горизонтальную линию этой гистограммы можно окрашивать в два цвета (например сначала зеленый (наклон машек вверх), а потом красный (наклон машек вниз) 
что-то типа такого 

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

от MA-шек можно (и нужно) получать менее запаздывающие вещи. Ближе к теме ТС, делал себе индикатор считающий из толпы МА-шек кол-во взаимных пересечений вверх/вниз. Получается показатель линейности движения, актуальный и не опаздывающий. 

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