М
Миша16 листопада 2017 р. 02:42

Падает скорость вычисления массивов

Qt, QVector

Здравствуйте. Произвожу вычисления с участием массивов. Первые вычисления производит быстро. Далее скорость падает в геометрической прогрессии. Ниже код. Скажите пожалуйста, в чем причина и как ее исправить?
#include "mainwindow.h"
#include "ui_mainwindow.h"

void MainWindow::StrategyCod() //код стратегии
{
  for (int NMA=5;NMA<1000;NMA=NMA+50)//3-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  {
      //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      int NOpenPosition=0; //число открытых позиций
      double Profit=0;
      double PriceEnter,PriceExit; //цена входа и выхода
      QDate DateOpenPosition; //Дата открытия позиции
      //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //int NMA=20;//период ma
    QVector<double> SMA(NBar); //ma
    for(long long bar = NMA; bar <NBar; bar++) //ma
    {
        double Summa=0;//summa
        for(long long i=bar-NMA;i<bar;i++)//summa
        {
            Summa=Summa+Close[i];
        }
        SMA[bar]=Summa/NMA;
    }


    for(long long bar = NMA; bar <NBar; bar++)//основной цикл
    {
     if (NOpenPosition!=0)//2-------------------------------------------------------------------------------------------------------------------------------------------------------
         {
             if ((Close[bar-1]<SMA[bar-1])&&(Close[bar]>SMA[bar]))
             {
                 PriceExit=Close[bar]-qrand()%MaxSlippage; //цена закрытия позиции
                 if (PriceEnter>High[bar]){PriceEnter=High[bar];}
                 if (PriceEnter<Low[bar]){PriceEnter=Low[bar];}
                 NOpenPosition=NOpenPosition-1;
                 Profit=PriceEnter-PriceExit-Commission;
             }
         }
     else//1--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
         {
             if ((Close[bar-1]>SMA[bar-1])&&(Close[bar]<SMA[bar]))
             {
                 PriceEnter=Close[bar]+qrand()%MaxSlippage; //цена открытия позиции  //покупка
                 if (PriceEnter>High[bar]){PriceEnter=High[bar];}
                 if (PriceEnter<Low[bar]){PriceEnter=Low[bar];}
                 NOpenPosition=NOpenPosition+1;
                 DateOpenPosition=Date[bar];
             }
         }
     //1---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    }//2------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
qDebug()<<NMA;
qDebug()<<Profit;
qDebug()<<QDateTime::currentDateTime();
  }//3------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
}

 

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

12
BlinCT
  • 16 листопада 2017 р. 03:27

У вас очень большие проблемы с синтаксисом.
1. Между знаками < > = - и так далее должны быть пробелы. Не склеивайте все в одно, читать очень-очень тяжело.
2. Во вторых в цикле for используйте всегда префикс ++i вместо постфикса i++ если только вы точно не знаете что вам нужен постфикс.
3. Если у вас не очень сложный и большой цикл for то никогда для индекса не используйте ничего кроме одной буквы.
Неправильно:

for(int NMA=5;NMA<1000;NMA=NMA+50)
Правильно:
for (int i = 5; i < 1000; i = i + 50)
4. нету смысла в цикле обьявлять переменные. В первом цикле у вас

int NOpenPosition=0; //число открытых позиций
double Profit=0;
double PriceEnter,PriceExit; //цена входа и выхода
QDate DateOpenPosition; //Дата открытия позиции

Вынесите все это перед внешним циклом.

5. Во втором цикле нету смысла использовать long long так как исходя из первого цикла у вас од 0 до 1000. А это значит там или обычный int или без знаковый quint32.

