На главную страницу

Форум


Алгоритм оптимального вложения инвестиций

Юрий Решетов

(третья редакция)

1

Прелюдия


2

финансовая математика


3

Условные обозначения


4

Цель задачи оптимизации инвестиций


5

Алгоритм 1


6

Алгоритм 2


7

Проблема лишних денег


8

Доказательство математической  аналогии первого и второго алгоритмов


9

Доказательство того, что алгоритм находит оптимум (экстремум)


10

Сложность алгоритма


11

Виртуальные средства


12 программная реализация Механической торговой системы для биржевого терминала Metatrader4




Прелюдия

Нижеприведенный текст можно не читать, ведь итак все ясно, стоит только глянуть на имя автора. Автор будет утверждать, будто бы им решена задача о оптимальных инвестициях. Не верьте ему ни в коем разе, поскольку знающие люди скажут, что с такой фамилией и местом жительства можно только заблуждаться и ошибаться. 

Ну, кто такой этот самый Решетов из какого-то там Ташкента? Вечно он что либо изобретает. То опровергает теорему Геделя о неполноте формальных арифметик, то утверждает, что будто бы аксиомы математической индукции - полнейший бред, то безбожно ругает все теории относительности без исключения, настаивая на их субъективизме, или придумывает метод проверки чисел Мерсенна на простоту ,то изобретает систему шифрования, которую нагло именует идеальной, то разрешает делить числа на 0.

И наконец выдает на гора решение задачи об оптимальных инвестициях. Человечество столько тысячелетий занимается торговлей и такое количество математиков экономистов и прочих высококвалифицированных, дипломированных и сертифицированных специалистов пыталось решить эту самую задачу и тут на тебе, получи решение и распишись. А главное, от кого получи! Что он себе, этот Решетов возомнил? Какое он имеет право? Совсем обнаглел, не иначе! 

Но, впрочем, кому нужна эта самая оптимизация инвестиций. Ведь любой дурак заявит, что было бы что инвестировать, а куда и без всяких там Решетовых разберемся. Кому они нужны эти формулы, кроме их автора? Может он опять претендует на гениальность. Пусть даже не надеется. Гениальность ему не светит. 

То ли дело Карл Гаусс, прозванный королем математики и величайшим гением. Так тот действительно решал важные проблемы человечества. Например, доказал возможность построения одних многоугольников с помощью циркуля и линейки и невозможность других. Ведь человечество столько тысячелетий мучалось, не спало и не ело, а только ломало головы, циркули и линейки в тщетной попытке начертить какую либо геометрическую хрень. А тут появился Гаусс и все проблемы решил разом. Благодарное человечество вычертило циркулями и линейками правильные 3, 5, 17, 257 и даже 65537-и угольники, включая описания их построений и угомонилось, соорудив памятник гению на правильном 17-и угольном постаменте. Или взять Лобачевского. Тоже гений, поскольку спас человечество от головной боли, доказав с помощью самопальной кривой геометрии, что параллельные прямые обязательно должны где нибудь между собой пересечься и тем самым утер нос Евклиду. Или Уильям Шенкс, который всего за 20 лет вычислил аж 707 знаков после запятой для числа Pi. А ведь сколько до этого самого Шенкса бедные люди мучались неведением, каким будет тот или иной знак после запятой в этом самом числе. Правда, Уильям ошибся начиная с 520 знака. Но это ничего, поскольку ошибку выяснили лишь в 1945 году и морду бить было некому - математик скончался в славе и почете. А благодарное человечество выгравировало на могиле Шенкса число Pi золотыми цифрами. Ошибочные знаки просто не поместились на надгробную плиту. Потом появился Эйнштейн и не без помощи кривой геометрии Лобачевского и физики Пуанкаре (от которой сам Пуанкаре открещивался, после того, как убедился в ошибочности математического аппарата), доказывает, что E = m*c, что в движении, что в покое. Вот где гениальность! Два килограмма дерьма и критическая масса ружейного урана обладают абсолютно одинаковой энергией! Правда, не все были согласны с этим и как всегда нашлись злопыхатели в лице каких-то там Резерфордов, Томпсонов и прочих. Но кто этих самых Резерфордов и Томпсонов слушать будет? Ведь по расчетам получается, что пуд водорода способен дать в термоядерной реакции столько энергии, что Чубайс от зависти сдохнет. Подсчитайте во сколько обойдется выделение этого пуда водорода из воды! Вот и гоняют ученые головы плазму, заворачивая ее в каральки и бублики, пытаясь извлечь расчетное количество энергии. Правда пока не получается. Но зато есть откорячка - плазма, она ведь непослушная, то стенки прожжет, то лезет совсем не туда, куда хочется. Хотя есть и более простое объяснение, которое нашел Гайзенберг в виде принципа неопределенности приращения релятивистского импульса:

 2 * Pi * h / л < dp < oo

