Формы 13F, подготовка данных, разведка, уран

Каждый квартал американские фонды (с активами более $100 млн.) сдают отчет, в котором указывают размеры своих позиций по каждому инструменту, это называется форма 13F. У этих отчетов есть свои ограничения:

  • в 13F фонды не указывают шорт позиции
  • опционные позиции фонды указывают, то без детализации по страйку/экспирации
  • фонды могут обманывать (фонд Бернарда Мейдоффа исправно сдавал 13F, хотя позиций у него не было)
  • небиржевые и неамериканские позиции фонда могут отсутствовать, например фонд G&R из статьи про уран в каком-то из своих квартальных комментариев упоминал, что владеет казатомпромом и sprott, но в их форме 13F я этого не вижу

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

Блоки "Парсим архивы" и "Подготовка данных" потенциально будут более интересны программистам/дата-инженерам, те кому интересны чисто финансы могут пропустить эти два блока.

Парсим архивы

Данные за каждый квартал представляют собой zip архив, в архиве 7 tsv файлов с данными, html файл с описанием и json файл с машиночитаемым описанием. Архив за 2 квартал 2017 битый, поэтому я скачал все архивы начиная с 3к2017.

Основной файл INFOTABLE.tsv за 4кв2024 весит 328Мб, вроде не "бигдата", но например гугл таблицы уже не позволяют такое импортировать, да и локальный excel вроде смог откыть, но сразу закрылся (это на M1 Pro 16Гб).

Отступление про "бигдату"

Все еще нет устоявшегося понимания что уже является большими данными, а что нет. Кто-то считает что миллион строк это уже большие данные (даже не уточняя сколько там столбцов), кто-то считает что 100Тб видео это еще не слишком много. В моем предствалении есть три уровня "больших данных":

  1. Данные нельзя обработать на одном компе "стандартными" средствами. В случае tsv файла как в этой статье, стандартные средства это excel / гугл таблицы, и они не справляются даже с одним из семи файлов за один квартал (а там 30+ таких архивов). С трудом можно назвать такое "бигдатой", т.к. через программирование можно с этим работать за милисекунды, без особых хитростей.
  2. Данные не помещаются в оперативку на одном компе. По этому критерию тоже не сказать что данные большие, но уже при обработке даже через программирование придется изобетать какие-то хитрости. Все архивы 13F, в несжатом виде около 10Гб, т е можно целиком прочитать в оперативку и быстро обработать.
  3. Данные не помещаются на жесткий диск на одном компе, и их объем быстро растет. Чтобы обрабатывать такие данные нужно поднимать масштабируемый кластер из нескольких машин (потенциально десятков/сотен), и использовать специальные средства по репликации/отказоустойчивости и тд. Вот это уже bigdata.

Конец отступления.

ClickHouse

Так как данные не влезли в excel даже за один квартал, а изучать данные я планирую за 30 кварталов (c дальнейшим увеличением), следующее что приходит в голову это сложить их в БД. Помимо того, что получать ответы можно будет через написание SQL запросов, вместо написания скриптов (а это быстрее), доступ к БД можно выдать другим людям для делегирования задач (а людей знающих SQL больше, чем условный Python).

В данном случае можно было бы сложить и в Postgres, но я сложу в ClickHouse. Из OLAP-сценария тут как минимум то что данные будут записаны один раз, без дальнейших изменений, а чтений будет много. Этого в принципе достаточно. Развернутый в облаке ClickHouse у меня уже есть [тема для отдельной статьи?], и я дам к нему публичный доступ! Конечно readonly, т.е. можно будет выполнять запросы ко всем таблицам которые будут созданы ниже. Доступ к ClickHouse тут, писать запросы можно прямо в браузере [не надо дудосить пожалуйста].

Для начала я создам по одной таблице на каждый файл, каждая таблица будет содержать столько строковых столбцов, сколько есть в соответствующем tab-separated файле. Причем на этом этапе я даже не буду смотреть какие там столбцы, разведочный анализ я планирую делать уже силами кликхауса. Код по созданию таблиц и импорту в них данных выглядит так:

функция создания таблиц в CH
функция импорта одного архива
выполняем создание и импорт

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

Подготовка данных

Для начала посмотрим размеры таблиц, выполняем такой SQL запрос (по публичному доступу к CH, это можно сделать самостоятельно):

В основной таблице INFOTABLE 73 млн строк и весит она 2.6Гб. Смотрим что в ней:

таблица INFOTABLE (на скрин влезли не все столбцы)
оставшиеся столбцы

