[АРХИВ!] Любой вопрос новичка, чтоб не захламлять форум. Профи, не проходите мимо. Без вас никуда - 4. - страница 101

 
kon12:

Понял... Если другой путь с перерисовкой?
Код покажите и Вам сразу ответят.
 
Lisi4ka330:


Добрый день! Помогите пожалуйста разобраться с функцией ArrayMo (ф-я возвращает максимум кривой плотности ).

double ArrayMo(double& x[], int d=4) {
  double e, s=0;
  double m[][2];             // временный массив:
                             //  столбец 1 - количество значений
                             //  столбец 2 - значения
  int    i, k=ArraySize(x);
  int    n;                  // номер строки временного массива m
  int    r;                  // количество строк во временном массиве m

  if (k>0) {
    for (i=0; i<k; i++) {
      e=NormalizeDouble(x[i], d);
      n=ArraySearchDouble(m, e);
      if (n<0) {
        r=ArrayRange(m, 0);
        ArrayResize(m, r+1);
        m[r][0]++;
        m[r][1]=e;
      } else m[n][0]++;
    }
    ArraySort(m, WHOLE_ARRAY, 0, MODE_DESCEND);
    s=m[0][1];
  } else Print("ArrayMo(): Массив пуст!");

  return(s);
}

Возникли следующие вопросы:

1.С какой целью создается временный массив

m[][2]

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

n=ArraySearchDouble(m, e)

3. А дальше вообще для меня истина глубоко спрятана))))) После того как мы убедились, что значения нет, мы начинаем определять размер массива "непонятно каких значений".

Буду очень признательна за лучик света в этой истории))))


Мне кажется, функция все таки написана не вполне корректно. Основная причина - после объявления

double m[][2];

необходимо обязательно

ArrayResize(m,0);

иначе (цитирую)

int ArrayResize( void array[], int new_size)
Устанавливает новый размер в первом измерении массива. При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера, в противном случае возвращает -1, и массив не меняет размеры.
!!!Замечание: массив, объявленный на локальном уровне в какой-либо функции, у которого был изменен размер, останется неизменным после завершения работы функции. При повторном вызове функции такой массив будет иметь размер, отличный от объявленного.!!!

И таким образом при многочисленных вызовах функция "провалится в прошлое")

По поводу работы алгоритма. Сам массив m[][2] - это представление непосредственно эмпирического распределения количества попаданий переменной x[i] по ее различным значениям. Т.е. каждый элемент массива состоит из двух чисел - количество попаданий в некое значение (первое поле) и само это значение. В цикле для каждого x[i] осуществляется поиск такого же значения в массиве m, и если оно найдено - плюсуется поле количества, в противном случае - с помощью ArrayResize() создается новый элемент и наше x[i] пишется туда.

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

Это сделано строками

    ArraySort(m, WHOLE_ARRAY, 0, MODE_DESCEND);
    s=m[0][1];

хотя, мне кажется (не уверен насчет многомерного массива), можно было просто

    s=m[ArrayMaximum(m)][1];

В целом могу сказать (при всем уважении к автору кода), что даже при исправлении всех недочетов данный алгоритм крайне неэффективен и может часто давать неверный результат. Причина заключается в том, что мы работаем с типом double, а значит вероятность того, что величины x[i] будут попадать в очень близкие, но все таки различимые значения, достаточно велика. Это может оказаться не столь заметно, когда объем выборки много больше (в сотни раз и более) общего количества интервалов, на которые разрешена область определения x[i]. Однако в тех многочисленных случаях, когда данное ограничение не выполнено, неправильных вычислений будет очень много.

Более правильный путь вычисления моды такой: строится эмпирическая функция распределения (не путать с распределением частот), после чего она интерполируется от кусочно-линейной к гладкой, и в завершение ищется точка максимума производной. Такой алгоритм свободен от перечисленных выше недостатков и работает весьма эффективно даже с малыми объемами выборки. По крайней мере, мне приходилось решать на MQL как раз задачу нахождения мод на выборках всего в 50-100 элементов при сравнимом количестве интервалов, и все было ОК. Недостаток один - на интерполяциях как правило сильно падает скорость расчетов, если, конечно, хотим сглаживать качественно.

 
Здравствуйте уважаемые форумчане к кому можно обратиться по написанию советника. Советник без индикаторов в основе удвоение при движении не в нашу сторону.
 
Glazunov:
Здравствуйте уважаемые форумчане к кому можно обратиться по написанию советника. Советник без индикаторов в основе удвоение при движении не в нашу сторону.
сюда: https://www.mql5.com/ru/job
 