где:

2 * Pi * h / л - импульс фотона. Позже Нильс Бор обнаруживает и другие неопределенности для приращения других релятивистских величин, например, таких как энергия. А посему в формулу Е = mc, можно заменить на более уточняющую E < oo. 

Вот это были действительно гении. И Решетов им в подметки не годится.

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

Финансовая математика

 

В электротехнике существует Закон Ома (на самом деле их два: для участка цепи и для всей цепи), относительно которого можно плясать, то бишь делать какие либо расчеты. Существует ли подобный Закон в экономике? Как ни странно существует. Обозначим прежнюю цену товара через p, количество денег через m, количество товара через t. Тогда приращение этих величин будем обозначать через dp, dm и dt.

 В этом случае Закон Экономики можно выразить через формулу новой цены с учетом ценового, денежного и товарного прироста:

p + dp = -dm / dt

(0)

Ведь, когда совершается некая рыночная сделка, то товар t уменьшается или увеличивается на некую величину dt, и деньги m одновременно увеличиваются или уменьшаются на некую величину dm. При этом если товар увеличивается, то деньги умаляются и наоборот, а посему в формуле справа стоит отрицание. Сей Закон справедлив, как для продавца, так и покупателя. Относительно его и будем строить нижеследующую математическую модель.

Оптимум

Что такое классическая задача оптимизации? Она сводится к поиску экстремума (достижения наибольшего или наименьшего значения) функции от многих переменных вида:

s = a[1]*x[1] + a[2]*x[2] + ... a[n]*x[n]

где: 

s - сама функция для которой ищем экстремум.

a[i]- некие константы

x[i] - переменные, для которых заданы дополнительные условия. Необходимо подобрать такие значения этих самых переменных, при которых значение s будет максимальным или минимальным.

Суть решения данной задачи сводится к построению системы дифференциальных уравнений вида:

ds / dx[i] = 0, для всех i от 1 до n

В некоторых случаях, решение невозможно, а в некоторых существует более одного решения (несколько экстремумов отвечающих заданным условиям).

В свою очередь задачи поиска оптимального решения подразделяются на:

  1. Статические - когда константы ai задаются единожды. Например, теория игр для двух лиц с нулевой суммой или линейное программирование

  2. Динамические - когда константы меняются. Например, динамическое программирование, стратегические игры.

Можно точно сказать, что задача поиска решений для оптимального вложения инвестиций является динамической. Что на первый взгляд ее усложняет. Но, на самом деле, как будет выяснено дальше, решение весьма тривиально, после того, как оно было найдено и сводится к одной единственной формуле, которую можно всячески видоизменять, выражая одни неизвестные, через другие.

Условные обозначения

Сразу оговоримся о нижеследующих обозначениях. Нам понадобятся известные:

Их приращения. Символ d или дельта, часто употребляется в дифференциальном исчислении, показывая разницу между двумя значениями одной и той же переменной:

Следует учесть, что p[i] и dp[i] нам известны. Поскольку прежняя цена на товар наименования i, т.е. p[i], а новая цена с учетом роста или падения котировок на величину dp[i] будет обозначаться, через: p[i] + dp[i].

Коли m - известная наличность, а dm - это потенциальный приход или расход денег или объем сделки в денежном исчислении. Значит сумма денег после расчетной сделки должна составить m + dm. t[i] - товар наименования i, dt[i] - объем сделки в товарном исчислении. После сделки у нас в нашем распоряжении останется t[i] + dt[i] товара.

Цель задачи оптимизации инвестиций:

