Блог им. ArturMakoven

Я долго считал размер лота чисто техническим параметром торгов. Пока не попробовал воспроизвести целевые веса портфеля с небольшими регулярными пополнениями. Оказалось, что лот влияет не только на удобство покупки: он создаёт ошибки округления, накапливает перекосы между позициями и иногда меняет риск портфеля сильнее, чем движение самих котировок.
ВступлениеДопустим, я хочу собрать довольно скучный портфель. Пять бумаг, веса 30%, 25%, 20%, 15% и 10%. Никакой магии. Есть миллион рублей, умножаю капитал на долю каждой позиции, получаю нужную сумму и покупаю. Именно так портфель выглядит в Excel.
В терминале всё чуть менее красиво. Бумаги нельзя купить на 247 381 рубль или на 153 900 рублей просто потому, что мне так удобно. Есть цена одной бумаги, есть количество бумаг в лоте, а значит, есть минимальный денежный шаг, которым я могу увеличивать или уменьшать позицию. Чем меньше портфель и чем дороже этот шаг относительно капитала, тем сильнее реальная структура начинает отличаться от расчётной.
Я раньше списывал эту разницу на мелочь. Потом попробовал посчитать её не в рублях, а в долях портфеля. Вот там она перестала выглядеть мелочью.
1. Лот превращает непрерывную задачу в дискретнуюВ теории распределение капитала удобно считать как непрерывную величину. Пусть общий капитал равен VV, а целевой вес бумаги ii равен wiw_i. Тогда желаемая стоимость позиции элементарна:
Ti=V⋅wiT_i = V \cdot w_iЕсли капитал 600 000 рублей, а на бумагу я хочу выделить 17%, нужная позиция равна 102 000 рублей. На этом модель из таблицы обычно заканчивается.
Но биржа заставляет добавить ещё две переменные. Пусть цена одной акции равна PiP_i, а размер лота LiL_i. Тогда минимальная стоимость торговой единицы:
Qi=Pi⋅LiQ_i = P_i \cdot L_iИ реальная стоимость позиции уже не может быть произвольной. Она принимает значения 0, QiQ_i, 2Qi2Q_i, 3Qi3Q_i и так далее. Получается небольшая задача целочисленной оптимизации:
Ai=niQi,ni∈Z≥0A_i = n_iQ_i,\quad n_i \in \mathbb{Z}_{\geq0}где AiA_i — фактически вложенная сумма, а nin_i — количество купленных лотов.
На практике отсюда появляются сразу несколько эффектов:
целевой вес позиции почти никогда не совпадает с фактическим;
часть денег остаётся свободной просто потому, что её не хватает ещё на один лот;
бумаги с дешёвым торговым шагом легче приблизить к нужной доле;
дорогой лот способен сделать небольшую целевую позицию вообще недоступной;
при каждом пополнении возникают новые ошибки округления, которые могут складываться, а не компенсировать друг друга.
Допустим, у меня портфель 300 000 рублей и я хочу 10% держать в конкретной акции. Значит, целевая позиция — 30 000 рублей.
Если лот стоит 3 200 рублей, я могу купить девять лотов на 28 800 рублей или десять на 32 000. В первом случае получаю вес 9,6%, во втором — 10,67%.
На первый взгляд разница смешная.
Но теперь представим не одну бумагу, а десять. У каждой собственная ошибка округления. Причём ошибки не обязаны смотреть в разные стороны. Несколько позиций могут одновременно оказаться недовешенными, а несколько — перевешенными. И портфель, который в таблице выглядит как аккуратные 30/20/15/10 и далее, в реальности начинает жить собственной жизнью.
Я для себя стал считать относительную ошибку позиции:
ei=Ai−TiVe_i = \frac{A_i — T_i}{V}То есть мне важна уже не разница в рублях, а то, сколько процентных пунктов портфеля я потерял или добавил из-за дискретности сделки.
Вот после этого размер лота становится вполне инвестиционной характеристикой.
2. Особенно хорошо проблема видна на небольших пополненияхСамая неприятная ситуация возникает не при первоначальной сборке портфеля. Там обычно есть достаточно большая сумма, и ошибки округления относительно невелики. Настоящий перекос я заметил, когда стал моделировать ежемесячные пополнения.
Предположим, портфель стоит 1,2 млн рублей, а каждый месяц я добавляю 40 000. У меня есть бумага с целевой долей 8%. В идеальном мире на неё должно приходиться примерно 3 200 рублей каждого нового пополнения. Но если один доступный мне лот стоит 11 500 рублей, я физически не могу поддерживать вес плавно. Несколько месяцев позиция остаётся недовешенной. Потом возникает момент, когда я покупаю целый лот, и она сразу перескакивает выше цели.
Получается своего рода пилообразное отклонение. Вес медленно уходит вниз относительно модели, затем одной покупкой резко возвращается вверх или даже становится избыточным. Чем выше стоимость лота относительно регулярного денежного потока, тем грубее эта пила.
Это легко увидеть математически. Если ежемесячное пополнение равно CC, а на конкретный актив должно идти CwiCw_i, полезно сравнить эту сумму со стоимостью одного лота:
Ri=QiCwiR_i = \frac{Q_i}{Cw_i}Я называю это коэффициентом грубости пополнения.
Если Ri=0,2R_i = 0,2, всё спокойно: на целевую месячную сумму приходится примерно пять лотов, и позицию можно регулировать довольно точно.
Если Ri=1R_i = 1, один лот примерно равен всему месячному бюджету этой позиции.
Если Ri=4R_i = 4, начинается уже совсем другая механика. Нужно условно четыре месяца накапливать потребность в покупке, чтобы операция стала хотя бы приблизительно соответствовать модели.
И вот здесь возникает вещь, которую я раньше вообще не учитывал. Цена акции может стоять на месте, фундаментальная оценка компании может не меняться, никаких решений по стратегии я не принимал, но фактический риск портфеля всё равно дрейфует. Просто потому, что одну позицию я могу докупать почти каждый месяц, а другую — раз в несколько месяцев.
Если активы при этом имеют разную волатильность, то отклонение весов превращается уже в отклонение риска.
Для портфеля с весами ww и ковариационной матрицей доходностей Σ\Sigma дисперсия записывается стандартно:
σp2=w⊤Σw\sigma_p^2 = w^\top \Sigma wНо в реальной торговле вместо целевого вектора ww у меня существует фактический вектор w^\hat w. Тогда фактический риск:
σ^p2=w^⊤Σw^\hat\sigma_p^2 = \hat w^\top \Sigma \hat wРазница между ними появляется даже без изменения моего инвестиционного решения.
Особенно неприятно, когда перевешивается не самая спокойная бумага. Допустим, вместо целевых 7% она занимает 8,5%. Разница всего полтора процентных пункта. Но если её волатильность заметно выше средней и она хорошо коррелирует ещё с несколькими крупными позициями, вклад в портфельный риск растёт непропорционально.
В этот момент становится понятно, почему просто посмотреть на проценты около тикеров недостаточно.
3. Ребалансировка тоже упирается в размер торгового шагаКогда я впервые попытался исправлять такие перекосы, решение казалось очевидным: периодически проводить ребалансировку. Но здесь размер лота появляется второй раз.
Допустим, целевой вес позиции 12%, фактический 13,1%. Формально её надо немного сократить. Только продажа одного лота может уменьшить вес сразу до 11,4%. Получается, что точка 12% для моего капитала вообще недостижима.
Поэтому я перестал относиться к целевому весу как к одной точке. Гораздо практичнее задавать допустимый диапазон. Например, если цель 12%, меня может устраивать коридор 11–13%. Сделку имеет смысл совершать только тогда, когда позиция выходит за его пределы и операция действительно уменьшает отклонение.
Для себя я свёл процесс примерно к такой логике:
считаю целевые суммы по всем позициям;
считаю фактические суммы с учётом текущих цен;
нахожу отклонение каждой позиции в процентных пунктах портфеля;
проверяю, сколько изменит вес покупка или продажа одного лота;
сначала направляю новые деньги в самые недовешенные позиции;
не продаю актив только ради красивой цифры, если следующий доступный торговый шаг перебросит вес через цель в другую сторону;
отдельно слежу за остатком денежных средств, потому что хронический кэш тоже становится незапланированной позицией.
Есть ещё более интересный вариант — рассматривать покупку новых лотов как оптимизационную задачу.
Пусть после пополнения у меня есть сумма CC. Нужно подобрать число покупаемых лотов xix_i, чтобы итоговые веса максимально приблизились к целевым:
minx1,…,xn∑iαi(w^i(x)−wi)2\min_{x_1,\ldots,x_n} \sum_i \alpha_i(\hat w_i(x)-w_i)^2при ограничении
∑ixiQi≤C\sum_i x_iQ_i \leq Cи
xi∈Z≥0x_i \in \mathbb{Z}_{\geq0}Коэффициент αi\alpha_i можно оставить равным единице, а можно сделать его зависимым от риска. Например, сильнее штрафовать отклонение высоковолатильных или системно важных позиций.
Самое забавное, что для портфеля из десяти бумаг такая постановка звучит значительно страшнее, чем работает на практике. Даже простой перебор разумных комбинаций или жадный алгоритм часто даёт результат заметно лучше правила купить всё понемногу.
Например, я могу для каждого дополнительного лота рассчитывать, насколько покупка уменьшит функцию ошибки портфеля:
ΔEi=Ebefore−Eafter,i\Delta E_i = E_{before} — E_{after,i}и покупать тот лот, у которого отношение уменьшения ошибки к стоимости максимально:
Si=ΔEiQiS_i = \frac{\Delta E_i}{Q_i}После покупки пересчитываю портфель и повторяю процедуру, пока денег не перестанет хватать на следующие полезные операции.
Это уже не идеальная глобальная оптимизация, зато такой алгоритм элементарно реализуется хоть в Python, хоть в Excel с небольшим количеством ручной работы.
И результат иногда получается неожиданным. Самая недовешенная позиция необязательно должна получить деньги первой. Если её лот слишком дорогой, покупка может перебросить вес выше цели, тогда как два-три дешёвых лота других бумаг суммарно приблизят портфель к модели гораздо сильнее.
ВыводПосле этих расчётов я перестал считать размер лота технической мелочью из спецификации инструмента. Для крупного портфеля его влияние действительно постепенно растворяется. Но при небольшом капитале, регулярных пополнениях и большом количестве позиций дискретность становится полноценным ограничением конструкции портфеля.
Причём проблема не в том, что где-то вместо 10% получилось 9,7%. Самое интересное начинается, когда ошибки округления постоянно повторяются. Они влияют на очередность покупок, оставляют деньги без работы, создают дрейф весов и меняют фактическую чувствительность портфеля к отдельным факторам риска.
Теперь перед добавлением новой бумаги я смотрю не только на компанию, цену и желаемую долю. Я проверяю стоимость одного торгового шага относительно размера портфеля и обычного пополнения.
Иногда после этого оказывается, что идея нормальная, компания мне подходит, целевой вес тоже выглядит разумно, но сама позиция получается неудобной конструктивно.
И это тот редкий случай, когда проблема портфеля возникает ещё до первой сделки.