ilunga:
сюда: https://www.mql5.com/ru/job

Спасибо. Может быть есть ещё варианты.
 
Glazunov:

Спасибо. Может быть есть ещё варианты.
попробуйте в поиске на сайте набрать "мартингейл" - удивитесь
 
YOUNGA:
попробуйте в поиске на сайте набрать "мартингейл" - удивитесь

Уже смотрел! Но того что я хочу нет(
 
Glazunov:
Здравствуйте уважаемые форумчане к кому можно обратиться по написанию советника. Советник без индикаторов в основе удвоение при движении не в нашу сторону.


Посмотрите здесь

https://www.mql5.com/ru/forum/136747

 

Здравствуйте. В MQL4 только начал.

Подскажите по функции OrderModify. В учебниках и примерах эту функцию рассматривают для трала, т.е. изменение stop loss. Мне нужно изменить только take profit на открытом ордереПри открытии stop loss не задавался, при модефикации также должен остаться на 0.

Как при этом должен выглядеть подсчет и выбор ордеров ?

Конечная цель должна выглядеть как то так:

if (OrderType()==OP_BUY && OrderOpenPrice()-Bid>kof*Point) // есть buy, но ушло вниз на величину kof
{
OrderModify(OrderTicket(),OrderOpenPrice(),0,OrderOpenPrice()+tpnew*Point,0,CLR_NONE);// переносим TP пониже выставленного ранее

По sell аналогично.

Спасибо за любые ответы.

 

И снова здравствуйте! :)

Как я и думал, проблемы возникли. Вот код. Смысл в том, что ордера на тестере закрываются по TP, а по функции TP убирается при модификации ордера во время Трейлинг стопа.

double my_ord[31][2];                                           //ордера советника
                                                                //[][0] Ticket
                                                                //[][1] Вид операции 
//---------------------------------------------------------------------------------

void FindMyOrders()                                             //ищем свои ордера(от советника)
   {
    for (int a = 0;a<32;a++)                                    //во избежание ошибок заполняем все нулями
      {
       my_ord[a][0]=0;
       my_ord[a][1]=0;
      }
    int pos = 0;
    for(int i=0; i<32; i++)
      {
       if (Mas_Ord_New[i][8]==1)                                //есть ли комментарий
         {
          int num = Mas_Ord_New[i][4];
          OrderSelect(SELECT_BY_TICKET, num);
          string str = OrderComment();
          if (str == "AO Day Profiter Trade")                   //наш ли это комментарий
            {
             my_ord[pos][0] = num;
             my_ord[pos][1] = Mas_Ord_New[i][6];                //если наш, записываем Ticket и вид операции
             pos++;
            }
          else { }
         }
       else { }
      }
   }
//---------------------------------------------------------------
void TrailStop(int ticket, int TStop)                           //ф-ция трейлинг стопа, TStop-расстояние в пп
   {
    int minDist = MarketInfo(symb, MODE_STOPLEVEL);
    if (TStop<minDist)
      {
       TStop = minDist;
      }
    else { }
    if (TStop>0)
      {
       OrderSelect(ticket, SELECT_BY_TICKET);
       if(OrderType()==OP_BUY)
         {
          if(Bid - OrderOpenPrice()>Point*TStop)
            {
             if(OrderStopLoss()<Bid-Point*TStop)
               {
                OrderModify(OrderTicket(), OrderOpenPrice(), 
                Bid-Point*TStop, 0, 0, Blue);
                return;
               }
             else { }
            }
            else{ }
         }
       else if (OrderType()==OP_SELL)
         {
          if(OrderOpenPrice() - Ask>Point*TStop)
            {
             if(OrderStopLoss()>Ask + TStop*Point)
               {
                OrderModify(OrderTicket(), OrderOpenPrice(), 
                Ask+Point*TStop, 0, 0, Blue);                           //ordertakeprofit!!
                return;
               }
             else { }
            }
          else { }
         }
       else { }
      }
    else { }
    }
//-----------------------------------а это кусочек Start(), отвечающий за трейлинг стоп
   for (int i = 0; i<32; i++)                                   //трейлинг стоп для наших ордеров
      {
       if (my_ord[i][0]>0)
         {
          TrailStop(my_ord[i][0], TralingStop);
         }
       else {break;}
      }
А значит, трейлинг стоп не исполняется, при этом в журнале тестера ошибок с неправильным TP и SL не было. Что же неверно?
Причина обращения: