Logo

Вход

Войти с помощью соц. сетей
Пока нет объявлений.
X
 
  • Фильтр
  • Время
  • Показать
Очистить всё
новые сообщения
  • #1 Свернуть

    Работа с массивами

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

    double arr_Orders[10][10];
    int Qnt=0; // объявление и обнуление счётчика ордеров
    ArrayInitialize (arr_Orders,0); // обнуление массива
    for(int i=0; i<OrdersTotal();i++) // ищем ордера и заполняем массив
    {
    if((OrderSelect(i,SELECT_BY_POS)==true)
    && (OrderSymbol()==Symbol()))
    { Qnt++;
    arr_Orders[Qnt][1]=OrderOpenPrice();
    arr_Orders[Qnt][2]=OrderStopLoss();
    arr_Orders[Qnt][3]=OrderTakeProfit();
    arr_Orders[Qnt][4]=OrderTicket();
    arr_Orders[Qnt][5]=OrderLots();
    arr_Orders[Qnt][6]=OrderType();
    arr_Orders[Qnt][7]=OrderMagicNumber();
    arr_Orders[Qnt][8]=OrderProfit();
    arr_Orders[Qnt][9]=OrderOpenTime();
    } } arr_Orders[0][0]=Qnt;

    Задача 1: Выдернуть из его два ордера с одинаковым OrderOpenTime(), чтобы один из них убыточный закрыть по тикеру.
    Задача 2: Достать из его ордер с наименьшим OrderProfit(), чтобы с ним тоже чё-нить сделать тоже по тикеру.
    Нутром чую - нужен перебор и функция MathMin, а с какой стороны подступиться не пойму... Уже неделю сижу - мозги набекрень. Буду рад получить форУмный совет. ВСЕМ Спасибо.
  • <a href="https://www.instaforex.org/ru/?x=ruforum">InstaForex</a>
  • #2 Свернуть

    int index1=0;
    int index2=0;
    for (int i=0;i<10;i++)
    {
    for (int j=i+1;j<10;j++)
    {
    if (arr_Orders[i][9]= arr_Orders[j][9])
    {
    index1=i;
    index2=j;
    i=11;
    }
    }
    }

    Как-то так найти можно два индекса элементов массива с одинаковыми OpenTime.
     

    Комментарий

    • #3 Свернуть

      int index1=0;
      double min= 10000000;
      for (int i=0;i<10;i++)
      {
      if (arr_Orders[i][8]< min)
      { index1=i; min=arr_Orders[i][8]}
      }

      А так найти индекс элемента массива с минимальным Profit
         

      Комментарий

      • #4 Свернуть

        Добрый день форУмным людям!

        MIXAN,здравствуйте! Чесно говоря, не думал что так быстро кто-нибудь откликнется. Спасибо большое! По существу: по поводу

        ордеров с одинаковым временем открытия (OrderOpenTime()) я так и думал, что надо два цикла, только у меня по другому скобки

        стояли. Вот не понял только назначения у Вас этого - i=11; Всё равно большое спасибо, буду пробовать. А вот по второму

        вопросу, видимо, нужно уточнить: найти ордер с наименьшим OrderProfit() среди всех ордеров в массиве. И найти именно тикер,

        а не индекс. Тут посложнее. Видимо опять применить два перебора как-то с функцией MathMin, чтоли? Может поможете? Да скажите

        куда спасибо положить. Очень мне помогаете. Думаю (с учётом форума) не только мне. С форУмным приветом - Влад Рус.
         

        Комментарий

        • #5 Свернуть

          Сообщение от Влад Рус Посмотреть сообщение
          у Вас этого - i=11
          Чтобы закрыть первый цикл (с счетчиком i). Можно, конечно добавить для наглядности переменную типа bool - для проверки того, что оба индекса найдены. но проще присвоить i=11 , тогда при следующем проверки значения переменной-счетчика верхний цикл прекратит работу.
             

          Комментарий

          • #6 Свернуть

            Сообщение от Влад Рус Посмотреть сообщение
            найти ордер с наименьшим OrderProfit() среди всех ордеров в массиве. И найти именно тикер,

            а не индекс.
            Сообщение от MIXAN Посмотреть сообщение
            int index1=0;
            double min= 10000000;
            for (int i=0;i<10;i++)
            {
            if (arr_Orders[i][8]< min)
            { index1=i; min=arr_Orders[i][8]}
            }
            Соответственно arr_Orders[index1][4] - будет тикет сделки с минимальным прифитом. Где index1- индекс элемента массива с минимальным профитом. А 4 - индекс элемента второго измерения массива, в котором записан (arr_Orders[Qnt][4]=OrderTicket() тикет ордера.
               

            Комментарий

            • #7 Свернуть

              Добрый день форУмным людям!

              MIXAN, здравствуйте! По второй задаче кажется я догнал. Я то думал что надо сначала сравнивать первую строку массива с остальными, потом вторую с остальными и т.д. и с помощью какой-либо ф-ции сравнивать их и выделять меньшую. Тут я, как чайник может и прав был. Но когда разглядел Ваш вариант - офонарел - как всё оригинально, экономично и просто. Выходит double min= 10000000; эта несуществующая в общем-то величина является как бы вспомогательной, с помощью которой в цикле for оператор if и находит то, что нам нужно. Я правилно рассудил? Гениально.
              Можно я ещё спрошу? Насчёт тикера. Допустим нужно закрыть найденный тикер. Теперь в вызове ф-ции закрытия в качестве передаваемого параметра (тикера ) так и указывать arr_Orders[i][8]? А сам тикер, как таковой уже не виден? Правильно ли будет так: OrderClose(arr_Orders[i][8]) ? Заранее спасибо!
                 

              Комментарий

              • #8 Свернуть

                Сообщение от Влад Рус Посмотреть сообщение
                Можно я ещё спрошу? Насчёт тикера. Допустим нужно закрыть найденный тикер. Теперь в вызове ф-ции закрытия в качестве передаваемого параметра (тикера ) так и указывать arr_Orders[i][8]? А сам тикер, как таковой уже не виден? Правильно ли будет так: OrderClose(arr_Orders[i][8]) ?
                да, только не i a index1 . Если i использовать( а оно равно 10 после предыдущего цикла - так как прошло все 9 индексов для определения минимальной прибыли) Правильно ли будет так: OrderClose(arr_Orders[index1][8])
                   

                Комментарий

                • #9 Свернуть

                  Добрый день форУмным людям!

                  MIXAN, приветствую! Я потихоньку достаю Вас своими распросами. Вы уж извините за достачу - пока учишься всегда много вопросов. Из последней Вашей строчки я понял что Правильно будет так: OrderClose(arr_Orders[index1][8]). Небольшое сомнение, просто вопрос: я вроде нигде раньше не встречал чтобы в квадратных скобках массивов стояли ещё и слова: [index1][8]. Это если следовать букве тех учебников (тоже из сети), которые я прочитывал. Может быть правильно будет не OrderClose(arr_Orders[index1][8], а OrderClose(arr_Orders[index1][4] ? Нам ведь с Вами нужен тикер ( [4] ), а не профит ( [8] ) ?
                  И ещё: если OrderProfit() указывать в пунктах, как я почему-то хочу, то double min= 10000000,0; может быть можно сделать поменьше, как Вы посоветуете?
                  И хотелось бы последнее: В первой задаче, где Вы помогли мне найти ордера с одинаковым OrderOpenTime(), там получились тоже индексы index1=i и index2=j. Там в квадратных скобках тоже вставить слова "index" ? Как-то непривычно... Поскольку наименьший из них нужно закрыть, правильно ли будет так:
                  if (arr_Orders[index1][8]>arr_Orders[index2][8])
                  OrderClose(arr_Orders[index2][8]);
                  else
                  OrderClose(arr_Orders[index1][8];
                  Ещё раз извините за достачу. Спасибо.
                     

                  Комментарий

                  • #10 Свернуть

                    Сообщение от Влад Рус Посмотреть сообщение
                    Я потихоньку достаю Вас своими распросами. Вы уж извините за достачу - пока учишься всегда много вопросов.
                    Нет. Вы не достаете. Я когда начинал -мне не у кого было спросить, поэтому я вас очень хорошо понимаю.

                    Сообщение от Влад Рус Посмотреть сообщение
                    Вашей строчки я понял что Правильно будет так: OrderClose(arr_Orders[index1][8]). Небольшое сомнение, просто вопрос: я вроде нигде раньше не встречал чтобы в квадратных скобках массивов стояли ещё и слова: [index1][8]. Это если следовать букве тех учебников (тоже из сети), которые я прочитывал. Может быть правильно будет не OrderClose(arr_Orders[index1][8], а OrderClose(arr_Orders[index1][4] ? Нам ведь с Вами нужен тикер ( [4] ), а не профит ( [8] ) ?
                    в квадратных скобках можно что угодно поставить - даже разные математические вычисления, главное чтобы их результат был целочисленным и не выходил за рамки размеров массива. Т.о. index1 - переменная в которой хранится нужный нам индекс: индекс элемента массива с минимальным 8 элементом(профитом) второго измерения.

                    Это опечатка. Вы правы - правильно OrderClose(arr_Orders[index1][4])
                    Сообщение от Влад Рус Посмотреть сообщение
                    double min= 10000000
                    это не имеет значения. просто если инициализировать с 0(double min= 0) - то цикл найдет наименьший профит если только он отрицательный. а так - все обыщет.
                    Можно еще привязать инициализацию к самому массиву (double min= arr_Orders[0][8]) тогда изначально минимальным значением будет профит первого элемента массива. Тоже вариант.

                    Сообщение от Влад Рус Посмотреть сообщение
                    правильно ли будет так:
                    if (arr_Orders[index1][8]>arr_Orders[index2][8])
                    OrderClose(arr_Orders[index2][8]);
                    else
                    OrderClose(arr_Orders[index1][8];
                    Да. Так правильно.
                       

                    Комментарий

                    • #11 Свернуть

                      Добрый день форУмным людям!
                      Уважаемый MIXAN, здравствуйте! Продолжаем набивать шишки. Дело в том, что на разных форумах форумчане говорят о том, что OrderOpenTime() двух соседних ордеров, хоть и открытых в одно время, на сервере отличается. Я проверил. При одновременном открытии двух сделок в разные стороны сервер показал OrderOpenTime() 1323064782 и 1323064785. Выходит, зря стараемся? А может можно как-нибудь округлить время открытия ордеров до минут, так как МТ4 показывает это время в окне "Терминал" ? А там показано одинаковое время в минутах. Вот роюсь, примеров таких чегой-то не нахожу. Нестандартный, видимо, приём. До связи.
                         

                      Комментарий

                      • #12 Свернуть

                        Доброй ночи, Влад Рус.
                        Округлить конечно можно, только встает вопрос до какого периода?
                        А сделать это легко. - if (OrderOpenTime() - OrderOpenTime < x) {операторы;}
                        То есть так:

                        int x = PeriodSeconds(PERIOD_M1 ); //Максимальное время в секундах, на которое могут различаться время открытия ордеров (зависит от вашей ТС)

                        if (arr_Orders[index1][9]- arr_Orders[index2][9] < x )
                        if (arr_Orders[index1][8]> arr_Orders[index2][8] )
                        {
                        OrderClose(arr_Orders[index2][8]);
                        else
                        OrderClose(arr_Orders[index1][8];
                        }
                           
                        Последний раз редактировалось MIXAN; 06.12.2011, 01:17.

                        Комментарий

                        • #13 Свернуть

                          Переменная типа datetime не что иное как числовая переменная, где каждым ее значением закодировано текущее время в секундах начиная с 1 января 1970 года до 31 декабря 3000 года.
                          Поэтому код

                          datatime x=1;
                          Print (TimeToString(x));


                          выведет (1970.01.01 00:00:01) или около того. Поэтому с этой переменной можно оперировать как с числами - проверять сколько прошло времени с какого-то события к примеру.
                             

                          Комментарий

                          • #14 Свернуть

                            Добрый день форУмным людям!
                            MIXAN, а Вам доброй ночи. Пример из поста #12, как мне кажется, больше всего подойдёт для моих целей. Если взять " X " равным, с запасом, эдак 30, то можно готовый модуль вставлять и работать, имхо.
                            Переменная типа datetime вещь, конечно, хорошая, но дату выдаст опять же с секундами, с разными. Вот я и думаю как бы их отсечь? Опять же String-овый тип данных, а хотелось бы поменьше преобразований, а то мужики говорят что они (преобразования) сильно тормозят работу. В любом случае за #12 большое спасибо.
                            Всё время подмывает спросить по уже пройденому: там в #5 Вы говорили "... добавить для наглядности переменную типа bool - для проверки того, что оба индекса найдены." Неплохо было бы посмотреть, что Вы имели в виду, куда её добавить? Ещё раз Спасибо.
                               

                            Комментарий

                            • <a href="https://www.instaforex.org/ru/?x=ruforum">InstaForex</a>
                            • #15 Свернуть

                              Сообщение от Влад Рус Посмотреть сообщение
                              Всё время подмывает спросить по уже пройденому: там в #5 Вы говорили "... добавить для наглядности переменную типа bool - для проверки того, что оба индекса найдены." Неплохо было бы посмотреть, что Вы имели в виду, куда её добавить? Ещё раз Спасибо.
                              PHP код:
                              int index1=0;
                              int index2=0;
                              bool VseNashli=false;
                              for (
                              int i=0;i<10;i++)
                               {
                                for (
                              int j=i+1;j<10;j++)
                                 { 
                                  if (
                              arr_Orders[i][9]= arr_Orders[j][9])
                                  {
                                   
                              index1=i;
                                   
                              index2=j;
                                   
                              VseNashli=true;
                                  } 
                                }
                                 if (
                              VseNashli) break;

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



                              PHP код:
                              int i,j;
                              bool VseNashli=false;
                              for ( 
                              i=0;i<10;i++)
                               {
                                for (
                              j=i+1;j<10;j++)
                                 { 
                                   if (
                              arr_Orders[i][9]= arr_Orders[j][9])
                                    
                              VseNashli=true;
                                }
                                 if (
                              VseNashli) break;

                              и дальше вместо index1 и index2 использовать i и j - они будут иметь те же значения как и в предыдущем случае, но быстродействие увеличится за счет отсутствия переменной для цикла1 и 2.
                                 

                              Комментарий

                              Сейчас онлайн

                              working...
                              X