Исправте это все и проверте.
И еще, отступы для новой строки должны быть 1 таб это 3 пробела. У вас там походу 2 пробела. Смотрится ужасно.

    Evgenii Legotckoi
    • 16 листопада 2017 р. 03:34
    • (відредаговано)

    День добрый!

    SMA - Средняя скользящая за период значит...
    Причина падения скорости очевидно в том, что циклы внутри циклов напиханы с возрастающим размером QVector. Это всегда ведёт к квадратичной зависимости сложности алгоритма и времени вычисления.
    Вообще, средняя скользящая не должна вычисляться слишком долго. Линейная зависимость от количества элементов в массиве, поскольку её обычно вычисляют всегда за период.
    Скорее всего ваш основной цикл лишний. Вычисления SMA у вас в первом цикле, что происходит в основном мне не ясно.
    Зачем вы поместили сюда открытые позиции? Средняя скользящая это индикатор. А позиции в моём понимании - это сделки, они здесь не нужны при вычислении средней скользящей.
      М
      • 16 листопада 2017 р. 03:44

      long long нужен, т.к. NBar может быть больше int.

      Использовал for(int NMA=5;NMA<1000;NMA=NMA+50), т.к. предусматривается несколько циклов. И название переменной подразумевает под собой некий смысл.
      Средняя скользящая - необходимый элемент расчета.
      После расчета скользящей прогоняется расчет по открытию и закрытию позиций. Затем пересчитвается скользящая и идет новый расчет.
      Вынес за пределы цикла:
      int NOpenPosition=0; //число открытых позиций
      double Profit=0;
      double PriceEnter,PriceExit; //цена входа и выхода
      QDate DateOpenPosition; //Дата открытия позиции
      
      Трудность осталась.
      QVector с каждым циклом переопределяется. Разве он от этого увеличиться?
        Evgenii Legotckoi
        • 16 листопада 2017 р. 03:49
        • (відредаговано)

        Напомните смысл SMA и NMA. Насколько помню - это два различных индикатора средней скользящей?
        Не вижу смысла делать расчёт для SMA при каждом расчёте одной позиции NMA. Почему бы не рассчитать отдельно SMA и NMA, а потом уже в цикле сравнить их?

          М
          • 16 листопада 2017 р. 03:54

          в моем случае, NMA - размер цикла SMA. Размер цикла меняется->нужно менять среднюю.

            Evgenii Legotckoi
            • 16 листопада 2017 р. 04:09

            Хорошо. Тогда здесь нет ничего удивительного, что увеличивается время подсчёта. Вы увеличиваете NMA, что означает, что для SMA нужно подсчитать больше элементов для расчёта одной точки на графике. Чем больше NMA, тем длительнее расчёт.

            Не думаю, что вы здесь сможете что-то оптимизировать. Можете лишь распараллелить расчёт SMA для различных значений NMA.
              М
              • 16 листопада 2017 р. 04:12

              Спасибо.

                Evgenii Legotckoi
                • 16 листопада 2017 р. 04:16

                По поводу распараллеливания. Думаю, что это можно сделать следующим способом.

                Делаете класс, отвечающий за расчёт. Создаёте объект для рассчета этого класса, копируете в него массив для рассчёта вместе со значением NMA, кидаете объект через moveToThread . Он там считает, как посчитал, выдёргиваете из него результат. Таким образом можно будет распараллелить вычисления. Это несколько ускорит подсчёт данных.
                  М
                  • 16 листопада 2017 р. 04:53

                  Изменил логику расчета, теперь считает все в 1000 раз быстрее.

                    Evgenii Legotckoi
                    • 16 листопада 2017 р. 05:13

                    Молодцом. В чём заключалось изменение?

                      М
                      • 16 листопада 2017 р. 05:46

                      Пересчет суммы. Я от предыдущей отнимаю одно и добавляю одно значение, а не пересчитываю все заново.

                        Evgenii Legotckoi
                        • 16 листопада 2017 р. 06:24
                        • (відредаговано)

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

                          Коментарі

                          Only authorized users can post comments.
                          Please, Log in or Sign up
                          AD

                          C++ - Тест 004. Указатели, Массивы и Циклы

                          • Результат:50бали,
                          • Рейтинг балів-4
                          m
                          • molni99
                          • 26 жовтня 2024 р. 08:37

                          C++ - Тест 004. Указатели, Массивы и Циклы

                          • Результат:80бали,
                          • Рейтинг балів4
                          m
                          • molni99
                          • 26 жовтня 2024 р. 08:29

                          C++ - Тест 004. Указатели, Массивы и Циклы

                          • Результат:20бали,
                          • Рейтинг балів-10
                          Останні коментарі
                          ИМ
                          Игорь Максимов22 листопада 2024 р. 19:51
                          Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                          Evgenii Legotckoi
                          Evgenii Legotckoi31 жовтня 2024 р. 21:37
                          Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                          A
                          ALO1ZE19 жовтня 2024 р. 15:19
                          Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                          ИМ
                          Игорь Максимов05 жовтня 2024 р. 14:51
                          Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                          d
                          dblas505 липня 2024 р. 18:02
                          QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                          Тепер обговоріть на форумі
                          Evgenii Legotckoi
                          Evgenii Legotckoi24 червня 2024 р. 22:11
                          добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                          t
                          tonypeachey115 листопада 2024 р. 14:04
                          google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                          NSProject
                          NSProject04 червня 2022 р. 10:49
                          Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                          9
                          9Anonim25 жовтня 2024 р. 16:10
                          Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                          Слідкуйте за нами в соціальних мережах