Задача сводится к поиску неизвестных dm и dt[i], когда известны изменившиеся цены p[i] + dp[i] для всех i. Цель задачи - минимизировать расходы, дабы максимизировать доходы от сделок с учетом рыночных цен. Условия задачи состоят в том, что: 

m > 0 

t[i] > 0 

p[i] > 0

p[i] + dp[i] > 0

m + dm > 0

t[i] + dt[i] > 0

То бишь кредиты, долговые обязательства и прочая маржа не используется.

Алгоритм 1

Начнем с простейшего алгоритма, с помощью которого можно найти решение для оптимальных инвестиций.

  1. Возьмем все имеющиеся в нашем распоряжении деньги и товары и вычислим наше  благосостояние по текущим рыночным ценам: s = m + t[1] * (p[1] + dp[1]) + t[2] * (p[2] + dp[2]) + ... + t[n] * (p[n] + dp[n])

  2. Вычислим среднеарифметическое sm = s / (n + 1)

  3. Вычислим dm = sm - m

  4. Цикл для всех i от 1 до n

  5. Вычислим dt[i] = -dm / (p[i] + dp[i])

  6. Если dt[i] < 0, то реализуем товар по рыночной цене (p[i] + dp[i]) в объеме -dt[i].

  7. Если dt[i] > 0, то закупим товар по рыночной цене (p[i] + dp[i]) в объеме dt[i].

  8. p[i] = p[i] + dp[i]

  9. Конец цикла заданного в п. 5

  10. Ждать изменения цен

  11. Перейти к п.1

В результате, после всех сделок совершенных в пунктах 6. и 7. алгоритма, при переходе к п. 10,  на нашем счету останется сумма денег равная m + dm.

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

Алгоритм вроде бы хорош, но не слишком. Основные недостатки данного алгоритма заключаются в:

  1. Не всегда предоставляется возможность произвести нужные закупки и продажи до того, как цены успеют измениться. Что приведет к потере оптимальности

  2. Все расчеты должны производиться в действительных числах с плавающей запятой, что во многих случаях неприемлемо. Например, некоторые товары нельзя купить иначе, как в количестве целочисленном. А на биржах принято торговать крупными партиями  - лотами.

  3. Алгоритм не учитывает спред - разницу между ценой продажи и ценой покупки.

Этих трех пунктов более чем предостаточно. А посему необходим алгоритм, который данных безобразий не содержит, но является таким же оптимальным. В нижеследующем алгоритме все указанные недостатки устранены.

Алгоритм 2

  1. Взять текущее коммерческое предложение. Т.е. нам предлагается закупить или реализовать товар в количестве count по цене p[i] + dp[i])

  2. Если предложение на продажу  нам товара и значение count положительно, то выясним цену  реализации товара (p[i] + dp[i]). Если предложение на покупку товара у нас и значение count отрицательно, то перейти на п. 13. Т.е. мы тогда будем со своей стороны рассчитывать выгодность покупки.

  3. Вычислим объем сделки dt[i] = (int)(n * (m / (p[i] +dp[i]) - t[i])/(n + 1)). (int) - означает, что нужно взять целую часть от того, что идет после него, отбросив дробную.

  4. Уточним через count - предлагаемый продавцом объем сделки. Имеется в виду, что продавец может и не располагать товаром в нужном нам количестве, т.е. dt[i] > count. Уточняем: dt[i] = min(dt[i], count)

  5. Если dt[i] <= 0, то перейти на п. 1. Сие означает, что если dt[i] меньше 0, то по такой цене (p[i] + dp[i]) оптимально реализовать товар i. Значит, сделка невыгодна и не состоится

  6. Поскольку мы отбрасывали дробную часть и уточняли объем сделки также в сторону умаления, то необходимо пересчитать оптимальную цену сделки: price = m / (t[i] + (n + 1)*dt[i] / n)

  7. Отдадим продавцу деньги в размере: dm = dt[i] * (p[i] + dp[i])

  8. Зачтем на наш счет m = m + price * dt[i]

  9. Заберем у продавца товар i  в объеме dt[i].

  10. Возьмем его себе на учет: t[i] = t[i] + dt[i]

  11. Вычислим лишние деньги: profit = profit + (price - p[i] - dp[i]) * dt[i]

  12. Перейти к п. 1

  13. Возьмем  рыночную закупочную цену товара (p[i] + dp[i]). Т.е. мы будем со своей стороны рассчитывать выгодность реализации товара по данной цене.

  14. Вычислим объем сделки dt[i] = (int)(n * (m / (p[i] + dp[i]) - t[i]) / (n + 1)). 

  15. Уточняем: dt[i] = max(dt[i], count)

  16. Если dt[i] >= 0, то перейти на п. 1. Сие означает, что коли по расчетам dt[i] > 0, то по такой цене выгоднее было бы продавать данный товар. А посему, сделка не состоится.

  17. Поскольку мы отбрасывали дробную часть и уточняли объем сделки  в сторону умаления, то необходимо пересчитать оптимальную цену сделки: price = m / (t[i] + (n + 1)*dt[i] / n)  

  18. Возьмем с покупателя деньги в размере dm = -dt[i] * (p[i] + dp[i])

  19. Запишем на свой счет: m = m + price * dt[i]

  20. Отдадим покупателю товар i  в объеме -dt[i].

  21. Снимем со своего учета товар i в количестве dt[i], т.е. t[i] = t[i] + dt[i]

  22. Вычислим лишние деньги: profit = profit + (price - p[i] - dp[i]) * dt[i]

  23. перейти на п. 1

