Реализация простейшей стратегии инвестирования на базе API MOEX (Московской биржи)

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

Сущность стратегии: с помощью простейшего технического анализа в виде слежения за простыми скользящими средними вы находите точку смены тренда и продаете или покупаете актив. Я ни в коем случае не агитирую за то, чтобы вы сразу бросались и начинали торговать на бирже, потому что это 100% работает. Это работает только (!) в комплексе с пониманием фундаментальных процессов происходящих в компании.

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

nmubchb6f5wv1wx6uzxmzfb9lsm.jpeg

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

Второй вариант.
Также, у каждого инвестора есть подавленный спекулянт, и эта спекулятивная жилка периодически просыпается в каждом из нас. Конечно, лучше всего, если она просыпается в спокойное время, а не во время коррекции, когда мозг упорно убеждает «Продавай-продавай-продавай». Чтобы накормить нашего внутреннего спекулянта, мы можем пользоваться простейшей стратегией, которой пользуются очень многие трейдеры и в то же время она является достаточно простой и надежной. Стратегия «следования тренду» (описание). Может быть вы встречались ранее с этими терминами, например на рынке форекс или на других около рыночных ресурсах, но с точки зрения комбинации спекуляции + инвестирование есть существенное отличие, которое заставляет посмотреть на эту стратегию с другой стороны.

Приведу в пример парочку компаний за которыми я слежу и считаю их достаточно хорошими в фундаментальном смысле (хороший бизнес, отчетность, наличие дивидендов):
Пример 1: Enel
y2_tpotlm8bbmpjn-fg6i8ra9gi.jpeg
Пример 2: Аэрофлот
ca55kerwix1ttxdyccydhmkzd_8.jpeg
Красными кружками отмечены точки пересечения двух скользящих средних с разными периодами, что является сигналом к тому, что тренд достаточно крепкий и можно принимать решение о действии (покупки\продажи), в соответствии с фундаментальной обстановкой. Например, аэрофлот можно было бы продать на квартал, именно из за его последнего квартального отчета. Многим спекулянтам достаточно этого фактора, чтобы начать продажу. Для долгосрочного же инвестора это является сигналом к тому, что можно хорошо усреднить среднюю стоимость покупки (докупить бумагу по меньшей цене) или сделать ребалансировку.

Техническая часть.
Так как я не любитель просиживать штаны за терминалом, а мой брокер не предоставляет функций слежения за трендами, то я решил изучить доступное описание API Московской биржи, справочник запросов и написать скрипт, который будет информировать меня о смене тренда для интересующих меня инструментов (читать «всех ценных бумаг из которых состоит портфель») по почте.
Для начала был написан небольшой класс:

Код класса
class emitent {
    public $name;
    public $cost; //текущая цена
    public $trand; //направление тренда
    public $closeCost; //цена закрытия
    public $average50; //значение скользящей средней 50 дней
    public $average15; //значение скользящей средней 15 дней
    
    public function getPrice($emitent,$format){
        $uri = 'https://iss.moex.com/iss/engines/stock/markets/shares/securities/'.$emitent.$format;
        $result = file_get_contents($uri);
        $resultObject = json_decode($result,true);
        /* @var $resultObject type */
        $this->cost = $resultObject['marketdata']['data'][2][12];
        return $this->cost;
    }
 public function getAverage50($emitent,$format){
        $historyPrice = [];
        $historydata = [];
        $date1 = date("y-m-d",strtotime("-1 days"));
        $date2 = date("y-m-d",strtotime("-100 days"));
        $uri = 'https://iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/securities/'.$emitent.$format.'?from='.$date2.'&till='.$date1;
        $result = file_get_contents($uri);
        $resultObject = json_decode($result,true);
        $historydata = $resultObject['history']['data'];
        $historydata_reverse = array_reverse($historydata);
        for ($i=0;$i<50;$i++){
                array_push($historyPrice,$historydata_reverse[$i][11]);
        }
        $average50 = array_sum($historyPrice)/count($historyPrice);
        return $average50;
    }
    public function getAverage15($emitent,$format){
        $historyPrice = [];
        $historydata = [];
        $date1 = date("y-m-d",strtotime("-1 days"));
        $date2 = date("y-m-d",strtotime("-50 days"));
        $uri = 'https://iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/securities/'.$emitent.$format.'?from='.$date2.'&till='.$date1;
        $result = file_get_contents($uri);
        $resultObject = json_decode($result,true);
        $historydata = $resultObject['history']['data'];
        $historydata_reverse = array_reverse($historydata);
        for ($i=0;$i<15;$i++){
                array_push($historyPrice,$historydata_reverse[$i][11]);
        }
        $average15 = array_sum($historyPrice)/count($historyPrice);
        return $average15;  
    }
 }