Чтобы лучше понимать данные, нужно ответить на вопросы по каждой таблице:

  1. Сколько уникальных значений в каждом столбце?
  2. Сколько пустых значений в каждом столбце?
  3. В каких столбцах на самом числа/даты вместо строк? Каково распределение этих значений?
  4. Нужно ли дополнительно нормализовать значения (привести к регистру, убрать пробелы/запятые)?
  5. Какие столбцы лишние (не пригодятся для наших целей)?
  6. Как таблицы связаны между собой?

Некоторые SQL запросы на примере таблицы INFOTABLE и их результаты скринами ниже:

распределение числовых столбцов
Количество записей по справочнику PUT/CALL
Количество записей по справочнику SSHPRNAMTYPE
Количество записей по справочнику INVESTMENTDISCRETION
Названия инструментов с разной степенью нормализации
количество уникальных значений по столбцам
количество пустых значений по столбцам

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

  • Название фонда это столбец FILINGMANAGER_NAME в таблице COVERPAGE, столбец требует нормализации
  • Период это столбец PERIODOFREPORT в таблице SUBMISSION, в формате день-месяц-год (например) 30-JUN-2017
  • Из таблицы INFOTABLE интересны NAMEOFISSUER (название инструмента, требует нормализации), CUSIP (уникальный ID инструмента), TITLEOFCLASS (тип инструмента, например привелигированные или обычные акции гугла), PUTCALL (является ли позиция опционной),
  • SSHPRNAMT (размер позиции), VALUE (размер позиции в $)
  • Можно игнорировать все записи INFOTABLE с SSHPRNAMTTYPE != SH (таких записей очень мало, а учет этого признака сильно усложнит дальнейший анализ
  • таблицы INFOTABLE, SUBMISSION, COVERPAGE связаны по столбцу ACCESSION_NUMBER
  • Остальные таблицы не представляют интереса

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

Сейчас размеры позиций за определенный период это отдельные строки, а для целей аналитики хорошо бы, чтобы они были столбцами в одной строке. Например если я захочу посмотреть какие позиции были увеличены в 2 раза, я бы хотел написать условие типа:

WHERE value_2024_q3 > 2 * value_2024_q2

Cейчас для этих целей мне придется сначала сделать join таблицы с ней самой, что сильно усложнит и написание запросов и их понимание. В итоге запрос на создание финальной таблицы будет выглядеть так:


создаем финальную таблицу
создаем финальную таблицу

Сервер где у меня развернут кликхаус имеет всего 8Гб ram, а чтобы записать данные в финальную таблицу одним запросом, нужно сначала сделать join таблиц INFOTABLE, SUBMISSION, COVERPAGE, а затем этот результат заджоинить с самим собой еще 36 раз. Выполнение такого запроса на моем сервере отваливается по out of memory (срабатывает критерий 2 бигдаты, из отступления про большие данные). Поэтому нужно придумывать некие хитрости, сначала я создам промежуточную таблицу form13f_temp, с точно такой же структурой, как у финальной, и запишу туда данные 36 раз. Можно было бы выполнить эти запросы руками, но я сделаю через цикл в эликсире:

вставка данных в промежуточную таблицу
вставка данных в промежуточную таблицу

Теперь есть таблица, в которой за размер позиции в разных периодах отвечают разные столбцы, а не строки. Но в каждой отдельной строке этой таблицы, только один столбец имеет не нулевое значение, т.е. в финальную таблицу нужно записать результат агрегации по промежуточной. К сожалению агрегация этой таблицы целиком тоже отваливается по out of memory, поэтому записывать буду частичными агрегациями, итерируя по какому нибудь столбцу, например instrument_cusip:


вставка данных в финальную таблицу
вставка данных в финальную таблицу

Анализируем

Данные подготовлены для аналитики, теперь простой запрос типа:

смотрим в карман Джорджу Соросу
смотрим в карман Джорджу Соросу

показывает какие позиции в портфеле у фонда Сороса, и как они поменялись в четвертом квартале 2024. Например позиция по гуглу увеличена в четыре раза, а страховой компании "Arthur J. Gallagher & Co." в прошлом квартале не было вообще, а сейчас она есть, причем на существеный объем.

Разведка данных

Подготовленная таблица состоит из столбцов:

  • manager - Название фонда
  • instrument_cusip - Уникальный идентификатор инструмента
  • instrument - Наименование инструмента
  • class - класс инструмента (например привелигированные или обычные акции)
  • put_call - является ли позиция опционной и в какую сторону
  • столбцы pos_2017_2 - pos_2025_4 - поквартальный размер позиции
  • столбцы money_2017_2 - money_2025_4 - размер позиции "в деньгах"

В таблице более 8 млн строк, 11 517 фондов, 87 052 инструментов, чтобы подступиться к анализу этих данных, нужно их как-то категоризировать/систематизировать. Начнем с ответа на следующие вопросы:

Каков разброс фондов по объему денег?

Разброс фондов по объему денег серьезно смещен вправо:

BlackRock и его $2трлн
BlackRock и его $2трлн

Но если выделить топ 1%, то какую-то структуру прикинуть можно:

мало денег в фонде != фонд не представляет интереса
мало денег в фонде != фонд не представляет интереса

Каков разброс по количеству торгуемых инструментов?

Этот разброс похож по смещению, и вместо него имеет смысл посмотреть на разброс значений на стыке объем портфеля/количество инструментов:

по Y размер портфеля в $, по X количество позиций
по Y размер портфеля в $, по X количество позиций

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

Мало торгуемых инструментов при портфеле от $120 до $150млн
Мало торгуемых инструментов при портфеле от $120 до $150млн

Получается что фонды с самыми малыми объемами портфелей делятся на тех кто торгует cотни/тысячи позиций, и тех кто сосредотачивается на небольшом количестве инструментов. После этих наблюдений возникает доп. вопрос:

Как распределены фонды по среднему размеру позиций относительно размера портфеля?


по Y размер портфеля в $, по X средний размер позиции в % от портфеля
по Y размер портфеля в $, по X средний размер позиции в % от портфеля

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

Какие фонды торгуют опционами, а какие только базовыми активами?

Фонды и опционы
Фонды и опционы

Фондов которые торгуют опционами всего 1002 (против 6856 которые торгуют только базовыми активами), при этом денег у таких фондов в среднем в 2-3 раза больше, а количество инструментов +- похоже (100 и 74).

Были и другие вопросы, но ответы на них не принесли ничего информативного, поэтому я их пропущу. Примеры таких вопросов:

  • Как инструменты торгуются бОльшим/меньшим количеством фондов?
  • Многие ли инструменты имеют разный класс? Что это за классы?
  • другие виды распределений + те же распределения при фильтрации по какому-то признаку (объем/опционы/отрасли)

Формы 13F, УРАН

В продолжение урановой темы мне интересно изменение урановых позиций компаниями, кто продает, кто докупает. Самая урановая компания в США – Cameco, по ней удобно посмотреть текущие действия фондов на тему урана. Сейчас (июль 2025) Cameco на исторических верхах, хотя долгосрочная цена на уран все еще в районе 80$, как и в январе 2024 (т.е. тезисы о структурном дефиците урана еще не сыграли).

NYSE:CCJ
NYSE:CCJ

Пишу такой запрос:

Смысл запроса в следующем – показать изменение позиции по Cameco за последние четыре квартала, среди фондов которые:

  • не торгуют опционами, т.е. в теории должны играть в долгую, на фундаментальных тезисах
  • в какой-то квартал за последний год владели в последний Cameco год хотя бы на $2млн

Таких фондов нашлось 179, из них:

  • 12 имели позицию ноль (или почти ноль) и закупили в первом квартале 2025
  • 16 имели позицию и увеличили ее от 10 до 100%
  • 57 имели позицию докупили/слили +- 10%
  • остальные слили от 10 до 100%

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

Полный список фондов и их позиций можно получить выполнив тот же запрос по публичному доступу.

Из того что зацепил мой взгляд:

  • MORGAN STANLEY слил 70% позиции, более чем на $1 млрд
  • ROCKEFELLER CAPITAL MANAGEMENT LP слил 15%
  • VANGUARD GROUP INC докупает по 2% каждый квартал
  • многие фонды не владели позицией, но внезапно купили в 1кв 2025, являются "фондами тех анализа" т.е. "покупают то что растет"
  • самый крупный владелец Cameco (судя по формам 13F) MIRAE ASSET GLOBAL ETFS HOLDINGS LTD слил 13%
  • G&R слили 9% не смотря на их тезисы о долгосрочном бычьем рынке урана

Поиск блогов/квартальных комментариев этих фондов особого результата не дал, есть упоминание от фонда FOUNDATION RESOURCE MANAGEMENT INC тут о том что на тарифные войны вряд ли создадут проблемы для Сamecо. Есть подкаст от TITAN GLOBAL CAPITAL MANAGEMENT USA LLC тут о том, что на AI пузырь лучше ставить через медь и уран. Ну и фонд G&R чьи тезисы известны из предыдущей статьи.

Итоги

Планировал еще сделать блок про медь (самая медная компания - Freeport McMoran), по нему тоже есть намеки на наличие дефицита от Кримсона, но нет фактуры, а G&R например c Кримсоном не вполне согласны. Но наверно медь тоже лучше начать с фреймворка, как с ураном. Для форм 13F теперь есть свой скринер, все какие я видел в интернете не позволяли делать даже то что в этой статье.

Бесплатный