Проблема лишних денег

Наиболее странными в данном алгоритме являются пункты: 11 и 22. Знающие люди скажут, что деньги лишними не бывают. Но автор ведь этого не знает и наивно полагает, что излишек денег приводит к отклонению от оптимальной стратегии. Ведь с продавцами и покупателями мы рассчитываемся по рыночной цене p[i] + dp[i], а собственный расчетный счет пополняем или умаляем по расчетной (уточненной цене) price. В результате разница между этими ценами помноженная на объем сделки dt[i] и составит лишние деньги. Что делать с этими самыми лишними деньгами? Да что хотите: растратьте, пропейте, прогуляйте, подарите и т.д. и т.п. В общем ими можно распоряжаться как угодно, кроме использования в дальнейших расчетах. И не стоит полагать, что излишек  каждый раз окажется обязательно крупным. В некоторых случаях его значение может достигать коммерчески ничтожной величины. Но, по этим самым ничтожным крупицам при приличных торговых оборотах, можно собрать весьма солидный капитал. Я, например, подсчитал, что если государство возьмет на себя, скажем весь межбанковский иностранной валюты на национальную валюту по вышеприведенному алгоритму (т.е. все межбанковские сделки будут осуществляться только через государственный валютный резерв), то ему не надо будет заниматься сбором налогов с населения, искать деньги бюджетникам и сталкиваться с прочими финансовыми проблемами и выдумывать антисоциальные реформы. Помимо валютного, есть еще и фондовые и товарно-сырьевые биржи. Почему бы не монополизировать  их, вместо того, чтобы дарить столь лакомый кусок Лондону, Токио, Нью-Йорку или какому-то Гонконгу?

Доказательство математической  аналогии первого и второго алгоритма

Итак,  в алгоритме2 мы используем формулы:


dt[i] = n * (m / ( p[i]+ dp[i]) - t[i]) / (n + 1)

(1)

и


p[i]+ dp[i] = m / (t[i] + (n + 1) *dt[i] / n)


(2)

Как удостовериться в том, что второй алгоритм аналогичен первому? Пойдем с самого начала. Вычислим наше благосостояние по текущим рыночным ценам.


s = m + (p[1]+ dp[1])*t[1] + (p[2]+ dp[2])*t[2] ...(p[n]+ dp[n])*t[n]


(3)


Вычислим среднеарифметическое


sm = s / (n + 1)

(4)


Будем производить реинвестиции, так чтобы выполнялись равенства:


m + dm = (p[i]+ dp[i])*(t[i] + dt[i]) = sm, для всех i

(5)

И далее:


(p[i]+ dp[i])*(t[i] + dt[i]) = sm = (m + ( p[1] + dp[1])*t[1] + ( p[2] + dp[2])*t[2] +...+ ( p[i] + dp[i])*t[i] +...+( p[n] + dp[n])*t[n])) / (n + 1)


(6)

Перенесем текущую цену p[i]+ dp[i] в знаменатель правой части:


