Немного о тексте ниже

Самый ленивый портфельный инвестор обычно поступает так: идет к финансовому управляющему, они вместе составляют профиль инвестора и на основании этого профиля они собирают портфель из активов, которые соответствуют тем показателям риска\доходности, которые портфельный инвестор готов принять.
Если инвестор очень долгосрочный и портфель составлен правильно, то он может покупать бумаги в любое время и по любой цене, 10-тилетний временной промежуток сгладит разницу за счет див.выплат (конечно мы должны искать ценные бумаги с постоянным денежным потоком).
Рассмотрим ситуацию, в которой вам надо найти ценные бумаги (далее я буду подразумевать конкретный тип бумаг — акции, с облигациями все понятно, там купон), которые приносит в виде дивидендов денежный поток, удовлетворяющий вашему финансовому плану. Самый простой пример — найти акцию, денежный поток которой превышает значение инфляции, т.е. 4% (по данным Росстата)
Давайте рассмотрим второй фактор из этой пары риск/доходность — собственно доходность
Доходность акции – это показатель, который позволяет оценить, какую прибыль можно получить с момента приобретения ценной бумаги. Доходность может быть не только положительной, но и отрицательной – в том случае, когда акция принесла инвестору убыток. В общем виде доходность акции рассчитывает по следующей простой формуле:
Агрегаторы
Сразу приведу пару ресурсов, которые уже содержат в себе те данные, которые нам нужны. Там приведены данные по доходностям ценных бумаг и факторы, на которые надо обратить внимание при их покупке. Сам я тоже периодически заглядываю на эти ресурсы:Доход.ру и Инвестиционный раздел Смартлаба.
Вы можете спокойно пользоваться ими, я же поставил себе задачу автоматизировать некий процесс + иметь возможность работать с данными по дивидендным выплатам за некий возможный период времени.
Пишем парсер
Перебрав несколько вариантов, я остановился на phpQuery, хотя до этого попытался реализовать парсер на Simple HTML DOM. Результат обрабатывался очень долго, поэтому пришлось сменить. Данные парсим с сайта investfunds.ru
Код парсера
public function getDivsFromCode($code){ //код эмитента - номер эмитента на сайте, откуда берутся данные. include_once './phpQuery.php'; if ( $curl = curl_init () ) //инициализация сеанса { curl_setopt ($curl, CURLOPT_URL, 'http://stocks.investfunds.ru/stocks/'.$code.'/dividend/');//указываем адрес страницы curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl, CURLOPT_POST, true); curl_setopt ($curl, CURLOPT_HEADER, 0); $result = curl_exec ($curl);//выполнение запроса curl_close ($curl);//закрытие сеанса } $html = phpQuery::newDocumentHTML($result); phpQuery::selectDocument($html); $a = [1,3,5]; //номера столбцов из которых надо извлечь данные(год, дата выплаты и сумма) $emitent_string = htmlentities(pq('h1')->text(),ENT_COMPAT,'UTF-8'); if ($emitent_string === ""){ $divs['emitent'] = 'Нет эмитента'; return $divs; } $re = [' акция привилегированная, Дивиденды', ' акция обыкновенная, Дивиденды',' акция обыкновенная',' акция привилегированная']; $emi = str_replace($re,'',$emitent_string); $divs['emitent'] = $emi; $divs['code'] = $code; /*находим количество лет, когда выплачивали дивы*/ $i = pq('[cellpadding="0"] tr td:nth-child(1)'); $l = substr_count($i,'td style'); /*помечаем, что эмитент не выплачивал дивы*/ if ($l === 0){ $divs['data']= 'No divs'; return $divs; } /******играемся с регулярными выражениями и css************************/ for ($i =3;$i<$l+3;$i++){ foreach ($a as $j){ switch ($j) { case 1: $divs['data'][$i-2]['year'] = str_replace(' ','',htmlentities(pq("[cellpadding='0'] tr:nth-child($i) td:nth-child($j)")->text(),ENT_COMPAT,'UTF-8')); break; case 3: $divs['data'][$i-2]['date'] = str_replace(' ','',htmlentities(pq("[cellpadding='0'] tr:nth-child($i) td:nth-child($j)")->text(),ENT_COMPAT,'UTF-8')); break; case 5: $string = htmlentities(pq("[cellpadding='0'] tr:nth-child($i) td:nth-child($j)")->text(),ENT_SUBSTITUTE,'UTF-8'); $re = '/[ \s]|[руб]/'; $divs['data'][$i-2]['price'] = (float)preg_replace($re,'',$string); break; default: break; } } } /*возвращаем массив, который содержит в себе название эмитента, год выплаты, дату выплаты и сумму выплаты */ return $divs; }
результатом работы функции будет массив с данными по одному эмитенту. Далее, я импортирую результат в companies.json
импорт
$divs = $emitent->getDivsFromCode($i); if ($divs['emitent'] != 'Нет эмитента'){ array_push($json_div, $divs); } } file_put_contents('companies_part1.json',json_encode($json_div,JSON_UNESCAPED_UNICODE));
Пример массива
[{"emitent":"АВТОВАЗ, (RU0009071187, AVAZ)", "code":3, "data": {"1": {"year":"2007","date":"16.05.2008","price":0.29}, "2": {"year":"2006","date":"06.04.2007","price":0.1003}, "3": {"year":"2005","date":"07.04.2006","price":0.057} } }]
Минусы парсера: сначала я думал, что придется спарсить около 1000 страниц, потому что после 800 мне стали попадаться только доп.эмиссии. Но потом, не найдя одного из эмитентов, я решил продолжить парсинг и выяснилось, что даже и после 5к страниц может что-то попадаться. Решение — переписать парсер с использованием multicurl для скорости обработки. До этого у меня руки не дошли (начал читать), но по правильному, стоило бы поступить именно так. Может кто-то из читателей мне поможет. Опять же, базу с дивами можно обновлять раз в пол года. Этого хватит, если вы оперируете годовыми доходностями.
Высчитываем норму доходности и полную доходность акции с момента покупки
Формулу я уже привел выше. Для автоматизации я написал скрипт, который использует исходные данные, вводимые вручную и считает требуемые показатели.
$name = 'GAZP'; //Тикер эмитента $year_buy = 2015; //Год покупки актива $buy_price = 130; //Цена покупки актива $year_last_div = 2016; //Год последних выплаченных диви $v_need = 4; //требуемая доходность
Для удобства я написал небольшую функцию. которая по тикеру находит данные эмитента в json
Поиск по тикеру
public function getDivsFromName($name){ $file = file_get_contents('companies.json'); $array = json_decode($file,true); foreach ($array as $emitent) { if ((stristr($emitent['emitent'],$name))&&(!stristr($emitent['emitent'],$name.'-'))){ return $emitent; } } }
Теперь мы можем посчитать интересующие нас данные. Для получения текущей цены (переменная $today_price) я использую функцию, в которой я писал в своем предыдущем посте и которая использует API Московской биржи. Все формулы взяты из вот этой статьи.
$emitent = new emitent(); $v_today; //Текущая норма прибыли; $v_need = $v; //Требуемая норма доходности; $div = $emitent->getDivsFromName($name); $sum = $emitent->getSumDivs($year_buy, $div); $last_div = $emitent->getSumDivs($year_last_div, $div,1); //Считаем доходность c момента покупки /*r = (D + (P1 - P0))/P0 * 100% * P0 - цена покупки * P1 - цена продажи * D - сумма дивидендов * */ $today_price = $emitent->getPrice($name, '.json'); $r = ($sum + ($today_price-$buy_price))/$buy_price*100; $v_today = $last_div/$today_price*100; $P = ($last_div/$v_need)*100; //целевая цена покупки
Теперь немного анализа получившихся результатов. Для примера я беру две крупных компании, входящих INDEX MSCI RUSSIA
Газпром

и Алроса (Допустим, мы ее брали по 60р. в 2015 году.)

Как видите, несмотря на то, что цена акции газпрома практически не отличается от цены покупки, мы все равно имеем доходность 12% за счет дивидендов. У Алросы дела обстоят еще лучше. Можем пересчитать для доходности ставок по депозитам с сайта банки.ру из списка банков top-50. Сейчас банки дают нам 6,5%

Соответственно, так вы можете, варьируя нужную норму доходности, понять удовлетворяет ли текущая цена акции вашим запросам и вашим финансовым целям.
Замечу, что как и в прошлой статье, это лишь нахождение одного из факторов, влияющих на принятие решения.
Многие инвесторы делают вышеописанные расчеты в Excel. Этот инструмент предоставляет множество формул для расчетов прибыли, денежных потоков и т.д. Но я ставил целью автоматизировать сбор данных по дивидендам и автоматизированную обработку этих данных.
Статья в этот раз включает меньше теории и больше кода потому, что теория очень обширна, а привязать данную задачу к общей теории построения портфеля — надо писать цикл статей. Да и формат Хабра не подразумевает написание чисто инвестиционных статей, тем более сейчас на просторах сети их огромное множество.
Предыдущая статья
Спасибо за внимание!