Из тонких моментов, которые я взял из справочника:

https://iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/securities/


History — запрос цен из нужного периода времени
Stock — торговая система (engines) «Фондовый рынок и рынок депозитов»
Shares — конкретный рынок (markets) «Рынок акций»
TQBR — конкретный режим торгов (boards) «Т+ Акции и ДР»
Ответ сервера или json или xml. Вы получаете массив с данными. Данные в массиве могут варьироваться в зависимости от запроса, который вы посылаете. Описание полей массивов хранятся в тех же данных в блоке «COLUMNS». Значения — в блоке «DATA».
Полное описание всех полей, относящимся, например, к рынку акций, можно посмотреть на этой странице.(Кстати, нашел я это описание только при подготовке статьи).

Замечание. Если вы берете промежуток больше 100 дней, то там надо делать несколько запросов, перемещая указатель массива. Ситуация описана на последней странице Руководства Moex API


После этого был написан сам скрипт (за качество кода палками прошу не бить):

Код скрипта
require_once ($_SERVER["DOCUMENT_ROOT"].'/classes.php');
$file = 'portfolio.json'; //Сохраненные данные по прошлым трендам
$portfolio = json_decode(file_get_contents($file), true);
foreach ($portfolio as &$emitent) {
    $sending_mail = false;
    $emitentMoex = new emitent();
    $emitentMoex->name = $emitent[0];
    $emitentMoex->trand = $emitent[1];
    $format = '.json';
    $price     = $emitentMoex ->getPrice($emitentMoex->name, $format);
    $history15 = $emitentMoex ->getAverage15($emitentMoex->name, $format);
    $history50 = $emitentMoex ->getAverage50($emitentMoex->name, $format);
        if ($history15<$history50){
            $trend_course = "Тренд вниз";
            $trand_course_bool = false;
        } else {
            $trend_course = "Тренд вверх";
            $trand_course_bool = true;
        }
        if ($trand_course_bool != $emitentMoex->trand){
            $sending_mail = true;
            $trend_course .='. Тренд изменился';
            (boolean)$emitent[1] = $trand_course_bool; 
        }

        if ($sending_mail){
            $date = date("y-m-d");
            $headers  = "Content-type: text/html; charset=UTF-8 \r\n"; 
            $headers .= "From: Change trands alert \r\n"; 
            $message = "Эмитент: ".$emitentMoex->name."
"."Цена сейчас: ".$price. "
"."Средняя на 15: ".$history15."
"."Средняя на 50: ".$history50."
".$trend_course; mail("yourmail@box.com", 'test'.$date , $message,$headers); } } file_put_contents($file, json_encode($portfolio,true)); ?>


Он получает из массива json, лежащим в той же папке список тикеров и метку направления тренда. Запрашивает цены за указанные промежутки времени и высчитывает значения простых скользящих средних по формуле:

$\frac{\sum\limits_{i=1}^n P_i}{n}$


Где P — цена закрытия, а n — количество промежутков времени, за которые берутся значения цен.

пример массива
[
    ["GAZP",true],
    ["MTSS",true],
    ["FEES",false],
    ["ENRU",true],
    ["IRAO",0],
    .
    .
    .
    ["AFLT",0],
    ["LKOH",true],
    ["GMKN",true]
]


Далее определяет текущее направление в зависимости больше или меньше значение меньшей средней (15-тидневной) чем значение большой (50-тидневной). Сравнивает текущее направление с сохраненным и при изменении значения присылает оповещение на почтовый ящик.
Далее я открываю новости по тикеру и анализирую ситуацию.

Итог.
Биржа предоставляет доступ к информации бесплатно, с условием задержки в 20 минут. Для спекуляций внутри дня данные не подходят, но вот написать какие-либо инструменты, которые помогут принимать решения в среднесрочном периоде времени очень даже подойдут. С ходу, например, индикатор достижения целевой цены. Многие брокеры и консультанты выкладывают рекомендации по целевым ценам в открытый доступ и вы спокойно можете написать скрипт, который будет отслеживать цену. У yahoo.finance, например, этот инструмент сначала сломался, а потом его и вовсе убрали. Также, публичные зарубежные сервисы криво получают информацию о ценах наших эмитентов.

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

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

© Habrahabr.ru