Тут есть варианты - сохранять промежуточные расчеты в базу. Паралелить вычисления, которые идут в день (считаем 4 день в несколько потоков - примеирно как майнинг, где можно было задать сколько ядер проца задействовать) - кстати на это намекает то, что 12 ядерный комп не загружен. Если расчеты единоразовы - то проще базу (это просто и дешево), если что то меняется в параметрах - тюнить алгоритм (дольше и дороже).
Mercator @ 21.12.21То, как устроен Бифф, не предполагает увеличения скорости от сторонних вычислений, т.к. он идет последовательно, а не параллельно. С этим ничего поделать нельзя, т.к. суть там в следующем (упрощенно):
Мы посчитали все возможные варианты на день 1, дальше, зная что получилось, можем посчитать все варианты на день 2, дальше на день 3 и т.д. Никак не начать считать день 4 без знаний, с какими результатами мы к нему подошли.
sanitar @ 20.12.21Все зависит от рынка и непредсказуемо, может раз в год возьмут в шорт твои бумаги, может несколько раз, а может вообще ни разу.
Sanitar, любопытства ради посмотрел, сколько раз мои ETF были взяты под шорт за 2021.
280 раз :) Месяц к месяцу вариативность, конечно, есть, но в моем конкретном случае за последние 8 месяцев она между $x и $2x, то есть всего +/- 30%.
Mercator, Я не вцепился во фразу. Просто не понимаю, почему нельзя параллелить и хотел разобраться.
Mercator @ 21.12.21Мы посчитали все возможные варианты на день 1, дальше, зная что получилось, можем посчитать все варианты на день 2, дальше на день 3 и т.д. Никак не начать считать день 4 без знаний, с какими результатами мы к нему подошли.
у тебя в п1 уже можно считать в несколько потоков: стартовая цифра одна, а к ней применяются разные сценарии.
Mercator @ 21.12.21Я более-менее разобрался в ситуации. Оказалось, что на данный момент подключать внешние вычислительные мощности рано. Я не знал, что скорость можно увеличивать только за счет параллельных вычислений, но не за счет более мощного оборудования.
То, как устроен Бифф, не предполагает увеличения скорости от сторонних вычислений, т.к. он идет последовательно, а не параллельно. С этим ничего поделать нельзя, т.к. суть там в следующем (упрощенно):
Мы посчитали все возможные варианты на день 1, дальше, зная что получилось, можем посчитать все варианты на день 2, дальше на день 3 и т.д. Никак не начать считать день 4 без знаний, с какими результатами мы к нему подошли.
Еще раз, это очень упрощенно, лишь показываю суть.
Может быть, что-то еще возможно распараллелить внутри "дня", в эту сторону будем копать.
Спасибо всем за инфу. Еще и лично нападало ответов, тоже спасибо.
Я не уверен, что даже в такой конфигурации ты не можешь реализовать распараллеливание
Ты можешь попробовать разбить скажем все периоды по 5 лет, считать старо каждого периода с единицы.
А потом финальным скриптом последовательно все умножаешь на результат предыдущего периода
Не знаю насколько пригодится (возможно вы это и так применяете)
В теории игр - если у меня есть какой-то гарантированный исход, который при лучшей игре меня и соперника приведет к результату, например + 90, и если я , просчитывая какую-то следующую ветвь наткнулся на результат + 50 = опять же при наилучшей игре меня и соперника, то дальше эту ветку можно не считать, а просто выбраковывать всю.
Это немного противоречит тому, что ты написал = сначала считаешь день 1, потом исходя из него день 2. Но возможно, сумеешь прикрутить. Такая выбраковка ветвей в программировании логических игр позволяет уменьшать время отсчета в 10+ раз (в зависимости от игры)
Вот репозиторий Биффа.
Лицензия GNU General Public License 3.0. Это означает, что любой может делать с кодом что угодно, но продавать его или регистрировать на себя нельзя.
https://github.com/Mercator2111/Biff
Самое главное. Бифф в работе, это не просто не окончательная версия, это вообще не версия. Она что-то делает, но там даже функционал еще не весь привинчен. Например, нет плавающей даты финала, нет третьего актива (золота), а есть только упро и воо, нет корреляции волатильности.
По интерфейсу тоже еще не приступали даже. Стоят всякие фразы-заглушки на полурусском-полуанглийском. Чисто, чтобы было понятно.
Зато есть ошибки, это мы точно знаем, работа по ним ведется.
В двух словах о том, что на данный момент представляет из себя Бифф.
Есть 4 алгоритма.
Бифф 1 считает БестРатио, и раз и навсегда его придерживается. Понятно, что это только вспомогательный алгоритм.
Бифф 1,5 - промежуточный алгоритм, его можете даже не смотреть.
Бифф 2 уже считает (будет считать) всё как надо, скорость будет наилучшей из возможных (но всё равно расчет будет идти оч долго). Он работает на основе формулы. Сама формула в процессе поиска, пока что она неточна. Работает неплохо на одних параметрах и плохо на других.
Бифф 3 тоже считает как надо. На данный момент он может показать результат на любых параметрах, но точность хромает. Плюс он очень долгий.
К написанию инструкции еще не приступали, поэтому только общие вводные дам, а разбираться уже вам самим предстоит.
Для начала выберите нужный Бифф. Для Бифф2 и 3 надо построить таблицу (Fill Table). Когда таблица будет готова, жмите Find Best Ratio. Потом под бест ратио можете посмотреть ЕВ через Calculate EV.
Постановка задачи есть (словесное описание или блок схема)?
Как я понял, используется модель монте-карло: есть массив данных, выбирается N значений и как-то обсчитывается.
Marauder62 @ 22.12.21Постановка задачи есть (словесное описание или блок схема)?
В том виде, как реализовано на данный момент:
Дано
- Есть инвестор, который уже имеет капитал и не имеет внешних источников дохода. (От прикручивания зарплаты отказались. Кому не лень прикрутить - велкам.)
- У него есть фиксированный расход (в долларах в день), который растет параллельно инфляции. Под днем подразумевается 1/251,2 года (именно столько рабочих дней в году). Для корректных расчетов инфляцию надо учесть, для этого специальная галка внизу.
- Есть срок инвестиций в днях. (На данный момент можно задать только фиксированный срок, потом будет плавающая дата)
- Есть риск разорения, который устраивает инвестора. Под риском понимается вероятность того, что капитал будет потрачен раньше, чем закончится срок инвестиций.
- Есть вероятность, что Упро в любой момент растворится с деньгами. По умолчанию такая вероятность 1/50000 в день. Рекомендуется ее не трогать. (Вероятность того, что Воо растворится в закате, принята за 0).
- Принято за аксиому, что в будущем все возможные суточные колебания упро и воо равновероятны каждому из 24550 суточных колебаний, которые мы наблюдали за последние 94 года. Если вы с этим не согласны, Бифф не для вас. Дивиденды реинвестированы. Данные по колебаниям 1927-2009 расчетные, но очень похоже, что там ошибок нет. (Потом еще добавим корреляцию волатильности).
-------------
Найти
соотношение упро/воо при котором ожидаемый рост капитала будет максимальным при условии, что риск не будет превышать заданный. (Потом будет добавлен дей-бай-дей чарт, какое ратио нужно для каждого размера капитала для поддержания общего риска за весь период на заданном уровне, это уже считается, просто не выводится).
Marauder62 @ 22.12.21Как я понял, используется модель монте-карло: есть массив данных, выбирается N значений и как-то обсчитывается.
Да. Обсчет идет по монте-карло. А что можно формализовать, то формулами прописано.
-----------------
Для того, чтобы каждый подсчет не занимал часы/дни/недели, в Биффе реализованы таблицы. Юзер при первом вводе параметров включает расчет таблиц, а потом, уже на основании этих таблиц, каждый день за несколько секунд может получить Бестратио.
И вот этот расчет таблиц и занимет туеву прорву времени. И, как мы сейчас полагаем, его не оптимизировать никак. Если кто-то придумает способ (не теоретический, а прямо в коде), тот большой молодец. Все предложенные выше способы изучены. К сожалению, они не принесли добавки в скорости ввиду специфики программы.
Инфляцию тоже через Монте-Карло симулируете?
БоевойСлон @ 22.12.21Инфляцию тоже через Монте-Карло симулируете?
Под учетом инфляции подразумевается работа с данными, где был произведен ежедневный дисконт изменений цен на фактическую инфляцию за данную дату.
То есть есть два ВИЦ: в абсолютных долларах и в долларах, очищенных от инфляции (реальных).
Если выбрать реальные доллары, то просто симуляции по монте-карло будут строиться на этих ВИЦ.
Вот сами данные для понимания.
Колонки: Дата - изменение VOO - изменение UPRO
price_new.txt (959 килобайт)
Это фактические данные
price_i.txt (815.1 килобайт)
Это данные, очищенные от инфляции
P.S. Забавная дата 19.10.1987
Mercator, Я в коде мало понимаю, но то, как алгоритм описан, он должен легко оптимизироваться и параллелиться. Ибо все ветки в дереве независимы друг от друга.
Soul @ 23.12.21Ибо все ветки в дереве независимы друг от друга.
Ты всерьез думаешь, что для 10к дней мы делаем 24550^10000 веток и проблема именно в этом? Для справки, подсчет такого количества веток в лоб занял бы миллион лет навскидку. А у нас считается десятки часов.
Так что тот уровень оптимизации, который тебе пришел в голову, был реализован еще на стадии разработки идеи. Были отсечены лишние ветки и сгруппированы ветки с идентичными промежуточными результатами.
Да и вообще метод монтекарло не предполагает полного перебора. Там достаточно сделать нужное число симуляций для получения более-менее точного результата.
Желательно, чтобы советы шли от тех, кто понял принципы работы Бифф2 и Бифф3, для этого есть код.
Основная идея в том, что для того, чтобы понять, какое бестратио нужно в день n, надо УЖЕ знать все расклады на дни начиная с n+1 и до конца. Таким образом, просчет можно строить от конца к началу и каждый день возвращает дерево к исходному состоянию, в результате чего необходимое количество действий растет экспоненциально.
В общем, хотелось бы советов не в стиле "чтобы ехать побыстрее, просто нажмите на газ посильнее, я так всегда делал, мне помогало".
Желательно, чтобы советующий понимал, как устроены Биффы и где в коде осталось место для ускорения.
Я, как программист проекта Бифф, могу более подробно описать алгоритм работы программы. Тема довольно специфичная и возможно интересна только узкому кругу математиков и программистов. Но если есть желание начать дискуссию ставьте плюсик.
(Вкратце я уже писал это в личку Меркатору, но с тех появилась новая инфа, поэтому повторю здесь).
Выделите код, выполняющий расчёт таблиц, в отдельный исполняемый файл. Опубликуйте примеры входных и правильных выходных данных, желательно разного объёма. И дальше можно хоть награду за ускорение объявлять :) С приватными тестами, конечно.
В этом файле и кода будет гораздо меньше, без реализации GUI, и самое главное, писать его можно будет на любом языке, не только на Паскале.
Galax @ 23.12.21Я, как программист проекта Бифф, могу более подробно описать алгоритм работы программы. Тема довольно специфичная и возможно интересна только узкому кругу математиков и программистов. Но если есть желание начать дискуссию ставьте плюсик.
Скачал код, посмотрел. Я лет 20 не писал на Delphi, но, кажется, использование типа real для хранения вещественных чисел никогда не было хорошей идеей. Это же какой-то специфичный для Паскаля 6-байтный тип данных, и все вычисления в нём делаются программно. Желательно всё переделать под double (он 8-байтный) или single (аналог 4-байтного float для Паскаля, если такой точности будет достаточно).
Это нативные типы данных для сопроцессора и вычисления в них выполняются существенно быстрее.
Хотя может быть они real в какой-то версии Delphi уже переделали под double и я просто не в курсе.
Также можно подумать над тем, чтобы все вычисления сделать целочисленными, если это возможно, это будет ещё быстрее.
Итак, алгоритм Биффа.
Постановку задачи сформуллировал Игорь выше.
Мы будем использовать Монте-Карло для симуляции нашего банкрола после N к-ва дней.
Для этого опишем один торговый день.
Вначале у нас есть какой-то капитал - StartCapital и он распределен между V00 UPRO в каком-то соотношении (весь капитал в этих двух активах).
Далее мы берем случайное число из 24550 (длина нашего массива данных) и выбираем по этому индексу исторические данные. Это будет изменение в процентах VOO и соответствующее этому изменение UPRO. Тут мы применяем принятую нами аксиому, что завтра индексы изменятся равновероятно на одну из 24550 величин, которые были до этого за последние 94 года.
Умножаем часть капитала в VOO на процент изменения VOO и соответственно для UPRO мы получаем наш новый капитал.
Но предварительно мы проверяем не произошло ли банкротство UPRO. Если выпадает шанс один из 50000, то часть капитала, которая была в UPRO обнуляется. Важный нюанс - при банкротстве UPRO мы еще не банкроты - у нас остается часть в VOO и мы можем дальше перераспределять наши активы по аналогам UPRO (на рынке найдется похожий инструмент UPRO 2).
В конце дня мы отнимаем от капитала величину прописаную в расходах (Rasxod) и если наш капитал стал меньше или равен нулю - то мы банкроты.
Это схема, что мы делаем за один торговый день - назовем это элементарный день.
Чтобы расчитать, что будет через N дней, нам нужно принять какое-то правило, как мы будем перераспределять отношение VOO/UPRO (оно может менятся со временем и может менятся от текущего капитала).
Итак берем первое упрощение - считаем, что со временем мы это соотношение менять не будем и выбрав какое-то соотношение в первый день, мы его придерживаемся до конца, до дня N. Эту модель мы для удобства назовем Бифф 1.
Теперь мы в цикле от 1 до N повторяем N раз элементарный день и если по дороге мы банкрот, то увеличиваем счетчик банкротств, если нет, то в конце прибавляем конечный капитал к Total_EV. И вот этот цикл - это одна симуляция. Таких симуляций мы производим много раз (100 000 необходимый минимум, 1000 000 - довольно точный результат). В результате для заданного отношения VOO/UPRO (мы его сами задаем заранее) мы вычисляем процент банкротств и ожидаемое ЕВ в конце и также можем посчитать EV одного дня. При увеличении к-ва симуляций полученные результаты довольно надежно стремятся к определенным цифрам и мы легко можем оценить погрешность и точность вычислений. Скорость этих вычислений довольно высокая - для 1000 дней и 100 000 симуляций уйдет пару сек.
Следующий этап - это используя эту процедуру нужно найти оптимальное соотношение для VOO / UPRO, чтобы процент банкротств не превысил наш заданный порог, но максимально близко к нему приблизился. Для этого я использую несколько усовершенствованный алгоритм двоичного поиска и получаю искомый результат. Это и есть ответ, который дает Бифф 1. Он тоже очень быстрый (пару сек) и дает нам первое приближение в наших следующих расчетах.
Но, напомню, что мы получаем оптимальное соотношение, при котором мы не превысим заданный порог риска, но при этом мы это соотношение не будем менять до конца нашего периода.
Теперь можно обсудить - принимаем ли мы эту модель, так как все следующие обсуждения от этого зависят. Это первый элементарный кирпичик в нашей программе.
Galax, сделал примерно как у тебя описано.
Единственное, я решил что нет смысла в каждой итерации проверять банкротство. Если мы ушли в минус - то в плюс уже никогда не вылезем, а сама проверка срабатывает очень редко, но кушает ресурсы в каждой итерации.
На моём "супер" железе (i5 2400s, 6gb оперативки) в 4 потока 100к итераций заняли всего 221.2s.
Кстати результаты весьма интересные.
Насиловать миллионами я не стал, сделал по 50к итераций с разными весами индексов в портфеле.
Стартовые условия такие: депозит 5к, кушаем в день на 1 доллар, 2000 рабочих дней.
Короче вывод конечно же простой, если у тебя всего 5к, то надо не кушать с депозита, а докидывать.
Надо будет проверить алгоритм, если оставить колебания индекса +1% и -1%, ничего не есть и вложить только в VOO, то мат.ожидание этого мероприятия должно быть около стартового депозита.
Если распараллелить нельзя - то с 10 часов до 10 минут ускориться никак не получится. Так что да, только железо помощнее. 12 ядер соответственно тоже не помогут, поможет только более новое "ядро", разогнать еще можно. И облака не помогут.
Вот что может помочь - так это специализированный чип (наверно искать спеца по аббревиатуре ПЛИС, или FPGA). То есть сделать отдельную USB железяку которая будет делать именно твои расчеты. Это единственное что приходит мне в голову, если надо ускорится на порядок (порядки), но я не спец, я не уверен в успехе.