(n + 1)*(t[i] + dt[i]) = (m + ( p[1] + dp[1])*t[1] + ( p[2] + dp[2])*t[2] +...+ (p[i] + dp[i])*t[i] +...+ ( p[n] + dp[n])*t[n])) / (p[i] + dp[i])


(7)

Вынесем  t[i] за скобки в правой части:


(n + 1)*(t[i] + dt[i]) = t[i] + (m + (p[1] + dp[1])*t[1] + ( p[2]+ dp[2])*t[2] +...+ ( p[n] + dp[n])*t[n])) / (p[i] + dp[i])

(8)

Вычтем из левой части уравнения t[i] стоящую в правой части:


n*t[i] + (n + 1)*dt[i] = (m + ( p[1] + dp[1])*t[1] + ( p[2] + dp[2])*t[2] +...+ ( p[n] + dp[n])*t[n])) / ( p[i] + dp[i])

(9)

Перенесем текущую рыночную цену p[i]+ dp[i] из знаменателя правой части в левую часть, а из левой части n*t[i] + (n + 1)*dt[i] отправим в знаменатель правой части:


p[i]+ dp[i] = (m + p[1]*t[1] + p[2]*t[2] +...+ p[n]*t[n])) / (n*t[i] + (n + 1)*dt[i])

(10)


С учетом формулы (6), то бишь на каждом шаге алгоритма, мы уравниваем для всех y:


m = (py + dpy)* ty 


Значит в числителе правой части формулы (10) все py*ty можно заменить на m, в результате чего получаем окончательно:


p[i]+ dp[i] = n * m / (n*t[i] + (n + 1)*dt[i]) 

(11)


Формула (11) равносильна формуле (2):


p[i]+ dp[i] = n * m / (n*t[i] + (n + 1)*dt[i]) = m / ( t[i] + (n + 1) *dt[i] / n)


В более общем виде эту равносильность можно вывести несколькими способами, через Основной Закон Экономики и формулу 0. В каждом из этих способов фигурируют то одни, то другие неизвестные. Но, в некоторых случаях, решение  сводится к тому, что в выражении присутствует всего одна неизвестная (и такие случаи присутствуют для всех неизвестных без исключения), которую уже можно запросто вычислить, через оставшиеся известные, но при этом справедливость для остальных неизвестных полностью соблюдается:



p[i]+ dp[i] = -dm/dt[i] = (m +  dm ) / (t[i] + dt[i]) = n * m / (n*t[i] + (n + 1)*dt[i]) = (n*m + (n + 1)*dm) / (n*t[i])

(12)


Таким образом, мы доказали, что каждый шаг нашего алгоритма соответствует формулам (2) и (11)

Доказательство того, что алгоритм находит оптимум

Но это вовсе не значит, что алгоритм является оптимальным для решения инвестиционной задачи. Для доказательства оптимальности формулы (4), необходимо составить систему дифференциальных уравнений таким образом, чтобы:


ds / dm  = ds / dt[i] = 0

Без учета dp[i] = const.


Для этого необходимо и достаточно, чтобы в числителях системы уравнений были 0. А поскольку все числители - это ds, а:


ds = dm + (сумма по всем i для dp[i]*dt[i])


Но, мы не будем строить систему дифференциальных уравнений, а возьмем пример с Огустьена Луи Коши, который прибегал к различным ухищрениям, дабы решить подобные задачи без применения этих самых систем. Ведь, в качестве альтернативы нам необходимо и достаточно лишь доказать  условия при которых dm и dt[i] равны 0. Если эти условия совпадают с нашим алгоритмом, то задача решена.


Вычислим dt[i] из формулы (2):


dt[i] = n * (m / (p[i]+ dp[i]) - t[i]) / (n + 1) = 0


Очевидно, что n не может быть равна 0. Следовательно, остается только:


m / ( p[i]+ dp[i]) - t[i] = (m - t[i] * (p[i]+ dp[i])) / (p[i]+ dp[i]) = 0


Отбросим знаменатель (p[i]+ dp[i]), поскольку в правой части уравнения 0:


m - t[i] *(p[i]+ dp[i]) = 0


или же:


m = t[i] * (p[i]+ dp[i])


Что собственно наш алгоритм и делает, всякий раз уравнивая m и  t[i] * (p[i]+ dp[i]).


