М
МишаNov. 16, 2017, 2:42 a.m.

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

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------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
}

 

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

12
BlinCT
  • Nov. 16, 2017, 3:27 a.m.

У вас очень большие проблемы с синтаксисом.
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
    • Nov. 16, 2017, 3:34 a.m.
    • (edited)

    День добрый!

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

      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
        • Nov. 16, 2017, 3:49 a.m.
        • (edited)

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

          М
          • Nov. 16, 2017, 3:54 a.m.

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

            Evgenii Legotckoi
            • Nov. 16, 2017, 4:09 a.m.

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

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

              Спасибо.

                Evgenii Legotckoi
                • Nov. 16, 2017, 4:16 a.m.

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

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

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

                    Evgenii Legotckoi
                    • Nov. 16, 2017, 5:13 a.m.

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

                      М
                      • Nov. 16, 2017, 5:46 a.m.

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

                        Evgenii Legotckoi
                        • Nov. 16, 2017, 6:24 a.m.
                        • (edited)

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

                          Comments

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

                          C ++ - Test 004. Pointers, Arrays and Loops

                          • Result:50points,
                          • Rating points-4
                          m

                          C ++ - Test 004. Pointers, Arrays and Loops

                          • Result:80points,
                          • Rating points4
                          m

                          C ++ - Test 004. Pointers, Arrays and Loops

                          • Result:20points,
                          • Rating points-10
                          Last comments
                          ИМ
                          Игорь МаксимовNov. 22, 2024, 11:51 a.m.
                          Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                          Evgenii Legotckoi
                          Evgenii LegotckoiOct. 31, 2024, 2:37 p.m.
                          Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                          A
                          ALO1ZEOct. 19, 2024, 8:19 a.m.
                          Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                          ИМ
                          Игорь МаксимовOct. 5, 2024, 7:51 a.m.
                          Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                          d
                          dblas5July 5, 2024, 11:02 a.m.
                          QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                          Now discuss on the forum
                          Evgenii Legotckoi
                          Evgenii LegotckoiJune 24, 2024, 3:11 p.m.
                          добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                          t
                          tonypeachey1Nov. 15, 2024, 6:04 a.m.
                          google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                          NSProject
                          NSProjectJune 4, 2022, 3:49 a.m.
                          Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                          9
                          9AnonimOct. 25, 2024, 9:10 a.m.
                          Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                          Follow us in social networks