Теперь выясним условия, при которых dm = 0. Из формулы (12):


dm = n*((p[i]+ dp[i])*t[i] - m) / (n + 1) = 0


Опять же, поскольку n не равен 0, то:


(p[i]+ dp[i])*t[i] - m = 0


а следовательно условием когда dm = 0, является (p[i] + dp[i])*t[i] = m.

Условия, при которых ds = 0 совпали. Тем самым, наш алгоритм ведет к экстремуму, а следовательно и является оптимальным. Что и следовало доказать. Конечно же, и этого не достаточно, поскольку экстремумы подразделяются на две разновидности, а именно, максимумы и минимумы. Следовательно, для выяснения разновидности, нужно было бы вычислить еще и вторую производную. Но мы этого делать не будем. А просто взглянем на формулу (2):

Наш алгоритм имеет свой спред, а следовательно цена продажи выше цены покупки, поскольку dt[i] стоит в знаменателе.

(p[i]+ dp[i]) = n * m / (n*t[i] + (n + 1)*dt[i])

Когда мы продаем, то dt[i] отрицателен и цена выше, когда покупаем - цена ниже. Что собственно и требуется для нашей задачи.

Сложность алгоритма

Поскольку в алгоритме используется явная формула (12), а в ней элементарные арифметические операции, то его сложность O(1). Т.е. своего рода рекордсмен среди алгоритмов оптимизации.

Это очень важно, поскольку для реализации не потребуется привлечение значительных вычислительных ресурсов. И что не менее важно, алгоритм одновременно к своей основной задаче выяснения выгодности сделок и их осуществления, еще и ведет учет всех материальных средств.

Виртуальные материальные средства

С одной стороны мы имеем алгоритм ничтожной сложности. С другой стороны осталась еще одна нерешенная проблема. А именно маржа. Ведь, с помощью маржи можно осуществлять торговые операции, имея не слишком большие материальные  средства в своем распоряжении. А в данном алгоритме, если предусмотреть маржевое плечо свыше, чем 1:2 (такое плечо вполне достаточно для фондового рынка, но явно недостаточно для валютного), то теряются оптимизационные свойства. (по крайней мере, мне не удалось решить эту задачу, что вовсе не означает, что она неразрешима).

В общем то, это не столь уж сложная проблема. Ведь маржу предоставляют, как правило брокерские конторы, а посему это их головная боль.

С другой стороны, если посмотреть на условия задачи, то выяснится, что часть наших материальных окажется необоротными. Ведь объемы сделок не предусмотрены на всю сумму денег или на весь товар того или иного наименования. Если котировки будут колебаться в пределах ±n%, то и оборот наших средств также окажется затронутым примерно в пределах 2*n%.

Чтобы избежать вышеприведенного недостатка, можно использовать виртуальные материальные средства, помимо имеющихся в наличии. Например, если у нас есть товар наименования i в количестве t[i], а колебания котировок порядка ±5%, то можно было бы ввести и виртуальный товар vt[i] = 9*t[i] в виде константы и виртуальные деньги vm = 9*m также в виде константы. Т.е. 10% реальных и 90% виртуальных. И получаем своего рода аналог маржевого плеча 1:10 при реальном плече 1:1

В этом случае в алгоритме необходимо заменить все t[i], на t[i] + vt[i], а все m на vm + m. Помимо этого еще предусмотреть дополнения в виде подпунктов:

5a. Уточним dt[i] = min(dt[i], (int)(m / (p[i] + dp[i]))). Т.е., проверим, хватит ли нам наличных денег, дабы оплатить покупку.

и

14a. Уточним dt[i] = max(dt[i], t[i]). Т.е. имеется ли в нашем распоряжении достаточное количество товара, дабы его реализовать.

Виртуальные материальные средства в виде констант никак не влияют на оптимизационные свойства алгоритма, но позволяют значительно повысить оборот, а следовательно и также значительно понижают необходимость в наличии средств реальных, для совершения торговых операций в больших объемах.


Программная реализация механической торговой системы по вышеуказанному алгоритму для биржевого терминала МetaTrader4

Скачать исходные коды МТС Swaper_1.1 можно ЗДЕСЬ



г. Ташкент