tag:blogger.com,1999:blog-52531970499475322032024-02-07T14:13:36.697+03:00Тимур Гильмуллин про автоматизацию и процессыСтатьи по автоматизации разработки и тестирования, построение процессов и карьерный рост. DevOps и SecDevOps. Алгоритмический трейдинг и автоматизация торгов на бирже.Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comBlogger67125tag:blogger.com,1999:blog-5253197049947532203.post-5008772168325075322023-02-13T20:26:00.000+03:002023-02-13T20:26:24.407+03:00Детектор аномальных объёмов — анализируем спрос и предложение с помощью платформы TKSBrokerAPI<p></p><div class="separator" style="clear: both; text-align: left;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/media/TKSBrokerAPI-Logo-mini.png?raw=true" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="799" data-original-width="800" height="64" src="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/media/TKSBrokerAPI-Logo-mini.png?raw=true" width="64" /></a>Автоматизация различных операций на бирже сегодня очень популярная тема. Автоматизировать можно всё, что угодно: подготовку отчётов, визуализацию графиков, получение истории цен по выбранному инструменту, совершение торговых операций по заранее заданному алгоритму, оповещения о событиях на рынке и многое другое.</div><p></p><p>В частности, трейдерам бывает интересно автоматически анализировать биржевой стакан текущих цен. Им нужно получать оперативные оповещения о появлении в нём аномальных (относительно других значений) объёмов предложений продавцов или покупателей. Существует гипотеза о том, что если на рынке в текущий момент времени преобладают объёмы покупателей, а также появились большие или сверхбольшие предложения на покупку, то цена инструмента будет расти в краткосрочной перспективе, или, как минимум, не будет падать ниже этих предложений. И, тоже самое, но наоборот: если преобладают объёмы продавцов и в них присутствуют аномальные значения, то цена будет снижаться или не будет расти.</p><p>Следующий скриншот иллюстрирует стакан цен с объёмами предложений продавцов и покупателей, которые трейдер визуально может принять за аномалии:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/media/AnomalyVolumes-example-RU.png?raw=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="800" data-original-width="800" height="640" src="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/media/AnomalyVolumes-example-RU.png?raw=true" width="640" /></a></div><p>Но как же их определять автоматически?<span></span></p><a name='more'></a><p></p><p>Теоретические основы детектирования аномалий можно изучить в предыдущей статье: «<a href="https://forworktests.blogspot.com/2022/12/blog-post.html" rel="nofollow" target="_blank">Как быстро найти аномалии в числовых рядах с помощью метода Хампеля</a>», а также посмотреть практические примеры в <a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb" rel="nofollow" target="_blank">юпитер-ноутбуке</a>. Этот метод хорошо себя зарекомендовал на практике для быстрого анализа числовых рядов на наличие в них аномальных выбросов. Объёмы предложений в стакане цен — это тоже числовые ряды, а значит метод Хампеля может быть применён и к ним.</p><p>Для автоматизации поиска аномалий в объёмах понадобятся: Python (3.9, либо старше), библиотека <a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop" rel="nofollow" target="_blank">TKSBrokerAPI</a> (для работы с API брокера <a href="https://tinkoff.ru/sl/AaX1Et1omnH" rel="nofollow" target="_blank">Тинькофф Инвестиции</a>) и известная сетевая библиотека requests (для отправки сообщений через API Телеграм). На выходе может получиться, например, такой скрипт: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/AnomalyVolumesDetector/TKSAVDetector.py" rel="nofollow" target="_blank">TKSAVDetector.py</a>.</p><p><b><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop/docs/examples/AnomalyVolumesDetector" rel="nofollow" target="_blank">Детектор аномальных объёмов</a></b> — это простой Телеграм бот для анализа объёмов спроса и предложения покупателей и продавцов.</p><p>Бот следит за объёмами покупателей и продавцов в биржевом стакане, ищет аномалии в числовом ряду объёмов и оповещает о них в Телеграм. Оповещение содержит: текущую цену инструмента и цены с аномальными объёмами.</p><h1 style="text-align: left;">Концепция</h1><p>Основные шаги работы детектора аномальных объёмов:</p><p></p><ol style="text-align: left;"><li>Скрипт выходит на рынок по расписанию, например, в формате crontab:<br /><span style="font-family: courier;">timeToWork: "*/2 10-21 * * 1-5"<br /></span>что означает, c 10:00 утра до 22:00 вечера (включительно) в будние дни, каждые 2 минуты. Можно посмотреть другие примеры <a href="https://crontab.guru/#*/2_10-21_*_*_1-5" rel="nofollow" target="_blank">по ссылке</a>.<br /><br /></li><li>В параллельном (мультипроцессном) конвейерном режиме скрипт запрашивает данные по состоянию биржевого стакана по указанным инструментам и с указанной глубиной стакана (<span style="font-family: courier;">depth <= 50</span>).<br /><br /></li><li>Для каждого стакана скрипт ищет все текущие аномалии в объёмах продавцов и покупателей (фильтрация <a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb" rel="nofollow" target="_blank">методом Хампеля</a> по всей длине числового ряда текущего стакана).<br /><br /></li><li>Если список аномалий по инструменту получился не пустой, то скрипт формирует оповещение, например, такого вида:<br /><br /><span style="font-family: courier;">Обнаружены аномальные объёмы<br />продавцов и покупателей:<br /> - [YNDX] [Shares] [Yandex]<br /> - Время обнаружения:<br /> 2023-01-29 14:49:31 UTC<br /> - Есть в портфеле: Нет<br /><br /> - Текущая цена/объём/стоимость<br /> - Купить:<br /> [0] 1927.6/4/7710.4 руб<br /> - Продать:<br /> [0] 1915.9/4/7663.6 руб<br /><br /> - Аномалии<br /> - в объёмах продавцов:<br /> [0] 1927.6/4/7710.4 руб<br /> [3] 1928.2/6/11569.2 руб<br /> - в объёмах покупателей:<br /> [0] 1915.9/4/7663.6 руб<br /> [1] 1915.7/6/11494.2 руб<br /><br />Сгенерировано ⚙️ TKSBrokerAPI</span><br /><br /></li><li>Скрипт подключается к указанному ТГ-боту по токену и отправляет через него оповещение (не обязательно, так как можно следить за информацией в логах и без оповещений):<br /><br /><div class="separator" style="clear: both; text-align: left;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/raw/develop/docs/media/AnomalyVolumesDetector-TG-example-RU.jpg?raw=true" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="800" data-original-width="364" height="640" src="https://github.com/Tim55667757/TKSBrokerAPI/raw/develop/docs/media/AnomalyVolumesDetector-TG-example-RU.jpg?raw=true" width="291" /></a></div></li></ol><p></p><p>Подробнее о настройке и запуске бота вы можете прочитать <a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop/docs/examples/AnomalyVolumesDetector#описание" rel="nofollow" target="_blank">в инструкции</a>. На этом пример анализа объёмов закончен, а в следующих статьях расскажу, какие ещё биржевые операции можно автоматизировать при помощи модуля <a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop" rel="nofollow" target="_blank">TKSBrokerAPI</a>.</p><p><br /></p><b>Упоминаемые в статье ссылки</b><p></p><ul style="text-align: left;"><li>Статья «Как быстро найти аномалии в числовых рядах с помощью метода Хампеля»:<br /><a href="https://forworktests.blogspot.com/2022/12/blog-post.html" rel="nofollow" target="_blank">https://forworktests.blogspot.com/2022/12/blog-post.html</a></li><ul><li>(EN) «How to quickly find anomalies in number series using the Hampel method»:<br /><a href="https://forworktests.blogspot.com/2023/01/how-to-quickly-find-anomalies-in-number.html" rel="nofollow" target="_blank">https://forworktests.blogspot.com/2023/01/how-to-quickly-find-anomalies-in-number.html</a></li></ul><li>Юпитер-ноутбук с практическими примерами детектирования аномалий методом Хампеля:<br /><a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb" rel="nofollow" target="_blank">https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb</a></li><ul><li>(EN) Jupyter Notebook:<br /><a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample_EN.ipynb" rel="nofollow" target="_blank">https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample_EN.ipynb</a></li></ul><li>TKSBrokerAPI — это платформа для упрощения автоматизации торговых сценариев на Python и работы с Tinkoff Invest API сервером через REST-протокол:<br /><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop" rel="nofollow" target="_blank">https://github.com/Tim55667757/TKSBrokerAPI/tree/develop</a></li><li>Детектор аномальных объёмов (Anomaly Volumes Detector):<br /><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop/docs/examples/AnomalyVolumesDetector">https://github.com/Tim55667757/TKSBrokerAPI/tree/develop/docs/examples/AnomalyVolumesDetector</a></li></ul><div><br /></div><div>______________________________</div><div><br /></div><div>Подписывайтесь на меня в Пульсе (профиль: <a href="https://www.tinkoff.ru/invest/social/profile/TimurGilmullin/" rel="nofollow" target="_blank">TimurGilmullin</a>), буду рассказывать там про автоматизацию на бирже и разработку торговых роботов.</div><div><br /></div><div>Если вы хотите упростить свои рутинные операции на бирже — закажите автоматизацию у меня. Пишите, обсудим вашу задачу и чем я могу помочь. Контакт в Телеграм: <a href="https://t.me/tgilmullin" rel="nofollow" target="_blank">@tgilmullin</a>.</div><div><i><b><br /></b></i></div><div><i><b>Поддержите разработку платформы TKSBrokerAPI: <a href="https://yoomoney.ru/to/410015019068268" rel="nofollow" target="_blank">https://yoomoney.ru/to/410015019068268</a></b></i></div><div><br /></div><div>🚀 Успехов вам в автоматизации биржевой торговли! И профита!</div><p></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-17064274934372050232023-02-11T12:55:00.001+03:002023-02-11T13:07:26.341+03:00Как сделать +16% на бирже за 2 часа? Помогут роботы!<p>Всем привет! Недавно я упоминал про REST API от <a href="https://tinkoff.ru/sl/AaX1Et1omnH" target="_blank">Тинькофф Инвестиции</a> и про платформу ⚙️<a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/README.md" rel="nofollow" target="_blank">TKSBrokerAPI</a> на Python, для упрощения автоматизации работы с биржей через брокера Тинькофф. Сам я тоже использую эту платформу: для получения кастомных отчётов и автоматизации трейд-роботов и различных ботов-оповещалок.</p><p>На этой неделе очень порадовал <a href="https://www.tinkoff.ru/invest/social/profile/TimurGilmullin/677d40b1-aeb4-434a-afa3-b6541f2257ab/" rel="nofollow" target="_blank">$KROT</a>, который последние дни невероятно волатилен (в том числе из-за новостей об ограничениях биржи на бумаги <a href="https://www.tinkoff.ru/invest/social/profile/Tinkoff_Investments/de96396a-5947-47c1-91ba-c24984b67e50/" rel="nofollow" target="_blank">третьего эшелона</a>), но зато хорошо подходит для тестов, спасибо ему за это! А также порадовал алгоритм моего нового торгового робота в основе которого используется ⚙️<a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/README.md" rel="nofollow" target="_blank">TKSBrokerAPI</a>: впервые удалось протестировать его на сильных движениях и заметить в телеметрии, что он достаточно неплохо поймал второй откат на пятиминутках, самостоятельно вошёл в позицию, дождался хорошей возможности и вышел в плюс (изобразил это на графике ниже).</p><p>На одном лоте получилось более +16% прибыли, 280 рублей разницы в цене и 2800 руб. профита 🙂 Неплохой результат, так как до этого рынок был, в основном, спокойный и удавалось поймать роботом не более +0.5-1.5% за сделку. Поэтому я долгое время не знал, как он себя поведёт при сильных движениях, сможет ли дождаться большей прибыли и устоит ли на волатильном рынке. Сейчас убедился на тестовом счёте, что сможет 😊</p><p>Про трейд-робота, алгоритмы и торговые сценарии расскажу чуть позже, а пока сохраню себе на память записи телеметрии:</p><p></p><ul style="text-align: left;"><li><span style="font-family: courier;">10:25 UTC "message": "BUY-стоп выставлен по цене первого покупателя: [1695 rub], лотов: [1]"</span></li><li><span style="font-family: courier;">12:04 UTC "message": "SELL-маркет исполнен по [1975 rub], ср. [1695 rub], лотов [1], профит 16.52%"</span></li></ul>Конечно же, любому роботу нужна (авто-)оптимизация, потому что далее через пару часов, если посмотреть график $KROT за 9.02.2023, можно было выйти ещё рублей на 200 выше, но робот этого уже не дождался.<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEistFmCJsQCOppidMHD-F2aU9TqAqixjznNEulwNMSnqCZLRjbXxDXmZYBzH3TQyDmbD38pwT7Yx7t8JgfkFCMx_G8o9ofi0snd5KxiLqdGjImEi_1YAo47nBdqqfxBWNmq4HK0kXpYtsyAe0cndo0lEIg5Dm-k5SL8HSQXdLfNWWYMnwFp72Blh4DElA/s1741/image_2023-02-09_15-16-03.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="896" data-original-width="1741" height="330" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEistFmCJsQCOppidMHD-F2aU9TqAqixjznNEulwNMSnqCZLRjbXxDXmZYBzH3TQyDmbD38pwT7Yx7t8JgfkFCMx_G8o9ofi0snd5KxiLqdGjImEi_1YAo47nBdqqfxBWNmq4HK0kXpYtsyAe0cndo0lEIg5Dm-k5SL8HSQXdLfNWWYMnwFp72Blh4DElA/w640-h330/image_2023-02-09_15-16-03.png" width="640" /></a></div><p>Подписывайтесь на меня в Пульсе (профиль: <a href="https://www.tinkoff.ru/invest/social/profile/TimurGilmullin/" rel="nofollow" target="_blank">TimurGilmullin</a>), буду рассказывать там про автоматизацию на бирже и разработку торговых роботов.</p><p>Если вы хотите упростить свои рутинные операции на бирже — закажите автоматизацию у меня, пишите, обсудим вашу задачу и чем я могу помочь. Контакт в Телеграм: <a href="https://t.me/tgilmullin" rel="nofollow" target="_blank">@tgilmullin</a>.</p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-11920943674850943252023-01-07T13:10:00.001+03:002023-01-07T14:07:52.066+03:00How to quickly find anomalies in number series using the Hampel method<p style="text-align: right;"></p><div style="text-align: right;"><span style="text-align: left;">Translated from Russian. The original article is here</span><span style="font-family: inherit;">:</span></div><span style="font-family: inherit;"><div style="text-align: right;"><a href="https://forworktests.blogspot.com/2022/12/blog-post.html" rel="nofollow" style="font-family: inherit;" target="_blank">https://forworktests.blogspot.com/2022/12/blog-post.html</a></div></span><p></p><p><span style="font-family: inherit;">In practice, there are issues for the solution of which it is required
to find anomalies in the numerical series. For ease of understanding, we can
assume that these are values that differ from most numbers in the series in
some way (outlier, non-standard value, deviation from the norm). Such tasks are
found in various areas:</span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 3.0pt; margin-left: 36.0pt; margin-right: 0cm; margin-top: 0cm; margin: 0cm 0cm 3pt 36pt; mso-list: l4 level1 lfo1; tab-stops: list 36.0pt; text-indent: -36pt;"></p><ul style="text-align: left;"><li><span style="font-family: inherit;"><span lang="EN-US" style="color: #333333;">cleaning of noisy data in </span><a href="https://en.wikipedia.org/wiki/Data_science" target="_blank"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">Data Science</span></a><span lang="EN-US" style="color: #333333;">;<o:p></o:p></span></span></li><li><span style="font-family: inherit;"><span lang="EN-US" style="color: #333333;">outlier filtering in the training sample for neural
networks in </span><a href="https://en.wikipedia.org/wiki/Machine_learning" target="_blank"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">Machine Learning</span></a><span lang="EN-US" style="color: #333333;">;<o:p></o:p></span></span></li><li><span style="font-family: inherit;"><span lang="EN-US" style="color: #333333;">search for abnormal network hacker activity, while
monitoring traffic and events in </span><a href="https://en.wikipedia.org/wiki/Cyber_security" target="_blank"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">Cybersecurity</span></a><span lang="EN-US" style="color: #333333;">;<o:p></o:p></span></span></li><li><span style="font-family: inherit;"><span lang="EN-US" style="color: #333333;">detection of outliers or tails in the stock data
stream in </span><a href="https://en.wikipedia.org/wiki/Algorithmic_trading" target="_blank"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">Algorithmic Trading</span></a><span lang="EN-US" style="color: #333333;">;<o:p></o:p></span></span></li><li><span style="font-family: inherit;"><span lang="EN-US" style="color: #333333;">as well as in any anomaly search tasks, where data can
be presented as a numerical series.</span></span></li></ul><p></p>
<p class="MsoNormal"><span lang="EN-US" style="line-height: 107%;"><span style="font-family: inherit;">The concepts of a number series in mathematical analysis and in
statistics are different. We accept a numerical series as its statistical
understanding, that is, a finite sequence of numbers (analogous to a sample).
There are various interpretations of the anomaly in the numerical series. We
will consider them further.</span></span></p><p class="MsoNormal"><span lang="EN-US" style="line-height: 107%;"><span>The article also shows examples of how to find anomalies quickly and efficiently in numerical series using the modified <b>Hampel method </b>(Hampel F.R.).</span></span></p><p class="MsoNormal"><a name="_Hlk123061868"><span lang="EN-US" style="line-height: 107%;"><span style="font-family: inherit;"><span></span></span></span></a></p><a name='more'></a><a name="_Hlk123061868"><span lang="EN-US" style="line-height: 107%;"><span style="font-family: inherit;"><o:p></o:p></span></span></a><p></p>
<h3 style="text-align: left;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;"><span style="font-family: inherit;">The concept of the
number series anomaly</span></span></span></h3>
<p class="MsoNormal"><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;">For one-dimensional
data, outlier estimation is extensively researched in the statistical
literature. Traditionally, the most useful estimates for characterizing the
variance of data are the </span></span><a href="https://en.wikipedia.org/wiki/Sample_mean_and_covariance" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; line-height: 107%; text-decoration: none;">sample
mean</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;"> and </span></span><a href="https://en.wikipedia.org/wiki/Variance" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; line-height: 107%; text-decoration: none;">variance</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;"> of the sample. They give a good estimate of the
location and scatter of the data in the sample, but only if the outliers
"do not pollute" it. Even if the data contains only one observation
that is significantly different from the rest in the sample, then the sample
mean can also deviate significantly from the sample mean without this outlier.<o:p></o:p></span></span></span></p>
<p class="MsoNormal"><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;">To measure the
robustness of a chosen statistical estimation method against outliers, Hampel
introduced the concept of a </span></span><a href="https://en.wikipedia.org/wiki/Robust_statistics#Breakdown_point" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; line-height: 107%; text-decoration: none;">breakdown point</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;">. The <b><i>breakdown point</i></b> is the largest
percentage of "polluted data" (the proportion of incorrect
observations or outliers) that the chosen method can process before it starts
to produce an incorrect result. These can be arbitrarily large aberrant
(abnormal, erroneous) values.<o:p></o:p></span></span></span></p>
<p class="MsoNormal"><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;">Intuitively, one can
understand that the breakdown point cannot exceed 50%, because if more than
half of the observations are "polluted", then it is impossible to
distinguish the main distribution of the series from the polluting
distribution. Therefore, the maximum outlier fraction for the breakdown point
is 0.5. There are examples of statistics that reach the maximum value for the breakdown
point. For example, it is 0.5 for </span></span><a href="https://en.wikipedia.org/wiki/Median" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; line-height: 107%; text-decoration: none;">Median</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;">. And for the sample mean, it is equal to 1/n, where n
is the sample size.<o:p></o:p></span></span></span></p>
<p class="MsoNormal"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;"><span style="font-family: inherit;">It is generally
believed that the higher the breakdown point value, the more reliable the
statistical evaluation method. A statistic with a high breakdown point value is
sometimes called a robust (resistant) statistic.<o:p></o:p></span></span></span></p>
<p class="MsoNormal"><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;">To estimate more
reliably the location and scatter of sample elements, it is often recommended
to combine the Median and the </span></span><a href="https://en.wikipedia.org/wiki/Median_absolute_deviation" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; line-height: 107%; text-decoration: none;">Median
Absolute Deviation</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;"> (MAD). It is they
that underlie the method of filtering the sample for outliers according to
Hampel <b>[1]</b>.<o:p></o:p></span></span></span></p>
<p class="MsoNormal"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="line-height: 107%;"><span style="font-family: inherit;">The <b>MAD </b>value is
calculated like this:<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">MAD (X) =
Median <b>(</b> | x<sub>1</sub> − Median (X) | , …,
| x<sub>n</sub> − Median (X) | <b>)</b>,
<b>(
1 )</b><o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">where X is
a sample of n observations x<sub>1</sub>, …, x<sub>n</sub>.<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">According
to Hampel, a <i><b><a href="https://en.wikipedia.org/wiki/Outlier" rel="nofollow" target="_blank">sample </a></b></i></span></span><span style="mso-bookmark: _Hlk123061868;"><i><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;"><b><a href="https://en.wikipedia.org/wiki/Outlier" rel="nofollow" target="_blank">outlier</a></b></span></i></span><span style="mso-bookmark: _Hlk123061868;"><b><i><span lang="EN-US"> </span></i></b></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">is a number x from a sample X, the modulus
of the difference of which and the sample median is greater than the MAD of the
sample, calculated by formula (1) and multiplied by a special coefficient k (</span></span><a href="https://en.wikipedia.org/wiki/Scale_parameter#Estimation" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">scale factor</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">), depending on the distribution (≈1.4826
for normal) <b>[2]</b>.<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">In
practice, to build a Hampel outlier filter, this definition is modified using </span></span><a href="https://www.geeksforgeeks.org/window-sliding-technique/" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">sliding windows</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> and the parameter s (</span></span><a href="https://en.wikipedia.org/wiki/Standard_deviation" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">sigma</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">), a threshold number of standard deviations. This means that the median
and MAD are calculated for all sliding windows consisting of the elements of
the sample. Further, all modules of the difference between the elements of the
sample and the median are compared with MAD, multiplied by the coefficient k
and multiplied by the parameter s <b>[3]</b>.</span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="mso-ansi-language: EN-US;"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">A higher standard deviation threshold s
makes the filter more sparing; a lower threshold identifies more numbers as
outliers.<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Now let's
define the basic concept: what we mean by an anomaly in a finite number series
for practical issues.<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><b><span lang="EN-US">Definition 1.</span></b></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> The <b><i>anomaly of a number series</i></b> is a number x from the
series X, which modulo differs from the median of the sliding window by more
than s times from the MAD of this window, multiplied by the coefficient k.<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">To
generalize the anomaly filter as much as possible and abstract it from the practical issue being solved, we propose the following set-theoretic interpretation.<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">All
anomalies of the series form some of its subset A:<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">A = <b>{</b> a <b>|</b> |
a − Median (X<sub>i</sub>) | > s ∙ k ∙ MAD (X<sub>i</sub>) <b>}</b>,
<b>( 2 )</b><o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">where a is
an anomalous element from X calculated according to Definition 1, X is the
initial number series, X<sub>i</sub> is the number series of the
i-th sliding window, total windows: (n − w + 1), where w is the window size.<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><b><i><span lang="EN-US">The anomalies filter of the number series</span></i></b></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> is defined as a function:<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">F:
X → { True, False }. F (x<sub>i</sub>) = True, if x<sub>i</sub> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">∈</span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> A; False, if x<sub>i</sub> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">∉</span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> A.</span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> </span></span><span style="mso-bookmark: _Hlk123061868;"><b>(
3 )</b></span><span style="mso-bookmark: _Hlk123061868;"><o:p></o:p></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Here X is
the original number series consisting of n elements x<sub>i</sub>, A is
the set of anomalies (2).<o:p></o:p></span></span></span></p>
<h3 style="text-align: left;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Filtering the number series for anomalies by the Hampel method</span></span></span></h3>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">To filter
a number series for the presence of anomalies in it, it is proposed to use the
Python implementation of the </span></span><a href="https://github.com/Tim55667757/TKSBrokerAPI/commit/312b3022df69aad85f0110eb06f609cc815c23db#diff-2a061adbfc8570a3c83bfcf27ee921b75c7ccbc5f0ebc4397910e8fed6f040e7R268-R332" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">HampelFilter()</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span class="MsoHyperlink"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;"> </span></span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">function. This function allows you to
detect anomaly among the values of any number series using the Hampel filtering
method. The filter detects anomalies determined according to (2). Configurable
parameters in this filter function: window (variable w from the formulas above)
— size of the sliding window (5 by default), sigma (variable s) — threshold number
of standard deviations (3 by default), scaleFactor (variable k) — special
coefficient, depending on the distribution of the series (</span></span></span>1.4826<span style="font-family: inherit;"> by default).</span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">The
HampelFilter() filtering function returns a new series F, according to
(3) consisting of True or False values, where True means the presence of an
anomalous element at the corresponding position in the original series.<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><b><span lang="EN-US"><span style="font-family: inherit;">Input examples and results, HampelFilter(window=5, sigma=3,
scaleFactor=1.4826)<o:p></o:p></span></span></b></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: courier;">Input data Function output<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: courier;">[10, 10,
10, 10, 10] [False, False, False, False, False]<br />
[1, 10, 10, 10, 10] [True, False, False, False,
False]<br />
[1, 5, 10, 10, 10] [True, True, False, False,
False]<br />
[1, 5, 1, 1, 1] [False, True, False,
False, False]</span><span style="font-family: inherit;"><o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><b><span lang="EN-US"><span style="font-family: inherit;">Input examples and results, HampelFilter(window=3, sigma=3,
scaleFactor=1.4826)<o:p></o:p></span></span></b></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: courier;">Input data Function output<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: courier;">[1, 5, 1,
1, 1] [False, True, False, False,
False]<br />
[1, 10, 10, 1, 10, 1] [True, False, False, False, False,
False]<br />
[1, 10, 10, 10, 10, 1] [True, False, False, False, False,
True]<br />
[1, 1, 1, 10, 10, 10] [False, False, False, False, False,
False]</span><span style="font-family: inherit;"><o:p></o:p></span></span></span></p>
<h3 style="text-align: left;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Finding the index of the first anomalous element</span></span></span></h3>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">In
practice, it is often necessary to determine only the first anomalous or the
first among the largest elements in the number series. To do this, you can
use the Python implementation of the </span></span><a href="https://github.com/Tim55667757/TKSBrokerAPI/commit/65afba0d65c454b2c401fea799586bd17734d9c2#diff-2a061adbfc8570a3c83bfcf27ee921b75c7ccbc5f0ebc4397910e8fed6f040e7R338-R386" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">HampelAnomalyDetection()</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span class="MsoHyperlink"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;"> </span></span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">function. This function returns the
minimum index of an element in the list of found anomalies, or the index of the
first maximum element in the input series if its index is less than the index
of the anomalous element. If there are no anomalies in the number series, or if
all elements are equal (no maximums), then None is returned.<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><b><span lang="EN-US">Input examples and results, HampelAnomalyDetection() with default values</span></b></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: courier;">Input data Function output<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: courier;">[1, 1, 1,
1, 111, 1] 4<br />
[1, 1, 10, 1, 1, 1] 2<br />
[111, 1, 1, 1, 1, 1] 0<br />
[111, 1, 1, 1, 1, 111] 0<br />
[1, 11, 1, 111, 1, 1] 1<br />
[1, 1, 1, 111, 99, 11] 3<br />
[-111, 1, 1, 1, 1] 0<br />
[1, 2, 1, -1, 1] 1<br />
[1]
None<br />
[1, 2]
None<br />
[1, 1, 1, 1, 1, 1] None</span><span style="font-family: inherit;"><o:p></o:p></span></span></span></p>
<h3 style="text-align: left;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Filtering stock prices for anomalies</span></span></span></h3>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">You can
see the use of the above functions using the example of the task of finding
outliers in stock data. To do this, we generated time series with data similar
to random stock prices and anomalies in them using the </span></span><a href="https://github.com/Tim55667757/PriceGenerator" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">PriceGenerator</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span class="MsoHyperlink"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;"> </span></span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">library, and then applied these functions
to the data. The functions themselves are in the </span></span><a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/README_EN.md" rel="nofollow" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">TKSBrokerAPI</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"> library (it contains </span></span><a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/tksbrokerapi/TradeRoutines.py" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">TradeRoutines</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span class="MsoHyperlink"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;"> </span></span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">module).<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">The
solution to the issue was implemented on Jupyter Notebook: </span></span><span style="mso-bookmark: _Hlk123061868;"></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="text-decoration: none;"><a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample_EN.ipynb" rel="nofollow" target="_blank">HampelFilteringExample.ipynb</a></span></span><span style="mso-bookmark: _Hlk123061868;"></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">. After analysis by the Hampel method anomalies on the price chart can
be marked, for example, as shown in the illustration below.</span></span></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizugx8n_g0JoKf7tb01zvo1YtRqhAnzWFA_hPlx4-_altH46FMUq_ov_3S3BJI-CL88AIlyqtHOwjfigul6gmVJA3iOZ8m-EVY4prG5P6OpgFcjMc-GHhYTOz1KBSALwaKCcbeV1XfglCUKud-x-AV95a1uPrYTOhCkitfmI4BgEkCtaW9eoqlAs94tQ/s1825/HampelFilteringExample.png" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" data-original-height="955" data-original-width="1825" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizugx8n_g0JoKf7tb01zvo1YtRqhAnzWFA_hPlx4-_altH46FMUq_ov_3S3BJI-CL88AIlyqtHOwjfigul6gmVJA3iOZ8m-EVY4prG5P6OpgFcjMc-GHhYTOz1KBSALwaKCcbeV1XfglCUKud-x-AV95a1uPrYTOhCkitfmI4BgEkCtaW9eoqlAs94tQ/w640-h334/HampelFilteringExample.png" width="640" /></span></a></div>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">As can be
seen with the naked eye, there are clearly outliers in the series, tails at the
top and bottom of some candles. We are not interested in all such outliers, but
only in tails that are too long. For us, these are signs of a price anomaly.
The Hampel filter coped with the detection of anomalies in a series of 75
candles with a sliding window value equal to the series size, the
number of standard deviations equal to 3 (sigma parameter) and a constant
coefficient characterizing the normal distribution equal to 1.4826 (scale
factor parameter). Similarly, you can analyze for anomalies the size of the
bodies of the candles.<o:p></o:p></span></span></span></p>
<h3 style="text-align: left;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Conclusions</span></span></span></h3>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Of course,
Hampel's method also has its drawbacks. For example, when implementing the
algorithm, one may encounter the fact that the anomalies present in the first
and last elements of the series according to the original algorithm will be
ignored. This is due to the use of a sliding window. To workaround the issue,
we had to pre-expand the number series in front and behind by the size of this
window. Only after that it was possible to detect anomalies both in the first
and in the last elements of the initial series.<o:p></o:p></span></span></span></p>
<p><span style="font-family: inherit;"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">However,
in practice, the Hampel filter is extremely effective. Thanks to modern
libraries such as </span></span><a href="https://pandas.pydata.org/" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">Pandas</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">, it handles fairly large numerical series
of tens of thousands elements in a matter of seconds, and is also easy to
optimize and parallelize (using </span></span><a href="https://developer.nvidia.com/cuda-python" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">CUDA Python</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span class="MsoHyperlink"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;"> </span></span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">and </span></span><a href="https://numba.readthedocs.io/en/stable/user/jit.html#compiling-python-code-with-jit" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">Numba’s @cuda.jit</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span class="MsoHyperlink"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;"> </span></span></span><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">decorator, or </span></span><a href="https://superfastpython.com/threadpool-python/" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration: none;">Python Multiprocessing ThreadPool</span></span></a><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US">).<o:p></o:p></span></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;">Thus, if
you have an issue of finding anomalies in a number series, try looking towards
filtering them using the Hampel method. It gives fast results and is also easy
to understand and implement.<o:p></o:p></span></span></span></p><p><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US"><span style="font-family: inherit;"><br /></span></span></span></p>
<p><span lang="EN-US"><span style="font-family: inherit;"><b>Authors:</b>
<a href="https://www.linkedin.com/in/tgilmullin" rel="nofollow" target="_blank">Timur Gilmullin</a>, Ph.D., <a href="http://www.linkedin.com/in/mgilmullin" rel="nofollow" target="_blank">Mansur Gilmullin</a>, Ph.D.<o:p></o:p></span></span></p>
<p><span style="mso-bookmark: _Hlk123061868;"><b><span lang="EN-US"><span style="font-family: inherit;">Sources:</span></span></b></span></p><p></p><ol style="text-align: left;"><li><span style="font-family: inherit; text-indent: 0cm;">Hampel F. R. The influence curve and its role in robust estimation. Journal
of the American Statistical Association, 69, 382–393, 1974.</span></li><li><span style="font-family: inherit; text-indent: 0cm;">Hancong Liu, Sirish Shah and Wei Jiang. On-line outlier detection and
data cleaning. Computers and Chemical Engineering. Vol. 28, March 2004, pp.
1635–1647.<br /></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US">Link: </span></span><a href="https://sites.ualberta.ca/~slshah/files/on_line_outlier_det.pdf" style="font-family: inherit; text-indent: 0cm;" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration-line: none;">https://sites.ualberta.ca/~slshah/files/on_line_outlier_det.pdf</span></span></a></li><li><span style="font-family: inherit; text-indent: 0cm;">Lewinson Eryk. Outlier Detection with Hampel Filter. September 26, 2019.<br /></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US">Link: </span></span><a href="https://towardsdatascience.com/outlier-detection-with-hampel-filter-85ddf523c73d" style="font-family: inherit; text-indent: 0cm;" target="_blank"><span style="mso-bookmark: _Hlk123061868;"><span lang="EN-US" style="color: #0e2bd8; text-decoration-line: none;">https://towardsdatascience.com/outlier-detection-with-hampel-filter-85ddf523c73d</span></span></a></li></ol><p></p>
<p class="MsoNormal" style="margin-bottom: 0cm;"><span style="mso-bookmark: _Hlk123061868;"><b><span lang="EN-US" style="line-height: 107%;"><span style="font-family: inherit;">Source code of the
modules used in examples:</span></span></b></span></p><p class="MsoNormal" style="margin-bottom: 0cm;"></p><ul style="text-align: left;"><li><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><b><span lang="EN-US" style="color: #333333;">PriceGenerator </span></b></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US" style="color: #333333;">—</span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US" style="mso-ansi-language: EN-US;"> </span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US" style="color: #333333;">this module can generate time series with data like
random stock prices with anomalies.<br /></span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US">Link</span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span style="color: #333333;">: <a href="https://github.com/Tim55667757/PriceGenerator/blob/master/README.md" rel="nofollow" target="_blank">https://github.com/Tim55667757/PriceGenerator/blob/master/README.md</a></span></span></li><li><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><b><span lang="EN-US" style="color: #333333;">TKSBrokerAPI</span></b></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US" style="color: #333333;"> —
this module contains the TradeRoutines library with the necessary functions.<br /></span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US">Link<span style="color: #333333;">: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/README_EN.md" rel="nofollow" target="_blank">https://github.com/Tim55667757/TKSBrokerAPI/blob/master/README_EN.md</a></span></span></span></li><ul><li><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><b><span lang="EN-US" style="color: #333333;">TradeRoutines </span></b></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US" style="color: #333333;">— this library has methods for analyzing number series
for anomalies.<br /></span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US">Link<span style="color: #333333;">: <a href="https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TradeRoutines.html" rel="nofollow" target="_blank">https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TradeRoutines.html</a></span></span></span></li><li><span style="mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US"><b>TestAnomalyFilter</b> — a simple script with an example of generating an OHLCV time series and detecting for anomaly using the Hampel method.<br />Link: </span></span><a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/TestAnomalyFilter.py" rel="nofollow" target="_blank">https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/TestAnomalyFilter.py</a></li></ul><li><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><b><span lang="EN-US" style="color: #333333;">HampelFilteringExample.ipynb</span></b></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US" style="color: #333333;"> — Jupyter Notebook with an example of using
the Hampel filter for the issue of finding outliers in stock data.<br /></span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span lang="EN-US">Link</span></span><span style="font-family: inherit; mso-bookmark: _Hlk123061868; text-indent: 0cm;"><span style="color: #333333;">: <a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample_EN.ipynb" rel="nofollow" target="_blank">https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample_EN.ipynb</a></span></span></li></ul><div><br /></div><p></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-24499171716410269832023-01-06T23:46:00.001+03:002023-01-06T23:56:27.100+03:00Jupyter Notebook: теория и практика фильтрации данных методом Хампеля<p>Всем привет! Я сделал примеры с фильтрацией данных методом Хампеля в Jupyter Notebook, где можно поэкспериментировать с различными параметрами функции HampelFilter(). Показано применение этого фильтра для поиска аномальных выбросов в числовых рядах, полученных из биржевых цен. А также написал простой скрипт на Python, который можно запустить, и посмотреть, о чём идёт речь.</p><p></p><ul style="text-align: left;"><li><b>Jupyter Notebook:</b> <a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb" rel="nofollow" target="_blank">https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb</a></li><li><b>Python-скрипт:</b> <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/TestAnomalyFilter.py" rel="nofollow" target="_blank">https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/TestAnomalyFilter.py</a></li></ul><div>Эти примеры написаны для недавно опубликованной статьи: «<a href="https://forworktests.blogspot.com/2022/12/blog-post.html" rel="nofollow" target="_blank">Как быстро найти аномалии в числовых рядах с помощью метода Хампеля</a>».</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlGD9Y4JXC1APfG-58KJ6jCqNsArzS3KA5iTGOrrhjNXRRls5kxJloKfx48f8n-TV4fXWY_W4l6Z3Dc8QGGSnEbMFij0BAz-7tNThMmcm9jzkaV8TxM4dx6nqlkns2JUJuuTMrR0JS6tB_-deSFBLnLT8W6aaGX66dB2QK0nbDjSP_1tJwGckZv0p9sg/s738/hampel-filter.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="710" data-original-width="738" height="618" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlGD9Y4JXC1APfG-58KJ6jCqNsArzS3KA5iTGOrrhjNXRRls5kxJloKfx48f8n-TV4fXWY_W4l6Z3Dc8QGGSnEbMFij0BAz-7tNThMmcm9jzkaV8TxM4dx6nqlkns2JUJuuTMrR0JS6tB_-deSFBLnLT8W6aaGX66dB2QK0nbDjSP_1tJwGckZv0p9sg/w640-h618/hampel-filter.png" width="640" /></a></div><div style="text-align: right;"><i style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><b>Поддержать проект:</b> <a href="https://yoomoney.ru/to/410015019068268" rel="nofollow" style="color: #2988d5;" target="_blank">https://yoomoney.ru/to/410015019068268</a></i></div><p></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-11982238379510202062023-01-06T00:53:00.002+03:002023-01-07T13:44:01.192+03:00PriceGenerator: release-1.3.81<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw9zSGbdTHgN06d0w_zLxqKs_JqA7capBEvlWE_Gut_9748P-pp-fQQ96R89jJ_gyOjfBmIHsncadxrJjnIJmm-a4ba7w0nMSmwlStwdBFtct9Zz1OHtUnKruXD6C9K7aFxSvZDuh-_GQl05uGT8WEIBsJu_0OzfAE1hRauWaW-VYh_KdLNC9RJ-qe6A/s1819/anomaly-example.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="962" data-original-width="1819" height="153" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw9zSGbdTHgN06d0w_zLxqKs_JqA7capBEvlWE_Gut_9748P-pp-fQQ96R89jJ_gyOjfBmIHsncadxrJjnIJmm-a4ba7w0nMSmwlStwdBFtct9Zz1OHtUnKruXD6C9K7aFxSvZDuh-_GQl05uGT8WEIBsJu_0OzfAE1hRauWaW-VYh_KdLNC9RJ-qe6A/w289-h153/anomaly-example.png" width="289" /></a></div><span style="background-color: #fefdfa;"><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="color: #333333;">Опубликован очередной релиз платформы <a href="https://github.com/Tim55667757/PriceGenerator/releases/tag/1.3.81" rel="nofollow" target="_blank">PriceGenerator: </a></span></span><b style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><a href="https://github.com/Tim55667757/PriceGenerator/releases/tag/1.3.81" rel="nofollow" target="_blank">v1.3.81</a></b><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-size: 16px;">. Рассмотрим основные изменения.</span><p></p><div><p style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://github.com/Tim55667757/PriceGenerator/blob/develop/CHANGELOG.md" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;" target="_blank"><span style="box-sizing: border-box; font-weight: var(--base-text-weight-semibold, 600);">Release notes in english</span></a><br style="box-sizing: border-box;" /><a href="https://github.com/Tim55667757/PriceGenerator/blob/develop/CHANGELOG_RU.md" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;" target="_blank"><span style="box-sizing: border-box; font-weight: var(--base-text-weight-semibold, 600);">Release notes in russian</span></a><br style="box-sizing: border-box;" /><a href="https://github.com/Tim55667757/PriceGenerator/milestone/2?closed=1" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;" target="_blank"><span style="box-sizing: border-box; font-weight: var(--base-text-weight-semibold, 600);">Issues included in the release</span></a><br style="box-sizing: border-box;" /><a href="https://tim55667757.github.io/PriceGenerator/docs/pricegenerator/PriceGenerator.html" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;" target="_blank"><span style="box-sizing: border-box; font-weight: var(--base-text-weight-semibold, 600);">API-doc</span></a></p><h3 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">PyPI: <a href="https://pypi.org/project/pricegenerator/1.3.81/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">1.3.81 (2023-01-05)</a></h3></div><div><h3 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Дайджест</h3><p style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: var(--base-text-weight-semibold, 600);">Внимание!</span> Поддерживаемая версия Python не ниже 3.9.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Теперь можно добавлять кастомные линии (например, линии собственных индикаторов, рассчитанных заранее) и маркеры на основной график вместе с ценовыми свечами. Для этого используется метод <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">RenderBokeh()</code>.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Появилась возможность задавать направления генерируемых трендов простыми словами: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">up</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">down</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">no</code> или буквами: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">u</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">d</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">n</code> совместно с ключом <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">--split-trend</code> (в дополнение к уже существующей возможности указывать тренды символами <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">/\-</code>), например, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">--split-trend=up-down-no-up</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">--split-trend=u-d-n-u</code>.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Также можно выбирать тёмную или светлую темы для графиков, построенный через метод <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">RenderBokeh()</code>, при помощи нового параметра <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">darkTheme</code> (если <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">True</code>, то используется тёмная тема, иначе — светлая тема).</p></div><div><p style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Пример графика со светлой темой и с дополнительными кастомными маркерами и новой линией:</p></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbIergyZ6CBgWVSJSlKG7vWMPk_NNC747tCQyWXLDIBBkQBMI9YsSX3Q2z_iiU1i9x_0Tew34r_q9XxZ1oUSmQm73Hk5NGQ45o9CK19pg9pd22Yu5_HnA01zu_c7ej6BUX1hMPlf0znMiAS_iUVXVv0zRECHx8FGo71sdLvxtXeeeYpwm4EEnS3RiMaA/s1827/anomaly-example-light-theme.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="955" data-original-width="1827" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbIergyZ6CBgWVSJSlKG7vWMPk_NNC747tCQyWXLDIBBkQBMI9YsSX3Q2z_iiU1i9x_0Tew34r_q9XxZ1oUSmQm73Hk5NGQ45o9CK19pg9pd22Yu5_HnA01zu_c7ej6BUX1hMPlf0znMiAS_iUVXVv0zRECHx8FGo71sdLvxtXeeeYpwm4EEnS3RiMaA/w640-h334/anomaly-example-light-theme.png" width="640" /></a></div><br /><div style="text-align: right;"><i><b>Поддержать проект:</b> <a href="https://yoomoney.ru/to/410015019068268" rel="nofollow" target="_blank">https://yoomoney.ru/to/410015019068268</a></i></div><span><a name='more'></a></span><div style="text-align: left;"><br /></div><div><h3 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Новая функциональность</h3><ul style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"></ul></div><div><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-size: 16px;"><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Поддерживаемая версия Python изменена на 3.9.<br /><br /></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/17/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/17" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#17</a> В метод <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">RenderBokeh()</code> добавлен параметр <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">layouts</code>, с помощью которого можно добавлять новые Chart-объекты Bokeh на основной график.<br /><br />Добавлен параметр <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">darkTheme</code>, который регулирует выбор темы: если он равен <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">True</code>, то будет использоваться тёмная тема, если <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">False</code> (по умолчанию), то будет использоваться светлая тема.<br /><br />Также вы можете манипулировать графиком и добавлять новые линии или маркеры на основной график. Используйте для этого параметры <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">markers</code> и <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">lines</code>. Pandas DataFrame <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">markers</code> содержит ряды, которые показывают, какой маркер нанести для той или иной свечи. <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">None</code> по умолчанию.<br /><br />Маркер представляет собой некоторый символ, например, ×, ↓ или ↑ или какой-либо другой. Датафрейм с маркерами должен содержать, как минимум, два столбца. Это столбец <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">datetime</code>, с датой и временем, и один из столбцов или все сразу: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">markersUpper</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">markersCenter</code> или <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">markersLower</code>, с маркерами, которые нужно поставить сверху, по центру или снизу свечи соответственно. Длины рядов с маркерами должны быть равны длине основного ряда со свечами. <br /><br />Лист <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">lines</code> содержит ряды с данными о точках новых линий, которые нужно разместить на основном свечном графике. <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">None</code> по умолчанию. Датафрейм с линиями должен содержать, как минимум, два столбца. Это <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">datetime</code>, с датой и временем, и столбец <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">custom_line_name</code>, с произвольным именем, содержащий y-координаты точек линии. Длины рядов с точками линий должны быть равны длине основного ряда со свечами.<br /><br /></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/10/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/10" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#10</a> Добавлена возможность указания направлений генерируемых трендов с помощью слов или букв. Слова могут быть следующими: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">up</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">down</code> или <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">no</code>, а буквы могут быть такими: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">u</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">d</code> или <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">n</code>. Эти слова и знаки могут использоваться вместе с ключом <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">--split-trend</code>, в дополнение к уже имеющейся возможности указывать тренд символами <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">/\-</code>.<br /><br />Для разделения слов или букв используется символ дефиса. Например, можно задать последовательность трендов так: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">--split-trend=up-down-no-up,</code> или так: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">--split-trend=u-d-n-u</code>.<br /><br /></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/13/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/13" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#13</a> Была разработана <a href="https://tim55667757.github.io/PriceGenerator/docs/pricegenerator/PriceGenerator.html" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">API-документация</a> на модуль <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">PriceGenerator</code>.</li></ul></span></div><div><h3 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Улучшения</h3></div><div><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-size: 16px;"><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/15/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/15" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#15</a> Отображение блока статистики было улучшено.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/16/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/16" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#16</a> Добавлены примеры: <a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/16/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/16#issuecomment-1287875048" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">как сгенерировать цепочку случайных цен без свечей</a>.</li></ul></span></div><div><h3 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Баг-фиксы</h3><ul style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"></ul></div><div><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-size: 16px;"><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/19/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/19" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#19</a> Исправлена ошибка с генерацией некорректных значений high и low свечей, в случае, если задан тренд.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/18/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/18" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#18</a> Исправлена ошибка с отображением многочисленных всплывающих подсказок на графике, а также ошибка с неверным определением ширины области графика.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/PriceGenerator/issues/11/hovercard" href="https://github.com/Tim55667757/PriceGenerator/issues/11" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">#11</a> Некорректные предупреждения в логах отключены.</li></ul></span></div><div><span style="background-color: #fefdfa; color: #333333;"><br /></span></div><div><span style="background-color: #fefdfa; color: #333333;">Успехов вам в автоматизации биржевой торговли! А платформа PriceGenerator поможет протестировать ваши торговые сценарии :)</span></div><div><span style="background-color: #fefdfa;"><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="color: #333333;"><br /></span></span></div><div><span style="background-color: #fefdfa;"><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="color: #333333;"><br /></span></span></div><div><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333;"><i><b>Поддержать проект:</b> <a href="https://yoomoney.ru/to/410015019068268" rel="nofollow" target="_blank">https://yoomoney.ru/to/410015019068268</a></i></span></div><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-84088790711606738582022-12-27T17:35:00.003+03:002023-01-06T17:43:58.775+03:00Как быстро найти аномалии в числовых рядах с помощью метода Хампеля<p style="text-align: left;">На практике встречаются задачи, для решения которых требуется найти аномалии в числовых рядах. Для простоты понимания можно считать, что это значения, которые отличаются от большинства чисел в ряде по некоторым признакам (выброс, нестандартное значение, отклонение от нормы). Такие задачи встречаются в различных областях:</p><p></p><ul style="text-align: left;"><li>очистка зашумлённых данных в датасайнс (<a href="https://en.wikipedia.org/wiki/Data_science" rel="nofollow" target="_blank">Data Science</a>);</li><li>фильтрация выбросов в обучающей выборке для нейросетей в машинном обучении (<a href="https://en.wikipedia.org/wiki/Machine_learning" rel="nofollow" target="_blank">Machine Learning</a>);</li><li>поиск аномальной сетевой хакерской активности, при мониторинге трафика и событий в кибербезопасности (<a href="https://en.wikipedia.org/wiki/Cyber_security" rel="nofollow" target="_blank">Cybersecurity</a>);</li><li>выявление выбросов или хвостов в потоке биржевых данных в алгоритмической торговле (<a href="https://en.wikipedia.org/wiki/Algorithmic_trading" rel="nofollow" target="_blank">Algorithmic Trading</a>);</li><li>а также в любых задачах на поиск аномалий, где данные могут быть представлены в виде числового ряда.</li></ul><div>Понятия числового ряда в математическом анализе и в статистике отличаются. Мы принимаем под числовым рядом его статистическое понимание, то есть конечную последовательность чисел (аналог выборки). Существуют различные толкования аномалии в числовых рядах. Их мы рассмотрим далее.</div><div><br /></div><div>Также в статье показаны примеры, как быстро и эффективно найти аномалии в числовых рядах с помощью модифицированного <b>метода Хампеля</b> (Hampel F.R.).</div><div><br /></div><div><span><a name='more'></a></span></div><h3 style="text-align: left;">Понятие аномалии числового ряда</h3><p>Для одномерных данных оценка выбросов широко исследуется в статистической литературе. Традиционно наиболее полезными оценками для характеристики вариативности данных считаются выборочное среднее (<a href="https://en.wikipedia.org/wiki/Sample_mean_and_covariance" rel="nofollow" target="_blank">sample mean</a>) и дисперсия (<a href="https://en.wikipedia.org/wiki/Variance" rel="nofollow" target="_blank">variance</a>) выборки. Они дают хорошую оценку местоположения и разброса данных в выборке, но только если выбросы её «не загрязняют». Даже если данные содержат только одно наблюдение, которое значительно отличается от остальных в выборке, то выборочное среднее может также значительно отклоняться от среднего в выборке без этого выброса.</p><p>Чтобы измерить устойчивость выбранного метода статистической оценки к выбросам, Хампель ввёл понятие точки разрыва (<a href="https://en.wikipedia.org/wiki/Robust_statistics#Breakdown_point" rel="nofollow" target="_blank">breakdown point</a>). <i><b>Точка разрыва</b></i> — это наибольший процент «загрязнённых данных» (доля неправильных наблюдений или выбросов), которые выбранный метод может обработать, прежде чем начнёт выдавать неверный результат. Это могут быть произвольно большие аберрантные (отклоняющиеся от нормы, ошибочные) значения.</p><p>Интуитивно можно понять, что точка разрыва не может превышать 50%, потому что, если более половины наблюдений будут «загрязнены», то невозможно отличить основное распределение ряда от загрязняющего распределения. Следовательно, максимальная доля выбросов для точки разрыва равна 0.5. Существуют примеры статистик, которые достигают максимального значения для точки разрыва. Например, она равна 0.5 для медианы (<a href="https://en.wikipedia.org/wiki/Median" rel="nofollow" target="_blank">Median</a>). А для выборочного среднего она равна 1/n, где n — объём выборки.</p><p>Обычно считается, что чем выше значение точки разрыва, тем метод статистической оценки надёжнее. Статистику с высоким значением точки разрыва иногда называют устойчивой статистикой.</p><p>Чтобы более надёжно оценивать местоположение и разброс элементов выборки, часто рекомендуют комбинировать медиану и среднее абсолютное отклонение (<a href="https://en.wikipedia.org/wiki/Median_absolute_deviation" rel="nofollow" target="_blank">MAD, Median Absolute Deviation</a>). Именно они лежат в основе метода фильтрации выборки на выбросы по Хампелю <b>[1]</b>.</p><p>Значение <b>MAD</b> вычисляется так:</p><p>MAD (X) = Median <b>(</b> | <span face="Calibri, sans-serif" style="font-size: 13.5pt; line-height: 107%;">x<sub>1</sub></span> − Median (X) | , …, | <span face="Calibri, sans-serif" style="font-size: 13.5pt; line-height: 107%;">x<sub>n</sub></span> − Median (X) | <b>)</b>, <b>( 1 )</b></p><p>где X — выборка из n наблюдений <span face="Calibri, sans-serif" style="font-size: 13.5pt; line-height: 107%;">x<sub>1</sub></span>, …, <span face="Calibri, sans-serif" style="font-size: 13.5pt; line-height: 107%;">x<sub>n</sub></span>.</p><p>По Хампелю, под <i><b>выбросом (<a href="https://en.wikipedia.org/wiki/Outlier" rel="nofollow" target="_blank">outlier</a>) выборки </b></i>понимается такое число x из выборки X, модуль разности которого и медианы выборки больше, чем MAD выборки, вычисленное по формуле (1) и умноженное на специальный коэффициент k (<a href="https://en.wikipedia.org/wiki/Scale_parameter#Estimation" rel="nofollow" target="_blank">scale factor</a>), зависящий от распределения (≈1.4826 для нормального) <b>[2]</b>.</p><p>На практике для построения фильтра выбросов Хампеля это определение модифицируется с использованием скользящих окон (<a href="https://www.geeksforgeeks.org/window-sliding-technique/" rel="nofollow" target="_blank">sliding windows</a>) и параметра s (<a href="https://en.wikipedia.org/wiki/Standard_deviation" rel="nofollow" target="_blank">sigma</a>), порогового количества стандартных отклонений. Это значит, что медиана и MAD вычисляются для всех скользящих окон, состоящих из элементов выборки. Далее все модули разности элементов выборки и медианы сравниваются с MAD, умноженный на коэффициент k и умноженный на параметр s <b>[3]</b>. Более высокий порог s стандартного отклонения делает фильтр более щадящим, более низкий порог идентифицирует больше чисел как выбросы.</p><p>Теперь определимся с основным понятием: что мы будем понимать под аномалией в конечном числовом ряду для практических задач.</p><p><b>Определение 1.</b> Под <i><b>аномалией (anomaly) числового ряда </b></i>понимается такое число x из ряда X, которое по модулю отличается от медианы скользящего окна более чем в s раз от MAD этого окна, умноженного на коэффициент k.</p><p>Для того чтобы максимально обобщить фильтр аномалий и абстрагировать его от решаемой практической задачи, предлагаем следующее теоретико-множественное толкование.</p><p>Все аномалии ряда образуют его некоторое подмножество A:</p><p>A = <b>{</b> a <b>|</b> | a − Median (<span face="Calibri, sans-serif" style="font-size: 18px;">X</span><sub style="font-family: Calibri, sans-serif;">i</sub>) | > s ∙ k ∙ MAD (<span face="Calibri, sans-serif" style="font-size: 18px;">X</span><sub style="font-family: Calibri, sans-serif;">i</sub>) <b>}</b>, <b>( 2 )</b></p><p>где a — аномальный элемент из X, вычисленный согласно определению 1, Х — исходный числовой ряд, <span face="Calibri, sans-serif" style="font-size: 18px;">X</span><sub style="font-family: Calibri, sans-serif;">i</sub> — ряд чисел i-го скользящего окна, всего окон: <b>( </b>n − w + 1 <b>)</b>, где w — размер окна.</p><p><i><b>Фильтр аномалий числового ряда </b></i>определим как функцию:</p><p>F: X → { True, False }. F (<span face="Calibri, sans-serif" style="font-size: 18px;">x</span><sub style="font-family: Calibri, sans-serif;">i</sub>) = True, если <span face="Calibri, sans-serif" style="font-size: 18px;">x</span><sub style="font-family: Calibri, sans-serif;">i</sub> ∈ A; False, если <span face="Calibri, sans-serif" style="font-size: 18px;">x</span><sub style="font-family: Calibri, sans-serif;">i</sub> ∉ A. <b>( 3 )</b></p><p>Здесь Х — исходный числовой ряд, состоящий из n элементов <span face="Calibri, sans-serif" style="font-size: 18px;">x</span><sub style="font-family: Calibri, sans-serif;">i</sub>, A — множество аномалий (2).</p><h3 style="text-align: left;">Фильтрация числового ряда на аномалии методом Хампеля</h3><p>Для фильтрации числового ряда на наличие в нём аномалий, предлагается использовать Python-реализацию <span style="font-family: inherit;">функции</span><span style="font-family: inherit;"><span style="font-family: inherit;"> <span><a href="https://github.com/Tim55667757/TKSBrokerAPI/commit/312b3022df69aad85f0110eb06f609cc815c23db#diff-2a061adbfc8570a3c83bfcf27ee921b75c7ccbc5f0ebc4397910e8fed6f040e7R268-R332" rel="nofollow" target="_blank">HampelFilter()</a></span>. </span>Э</span>та функция позволяет обнаружить аномалию среди значений любого числового ряда, используя метод фильтрации по Хампелю. Фильтр обнаруживает аномалии, определяемые согласно (2). Настраиваемые параметры в этой функции-фильтре: window (переменная w из формул выше) — размер скользящего окна (по умолчанию 5), sigma (переменная s) — пороговое количество стандартных отклонений (по умолчанию 3), scaleFactor (переменная k) — специальный коэффициент, зависящий от распределения ряда (по умолчанию 1.4826).</p><p>Фун<span style="font-family: inherit;">кция фильтрации HampelFilter() возвращает новый ряд F, согласно (3) состоящий из значений <span>True</span> или <span>False</span>, где <span>True</span> означает наличие аномального элемента на соответствующей позиции в исходном ряду.</span></p><p><b style="font-family: courier;"></b></p><p><b>Примеры входных данных и результатов, HampelFilter(window=5, sigma=3, scaleFactor=1.4826)</b></p><p><span style="font-family: courier;">Входные данные Вывод функции</span></p><p><span style="font-family: courier;">[10, 10, 10, 10, 10] [False, False, False, False, False]<br /></span><span style="font-family: courier;">[1, 10, 10, 10, 10] </span><span style="font-family: courier;">[True, False, False, False, False]<br /></span><span style="font-family: courier;">[1, 5, 10, 10, 10] </span><span style="font-family: courier;">[True, True, False, False, False]</span><br /><span style="font-family: courier;">[1, 5, 1, 1, 1] [False, True, False, False, False]</span></p><p><b>Примеры входных данных и результатов, HampelFilter(window=3, sigma=3, scaleFactor=1.4826)</b></p><p><span style="font-family: courier;">Входные данные Вывод функции</span></p><p><span style="font-family: courier;">[1, 5, 1, 1, 1] [False, True, False, False, False]<br />[1, 10, 10, 1, 10, 1] [True, False, False, False, False, False]<br />[1, 10, 10, 10, 10, 1] [True, False, False, False, False, True]<br />[1, 1, 1, 10, 10, 10] [False, False, False, False, False, False]</span></p><h3>Поиск индекса первого аномального элемента</h3><p>На практике часто бывает нужно определить только первый аномальный или первый среди наибольших в числовом ряду элемент. Для этого можно испол<span style="font-family: inherit;">ьзовать Python-реализацию функц<span>ии <span><a href="https://github.com/Tim55667757/TKSBrokerAPI/commit/65afba0d65c454b2c401fea799586bd17734d9c2#diff-2a061adbfc8570a3c83bfcf27ee921b75c7ccbc5f0ebc4397910e8fed6f040e7R338-R386" rel="nofollow" target="_blank">HampelAnomalyDetection()</a></span>. Эт</span>а функци</span>я возвращает минимальный индекс элемента в списке найденных аномалий или индекс первого м<span style="font-family: inherit;">аксимального элемента во входном ряду, если его индекс меньше индекса аномального элемента. Если в числовом ряду нет аномалий или все элементы равны (нет максимумов), то возвращается <span>None</span>.</span></p><p><b>Примеры входных данных и результатов, HampelAnomalyDetection() со значениями по умолчанию</b></p><p><span style="font-family: courier;">Входные данные Вывод функции</span></p><p><span style="font-family: courier;">[1, 1, 1, 1, 111, 1] 4<br />[1, 1, 10, 1, 1, 1] 2<br />[111, 1, 1, 1, 1, 1] 0<br />[111, 1, 1, 1, 1, 111] 0<br />[1, 11, 1, 111, 1, 1] 1<br />[1, 1, 1, 111, 99, 11] 3<br />[-111, 1, 1, 1, 1] 0<br />[1, 2, 1, -1, 1] 1<br />[1] None<br />[1, 2] None<br /></span><span style="font-family: courier;">[1, 1, 1, 1, 1, 1] None</span></p><h3 style="text-align: left;">Фильтрация биржевых цен на аномалии</h3><p>Посмотреть использование указанных выше функций можно на примере задачи поиска выбросов в биржевых данных. Для этого мы сгенерировали временные ряды с данными, похожими на случайные биржевые цены, и аномалии в них при помощи библиотеки <a href="https://github.com/Tim55667757/PriceGenerator" rel="nofollow" target="_blank">PriceGenerator</a>, а затем применили к данным эти функции. Сами функции — в библиотеке <a href="https://github.com/Tim55667757/TKSBrokerAPI" rel="nofollow" target="_blank">TKSBrokerAPI</a> (модуль <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/tksbrokerapi/TradeRoutines.py" rel="nofollow" target="_blank">TradeRoutines</a>).</p><p>Решение задачи было реализовано на Jupyter Notebook: <a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb" rel="nofollow" target="_blank">HampelFilteringExample.ipynb</a>. Аномалии на графике цен после анализа методом Хампеля можно промаркировать, например, как показано на иллюстрации ниже.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-DOzm4YC2jBMrh-DgjvJkR0gUPYklpViy8TvieyG4iaJ7hvljOG11-UsPL1lO6w1TJrVhQ0-6b7EbGIKhYpvugzx0gUR8t5ZDtjiQB7doAGE_Fu5xdvFwnm6dEmHd23qCRb_cZY1Nc0Llssl0N04rbjcS4GGVEa0T8fa_jGryqn2UWbkd7laNXDEZMA/s1825/HampelFilteringExample.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="955" data-original-width="1825" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-DOzm4YC2jBMrh-DgjvJkR0gUPYklpViy8TvieyG4iaJ7hvljOG11-UsPL1lO6w1TJrVhQ0-6b7EbGIKhYpvugzx0gUR8t5ZDtjiQB7doAGE_Fu5xdvFwnm6dEmHd23qCRb_cZY1Nc0Llssl0N04rbjcS4GGVEa0T8fa_jGryqn2UWbkd7laNXDEZMA/w640-h334/HampelFilteringExample.png" width="640" /></a></div><p><span style="text-align: center;">Как видно невооружённым глазом, в ряду явно присутствуют выбросы, хвосты сверху и снизу у некоторых свечей. Нас интересуют не все такие выбросы, а только слишком длинные</span> <span style="text-align: center;">хвосты</span><span style="text-align: center;">. Для нас это признаки ценовой аномалии. Фильтр Хампеля справился с обнаружением аномалий в ряду из 75 свечей при величине скользящего окна (параметр sliding window) равного размеру ряда, количестве стандартных отклонений равном 3 (параметр sigma) и постоянном коэффициенте, характеризующем нормальное распределение, равном 1.4826 (параметр scale factor). </span><span style="text-align: center;">Аналогичным образом можно проанализировать на аномалии и размеры </span><span style="text-align: center;">тел</span><span style="text-align: center;"> свечей.</span></p><h3 style="text-align: left;">Выводы</h3><p>Конечно, у метода Хампеля есть и недостатки. Например, при реализации алгоритма можно столкнуться с тем, что присутствующие аномалии в первом и последнем элементах ряда по оригинальному алгоритму будут проигнорированы. Это связано с использованием скользящего окна. Чтобы обойти проблему, нам пришлось предварительно расширять числовые ряды спереди и сзади на размер этого окна. Только после этого удалось обнаружить аномалии и в первых, и в последних элементах исходных рядов.</p><p>Однако на практике фильтр Хампеля оказывается чрезвычайно эффективным. Благодаря современным библиотекам, таким как <a href="https://pandas.pydata.org/" rel="nofollow" target="_blank">Pandas</a>, он справляется с достаточно большими числовыми рядами на десятки тысяч элементов за считанные секунды, а также легко поддаётся оптимизации и распараллеливанию (с помощью <a href="https://developer.nvidia.com/cuda-python" rel="nofollow" target="_blank">CUDA Python</a> и декоратора <a href="https://numba.readthedocs.io/en/stable/user/jit.html#compiling-python-code-with-jit" rel="nofollow" target="_blank">@cuda.jit от Numba</a>, либо <a href="https://superfastpython.com/threadpool-python/" rel="nofollow" target="_blank">Python Multiprocessing ThreadPool</a>).</p><p>Таким образом, если у вас стоит задача поиска аномалий в числовом ряду, попробуйте посмотреть в сторону их фильтрации методом Хампеля. Он даёт быстрые результаты, а также прост в понимании и реализации.</p><p><br /></p><p><b>Авторы: </b><a href="https://www.linkedin.com/in/tgilmullin" rel="nofollow" target="_blank">Тимур Гильмуллин</a>, к.т.н., <a href="http://www.linkedin.com/in/mgilmullin" rel="nofollow" target="_blank">Мансур Гильмуллин</a>, к.п.н.</p><p><b>Источники:</b></p><p></p><ol style="text-align: left;"><li>Hampel F. R. The influence curve and its role in robust estimation. Journal of the American Statistical Association, 69, 382–393, 1974.</li><li>Hancong Liu, Sirish Shah and Wei Jiang. On-line outlier detection and data cleaning. Computers and Chemical Engineering. Vol. 28, March 2004, pp. 1635–1647.<br />Link: <a href="https://sites.ualberta.ca/~slshah/files/on_line_outlier_det.pdf" rel="nofollow" target="_blank">https://sites.ualberta.ca/~slshah/files/on_line_outlier_det.pdf</a></li><li>Lewinson Eryk. Outlier Detection with Hampel Filter. September 26, 2019.<br />Link: <a href="https://towardsdatascience.com/outlier-detection-with-hampel-filter-85ddf523c73d" rel="nofollow" target="_blank">https://towardsdatascience.com/outlier-detection-with-hampel-filter-85ddf523c73d</a></li></ol><div><b>Исходный код модулей, используемых в примерах:</b></div><div><ul style="text-align: left;"><li><b>PriceGenerator </b>— этот модуль умеет генерировать временные ряды с данными, похожими на случайные биржевые цены с аномалиями.<br />Ссылка: <a href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md" rel="nofollow" target="_blank">https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md</a></li><li><b>TKSBrokerAPI</b> — этот модуль содержит в себе библиотеку TradeRoutines с необходимыми функциями.<br />Ссылка: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/README.md" rel="nofollow" target="_blank">https://github.com/Tim55667757/TKSBrokerAPI/blob/master/README.md</a></li></ul><ol style="text-align: left;"><ul><li><b>TradeRoutines </b>— в этой библиотеке есть методы для анализа числовых рядов на аномалии.<br />Ссылка: <a href="https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TradeRoutines.html" rel="nofollow" target="_blank">https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TradeRoutines.html</a></li><li><b>TestAnomalyFilter </b>— простой скрипт с примером генерации временного OHLCV-ряда и поиска в нём аномальных значений методом Хампеля.<br />Ссылка: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/TestAnomalyFilter.py" rel="nofollow" target="_blank">https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/TestAnomalyFilter.py</a></li></ul></ol><ul style="text-align: left;"><li><b style="font-weight: bold;">HampelFilteringExample.ipynb</b> — Jupyter Notebook с примером использования фильтра Хампеля для задачи поиска выбросов в биржевых данных.<br />Ссылка: <a href="https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb" rel="nofollow" target="_blank">https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb</a></li></ul><div><br /></div></div><p></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-1489391707186868842022-11-24T19:35:00.002+03:002022-11-25T00:28:25.671+03:00TKSBrokerAPI Trade Automation Platform: release-1.5.120<p style="text-align: left;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqyT8qsgKm2s2qqCsMz9l0jJowuHNMvNiq3c7Q0U_bO_flCmlm0N5sohI-C3VIdbAwJxZqZkwJamS5aVY6ipsMNvbMkgY5P5VvrXtel4OWWRKPAK8NGjXmIiOe6hcgUUndAAIGDaaHULTcVx37IbFIRbPMSKGn_7yDi4hRXihTII3_YX5IJH--iwJMEQ/s1120/TKSBrokerAPI-Logo-mini.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="1119" data-original-width="1120" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqyT8qsgKm2s2qqCsMz9l0jJowuHNMvNiq3c7Q0U_bO_flCmlm0N5sohI-C3VIdbAwJxZqZkwJamS5aVY6ipsMNvbMkgY5P5VvrXtel4OWWRKPAK8NGjXmIiOe6hcgUUndAAIGDaaHULTcVx37IbFIRbPMSKGn_7yDi4hRXihTII3_YX5IJH--iwJMEQ/w300-h300/TKSBrokerAPI-Logo-mini.png" width="300" /></a></div>Опубликован очередной релиз платформы TKSBrokerAPI: <b>v1.5.120</b>. Рассмотрим основные изменения.<p></p><p style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="color: black;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/CHANGELOG_EN.md" style="box-sizing: border-box; text-decoration: none;">Release notes (in english)</a><br style="box-sizing: border-box;" /><a href="https://github.com/Tim55667757/TKSBrokerAPI/milestone/5?closed=1" style="box-sizing: border-box; text-decoration: none;">Issues included in the release</a></span></p><h3 style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">PyPI: <a href="https://pypi.org/project/tksbrokerapi/1.5.120/" rel="nofollow" style="box-sizing: border-box; text-decoration: none;">1.5.120 (2022-11-21)</a></h3><h3 style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Дайджест</h3><p style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В новой версии TKSBrokerAPI в отчёте о портфеле пользователя появилась новая секция с календарём платежей по облигациям (сам календарь, возможность обогащения облигаций данными и множество других интересных фич появились <a href="https://github.com/Tim55667757/TKSBrokerAPI/releases/tag/1.4.90" rel="nofollow" target="_blank">в предыдущей стабильной версии v1.4.90</a>, о них я писал <a href="https://forworktests.blogspot.com/2022/11/tksbrokerapi.html" rel="nofollow">в прошлом посте</a>). <span></span></p><a name='more'></a><p></p><p style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Календарь платежей строится автоматически, если имеется хотя бы одна облигация в портфеле (ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview-calendar</code>). Был добавлен ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--html</code> для сохранения любых пользовательских отчётов в HTML формат. Кроме того, появилась возможность закрывать позицию и все ордера по ключу <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--close-all</code> для одного инструмента, заданного через <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--ticker</code> или <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--figi</code>.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHSKKPrX2AgZPY3PRNmth6ufiJUtpKVoXuRc01jmDKzxfIj9uxZicu4ouDHQO-fKNfCh6Y3jyOyUvl0b6z0TIkWixXlTcsLFTSz8wbyzgsuGLeZbNNAQs3crzix5GMeM3Mj2m5HMomZYpCuUgfHYAx9bdfA2fCCsiX-NbxIl0B0-a5hF-SWD5YixxGwg/s2879/calendar.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1386" data-original-width="2879" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHSKKPrX2AgZPY3PRNmth6ufiJUtpKVoXuRc01jmDKzxfIj9uxZicu4ouDHQO-fKNfCh6Y3jyOyUvl0b6z0TIkWixXlTcsLFTSz8wbyzgsuGLeZbNNAQs3crzix5GMeM3Mj2m5HMomZYpCuUgfHYAx9bdfA2fCCsiX-NbxIl0B0-a5hF-SWD5YixxGwg/w640-h308/calendar.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: right;"><i><b>Поддержать проект:</b> <a href="https://yoomoney.ru/to/410015019068268">https://yoomoney.ru/to/410015019068268</a></i></div><div class="separator" style="clear: both; text-align: center;"><br /></div><p style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Торговый сценарий <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/examples/scenario1.py" style="box-sizing: border-box; text-decoration: none;">./docs/examples/scenario1.py</a> был переписан в парадигме ООП: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/examples/scenario1a.py" style="box-sizing: border-box; text-decoration: none;">./docs/examples/scenario1a.py</a>. Теперь это полноценный торговый шаблон на базе платформы TKSBrokerAPI. Его можно использовать за основу для разработки собственных сценариев.</p><p style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Пофикшен обидный баг при торговле "по рынку" (ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--trade</code>), когда TP/SL ордеры открывались даже если основная заявка не была исполнена. Теперь при любых ошибках TP/SL ордеры не выставляются. А также, для удобства отладки теперь можно указывать ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--more</code> вместе с любой другой командой. В логах появится больше информации, например, сетевые запросы, сетевые ответы и их заголовки.</p><h3 style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Новая функциональность</h3><ul style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/62/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/62" style="box-sizing: border-box; text-decoration: none;">#62</a> В отчёт о состоянии портфеля пользователя добавлена секция с календарём платежей по облигациям, который строится автоматически, если хотя бы одна облигация присутствует в портфеле (метод <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">Overview(details="calendar")</code>, ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview-calendar</code>).</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/80/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/80" style="box-sizing: border-box; text-decoration: none;">#80</a> Пример торгового сценария <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/examples/scenario1.py" style="box-sizing: border-box; text-decoration: none;">./docs/examples/scenario1.py</a> дополнительно переписан в парадигме ООП: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/examples/scenario1a.py" style="box-sizing: border-box; text-decoration: none;">./docs/examples/scenario1a.py</a>. Эти шаблоны можно брать за основу для разработки собственных торговых сценариев, на базе платформы TKSBrokerAPI.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/48/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/48" style="box-sizing: border-box; text-decoration: none;">#48</a> Если ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--close-all</code> будет указан совместно с одним из ключей <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--ticker</code> или <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--figi</code>, тогда будут закрыты все незаблокированные объёмы открытой позиции, отложенные лимитные и стоп ордеры для выбранного инструмента. Для поддержки этой фичи были реализованы дополнительные методы: <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">CloseAllByTicker()</code> — для закрытия всех позиций и ордеров по инструменту заданному тикером, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">CloseAllByFIGI()</code> — для закрытия всех позиций и ордеров по инструменту заданному FIGI идентификатором, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">IsInLimitOrders()</code> — функция, которая возвращает <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">True</code> или <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">False</code>, при наличии или отсутствии открытых отложенных лимитных ордеров, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">GetLimitOrderIDs()</code> — функция, которая возвращает список открытых отложенных лимитных ордеров, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">IsInStopOrders()</code> — функция, которая возвращает <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">True</code>или <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">False</code>, при наличии или отсутствии открытых стоп ордеров и <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">GetStopOrderIDs()</code> — функция, которая возвращает список открытых стоп ордеров для инструмента.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/83/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/83" style="box-sizing: border-box; text-decoration: none;">#83</a> Теперь можно указывать ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--html</code> для генерации дополнительных отчётов из Markdown-файлов в HTML формат. Рендеринг HTML и ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--html</code> были реализованы для отчётов, создаваемых командами <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--list</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--info</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--search</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--prices</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--deals</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--limits</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--calendar</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--account</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--user-info</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview-digest</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview-positions</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview-orders</code>, <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview-analytics</code> и <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview-calendar</code>. HTML-генератор основан на <a href="https://www.makotemplates.org/" rel="nofollow" style="box-sizing: border-box; text-decoration: none;">Mako Templates library</a>.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/67/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/67" style="box-sizing: border-box; text-decoration: none;">#67</a> Теперь можно указывать ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--more</code> вместе с любой командой. Он включает во всех методах TKSBrokerAPI больше отладочной информации и выводит её в логи. Например, сохраняются фактические сетевые запросы, ответы на них и заголовки.</span></li></ul><h3 style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Улучшения</h3><ul style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/74/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/74" style="box-sizing: border-box; text-decoration: none;">#74</a> Улучшен CI/CD скрипт <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">.travis.yml</code>. Теперь при запуске сборки из пулл-реквеста выполняются только шаги запуска юнит-тестов и сборки пакета. Выкладка пакета в PyPI не происходит. Публикация в PyPI теперь запускается только при сборке напрямую из ветки или после принятия пулл-реквеста.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/39/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/39" style="box-sizing: border-box; text-decoration: none;">#39</a> Теперь все операции закрытия позиций или ордеров (наборы ключей <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--close-***</code>) поддерживают возможность указания инструментов не только через тикеры, но и через FIGI идентификаторы.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/60/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/60" style="box-sizing: border-box; text-decoration: none;">#60</a> Теперь ключи <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--ticker</code> и <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--figi</code> — регистронезависимые. Можно указывать в консоли их значения в любом регистре, а внутри платформы TKSBrokerAPI они будут автоматически приведены к верхнему регистру.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/75/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/75" style="box-sizing: border-box; text-decoration: none;">#75</a> Если при запуске с ключом <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--limits</code> окажется, что нет доступных для вывода лимитов денежных средств, то теперь пустая таблица отображаться не будет.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/68/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/68" style="box-sizing: border-box; text-decoration: none;">#68</a> В отчёт по акции (метод <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">ShowInstrumentInfo()</code>, ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--info</code>) добавлена информация про тип акции: обыкновенная, привилегированная, американские депозитарные расписки, глобальные депозитарные расписки, товарищество с ограниченной ответственностью, акции из реестра Нью-Йорка, закрытый инвестиционный фонд или траст недвижимости.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/35/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/35" style="box-sizing: border-box; text-decoration: none;">#35</a> В таблице "Summary" с отчетом по операциям (ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--deals</code>) упрощены заголовки.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/51/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/51" style="box-sizing: border-box; text-decoration: none;">#51</a> Константа <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">NANO</code>, методы <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">NanoToFloat()</code> и <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">FloatToNano()</code> вынесены в новый модуль <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TradeRoutines</code>. Это библиотека с набором функций для упрощения реализации торговых стратегий на базе платформы TKSBrokerAPI.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/52/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/52" style="box-sizing: border-box; text-decoration: none;">#52</a> Метод <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">GetDatesAsString()</code> также перенесён в модуль <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TradeRoutines</code>.</span></li></ul><h3 style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; margin-bottom: 16px; margin-top: 24px;">Баг-фиксы</h3><ul style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/66/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/66" style="box-sizing: border-box; text-decoration: none;">#66</a> Исправлен баг в методе <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">Trade()</code> (ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--trade</code>). Теперь, в случае если основной рыночный ордер по инструменту не был исполнен, то TP/SL ордеры также не выставляются для этого инструмента. В предыдущих версиях TP/SL ордеры открывались даже в случае ошибок при открытии рыночного ордера, к которому они привязаны, что нарушало логику торговых сценариев.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/84/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/84" style="box-sizing: border-box; text-decoration: none;">#84</a> Исправлен баг в методе <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">Overview()</code> (ключ <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--overview</code>), который появился после решения задачи <a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/17/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/17" style="box-sizing: border-box; text-decoration: none;">#17</a>. В секциях лимитных и стоп ордеров в отчёте о состоянии портфеля пользователя отображались только первые ордеры в списке. Сейчас снова отображаются все открытые ордеры. Кроме того, улучшена производительность: теперь для ордеров по одному и тому же инструменту цена запрашивается только один раз, что критично, в случае большого числа открытых ордеров.</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: black;"><a data-hovercard-type="issue" data-hovercard-url="/Tim55667757/TKSBrokerAPI/issues/81/hovercard" href="https://github.com/Tim55667757/TKSBrokerAPI/issues/81" style="box-sizing: border-box; text-decoration: none;">#81</a> Исправлено отображение дробных чисел при печати биржевого стакана.</span></li></ul><div><br /></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Noto Sans, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji"><span style="caret-color: rgb(201, 209, 217);">Успехов вам в автоматизации биржевой торговли! А платформа <b>TKSBrokerAPI</b> вам в этом поможет :)</span></span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Noto Sans, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji"><span style="caret-color: rgb(201, 209, 217);"><br /></span></span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Noto Sans, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji"><span style="caret-color: rgb(201, 209, 217);"><br /></span></span></div><div><i style="text-align: right;"><b>Поддержать проект:</b> <a href="https://yoomoney.ru/to/410015019068268">https://yoomoney.ru/to/410015019068268</a></i></div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-55425776657824601422022-11-10T16:14:00.000+03:002022-11-10T16:14:34.072+03:00Получаем и расширяем биржевые данные с помощью TKSBrokerAPI — платформы для автоматизации торговых сценариев<p style="text-align: left;">В <a href="https://forworktests.blogspot.com/2022/10/tksbrokerapi-python-api.html" target="_blank">прошлый раз</a> я показал, как можно автоматизировать торговый сценарий на Python с помощью <a href="https://github.com/Tim55667757/TKSBrokerAPI" target="_blank">TKSBrokerAPI</a>. Это платформа для упрощения автоматизации торгов на бирже, которая работает через <a href="http://tinkoff.ru/sl/AaX1Et1omnH" target="_blank">Tinkoff Invest</a> REST API. Всё начинается с вашей гениальной торговой идеи и завершается автоматизацией сценария, а TKSBrokerAPI берёт на себя всю работу с инфраструктурой брокера.</p><p style="text-align: left;"></p><p></p><p style="text-align: left;">Но откуда же взять этот «гениальный торговый алгоритм»? Платформа TKSBrokerAPI поможет и для решения задачи получения первичных, «сырых» данных по торговым инструментам (акции, облигации, фонды, фьючерсы и валюты) с сервера брокера, для их последующего анализа в любом удобном для вас аналитическом инструменте.</p><p style="text-align: left;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqNiMiZ3u7JPn8xBklFOjqgSDNJ6YlC_ofwefy9DkrlQojGPgP0AjlEsERfnX1ADyf9X4-dQPdWHbroTG3INIdfawHUJhY6kQ1DWdPaZKkesiG7DU2CGx4SVxbIX3oxp9t0YQqrX-aDtzk8Qs4Fff0gUbRWiGLVf0_-Vynf-M-N8YWHyd2AmFKaKZdDQ/s2649/TKSBrokerAPI-extend-data-flow.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1109" data-original-width="2649" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqNiMiZ3u7JPn8xBklFOjqgSDNJ6YlC_ofwefy9DkrlQojGPgP0AjlEsERfnX1ADyf9X4-dQPdWHbroTG3INIdfawHUJhY6kQ1DWdPaZKkesiG7DU2CGx4SVxbIX3oxp9t0YQqrX-aDtzk8Qs4Fff0gUbRWiGLVf0_-Vynf-M-N8YWHyd2AmFKaKZdDQ/w640-h268/TKSBrokerAPI-extend-data-flow.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: right;"><i><b style="text-align: left;">Поддержать проект: </b><a href="https://yoomoney.ru/to/410015019068268" style="text-align: left;">https://yoomoney.ru/to/410015019068268</a></i></div><p></p><a name='more'></a><p></p><p style="text-align: left;">Для этого в методах модуля TKSBrokerAPI предусмотрена возможность обогащения, расширения и сохранения данных в классических форматах: XLSX и CSV (для анализа в табличных редакторах), Markdown (для удобства чтения), а также Pandas DataFrame (для датасайнтистов и биржевых аналитиков). Некоторые методы можно найти в разделе «<a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#Основные-возможности" target="_blank">Основные возможности</a>» или в полной «<a href="https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html" target="_blank">API-документации</a>» на модуль TKSBrokerAPI.</p><p style="text-align: left;">В качестве «сырых» данных может быть всё, что <a href="https://tinkoff.github.io/investAPI/swagger-ui/" target="_blank">возможно получить</a> с сервера брокера. После обогащения из этих данных можно построить, например, <a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#Построить-календарь-выплат-по-облигациям" target="_blank">сводный календарь</a> выплат по облигациям и подсчитать их <a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#Получить-обогащённые-данные-по-облигациям" target="_blank">купонные и текущие доходности</a>, или можно сформировать аналитику о состоянии портфеля пользователя и <a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#Получить-текущий-портфель-пользователя-и-статистику-распределения-активов" target="_blank">распределении активов</a> по типам, компаниям, отраслям, валютам и странам.<span style="background-color: white;"> <span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">Кроме того, можно скачать </span><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#%D0%A1%D0%BA%D0%B0%D1%87%D0%B0%D1%82%D1%8C-%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B2-%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B5-OHLCV-%D1%81%D0%B2%D0%B5%D1%87%D0%B5%D0%B9" style="box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; text-decoration: none;">исторические данные</a><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> по ценам любого инструмента в виде OHLCV-свечей.</span></span></p><p style="text-align: left;">Как обогащаются и используются данные в TKSBrokerAPI:</p><p style="text-align: left;"></p><ol style="text-align: left;"><li>Вы запрашиваете нужные вам данные с сервера брокера с помощью модуля TKSBrokerAPI:</li><ul><li>в этом модуле почти все методы возвращают «сырые» данные в виде словаря Python.</li></ul><li>Далее происходит их обработка, обогащение и расширение:</li><ul><li>добавляются различные статистические данные, параметры и некоторые аналитические отчёты.</li></ul><li>После обогащения данные сохраняются в пригодном для дальнейшего анализа виде:</li><ul><li>большинство методов возвращают обогащённые данные в виде словаря Python или Pandas DataFrame;</li><li>если вы запускали платформу TKSBrokerAPI в консоли, то данные будут сохранены в форматах XLSX, CSV или Markdown.</li></ul><li>Далее можно загрузить данные в привычную вам аналитическую систему и использовать различные методы анализа данных для поиска и выделения в них зависимостей, корреляций, делать прогнозы и строить предположения.</li><li>Далее, на основе анализа данных, вы придумываете тот самый «гениальный торговый алгоритм».</li><li>Автоматизируете торговый сценарий (<a href="https://forworktests.blogspot.com/2022/10/tksbrokerapi-python-api.html" target="_blank">по предыдущей схеме</a>).</li><li>Профит!</li></ol>Как начать работать с платформой TKSBrokerAPI я уже писал <a href="https://forworktests.blogspot.com/2022/07/tksbrokerapi-python-api-tinkoff-open.html" target="_blank">в одной из предыдущих статей</a>, повторно останавливаться на формате команд не буду. Давайте сразу рассмотрим некоторые примеры получения и обогащения данных.<p></p><h4 style="text-align: left;"><span style="font-size: large;">Получить все данные по всем инструментам, доступным на бирже</span></h4><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217);"><span style="font-size: xx-small;"><br /></span></span></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#Локальный-кэш-данных" target="_blank">Используется команда</a>: </span><span face="ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace" style="caret-color: rgb(201, 209, 217); font-size: 13.6px;">t<span style="font-family: courier;">ksbrokerapi -v 10 --list-xlsx</span></span></div><div><br /></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">Начиная с </span><a href="https://github.com/Tim55667757/TKSBrokerAPI/releases/tag/1.4.90" style="caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px;" target="_blank">TKSBrokerAPI v1.4.90</a><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> вы можете использовать ключ </span><code style="border-radius: 6px; box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--list-xlsx</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> (</span><code style="border-radius: 6px; box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">-x</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">), чтобы сохранить сырые данные по доступным инструментам в формате XLSX, пригодном для дальнейшей обработки датасайнтистами или биржевыми аналитиками. При этом запрашивается вся информация с сервера брокера по инструментам, доступным для текущего пользователя. Также данные по инструментам берутся из локального кеша </span><code style="border-radius: 6px; box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">dump.json</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">, затем они обогащаются и трансформируются в XLSX-формат и сохраняются в файл </span><code style="border-radius: 6px; box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">dump.xlsx</code><span style="caret-color: rgb(201, 209, 217); font-size: 16px;">.</span></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><br /></span></div><p dir="auto" style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Пример полученных данных можно посмотреть в файле <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/media/dump.xlsx" style="box-sizing: border-box; text-decoration: none;">./docs/media/dump.xlsx</a>. Что означают заголовки в XLSX-файле, смотрите в разделах документации: <span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">«</span><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%BE%D0%B1%D0%BE%D0%B3%D0%B0%D1%89%D1%91%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE-%D0%BE%D0%B1%D0%BB%D0%B8%D0%B3%D0%B0%D1%86%D0%B8%D1%8F%D0%BC" style="box-sizing: border-box; text-decoration: none;">Получить обогащённые данные по облигациям</a><span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">»</span> и <span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">«</span><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop#%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C-%D0%BA%D0%B0%D0%BB%D0%B5%D0%BD%D0%B4%D0%B0%D1%80%D1%8C-%D0%B2%D1%8B%D0%BF%D0%BB%D0%B0%D1%82-%D0%BF%D0%BE-%D0%BE%D0%B1%D0%BB%D0%B8%D0%B3%D0%B0%D1%86%D0%B8%D1%8F%D0%BC" style="box-sizing: border-box; text-decoration: none;">Построить календарь выплат по облигациям</a><span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">»</span>.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF74ZgopWWvbKPMi5T3rtvORO8LCF5Uj3w1t8hAdLPBvhK3dh-JTW1cDl4VtAKiPKOlAzX67w22dkqSrtKZWv5Zwb-zZiMQHXwsJuTylumuXEGzkECg6lrardTSXav6xFnyFfBcZ9Nkiz62Hr8c4cs5AkmqkjDTdh4GMyzbs8vh9y61hVNRpyiA1KIKg/s2879/dump.xlsx.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1209" data-original-width="2879" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF74ZgopWWvbKPMi5T3rtvORO8LCF5Uj3w1t8hAdLPBvhK3dh-JTW1cDl4VtAKiPKOlAzX67w22dkqSrtKZWv5Zwb-zZiMQHXwsJuTylumuXEGzkECg6lrardTSXav6xFnyFfBcZ9Nkiz62Hr8c4cs5AkmqkjDTdh4GMyzbs8vh9y61hVNRpyiA1KIKg/w640-h268/dump.xlsx.png" width="640" /></a></div><br /><h4><span style="font-size: large;">Получить обогащённые данные по всем облигациям</span></h4><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217);"><span style="font-size: xx-small;"><br /></span></span></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#Получить-обогащённые-данные-по-облигациям" target="_blank">Используется команда</a>: </span><span style="caret-color: rgb(201, 209, 217); font-family: courier; font-size: 13.6px;">tksbrokerapi -v 10 --bonds-xlsx</span></div><div><br /></div><div><a href="https://github.com/Tim55667757/TKSBrokerAPI/releases/tag/1.4.90" style="caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px;" target="_blank">TKSBrokerAPI v1.4.90</a><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> </span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">содержит новую консольную команду</span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> </span><code style="border-radius: 6px; box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--bonds-xlsx</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> </span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">(</span><code style="border-radius: 6px; box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">-b</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">). При запуске будут получены все доступные облигации (если указать только ключ) или список облигаций (если перечислить FIGI или тикеры), а затем обогащены данными и преобразованы в более широкий Pandas DataFrame с дополнительной информацией: текущие цены, календарь платежей по облигациям, купонные доходности, текущие доходности (зависящие от цены) и некоторые другие статистические данные.</span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji"><span style="caret-color: rgb(201, 209, 217);"><br /></span></span><p dir="auto" style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Затем эти данные экспортируются в XLSX-файл, пригодный для дальнейшего анализа датасайнтистами или биржевыми аналитиками, по умолчанию: <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">ext-bonds.xlsx.</code></p><p dir="auto" style="box-sizing: border-box; caret-color: rgb(201, 209, 217); margin-bottom: 16px; margin-top: 0px;"><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="font-size: 16px;">Это достаточно долгая операция, если с сервера брокера запрашивается слишком много или все облигации (ограничение: ~90-120 обогащённых информацией облигаций в минуту, в зависимости от пользовательских лимитов ограничения скорости).</span></p><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">Что означают заголовки в обогащённом XLSX-файле или в Pandas DataFrame </span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">смотрите в разделе документации: </span>«<a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/develop#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%BE%D0%B1%D0%BE%D0%B3%D0%B0%D1%89%D1%91%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE-%D0%BE%D0%B1%D0%BB%D0%B8%D0%B3%D0%B0%D1%86%D0%B8%D1%8F%D0%BC" style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; text-decoration: none;">Получить обогащённые данные по облигациям</a><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><span style="caret-color: rgb(0, 0, 0); font-size: medium;">»</span>.</span></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><br /></span></div><p dir="auto" style="box-sizing: border-box; caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Пример генерируемого XLSX-файла, с обогащёнными данными по облигациям, можно посмотреть здесь: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/media/ext-bonds.xlsx" style="box-sizing: border-box; text-decoration: none;">./docs/media/ext-bonds.xlsx</a>.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ9WR_5ji-QpX0uoBvO0BvgMdAlFnxLcPWX0cW0fyOsUCmmbjxf-FJyK5xdnxmGOzGcqW1MRe0veWKi60KXw2-unbrdfuT2q5MOzSn8H-un7-NCpjDWNnsvk63MDjW-PQY-I_pTk8qE05htXwWqktcu7sIGbpqcV7ERJnuMvueK3gOK9NFjOltU5uyGw/s2879/ext-bonds.xlsx.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1224" data-original-width="2879" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ9WR_5ji-QpX0uoBvO0BvgMdAlFnxLcPWX0cW0fyOsUCmmbjxf-FJyK5xdnxmGOzGcqW1MRe0veWKi60KXw2-unbrdfuT2q5MOzSn8H-un7-NCpjDWNnsvk63MDjW-PQY-I_pTk8qE05htXwWqktcu7sIGbpqcV7ERJnuMvueK3gOK9NFjOltU5uyGw/w640-h272/ext-bonds.xlsx.png" width="640" /></a></div><br /><h4><span style="font-size: large;">Построить календарь выплат по облигациям</span></h4><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217);"><span style="font-size: xx-small;"><br /></span></span></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#построить-календарь-выплат-по-облигациям" target="_blank">Используется команда</a>: </span><span style="caret-color: rgb(201, 209, 217); font-family: courier; font-size: 13.6px;">tksbrokerapi -v 10 --calendar RU000A1002C2 IBM RU000A101YV8 BBG00JS9D851</span></div><div><br /></div><div>В <a href="https://github.com/Tim55667757/TKSBrokerAPI/releases/tag/1.4.90" style="caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px;" target="_blank">TKSBrokerAPI v1.4.90</a><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> </span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;">имеется консольная </span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"">команда</span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji""> </span><code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--calendar</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji""> </span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"">(</span><code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">-c</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"">). Это действие отображает календарь платежей по облигациям в виде таблицы. Календарь строится для одной облигации или списка заданных тикеров или FIGI, либо для всех облигаций сразу, если после ключа не указывать никаких значений.</span></span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji"><span style="caret-color: rgb(201, 209, 217);"><br /></span></span><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><p dir="auto" style="box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Также календарь экспортируется в XLSX-файл для дальнейшего использования датасайнтистами или биржевыми аналитиками, по умолчанию в <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">calendar.xlsx.</code></p><p dir="auto" style="box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Для календаря в виде Pandas DataFrame заголовки данных аналогичны тем, которые описаны в поле <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">calendar</code> в разделе документации <span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">«</span><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%BE%D0%B1%D0%BE%D0%B3%D0%B0%D1%89%D1%91%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE-%D0%BE%D0%B1%D0%BB%D0%B8%D0%B3%D0%B0%D1%86%D0%B8%D1%8F%D0%BC" style="box-sizing: border-box; text-decoration: none;">Получить обогащённые данные по облигациям</a><span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">»</span>, под спойлером. Заголовки календаря для XLSX-файла перед сохранением приводятся в более человеко-читаемый формат, их можно посмотреть в разделе документации <span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">«</span><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#построить-календарь-выплат-по-облигациям" target="_blank">Построить календарь выплат по облигациям</a><span face="-webkit-standard" style="caret-color: rgb(0, 0, 0); font-size: medium;">»</span>.</p><p dir="auto" style="box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;"><span style="background-color: white;">Пример генерируемого XLSX-файла с календарём выплат по облигациям, можно посмотреть здесь: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/media/calendar.xlsx" style="box-sizing: border-box; caret-color: rgb(0, 0, 0); text-decoration: none;">./docs/media/calendar.xlsx</a>, а в виде Markdown-файла, здесь: <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/media/calendar.md" style="box-sizing: border-box; caret-color: rgb(0, 0, 0); text-decoration: none;">./docs/media/calendar.md</a>. В случае, если календарь строится более чем для одной облигации, то платежи в один и тот же месяц группируются.</span></p></span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtgZN-wHKn5JvHfNTtKLvtasL0cKZcZ2YWusGMmWjJNqE-CcKdDM2dvvtUJYLnuSg8-c5TbJS27wPPQcJvje5We6lcg_8DWfIXo7ZT1d1K0WXSoT1l2sDkwml0G05RBWRqDKUYoDpHfQQwktArI9EiFrRjC2bs_Fix9ib4bQJSooeKLEEgI-zGNxZpzQ/s2879/calendar.xlsx.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1225" data-original-width="2879" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtgZN-wHKn5JvHfNTtKLvtasL0cKZcZ2YWusGMmWjJNqE-CcKdDM2dvvtUJYLnuSg8-c5TbJS27wPPQcJvje5We6lcg_8DWfIXo7ZT1d1K0WXSoT1l2sDkwml0G05RBWRqDKUYoDpHfQQwktArI9EiFrRjC2bs_Fix9ib4bQJSooeKLEEgI-zGNxZpzQ/w640-h272/calendar.xlsx.png" width="640" /></a></div><br /><h4><span style="font-size: large;">Получить историю цен заданного инструмента</span></h4><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217);"><span style="font-size: xx-small;"><br /></span></span></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"><a href="https://github.com/Tim55667757/TKSBrokerAPI/tree/master#скачать-исторические-данные-в-формате-ohlcv-свечей" target="_blank">Используется команда</a>:</span></div><div><span style="caret-color: rgb(201, 209, 217); font-family: courier; font-size: 13.6px;">tksbrokerapi -v 10 --ticker GAZP --history 2022-10-15 2022-10-17 --interval hour --output GAZP_hour.csv --render-chart interact</span></div><div><br /></div><div>В <a href="https://github.com/Tim55667757/TKSBrokerAPI/releases/tag/1.4.90" style="caret-color: rgb(201, 209, 217); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px;" target="_blank">TKSBrokerAPI v1.4.90</a><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="caret-color: rgb(201, 209, 217); font-size: 16px;"> </span><span style="background-color: white;">можно получать исторические данные в формате OHLCV-свечей и </span><span style="background-color: white;">дополнительно строить их интерактивные или статические графики (для этого используется библиотека</span><span style="background-color: white;"> </span><a href="https://github.com/Tim55667757/PriceGenerator" style="background-color: white; box-sizing: border-box; text-decoration: none;">PriceGenerator</a><span style="background-color: white;">). Источником цен при этом могут быть как загруженные с сервера данные, так и ранее сохранённые файлы в формате CSV. </span><span style="background-color: white;">Для построения графиков цен используется общий ключ</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--render-chart</code><span style="background-color: white;">, который нужно указать совместно с одним из ключей</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--history</code><span style="background-color: white;"> </span><span style="background-color: white;">(загрузка данных с сервера) или</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--load-history</code><span style="background-color: white;"> </span><span style="background-color: white;">(загрузка из CSV-файла).</span></div><div><span style="background-color: white;"><br /></span></div><div><span style="background-color: white;">Для получения исторических цен с сервера также нужно указать инструмент с ключами</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--ticker</code><span style="background-color: white;"> </span><span style="background-color: white;">или</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--figi</code><span style="background-color: white;"> </span><span style="background-color: white;">(FIGI идентификатор) и задать интервал свечи с помощью ключа</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--interval</code><span style="background-color: white;">. </span><span style="background-color: white;">TKSBrokerAPI сохраняет историю в </span><span style="background-color: white;">CSV-</span><span style="background-color: white;">файл или возвращает Pandas DataFrame. </span><span style="background-color: white;">История скачивается между двумя заданными датами:</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">start</code><span style="background-color: white;"> </span><span style="background-color: white;">и</span><span style="background-color: white;"> </span><code style="background-color: white; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">end</code><span style="background-color: white;">, а также поддерживается докачка данных.</span><span style="background-color: white;"> </span><span style="background-color: white;">Сервер брокера по умолчанию использует время в формате ISO UTC.</span></div><div><br /></div><p dir="auto" style="box-sizing: border-box; margin-bottom: 16px; margin-top: 0px;"><span style="background-color: white;">Построенные графики различного типа по умолчанию сохраняются в файл <code style="border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">index.html</code>. На них дополнительно отображаются некоторые статистические значения и индикаторы, однако они представлены лишь для поверхностного ознакомления с поведением цены в заданном диапазоне. Для проведения полноценных аналитических исследований и технического анализа рекомендуется использовать иные профессиональные средства.</span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://raw.githubusercontent.com/Tim55667757/PriceGenerator/master/media/index.html.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="423" data-original-width="800" height="338" src="https://raw.githubusercontent.com/Tim55667757/PriceGenerator/master/media/index.html.png" width="640" /></a></div><p style="text-align: left;">Вопрос, какие методы и инструменты для работы с данными применить для анализа получаемой информации, выходит за рамки этой статьи. Однако, чтобы вы не использовали, платформа TKSBrokerAPI поможет вам и для задачи получения первичных, «сырых» данных, и для задачи автоматизации придуманной вами стратегии.</p><p style="text-align: left;"><br /></p><p style="text-align: left;"><b>Поддержать проект: </b><a href="https://yoomoney.ru/to/410015019068268">https://yoomoney.ru/to/410015019068268</a></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-63182277996195522302022-10-01T17:59:00.010+03:002022-11-10T01:33:37.582+03:00TKSBrokerAPI: демонстрация некоторых возможностей торговли на бирже через Python API<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikxGB77AGma8fzWPacvIS-4O1O3FUCMdm8haa9pJr0QH3dSxKgQ-5k9FTv7wSMvCZdAKch7bDC067HzaG9AUQezT52igGm1knqfLATcNh5MbtieVpTDtt8zuPkqfSOjUgGBOG8HF1qk5Mf_104Xe-spalzttc_Zc_lSpZodQCNzQ5fZ-XUY4kruHS9Lg/s2192/TKSBrokerAPI-flow.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1006" data-original-width="2192" height="294" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikxGB77AGma8fzWPacvIS-4O1O3FUCMdm8haa9pJr0QH3dSxKgQ-5k9FTv7wSMvCZdAKch7bDC067HzaG9AUQezT52igGm1knqfLATcNh5MbtieVpTDtt8zuPkqfSOjUgGBOG8HF1qk5Mf_104Xe-spalzttc_Zc_lSpZodQCNzQ5fZ-XUY4kruHS9Lg/w640-h294/TKSBrokerAPI-flow.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: right;"><b>Поддержать проект:</b> <a href="https://yoomoney.ru/to/410015019068268">https://yoomoney.ru/to/410015019068268</a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div>В <a href="https://forworktests.blogspot.com/2022/07/tksbrokerapi-python-api-tinkoff-open.html" target="_blank">прошлой статье</a> я рассказал про опенсорс разработку — платформу <b>TKSBrokerAPI</b> — это Python API для работы с Tinkoff Open API через REST протокол. Также этим инструментом можно пользоваться из консоли или встраивать его в CI/CD-системы, для автоматизации рутинных операций на бирже, через брокера Тинькофф Инвестиции.</div><div><br /></div><div>С помощью TKSBrokerAPI вы можете реализовать на языке Python любой торговый сценарий. В сегодняшней статье я хочу показать для разработчиков некоторые возможности этого инструмента, на примере абстрактного торгового сценария.</div><div><br /></div><div>Неважно, какую основную систему принятия торговых решений о покупке или продаже вы используете. Это может быть технический анализ, нейросети, парсинг отчётов или слежение за сделками других трейдеров. Но всё равно вам потребуется выполнять базовые торговые операции: получать рыночные данные, выставлять лимитные и стоп-ордера, открывать и закрывать сделки по рынку. Модуль TKSBrokerAPI будет выступать как посредник между кодом с логикой торгов и сервисной инфраструктурой брокера, а также выполнять рутинные задачи от вашего имени в брокерском аккаунте.</div><div><br /></div><div>Схема разработки с помощью TKSBrokerAPI очень простая:</div><div><ol style="text-align: left;"><li>Вы придумываете гениальный торговый алгоритм.</li><li>Записываете его пошагово в виде некоторого плана или торгового сценария.</li><li>Автоматизируете сценарий на Python при помощи TKSBrokerAPI.</li><li>TKSBrokerAPI берёт на себя всю работу с инфраструктурой брокера Тинькофф Инвестиции.</li><li>Профит!</li></ol></div><div><br /></div><span><a name='more'></a></span><h2 style="text-align: left;"><span style="font-size: large;">С чего начать</span></h2><div><div>Проще всего установить TKSBrokerAPI через PyPI:</div><div><br /></div><div><span style="font-family: courier;">pip install tksbrokerapi</span></div></div><div><br /></div><div>Либо скачать код проекта <a href="https://github.com/Tim55667757/TKSBrokerAPI">TKSBrokerAPI</a> из гитхаб-репозитория.</div><div><br /></div><div>Перед тем, как использовать API, вам нужно создать себе аккаунт у брокера <a href="http://tinkoff.ru/sl/AaX1Et1omnH" target="_blank">Тинькофф Инвестиции</a>. Для аутентификации через API вам также понадобятся <a href="https://github.com/Tim55667757/TKSBrokerAPI#аутентификация" target="_blank">токен и идентификатор счёта пользователя</a>. Полная документация по всем доступным свойствам и методам TKSBrokerAPI находится <a href="https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html" target="_blank">по ссылке</a>. Соответствие консольных ключей и методов также можно посмотреть в документации в разделе "<a href="https://github.com/Tim55667757/TKSBrokerAPI#Основные-возможности" target="_blank">Основные возможности</a>".</div><div><br /></div><div><div><b>Важное замечание</b>: модуль TKSBrokerAPI не предназначен для высокочастотной (HFT) торговли, из-за системы динамического формирования лимитов для пользователей сервиса TINKOFF INVEST API (подробнее <a href="https://tinkoff.github.io/investAPI/limits/" target="_blank">по ссылке</a>). В среднем, это 50-300 запросов в секунду, в зависимости от их типа, что очень мало для требований к скоростям HFT (но есть <a href="https://tinkoff.github.io/investAPI/speedup/" target="_blank">несколько рекомендаций</a> по ускорению исполнения поручений). Однако вы вполне можете использовать API для автоматизации своих интрадей, кратко-, средне- и долгосрочных торговых стратегий.</div><div><br /></div><h2 style="text-align: left;"><span style="font-size: large;">Пример реализации абстрактного сценария</span></h2><div>Так как функциональность<b> </b>TKSBrokerAPI достаточно обширная, мне не хочется акцентировать внимание на конкретных торговых сценариях, а лишь указать некоторые возможности для их автоматизации. Давайте рассмотрим один сценарий, основанный на сравнении объёмов текущих покупок и продаж в биржевом стакане, и реализуем его при помощи API, без использования дополнительных методов технического анализа.</div><div><br /></div><div>Действия будут следующие:</div></div><div><div><ul style="text-align: left;"><li>запросить текущий портфель клиента и определить доступные для торговли средства;</li><li>запросить стакан цен с глубиной 20 для выбранных инструментов, например, акции с тикерами `YNDX`, `IBM` и `GOOGLE`;</li><li>если инструмент ранее ещё не был куплен, то проверить:</li><ul><li>если резерв денежных средств (свободный кеш) в валюте инструмента больше, чем 5% от общей стоимости всех инструментов в этой валюте, то проверить:</li><ul><li>если в стакане объёмы на покупку больше объёмов на продажу минимум на 10%, то купить 1 акцию по рынку и выставить тейк-профит как стоп-ордер на 3% выше текущей цены покупки со сроком действия 1 час;</li></ul></ul><li>если инструмент имеется в списке открытых позиций, то проверить:</li><ul><li>если текущая цена уже выше средней цены позиции хотя бы на 2.5%, то выставить отложенный лимитный ордер на весь объём, но ещё чуть-чуть выше (на 0.1%) от текущей цены, чтобы позиция закрылась с профитом с большой вероятностью в течении текущей торговой сессии;</li></ul><li>после всех торговых операций напечатать в консоль текущее состояние портфеля пользователя.</li></ul></div><div>Для понимания примера сохраните и запустите скрипт под спойлером ниже (или скачайте его <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/docs/examples/scenario1.py" target="_blank">по ссылке</a>). Не забудьте перед этим подставить свой token и accountId в разделе инициализации в коде. Большая часть кода подробно прокомментирована и даны ссылки на соответствующие методы API.</div></div><div><br />
<div class="headline" onclick="showBlock('hidd_main')"><b>Пример кода с торговым сценарием</b></div>
<div class="hidden" id="hidd_main" style="font-family: "courier new"; font-size: 14px; overflow-x: auto;"><pre class="brush:python"># -*- coding: utf-8 -*-
# Author: Timur Gilmullin
# --- Секция инициализации: импорты, константы и переменные ------------------------------------------------------------
from datetime import datetime, timedelta
from dateutil.tz import tzlocal, tzutc
from math import ceil
from tksbrokerapi.TKSBrokerAPI import TinkoffBrokerServer, uLogger # основной модуль для выполнения торговых операций
uLogger.level = 10 # DEBUG (10) уровень логирования, рекомендованный по умолчанию для `TKSBrokerAPI.log`
uLogger.handlers[0].level = 20 # уровень логирования для вывода в консоль STDOUT, INFO (20) рекомендовано по умолчанию
start = datetime.now(tzutc())
uLogger.debug("=--=" * 20)
uLogger.debug("Trading scenario started at: [{}] UTC, it is [{}] local time".format(
start.strftime("%Y-%m-%d %H:%M:%S"),
start.astimezone(tzlocal()).strftime("%Y-%m-%d %H:%M:%S"),
))
# Установите здесь переменные и константы, необходимые для торговли по вашему алгоритму:
TICKERS_LIST_FOR_TRADING = ["YNDX", "IBM", "GOOGL"] # Вы можете задать список инструментов различным образом: перечислить их напрямую или задать как результат некоторой функции фильтрации или скринера
RESERVED_MONEY = 0.05 # Доля резервируемых средств (от 0 до 1), не участвующих в торгах, 0.05 (это 5%) по умолчанию
LOTS = 1 # Минимальное число лотов для покупки или продажи
TP_STOP_DIFF = 0.03 # 3% тейк-профит по умолчанию для стоп-ордеров
TP_LIMIT_DIFF = 0.025 # 2.5% тейк-профит по умолчанию для отложенных лимитных ордеров
TOLERANCE = 0.001 # Допустимое отклонение текущей рыночной цены от целевой цены установленных ордеров, 0.1% по умолчанию
DEPTH_OF_MARKET = 20 # Насколько глубоко запрашивать стакан цен для анализа текущих объёмов торгов, >= 1
VOLUME_DIFF = 0.1 # Достаточная разница в объёмах текущих предложений на покупку и продажу для открытия позиции, 10% по умолчанию
# Инициализация основного объекта трейдера, TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.__init__
trader = TinkoffBrokerServer(
token="", # Внимание! Установите строку с вашим токеном сюда или используйте переменную окружения `TKS_API_TOKEN`
accountId="", # Внимание! Установите строку с вашим accountId сюда или используйте переменную окружения `TKS_ACCOUNT_ID`
)
# --- Секция описания торгового сценария -------------------------------------------------------------------------------
for ticker in TICKERS_LIST_FOR_TRADING:
uLogger.info("--- Ticker [{}], data analysis...".format(ticker))
# - Шаг 1: запрос текущего портфеля клиента и определение доступных объёмов и валют для торговли
# Портфель пользователя. Это словарь с несколькими секциями: {"raw": {...}, "stat": {...}, "analytics": {...}}
portfolio = trader.Overview(showStatistics=False) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.Overview
uLogger.info("Total portfolio cost: {:.2f} rub; blocked: {:.2f} rub; changes: {}{:.2f} rub ({}{:.2f}%)".format(
portfolio["stat"]["portfolioCostRUB"],
portfolio["stat"]["blockedRUB"],
"+" if portfolio["stat"]["totalChangesRUB"] > 0 else "", portfolio["stat"]["totalChangesRUB"],
"+" if portfolio["stat"]["totalChangesPercentRUB"] > 0 else "", portfolio["stat"]["totalChangesPercentRUB"],
))
# Сколько денег в различных валютах доступно для торговли? Нужно посчитать (total - blocked).
funds = portfolio["stat"]["funds"] # Словарь, например: {"rub": {"total": 10000.99, "totalCostRUB": 10000.99, "free": 1234.56, "freeCostRUB": 1234.56}, "usd": {"total": 250.55, "totalCostRUB": 15375.80, "free": 125.05, "freeCostRUB": 7687.50}, ...}
uLogger.info("Available funds free for trading: {}".format("; ".join(["{:.2f} {}".format(funds[currency]["free"], currency) for currency in funds.keys()])))
# - Шаг 2: запрос стакана цен для текущего инструмента
trader.ticker = ticker
trader.figi = "" # Мы не знаем FIGI для каждого тикера, поэтому указываем здесь пустую строку. В этом случае TKSBrokerAPI определит FIGI автоматически.
trader.depth = DEPTH_OF_MARKET
# Получаем цены брокера для текущего инструмента:
ordersBook = trader.GetCurrentPrices(showPrice=False) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.GetCurrentPrices
if not (ordersBook["buy"] and ordersBook["sell"]):
uLogger.warning("Not possible to trade an instrument with the ticker [{}]! Try again later.".format(trader.ticker))
else:
# - Шаг 3: если инструмент отсутствует в списке текущих открытых позиций пользователя, то проверяем:
# - если денежный резерв (свободные деньги) в валюте инструмента больше, чем 5% от общей стоимости
# всех инструментов в этой валюте, то проверяем:
# - если объёмы покупателей в стакане больше хотя бы на 10% чем объёмы продавцов, тогда покупаем 1 лот инструмента
# по рынку и размещаем тейк-профит как стоп-ордер на 3% выше, чем текущая цена покупки, с отменой ордера через 1 час;
# Проверяем, есть ли открытые позиции по текущему инструменту, заданному через `ticker`, в портфеле пользователя:
isInPortfolio = trader.IsInPortfolio(portfolio) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.IsInPortfolio
if not isInPortfolio:
uLogger.info("Ticker [{}]: no current open positions with that instrument, checking opens rules...".format(trader.ticker))
# Так как инструмента нет среди открытых позиций, то получаем данные по инструменту и его валюте у брокера:
rawIData = trader.SearchByTicker(requestPrice=False, showInfo=False, debug=False) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.SearchByTicker
iCurr = rawIData["currency"] # валюта текущего инструмента
# Получаем аналитику портфеля: распределение активов по валютам, стоимость ранее купленных активов и доступный свободный остаток:
distrByCurr = portfolio["analytics"]["distrByCurrencies"] # распределение активов по валютам, оценка стоимости в рублях
assetsCostInRuble = distrByCurr[iCurr]["cost"] # стоимость активов в валюте инструмента, пересчитанная в рубли
currencyFreeCostInRuble = funds[iCurr]["freeCostRUB"] # оценка свободных средств, пересчитанная в рублях, для валюты текущего инструмента
# Прежде чем совершить сделку, проверяем резервы и разницу объёмов спроса и предложения, в соответствии с заданными параметрами:
if currencyFreeCostInRuble / assetsCostInRuble >= RESERVED_MONEY:
sumSellers = sum([x["quantity"] for x in ordersBook["buy"]]) # текущий объём предложений продавцов в стакане (у продавцов можно купить)
sumBuyers = sum([x["quantity"] for x in ordersBook["sell"]]) # текущий объём предложений покупателей в стакане (покупателям можно продать)
if sumBuyers >= sumSellers * (1 + VOLUME_DIFF):
# Получаем текущую цену, вычисляем цену потенциального тейк-профита и срок действия для стоп-ордера:
currentPriceToBuy = ordersBook["buy"][0]["price"] # первая цена в списке ордеров продавцов и есть актуальная цена, по которой можно купить
target = currentPriceToBuy * (1 + TP_STOP_DIFF) # целевая цена для тейк-профита, без учёта шага изменения цены
targetStop = ceil(target / rawIData["step"]) * rawIData["step"] # реальная цена тейк-профита для размещения стоп-ордера, с учётом допустимого шага цены
localAliveTo = (datetime.now() + timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S") # текущее время + 1 час
uLogger.info("Opening BUY position... (Buyers volumes [{}] >= {} * sellers volumes [{}] and current price to buy: [{:.2f} {}])".format(
sumBuyers, 1 + VOLUME_DIFF, sumSellers, currentPriceToBuy, iCurr,
))
# Открываем BUY позицию по рынку и создаём стоп-ордер по желаемой цене тейк-профита:
trader.Buy(lots=LOTS, tp=targetStop, sl=0, expDate=localAliveTo) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.Buy
else:
uLogger.info("BUY position not opened, because buyers volumes [{}] < {} * sellers volumes [{}]".format(sumBuyers, 1 + VOLUME_DIFF, sumSellers))
else:
uLogger.info("BUY position not opened, because the reserves in [{}] will be less than {:.2f}% of free funds".format(iCurr, RESERVED_MONEY * 100))
else:
# - Шаг 4: если по инструменту уже была открыта позиция, то проверяем:
# - если текущая средняя цена позиции хотя бы на 2.5% выше, чем средняя цена покупки, то размещаем отложенный
# лимитный ордер на весь объём позиции по цене на 0.1% выше, чем текущая рыночная цена. Это нужно для того, чтобы позиция
# закрылась с профитом, с большой вероятностью в течение текущей торговой сессии.
uLogger.info("Ticker [{}]: there is an open position with that instrument, checking closure rules...".format(trader.ticker))
# Получаем информацию по инструменту из списка текущих открытых позиций в портфеле пользователя:
iData = trader.GetInstrumentFromPortfolio(portfolio) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.GetInstrumentFromPortfolio
# Вычисляем количество доступных лотов для продажи, среднюю цену позиции и текущую рыночную цену инструмента:
lotsToSell = iData["volume"] - iData["blocked"] # не заблокированные лоты текущего инструмента, доступные для торговли
averagePrice = iData["average"] # средняя цена позиции
curPriceToSell = ordersBook["sell"][0]["price"] # первая цена в списке ордеров покупателей и есть актуальная цена, по которой можно продать инструмент
# Вычисляем цену с упреждением, по которой можно закрыть позицию, не дожидаясь строгого исполнения по цене тейк-профита:
curProfit = (curPriceToSell - averagePrice) / averagePrice # доля изменения между текущей рыночной ценой и средней позицией по инструменту
target = curPriceToSell * (1 + TOLERANCE) # достаточная цена для продажи
targetLimit = ceil(target / iData["step"]) * iData["step"] # целевая цена + упреждение, для размещения отложенного лимитного-ордера
# Проверяем на достаточную разницу в цене для профита:
if curProfit >= TP_LIMIT_DIFF:
uLogger.info("The current price is [{:.2f} {}], average price is [{:.2f} {}], so profit {:.2f}% more than {:.2f}%. Opening SELL pending limit order...".format(
curPriceToSell, iData["currency"], averagePrice, iData["currency"], curProfit * 100, TP_LIMIT_DIFF * 100,
))
# Открываем отложенный лимитный SELL ордер:
trader.SellLimit(lots=lotsToSell, targetPrice=targetLimit) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.SellLimit
else:
uLogger.info("SELL order not created, because the current price is [{:.2f} {}], average price is [{:.2f} {}], so profit {:.2f}% less than {:.2f}% target.".format(
curPriceToSell, iData["currency"], averagePrice, iData["currency"], curProfit * 100, TP_LIMIT_DIFF * 100,
))
# - Шаг 5: запрашиваем и отображаем изменения в портфеле пользователя после всех выполненных операций
uLogger.info("--- All trade operations finished. Let's show what we got in the user's portfolio after all trades.")
# Текущее состояние портфеля пользователя:
trader.Overview(showStatistics=True) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.Overview
# --- Секция финализации торговых операций -----------------------------------------------------------------------------
finish = datetime.now(tzutc())
uLogger.debug("Trading scenario work duration: [{}]".format(finish - start))
uLogger.debug("Trading scenario finished: [{}] UTC, it is [{}] local time".format(
finish.strftime("%Y-%m-%d %H:%M:%S"),
finish.astimezone(tzlocal()).strftime("%Y-%m-%d %H:%M:%S"),
))
uLogger.debug("=--=" * 20)
</pre></div>
</div><div><br /></div><div>Пусть вас не пугает кажущаяся сложность и объём кода. На самом деле, его большую часть занимают комментарии с примечаниями и логи, которые можно опустить в реальном проекте, а оставшийся алгоритм получится небольшим.</div><div><br /></div><div>В следующих статьях я планирую рассказать про новый опенсорс проект, в котором будут храниться готовые торговые шаблоны и стратегии, а также аналитика на Python с использованием модуля TKSBrokerAPI. Их можно будет подключать и использовать как самостоятельно, так и в составе ваших собственных торговых сценариев.</div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-36040513425126812562022-07-29T10:56:00.002+03:002022-11-10T16:27:22.162+03:00TKSBrokerAPI — python API для работы с Tinkoff Open API и доступа к торговому серверу брокера Тинькофф Инвестиции через REST протокол<p><b style="color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";">TKSBrokerAPI</b></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://app.travis-ci.com/Tim55667757/TKSBrokerAPI" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><img alt="Build Status" data-canonical-src="https://travis-ci.com/Tim55667757/TKSBrokerAPI.svg?branch=master" src="https://camo.githubusercontent.com/744019d83d9eff4e7edf215ee7f1eb8d761d796f853e3d8a7040e7513650b35f/68747470733a2f2f7472617669732d63692e636f6d2f54696d35353636373735372f544b5342726f6b65724150492e7376673f6272616e63683d6d6173746572" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://pypi.python.org/pypi/TKSBrokerAPI" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><img alt="pypi" data-canonical-src="https://img.shields.io/pypi/v/TKSBrokerAPI.svg" src="https://camo.githubusercontent.com/d6471a6b1ca09ba14308ef9f3de91237882c7bb4a85cb62036553717cff63a3a/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f544b5342726f6b65724150492e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/LICENSE" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><img alt="license" data-canonical-src="https://img.shields.io/pypi/l/TKSBrokerAPI.svg" src="https://camo.githubusercontent.com/5ceb124dc978b1fc5a6fd2b2472f25d39ad30d70ef34963debfa5286f8811840/68747470733a2f2f696d672e736869656c64732e696f2f707970692f6c2f544b5342726f6b65724150492e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://github.com/Tim55667757/TKSBrokerAPI/blob/master/README_EN.md" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><img alt="en-doc" data-canonical-src="https://badgen.net/badge/english/readme/pink" src="https://camo.githubusercontent.com/0838728bb541456f8572cce7483c37b789293809710399feeae9fcc6873f1a04/68747470733a2f2f62616467656e2e6e65742f62616467652f656e676c6973682f726561646d652f70696e6b" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><img alt="api-doc" data-canonical-src="https://badgen.net/badge/api-doc/TKSBrokerAPI/blue" src="https://camo.githubusercontent.com/30ed4cb1302de696f7c2860f8b72bb86f8cb92cfabc99f67f0d6cf57a636fed4/68747470733a2f2f62616467656e2e6e65742f62616467652f6170692d646f632f544b5342726f6b65724150492f626c7565" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://yoomoney.ru/quickpay/shop-widget?writer=seller&targets=%D0%94%D0%BE%D0%BD%D0%B0%D1%82%20(%D0%BF%D0%BE%D0%B4%D0%B0%D1%80%D0%BE%D0%BA)%20%D0%B4%D0%BB%D1%8F%20%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%BE%D0%B2%20%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0%20TKSBrokerAPI&default-sum=999&button-text=13&payment-type-choice=on&successURL=https%3A%2F%2Ftim55667757.github.io%2FTKSBrokerAPI%2F&quickpay=shop&account=410015019068268" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><img alt="gift" data-canonical-src="https://badgen.net/badge/gift/donate/green" src="https://camo.githubusercontent.com/b57ae6bc8f3073578e8bbfdcfd1e5e634062d61e0bf607b47f87be0d34c8e335/68747470733a2f2f62616467656e2e6e65742f62616467652f676966742f646f6e6174652f677265656e" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Ссылка на проект: <a href="https://github.com/Tim55667757/TKSBrokerAPI">https://github.com/Tim55667757/TKSBrokerAPI</a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Поддержать проект: <a href="https://yoomoney.ru/to/410015019068268">https://yoomoney.ru/to/410015019068268</a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Если вы занимаетесь одновременно инвестированием, автоматизацией и алгоритмической торговлей, то наверняка слышали про <a href="https://tinkoff.github.io/investAPI/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Tinkoff Open API</a> (к нему есть неплохая <a href="https://tinkoff.github.io/investAPI/swagger-ui/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Swagger-документация</a>) — это API, предоставляемое брокером Тинькофф Инвестиции для автоматизации работы биржевых торговых роботов. Если ещё не слышали, то можете <a href="http://tinkoff.ru/sl/AaX1Et1omnH" target="_blank">завести себе аккаунт</a> и протестировать его возможности сами.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">При работе с любыми API, всегда возникают технические трудности: высокий порог вхождения, необходимость в изучении документации, написание и отладка кода для выполнения сетевых запросов по формату API. Пройдёт много времени, прежде чем у вас дойдёт дело до реализации торгового алгоритма.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;"><a href="https://github.com/Tim55667757/TKSBrokerAPI" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">TKSBrokerAPI</a></span> — это более простой инструмент, который можно использовать как обычный python-модуль или запускать из командной строки, и сразу из коробки получить возможность работать со счётом у брокера Тинькофф Инвестиции: получать информацию о состоянии портфеля, включая элементарную аналитику, открывать и закрывать позиции, получать общую информацию о торгуемых на бирже инструментах, запрашивать цены и получать отчёты об операциях за указанный период. Все данные выводятся сразу в консоль: в текстовом виде или сохраняются в файлах формата Markdown.</p><span><a name='more'></a></span><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI7yG6lZR_VRFpevYGgxKVxGeHo4WOiy_pIW3_e7g7JyciAvIMRRhDVR0V3qhenx6d1s1BTMr-E3aXSX8qw7jL8F3r328mj_1RWR3KIdRf_sSmrQKgDOr_McNcE3ypghqcRwrBnj2HkIgKQpAbdNk7IvNf5GVyOsrtcwnF0fHNkEAIVu0YuD37vm2DMg/s1794/article-screenshot.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1552" data-original-width="1794" height="554" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI7yG6lZR_VRFpevYGgxKVxGeHo4WOiy_pIW3_e7g7JyciAvIMRRhDVR0V3qhenx6d1s1BTMr-E3aXSX8qw7jL8F3r328mj_1RWR3KIdRf_sSmrQKgDOr_McNcE3ypghqcRwrBnj2HkIgKQpAbdNk7IvNf5GVyOsrtcwnF0fHNkEAIVu0YuD37vm2DMg/w640-h554/article-screenshot.png" width="640" /></a></div><div style="text-align: center;"><br /></div><div style="text-align: center;"><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292f; font-size: 16px; text-align: start;"><i>Пример запроса клиентского портфеля и вывод информации в консоль</i></span></div><div style="text-align: center;"><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292f; font-size: 16px; text-align: start;"><br /></span></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">TKSBrokerAPI позволяет автоматизировать рутинные торговые операции и реализовать ваши торговые сценарии, либо только получать нужную информацию от брокера. Благодаря богатой системе консольных команд его достаточно просто встроить в системы автоматизации CI/CD.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В будущем, на основе этого модуля, в опенсорс будут выложены готовые торговые сценарии и шаблоны для написания собственных сценариев на языке Python.</p><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; text-align: left;"><span style="font-size: large;">Основные возможности</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">На момент последнего актуального <a href="https://github.com/Tim55667757/TKSBrokerAPI/releases/tag/1.1.48" target="_blank">релиза v.1.1.48</a> инструмент TKSBrokerAPI умеет:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Получать с сервера брокера список всех доступных для указанного аккаунта инструментов: валют, акций, облигаций, фондов и фьючерсов.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Запрашивать у брокера информацию об инструменте, зная его тикер или идентификатор FIGI.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Запрашивать у брокера стакан актуальных биржевых цен для указанного по тикеру или FIGI инструмента, при этом можно указать глубину стакана.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Получать с сервера брокера таблицу последних цен.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Получать информацию о состоянии портфеля пользователя и аналитику по нему: распределение портфеля по активам, компаниям, секторам и валютам активов.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Получать с сервера брокера информацию о совершённых сделках за указанный период и представлять её в табличном виде.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Совершать сделки по рынку, покупая или продавая активы в стакане, удовлетворяя имеющиеся заявки от продавцов или покупателей.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Открывать ордера любого типа: отложенные лимитные, действующие в пределах одной торговой сессии, и стоп-ордера, которые могут действовать до отмены или до указанной даты.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Закрывать открытые ранее ордера или списки ордеров любого типа по их ID.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Закрывать ранее открытые позиции полностью (кроме заблокированных объёмов), указав конкретный инструмент или список инструментов через их тикеры или FIGI.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Отменять все открытые ранее ордера и закрывать текущие позиции по всем инструментам сразу, кроме заблокированных объёмов и позиций по валютам, которые необходимо закрывать отдельно.</li></ul><h2 style="text-align: left;"><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji" style="color: #24292f; font-size: large;">Как установить</span></h2><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji" style="color: #24292f;"><br /></span></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Проще всего использовать установку через PyPI:</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre class="notranslate" lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background-color: transparent; background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip install tksbrokerapi
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">После этого можно проверить установку командой:</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre class="notranslate" lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background-color: transparent; background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip show tksbrokerapi
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Также можно использовать модуль TKSBrokerAPI, скачав его напрямую из <a href="https://github.com/Tim55667757/TKSBrokerAPI/" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">репозитория</a> через <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">git clone</code> и взяв кодовую базу любого протестированного <a href="https://github.com/Tim55667757/TKSBrokerAPI/releases" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">релиза</a>.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В первом случае инструмент будет доступен в консоли через команду <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">tksbrokerapi</code>, а во втором случае вам придётся запускать его как обычный python-скрипт, через <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">python TKSBrokerAPI.py</code> из каталога с исходным кодом.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F" target="_blank">В документации</a> все примеры написаны для случая, когда TKSBrokerAPI установлен через PyPI.</p><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; text-align: left;"><span style="font-size: medium;">Токен</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Сервис TINKOFF INVEST API использует для аутентификации токен. Токен — это набор символов, в котором зашифрованы данные о владельце, правах доступ и прочая информация, необходимая для авторизации в сервисе. Токен необходимо передавать на сервер с каждым сетевым запросом.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Модуль TKSBrokerAPI берёт всю работу с токенами на себя. Есть три варианта задания токена пользователя:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">при вызове <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">tksbrokerapi</code> в консоли укажите ключ: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--token "your_token_here"</code>;</li><li style="box-sizing: border-box; margin-top: 0.25em;">либо укажите <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">token</code> при инициализации класса в python-скрипте: <a href="https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.__init__" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TKSBrokerAPI.TinkoffBrokerServer(token="your_token_here", ...)</code></a>;</li><li style="box-sizing: border-box; margin-top: 0.25em;">или же можно заранее установить специальную переменную в пользовательском окружении: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TKS_API_TOKEN=your_token_here</code>.</li></ul><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><g-emoji alias="exclamation" class="g-emoji" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2757.png" style="box-sizing: border-box; display: inline-block; font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 1em; line-height: 1; min-width: 1ch; vertical-align: -0.075em;">❗</g-emoji> <span style="box-sizing: border-box; font-weight: 600;">Работа с TINKOFF INVEST API без выпуска и использования токена невозможна</span>. До начала работы с модулем TKSBrokerAPI, пожалуйста, откройте <a href="http://tinkoff.ru/sl/AaX1Et1omnH" target="_blank">брокерский счёт</a> в Тинькофф Инвестиции, а затем выберете нужный вам вид токена и создайте его, как указано по ссылке <a href="https://tinkoff.github.io/investAPI/token/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">в официальной документации</a>.</p><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; text-align: left;"><span style="font-size: medium;">Идентификатор счёта пользователя</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Второй важный параметр для работы TKSBrokerAPI — это числовой идентификатор счёта пользователя. Он не является обязательным, но без его указания будет невозможно выполнить многие операции через API, логически завязанные на конкретного пользователя (посмотреть портфель по брокерскому счёту, выполнить торговые операции и многие другие). Вы можете найти это число в любом брокерском отчёте, которые можно заказать либо из мобильного приложения Тинькофф Инвестиции, либо в личном кабинете на их сайте. Обычно идентификатор счёта пользователя находится сверху, в "шапке" отчётов. Также можно узнать этот номер спросив в чате техподдержки Тинькофф Инвестиции.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Есть три варианта задания идентификатора счёта пользователя:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">при вызове <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">tksbrokerapi</code> в консоли укажите ключ: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--account-id your_id_number"</code>;</li><li style="box-sizing: border-box; margin-top: 0.25em;">либо укажите <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">accountId</code> при инициализации класса в python-скрипте: <a href="https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.__init__" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TKSBrokerAPI.TinkoffBrokerServer(token="...", accountId=your_id_number, ...)</code></a>;</li><li style="box-sizing: border-box; margin-top: 0.25em;">или же можно заранее установить специальную переменную в пользовательском окружении: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TKS_ACCOUNT_ID=your_id_number</code>.</li></ul><h2 style="text-align: left;"><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji" style="color: #24292f; font-size: large;">Примеры использования</span></h2><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292f; font-size: 16px;">После того, как все необходимые настройки будут выполнены, вы получите токен и узнаете свой идентификатор аккаунта, можно начать полноценно использовать модуль TKSBrokerAPI. Смотрите примеры </span><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F" style="font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px;" target="_blank">по ссылке</a><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292f; font-size: 16px;">.</span></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292f; font-size: 16px;"><br /></span></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">При запуске программы в консоли можно указать множество параметров и выполнить одно действие. Формат любых команд следующий:</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre class="notranslate" lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background-color: transparent; background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">tksbrokerapi [необязательные ключи и параметры] [одно действие]</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><b>Примеры:</b></p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%98%D0%B7-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D0%BE%D0%B9-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Из командной строки</a><ul dir="auto" style="box-sizing: border-box; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D1%83-%D0%BF%D0%BE-%D0%BA%D0%BB%D1%8E%D1%87%D0%B0%D0%BC" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Получить справку по ключам</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%B2%D1%81%D0%B5%D1%85-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%BD%D1%8B%D1%85-%D0%B4%D0%BB%D1%8F-%D1%82%D0%BE%D1%80%D0%B3%D0%BE%D0%B2%D0%BB%D0%B8-%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Получить список всех доступных для торговли инструментов</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D1%8E-%D0%BF%D0%BE-%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%83" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Получить информацию по инструменту</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%97%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C-%D1%81%D1%82%D0%B0%D0%BA%D0%B0%D0%BD-%D1%86%D0%B5%D0%BD-%D1%81-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%BD%D0%BE%D0%B9-%D0%B3%D0%BB%D1%83%D0%B1%D0%B8%D0%BD%D0%BE%D0%B9" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Запросить стакан цен с заданной глубиной</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%97%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C-%D1%82%D0%B0%D0%B1%D0%BB%D0%B8%D1%86%D1%83-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BD%D0%B8%D1%85-%D0%B0%D0%BA%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85-%D1%86%D0%B5%D0%BD-%D0%B4%D0%BB%D1%8F-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0-%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Запросить таблицу последних актуальных цен для списка инструментов</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D1%82%D0%B5%D0%BA%D1%83%D1%89%D0%B8%D0%B9-%D0%BF%D0%BE%D1%80%D1%82%D1%84%D0%B5%D0%BB%D1%8C-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F-%D0%B8-%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D1%83-%D1%80%D0%B0%D1%81%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BE%D0%B2" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Получить текущий портфель пользователя и статистику распределения активов</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%BE%D1%82%D1%87%D1%91%D1%82-%D0%BF%D0%BE-%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F%D0%BC-%D1%81-%D0%BF%D0%BE%D1%80%D1%82%D1%84%D0%B5%D0%BB%D0%B5%D0%BC-%D0%B7%D0%B0-%D1%83%D0%BA%D0%B0%D0%B7%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BF%D0%B5%D1%80%D0%B8%D0%BE%D0%B4" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Получить отчёт по операциям с портфелем за указанный период</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%A1%D0%BE%D0%B2%D0%B5%D1%80%D1%88%D0%B8%D1%82%D1%8C-%D1%81%D0%B4%D0%B5%D0%BB%D0%BA%D1%83-%D0%BF%D0%BE-%D1%80%D1%8B%D0%BD%D0%BA%D1%83" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Совершить сделку по рынку</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9E%D1%82%D0%BA%D1%80%D1%8B%D1%82%D1%8C-%D0%BE%D1%82%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BB%D0%B8%D0%BC%D0%B8%D1%82%D0%BD%D1%8B%D0%B9-%D0%B8%D0%BB%D0%B8-%D1%81%D1%82%D0%BE%D0%BF-%D0%BE%D1%80%D0%B4%D0%B5%D1%80" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Открыть отложенный лимитный или стоп-ордер</a></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9E%D1%82%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-%D0%BE%D1%80%D0%B4%D0%B5%D1%80%D0%B0-%D0%B8-%D0%B7%D0%B0%D0%BA%D1%80%D1%8B%D1%82%D1%8C-%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D0%B8" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Отменить ордера и закрыть позиции</a></li></ul></li><li style="box-sizing: border-box; margin-top: 0.25em;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9A%D0%B0%D0%BA-python-API-%D1%87%D0%B5%D1%80%D0%B5%D0%B7-%D0%B8%D0%BC%D0%BF%D0%BE%D1%80%D1%82-%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8F-TKSBrokerAPI" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Как python API через импорт модуля TKSBrokerAPI</a></li><ul dir="auto" style="box-sizing: border-box; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><a href="https://github.com/Tim55667757/TKSBrokerAPI#%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8-%D0%B0%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%BE%D0%B3%D0%BE-%D1%81%D1%86%D0%B5%D0%BD%D0%B0%D1%80%D0%B8%D1%8F" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;">Пример реализации абстрактного сценария</a></li></ul></ul><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji" style="color: #24292f;"><br /></span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji" style="color: #24292f;"><br /></span></div><div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">На этом всё, вопросы задавайте в GitHub в разделе <g-emoji alias="point_right" class="g-emoji" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f449.png" style="box-sizing: border-box; display: inline-block; font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 1em; line-height: 1; min-width: 1ch; vertical-align: -0.075em;">👉</g-emoji> <a href="https://github.com/Tim55667757/TKSBrokerAPI/issues/new" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><span style="box-sizing: border-box; font-weight: 600;">Issues</span></a> <g-emoji alias="point_left" class="g-emoji" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f448.png" style="box-sizing: border-box; display: inline-block; font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 1em; line-height: 1; min-width: 1ch; vertical-align: -0.075em;">👈</g-emoji>, пожалуйста.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><g-emoji alias="rocket" class="g-emoji" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png" style="box-sizing: border-box; display: inline-block; font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 1em; line-height: 1; min-width: 1ch; vertical-align: -0.075em;">🚀</g-emoji> Успехов вам в автоматизации биржевой торговли! И профита!</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;"><a href="https://yoomoney.ru/quickpay/shop-widget?writer=seller&targets=%D0%94%D0%BE%D0%BD%D0%B0%D1%82%20(%D0%BF%D0%BE%D0%B4%D0%B0%D1%80%D0%BE%D0%BA)%20%D0%B4%D0%BB%D1%8F%20%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%BE%D0%B2%20%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0%20TKSBrokerAPI&default-sum=999&button-text=13&payment-type-choice=on&successURL=https%3A%2F%2Ftim55667757.github.io%2FTKSBrokerAPI%2F&quickpay=shop&account=410015019068268" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none; text-decoration: none;"><img alt="gift" data-canonical-src="https://badgen.net/badge/gift/donate/green" src="https://camo.githubusercontent.com/b57ae6bc8f3073578e8bbfdcfd1e5e634062d61e0bf607b47f87be0d34c8e335/68747470733a2f2f62616467656e2e6e65742f62616467652f676966742f646f6e6174652f677265656e" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a></p></div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-42429522652821860212022-01-11T23:40:00.001+03:002022-10-02T20:25:10.979+03:00PriceGenerator — модуль python для генерации тестовых данных по биржевым котировкам<p><span style="background-color: white; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";"><b>PriceGenerator</b></span></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://travis-ci.com/Tim55667757/PriceGenerator" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="Build Status" data-canonical-src="https://travis-ci.com/Tim55667757/PriceGenerator.svg?branch=master" src="https://camo.githubusercontent.com/1e0c2a88fc5e9e7581c6c9560dd4ae6d561ea5f96f54b4549046bca0f70aa9ac/68747470733a2f2f7472617669732d63692e636f6d2f54696d35353636373735372f507269636547656e657261746f722e7376673f6272616e63683d6d6173746572" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://pypi.python.org/pypi/PriceGenerator" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="pypi" data-canonical-src="https://img.shields.io/pypi/v/PriceGenerator.svg" src="https://camo.githubusercontent.com/8d835f28ccd6250338e2c4ffe17b269e92a15bcd4949d6949866c11e01b1f86f/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f507269636547656e657261746f722e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://github.com/Tim55667757/PriceGenerator/blob/master/LICENSE" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="license" data-canonical-src="https://img.shields.io/pypi/l/PriceGenerator.svg" src="https://camo.githubusercontent.com/bd7f178d55c2968c09d7cd841d92f42edc8b0efbb7d67b34fca6ad3c600fdbba/68747470733a2f2f696d672e736869656c64732e696f2f707970692f6c2f507269636547656e657261746f722e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a></p><p dir="auto" style="background-color: white; box-sizing: border-box; margin-bottom: 16px; margin-top: 0px;"><span style="color: #24292f; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;">Ссылка на проект: <a href="https://github.com/Tim55667757/PriceGenerator">https://github.com/Tim55667757/PriceGenerator</a></span></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Иногда для целей тестирования автоматизированных торговых алгоритмов бывает необходимо получить набор данных с биржевыми ценами, которые попадают под определённые статистические ограничения. Обычно трейдеры и аналитики используют модель цен вида <b>OHLCV-candlesticks</b> (open, high, low, close, volume), так называемые японские свечи. Одна строка таких данных представляет собой набор цен для построения одной японской свечи: дата открытия, цена открытия, наибольшая цена, наименьшая цена, цена закрытия на данном временном интервале и значение объёма торгов.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><b><span style="box-sizing: border-box;">PriceGenerator</span> </b>— это простая <a href="https://github.com/Tim55667757/PriceGenerator" target="_blank">библиотека</a> на python, которую можно использовать как модуль или запускать из командной строки и генерировать случайные ценовые данные, <b>максимально похожие</b> <b>на "настоящие цены"</b>, но с заранее заданными статистическими характеристиками. Можно задать интервал цен, таймфрейм, максимальное и минимальное значения для диапазона цен, максимальный размер для свечей, вероятность направления для очередной свечи, вероятность ценовых выбросов, количество генерируемых свечей и некоторые другие параметры.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Из статьи далее вы узнаете:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">как установить и использовать библиотеку PriceGenerator из командной строки, либо через импорт модуля;</li><li style="box-sizing: border-box;">про метод генерации цен, используемый в библиотеке;</li><li style="box-sizing: border-box;">как сгенерировать набор ценовых данных с параметрами по умолчанию, получить по ним статистику и нарисовать график (интерактивный или упрощённый);</li><li style="box-sizing: border-box;">как загрузить ранее сохранённые данные по ценам, построить график и посчитать статистику;</li><li style="box-sizing: border-box;">как переопределить статистические параметры генератора, заданные по умолчанию;</li><li style="box-sizing: border-box;">как разделить ценовые данные по трендам, чтобы цена вела себя по разному для различных временных периодов.</li></ul><p></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span></span></p><a name='more'></a><p></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Для дальнейшего статистического анализа цен в python очень часто используют библиотеку <b>Pandas</b>. Цены, сохранённые в виде Pandas DataFrame, могут выглядеть как-то так:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto !important; position: relative !important;"><pre lang="text" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;"> datetime open high low close volume
95 2021-02-03 11:00:00+03:00 76.82 78.43 76.21 78.13 33652
96 2021-02-03 12:00:00+03:00 78.13 78.37 78.12 78.36 9347
97 2021-02-03 13:00:00+03:00 78.36 78.40 78.05 78.07 27250
98 2021-02-03 14:00:00+03:00 78.07 78.61 75.72 76.42 22979
99 2021-02-03 15:00:00+03:00 76.42 77.37 76.25 77.16 30845
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><b>Библиотека PriceGenerator позволяет:</b></p><ul dir="auto" style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 16px; margin-top: 0px; orphans: 2; padding-left: 2em; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><li style="box-sizing: border-box;"><span style="color: #24292f;">сохранить сгенерированные цены в .csv-формате (пример:</span><span style="color: #24292f;"> </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/test.csv" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/test.csv</span></a><span style="color: #24292f;">);</span></li><li style="box-sizing: border-box; color: #24292f; margin-top: 0.25em;">сохранить сгенерированные цены в переменную формата Pandas DataFrame для дальнейшего использования в скриптах автоматизации;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: #24292f;">автоматически рассчитать некоторые статистические и вероятностные характеристики сгенерированных цен и сохранить их в markdown-формате (пример:</span><span style="color: #24292f;"> </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index.html.md" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/index.html.md</span></a><span style="color: #24292f;">);</span></li><li style="box-sizing: border-box; color: #24292f; margin-top: 0.25em;">загрузить цены реальных инструментов по модели OHLCV-candlesticks из .csv-файла и провести их статистический анализ;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="color: #24292f;">нарисовать график сгенерированных или загруженных реальных цен и сохранить его в html-формате (пример:</span><span style="color: #24292f;"> </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index.html" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/index.html</span></a><span style="color: #24292f;">);</span><ul dir="auto" style="box-sizing: border-box; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><p dir="auto" style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px;"><span style="color: #24292f;">сгенерированные цены, график и некоторые данные о поведении цен можно сохранить в виде обычной png-картинки (пример:</span><span style="color: #24292f;"> </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index.html.png" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/index.html.png</span></a><span style="color: #24292f;">):</span></p><div class="separator" style="clear: both; color: #24292f; text-align: center;"><a href="https://raw.githubusercontent.com/Tim55667757/PriceGenerator/master/media/index.html.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="423" data-original-width="800" height="338" src="https://raw.githubusercontent.com/Tim55667757/PriceGenerator/master/media/index.html.png" width="640" /></a></div><p dir="auto" style="box-sizing: border-box; color: #24292f; margin-bottom: 16px; margin-top: 16px;">Дополнительно на графике можно включить отображение некоторых популярных индикаторов (скользящие средние, полосы Боллинджера, ZigZag и другие).</p></li></ul></li></ul><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; text-align: left;"><span style="font-size: x-large;">Метод генерации цен</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Генерация набора свечей заданной длины <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">horizon</code> происходит по следующему упрощённому алгоритму:</p><ol dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Определяется или случайным образом генерируется в заданном диапазоне [<code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">minClose</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">maxClose</code>] цена открытия <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">open</code> первой свечи.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Случайным образом, в зависимости от значения вероятности направления очередной свечи <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">upCandlesProb</code> (по умолчанию 50%), определяется направление свечи. Если <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">random() ≤ upCandlesProb</code>, то будет генерироваться up-свеча (у которой <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">open ≤ close</code>), иначе будет генерироваться down-свеча (у которой <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">open > close</code>).</li><li style="box-sizing: border-box; margin-top: 0.25em;">После определения направления значение <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">close</code> свечи случайным образом генерируется так, чтобы для получившегося "тела" свечи было справедливо <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">|open - close| ≤ maxCandleBody</code>.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Случайным образом, в зависимости от значения вероятности ценовых выбросов свечи <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">maxOutlier</code> (по умолчанию 3%), генерируются значения <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">high</code> и <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">low</code> свечи. Если <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">random() ≤ maxOutlier</code>, то будет генерироваться свеча с ценовыми выбросами: "хвосты" свечи могут получиться достаточно большими, что будет имитировать реальные ценовые "выбросы" на рынке. Если свеча без аномалий, то "хвосты" будут генерироваться в диапазоне не более половины тела свечи.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Значение <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">close</code> сгенерированной свечи становится значением цены открытия <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">open</code> следующей свечи.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Далее повторяются шаги 2-5 пока не будет сгенерирована вся цепочка цен заданной длины <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">horizon</code>.</li></ol><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Все параметры можно задать после инициализации экземпляра класса <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">PriceGenerator()</code>. Результат генерации цен сохраняется в переменной класса <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">prices</code> в формате Pandas DataFrame и может использоваться для дальнейшего анализа. Также генератор может работать из командной строки и сохранять котировки в файл.</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-muted); box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; text-align: left;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md#%D0%BA%D0%B0%D0%BA-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D1%82%D1%8C" id="user-content-как-установить" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg><span style="font-size: x-large;"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></span></a><span style="font-size: x-large;">Как установить</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Проще всего использовать установку через PyPI:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip install pricegenerator
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">После этого можно проверить установку командой:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip show pricegenerator</code><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">
</code></pre></div><h2 dir="auto" style="background-color: white; border-bottom: 1px solid var(--color-border-muted); box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F" id="user-content-примеры-использования" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg><span style="font-size: x-large;"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></span></a><span style="font-size: x-large;">Примеры использования из командной строки</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Внутренняя справка по ключам:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pricegenerator --help</code><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Вывод:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important; text-align: left;"><pre lang="text" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;"><span style="font-size: 13.6px;">Запуск: python PriceGenerator.py [параметры] [одна или несколько команд]
Генератор биржевых цен. Генерирует цепочку японских свечей с заранее предопределёнными
параметрами, возвращает pandas dataframe или сохраняет цены как .csv-файл
в формате свечей OHLCV в каждой строке. Смотрите примеры здесь:
https://tim55667757.github.io/PriceGenerator
Возможные параметры командной строки:
-h, --help Показать эту подсказку и выйти
--ticker TICKER Параметр: название тикера, 'TEST' по умолчанию.
--precision PRECISION
Параметр: кол-во знаков после запятой, 2 по умолчанию.
--timeframe TIMEFRAME
Параметр: разница между двумя соседними свечами
в минутах, 60 (или 1 час) по умолчанию.
--start START Параметр: дата и время первой свечи в текстовом формате
'год-месяц-день часы:минуты', например '2021-01-02 12:00'.
--horizon HORIZON Параметр: количество загружаемых или генерируемых свечей.
--split-trend SPLIT_TREND
Параметр: количество различных периодов, например
--split-trend=/\- означает, что нужно сгенерировать
три последовательных периода, где сначала цепочка свечей
образует восходящий тренд, затем нисходящий, и в конце
период без тренда. Используется с ключом --split-count key.
--split-count SPLIT_COUNT [SPLIT_COUNT ...]
Параметр: устанавливает количество свечей в каждом периоде,
например --split-count 5 10 15 означает, что нужно
сгенерировать 3 тренда с 5, 10 и 15 свечами в каждой цепочке,
причём общая сумма свечей должна совпадать со значением ключа
--horizon. Используется с ключами --split-count и --horizon.
--max-close MAX_CLOSE
Параметр: максимальная цена закрытия среди всех свечей.
--min-close MIN_CLOSE
Параметр: минимальная цена закрытия среди всех свечей.
--init-close INIT_CLOSE
Параметр: цена открытия первой свечи в цепочке равна
этому значению, как бы 'последней' цене закрытия.
--max-outlier MAX_OUTLIER
Параметр: максимальное значение ценовых 'выбросов',
по умолчанию (max-close - min-close) / 10.
--max-body MAX_BODY Параметр: максимальный размер 'тела' свечей:
abs(open - close), по умолчанию max-outlier * 0.9.
--max-volume MAX_VOLUME
Параметр: максимальный торговый объём одной свечи.
--up-candles-prob UP_CANDLES_PROB
Параметр: число в отрезке [0; 1] означает вероятность того,
что очередная свеча будет вверх, 0.5 по умолчанию.
--outliers-prob OUTLIERS_PROB
Параметр: число в отрезке [0; 1] это вероятность
ценовых 'выбросов' или 'хвостов', 0.03 по умолчанию.
--trend-deviation TREND_DEVIATION
Параметр: относительное отклонение для определения тренда,
по умолчанию ±0.005. Нет тренда, если (1st_close -
last_close) / 1st_close <= trend-deviation.
--sep SEP Параметр: разделитель для csv-файла, если не указывать,
то будет определяться автоматически.
--zigzag ZIGZAG Параметр: относительное отклонение для определения точек
индикатора ZigZag, 0.03 по умолчанию (3%).
--debug-level DEBUG_LEVEL
Параметр: уровень логирования для STDOUT,
например, 10 = DEBUG, 20 = INFO, 30 = WARNING,
40 = ERROR, 50 = CRITICAL.
--load-from LOAD_FROM
Команда: загрузить .cvs-файл в Pandas dataframe. Также вы
можете нарисовать график цен, указав ключ --render-bokeh.
--generate Команда: сгенерировать цепочку свечей с предопределёнными
статистическими параметрами и сохранить историю цен
как pandas dataframe или .csv-файл, если ключ --save-to
будет указан. Также вы можете нарисовать график цен,
указав ключ --render-bokeh.
--save-to SAVE_TO Команда: сохранить сгенерированные или загруженные цены
в .csv-файл. Также вы можете нарисовать график цен,
указав ключ --render-bokeh.
--render-bokeh RENDER_BOKEH
Команда: нарисовать цепочку свечей как интерактивный
график из библиотеки Bokeh. Перед командой вы должны задать
ключи --load-from или --generate. Подробнее про Bokeh:
https://docs.bokeh.org/en/latest/docs/gallery/candlestick.html.
--render-google RENDER_GOOGLE
Команда: нарисовать цепочку свечей на простом не интерактивном
графике из библиотеки Google Candlestick chart. Подробнее:
https://developers.google.com/chart/interactive/docs/gallery/candlestickchart
Перед командой вы должны задать ключи --load-from или
--generate.</span><b><span style="font-size: x-large;">
</span></b></code></pre></div><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; text-align: left;"><span style="font-size: x-large;">Генерация цен с параметрами по умолчанию</span></h2><h4 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md#%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D1%86%D0%B5%D0%BD-%D1%81-%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D0%B0%D0%BC%D0%B8-%D0%BF%D0%BE-%D1%83%D0%BC%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8%D1%8E" id="user-content-генерация-цен-с-параметрами-по-умолчанию" style="background-color: transparent; box-sizing: border-box; float: left; font-size: 16px; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><span style="font-weight: normal;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg><span style="font-size: x-large;"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></span></span></a></h4><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Давайте попробуем сгенерировать случайные ценовые данные (ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--generate</code>) со всеми параметрами по умолчанию и сохранить их в файл <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">test.csv</code> (ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--save-to имя_csv_файла</code> ). Команда может выглядеть так:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pricegenerator --debug-level 10 --generate --save-to test.csv
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Должен получиться вывод логов примерно следующего содержания:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto !important; position: relative !important;"><pre lang="text" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">PriceGenerator.py L:605 DEBUG [2021-01-31 17:52:49,954] =--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--=
PriceGenerator.py L:606 DEBUG [2021-01-31 17:52:49,954] PriceGenerator started: 2021-01-31 17:52:49
PriceGenerator.py L:367 INFO [2021-01-31 17:52:49,954] Generating prices...
PriceGenerator.py L:368 DEBUG [2021-01-31 17:52:49,954] - Ticker name: TEST
PriceGenerator.py L:369 DEBUG [2021-01-31 17:52:49,954] - Interval or timeframe (time delta between two neighbour candles): 1:00:00
PriceGenerator.py L:370 DEBUG [2021-01-31 17:52:49,954] - Horizon length (candlesticks count): 100
PriceGenerator.py L:371 DEBUG [2021-01-31 17:52:49,954] - Start time: 2021-01-31--17-00-00
PriceGenerator.py L:372 DEBUG [2021-01-31 17:52:49,955] |-> end time: 2021-02-04--21-00-00
PriceGenerator.py L:373 DEBUG [2021-01-31 17:52:49,955] - Maximum of close prices: 79.21
PriceGenerator.py L:374 DEBUG [2021-01-31 17:52:49,955] - Minimum of close prices: 67.69
PriceGenerator.py L:375 DEBUG [2021-01-31 17:52:49,955] - Maximum of candle body sizes: 3.08
PriceGenerator.py L:376 DEBUG [2021-01-31 17:52:49,955] - Maximum of candle tails outlier sizes: 3.42
PriceGenerator.py L:377 DEBUG [2021-01-31 17:52:49,955] - Init close (1st open price in chain): 71.49
PriceGenerator.py L:378 DEBUG [2021-01-31 17:52:49,955] - Maximum of volume of one candle: 42340
PriceGenerator.py L:379 DEBUG [2021-01-31 17:52:49,955] - Probability that next candle is up: 50.0%
PriceGenerator.py L:380 DEBUG [2021-01-31 17:52:49,955] - Statistical outliers probability: 3.0%
PriceGenerator.py L:397 INFO [2021-01-31 17:52:49,958] Showing last 5 rows as pandas dataframe:
PriceGenerator.py L:399 INFO [2021-01-31 17:52:49,963] datetime open high low close volume
PriceGenerator.py L:399 INFO [2021-01-31 17:52:49,963] 95 2021-02-03 11:00:00+03:00 76.82 78.43 76.21 78.13 33652
PriceGenerator.py L:399 INFO [2021-01-31 17:52:49,963] 96 2021-02-03 12:00:00+03:00 78.13 78.37 78.12 78.36 9347
PriceGenerator.py L:399 INFO [2021-01-31 17:52:49,963] 97 2021-02-03 13:00:00+03:00 78.36 78.40 78.05 78.07 27250
PriceGenerator.py L:399 INFO [2021-01-31 17:52:49,963] 98 2021-02-03 14:00:00+03:00 78.07 78.61 75.72 76.42 22979
PriceGenerator.py L:399 INFO [2021-01-31 17:52:49,963] 99 2021-02-03 15:00:00+03:00 76.42 77.37 76.25 77.16 30845
PriceGenerator.py L:173 INFO [2021-01-31 17:52:49,963] Saving [100] rows of pandas dataframe with columns: ['date', 'time', 'open', 'high', 'low', 'close', 'volume']...
PriceGenerator.py L:174 DEBUG [2021-01-31 17:52:49,963] Delimeter: ,
PriceGenerator.py L:181 INFO [2021-01-31 17:52:49,976] Pandas dataframe saved to .csv-file [./test.csv]
PriceGenerator.py L:645 DEBUG [2021-01-31 17:52:49,976] All PriceGenerator operations are finished success (summary code is 0).
PriceGenerator.py L:650 DEBUG [2021-01-31 17:52:49,976] PriceGenerator work duration: 0:00:00.022938
PriceGenerator.py L:651 DEBUG [2021-01-31 17:52:49,976] PriceGenerator work finished: 2021-01-31 17:52:49
Process finished with exit code 0
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;"><span style="color: #24292f;">Также рядом будет сохранён файл </span><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; color: #24292f; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">test.csv</code><span style="color: #24292f;">, пример которого можно посмотреть здесь: </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/test.csv" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/test.csv</span></a><span style="color: #24292f;">.</span></p><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; text-align: left;"><span style="font-size: x-large;">Генерация цен, получение статистики и отрисовка графика</span></h2><h4 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md#%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D1%86%D0%B5%D0%BD-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B8-%D0%B8-%D0%BE%D1%82%D1%80%D0%B8%D1%81%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0" id="user-content-генерация-цен-получение-статистики-и-отрисовка-графика" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a></h4><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">В следующем примере давайте не только сгенерируем файл с данными по ценам, но и получим некоторые статистические параметры цен, а также отрисуем их на графике (ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--render-bokeh имя_html_файла</code>). Команда может быть примерно такой:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pricegenerator --debug-level 20 --generate --save-to test.csv --render-bokeh index.html
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">В случае успеха вы получите вывод в лог, похожий на этот:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto !important; position: relative !important;"><pre lang="text" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">PriceGenerator.py L:367 INFO [2021-01-31 18:00:31,711] Generating prices...
PriceGenerator.py L:397 INFO [2021-01-31 18:00:31,714] Showing last 5 rows of Pandas generated dataframe object:
PriceGenerator.py L:399 INFO [2021-01-31 18:00:31,719] datetime open high low close volume
PriceGenerator.py L:399 INFO [2021-01-31 18:00:31,719] 95 2021-02-03 11:00:00+03:00 76.82 78.43 76.21 78.13 33652
PriceGenerator.py L:399 INFO [2021-01-31 18:00:31,719] 96 2021-02-03 12:00:00+03:00 78.13 78.37 78.12 78.36 9347
PriceGenerator.py L:399 INFO [2021-01-31 18:00:31,719] 97 2021-02-03 13:00:00+03:00 78.36 78.40 78.05 78.07 27250
PriceGenerator.py L:399 INFO [2021-01-31 18:00:31,719] 98 2021-02-03 14:00:00+03:00 78.07 78.61 75.72 76.42 22979
PriceGenerator.py L:399 INFO [2021-01-31 18:00:31,719] 99 2021-02-03 15:00:00+03:00 76.42 77.37 76.25 77.16 30845
PriceGenerator.py L:173 INFO [2021-01-31 18:00:31,719] Saving [100] rows of pandas dataframe with columns: ['date', 'time', 'open', 'high', 'low', 'close', 'volume']...
PriceGenerator.py L:181 INFO [2021-01-31 18:00:31,731] Pandas dataframe saved to .csv-file [./test.csv]
PriceGenerator.py L:410 INFO [2021-01-31 18:00:31,731] Rendering pandas dataframe as Bokeh chart...
PriceGenerator.py L:300 INFO [2021-01-31 18:00:31,740] Some statistical info:
## Summary
| Parameter | Value
|----------------------------------------------|---------------
| Candles count: | 100
| Timeframe: | 1:00:00
| Precision (signs after comma): | 2
| Close first: | 71.49
| Close last: | 77.16
| Close max: | 79.21
| Close min: | 67.69
| Diapason (between max and min close prices): | 11.52
| Trend (between close first and close last: | UP trend
| - Trend deviation parameter: | ±0.5%
## Some statistics
| Statistic | Value
|----------------------------------------------|---------------
| Up candles count: | 53 (53.0%)
| Down candles count: | 47 (47.0%)
| Max of up candles chain: | 7
| Max of down candles chain: | 5
| Max delta (between High and Low prices): | 3.08
| Min delta (between High and Low prices): | 0.0
| Delta's std. dev.: | 0.86
| - 99 percentile: | ≤ 2.99
| - 95 percentile: | ≤ 2.89
| - 80 percentile: | ≤ 2.2
| - 50 percentile: | ≤ 1.15
| Cumulative sum of volumes: | 1777314
PriceGenerator.py L:563 INFO [2021-01-31 18:00:32,290] Pandas dataframe rendered as html-file [./index.html]
Process finished with exit code 0
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Также после выполнения команды выше вы получите три файла:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; color: #24292f; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">test.csv</code><span style="color: #24292f;"> — файл в .csv-формате, который содержит случайный набор цен, похожих на настоящие (пример: </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/test.csv" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/test.csv</span></a><span style="color: #24292f;">);</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; color: #24292f; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">index.html</code><span style="color: #24292f;"> — график цен и статистику, отрисованные при помощи библиотеки Bokeh и сохранённые в .html-файл (пример: </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index.html" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/index.html</span></a><span style="color: #24292f;">);</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; color: #24292f; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">index.html.md</code><span style="color: #24292f;"> — статистика в текстовом виде, сохранённая в маркдаун-формате (пример: </span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index.html.md" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/index.html.md</span></a><span style="color: #24292f;">).</span></li></ul><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; text-align: left;"><span style="font-size: x-large;">Статистика и график из сохранённых цен</span></h2><h4 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md#%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D0%B8-%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D0%BA-%D0%B8%D0%B7-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D1%91%D0%BD%D0%BD%D1%8B%D1%85-%D1%86%D0%B5%D0%BD" id="user-content-статистика-и-график-из-сохранённых-цен" style="background-color: transparent; box-sizing: border-box; float: left; font-size: 16px; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg><span style="font-size: x-large;"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></span></a></h4><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Если вам нужно получить статистику по уже сгенерированным или реальным ценам, вы можете просто загрузить файл (ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--load-from имя_csv_файла</code> ) и отрисовать график (ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--render-bokeh имя_html_файла</code>):</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pricegenerator --debug-level 20 --load-from test.csv --render-bokeh index.html
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">В результате выполнения команды вы получите аналогичный график в <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">index.html</code> и статистику в <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">index.html.md</code>.</p><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; text-align: left;"><span style="font-size: x-large;">Статистика и график на упрощённом шаблоне</span></h2><h4 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md#%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D0%B8-%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D0%BA-%D0%BD%D0%B0-%D1%83%D0%BF%D1%80%D0%BE%D1%89%D1%91%D0%BD%D0%BD%D0%BE%D0%BC-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B5" id="user-content-статистика-и-график-на-упрощённом-шаблоне" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a></h4><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">В примерах выше можно сделать отображение цен на простом, не интерактивном графике цен. Для этого используется библиотека <a href="https://developers.google.com/chart/interactive/docs/gallery/candlestickchart" target="_blank">Google Candlestick chart</a> и простейший jinja2 шаблон. Давайте опять загрузим цены (ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--load-from имя_csv_файла</code> ), но отрисуем график через Google библиотеку (ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--render-google имя_html_файла</code>):</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pricegenerator --debug-level 20 --load-from test.csv --render-google index_google.html
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;"><span style="color: #24292f;">В результате выполнения команды вы получите график (</span><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_google.html" style="background-color: transparent; box-sizing: border-box;"><span style="color: #2b00fe;">./media/index_google.html</span></a><span style="color: #24292f;">) и статистику в markdown файле. Выглядеть он будет примерно так:</span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_google.html.png?raw=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="419" data-original-width="800" height="335" src="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_google.html.png?raw=true" width="640" /></a></div><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; text-align: left;"><span style="font-size: x-large;">Переопределение параметров генератора</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Давайте изменим некоторые параметры по умолчанию, которые влияют на генерацию цен и нарисуем свой уникальный график:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pricegenerator --debug-level 10 --ticker "MY_PRICES" --precision 2 --timeframe 240 --start "2020-01-01 00:00" --horizon 150 --max-close 18000 --min-close 14000 --init-close 15000 --max-outlier 1000 --max-body 500 --max-volume 400000 --up-candles-prob 0.48 --outliers-prob 0.05 --trend-deviation 0.03 --zigzag 0.03 --generate --render-bokeh index_custom.html
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Параметры означают:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--ticker "MY_PRICES"</code> — установить название графика для ценовой последовательности как MY_PRICES;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--precision 2</code> — установить точность, то есть количество знаков после запятой;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--timeframe 240</code> — одна свеча должна отражать изменение цен за 4 часа (240 минут);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--start "2020-01-01 00:00"</code> — дата и время первой свечи 2020-01-01 00:00;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--horizon 150</code> — сгенерировать 150 свечей;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--max-close 18000</code> — максимальная цена закрытия у любой свечи должна быть не больше 18000;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--min-close 14000</code> — минимальная цена закрытия у любой свечи должна быть не больше 14000;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--init-close 15000</code> — цена закрытия "предыдущей" и, соответственно, цена открытия первой генерируемой свечи должна быть равной 15000;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--max-outlier 1000</code> — если у свечи есть "выбросы" и "хвосты" то они должны быть не больше чем 1000;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--max-body 500</code> — максимальный размер "тела" свечи должен быть не более 500;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--max-volume 400000</code> — максимальный объём торгов для каждой свечи должен быть не более 400000;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--up-candles-prob 0.48</code> — установить вероятность того, что очередная свеча будет вверх, равной 0.48 (48%);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--outliers-prob 0.05</code> — установить вероятность появления выбросов равной 0.05 (5%);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--trend-deviation 0.03</code> — для определения тренда относительное изменение цен закрытия первой и последней свечей должно отличаться на ±0.03 (3%);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--zigzag 0.03</code> — относительная разница между двумя точками ZigZag индикатора;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--generate</code> — запустить генерацию цен;</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--render-bokeh index_custom.html</code> — сохранить сгенерированные цены в файл index_custom.html и открыть его в браузере.</li></ul><div><div class="separator" style="clear: both; text-align: center;"><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_custom.html.png?raw=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="400" data-original-width="800" height="320" src="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_custom.html.png?raw=true" width="640" /></a></div></div><div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В результате выполнения команды у вас получится уникальный график случайных цен с переопределёнными базовыми параметрами генератора. В примере получились вот такие артефакты:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">картинка с изображением цен <a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_custom.html.png" style="background-color: transparent; box-sizing: border-box;">./media/index_custom.html.png</a>;</li><li style="box-sizing: border-box; margin-top: 0.25em;">график цен и статистика <a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_custom.html" style="background-color: transparent; box-sizing: border-box;">./media/index_custom.html</a>;</li><li style="box-sizing: border-box; margin-top: 0.25em;">статистика в текстовом виде <a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_custom.html.md" style="background-color: transparent; box-sizing: border-box;">./media/index_custom.html.md</a>.</li></ul><h2 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; text-align: left;"><span style="font-size: x-large;">Разделение данных по трендам</span></h2><h4 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/PriceGenerator/blob/master/README_RU.md#%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85-%D0%BF%D0%BE-%D1%82%D1%80%D0%B5%D0%BD%D0%B4%D0%B0%D0%BC" id="user-content-разделение-данных-по-трендам" style="background-color: transparent; box-sizing: border-box; float: left; font-size: 16px; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg><span style="font-size: x-large;"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></span></a></h4><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Эта фича появилась начиная с дев-версии <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">pricegenerator>=1.2.dev53</code> и в релизных версиях, старше чем <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">pricegenerator>=1.2.56</code>.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Появились два новых консольных ключа: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--split-trend</code> и <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--split-count</code>. Эти ключи указывают на внешний вид цепочки мини-трендов и количество свечей в каждом тренде.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--split-trend</code> показывает вид движения, например <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--split-trend=/\-</code> означает, что будет сгенерирована такая цепочка свечей, что сначала тренд будет возрастающий в её первой части, затем тренд сменится на нисходящий, и в последней цепочке свечей тренда не будет.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--split-count</code> устанавливает количество свечей в каждом мини-тренде, например <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">--split-count 5 10 15</code> означает, что в сгенерированной цепочке свечей будет три мини-тренда с 5, 10 и 15 свечами в каждом из них.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Чтобы понять, как это работает, попробуйте один из следующих примеров:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; overflow: auto !important; position: relative !important;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pricegenerator --horizon 300 --render-bokeh index.html --split-trend=/\- --split-count 50 100 150 --generate
pricegenerator --horizon 300 --render-bokeh index.html --split-trend=\/\ --split-count 50 100 150 --generate
pricegenerator --horizon 300 --render-bokeh index.html --split-trend=\-/ --split-count 50 100 150 --generate
pricegenerator --horizon 100 --render-bokeh index.html --split-trend=/\/\ --split-count 20 30 30 20 --generate
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Для последнего примера требуется разбить тренд по схеме: возрастание (20 свечей) - убывание (30 свечей) - возрастание (30 свечей) - убывание (20 свечей). В итоге получилась картинка движения цены, похожая на эту:</p></div><div class="separator" style="clear: both; text-align: center;"><a href="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_with_trends.html.png?raw=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="418" data-original-width="800" height="334" src="https://github.com/Tim55667757/PriceGenerator/blob/master/media/index_with_trends.html.png?raw=true" width="640" /></a></div><h3 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><span style="font-size: x-large;">Как работать с генератором через импорт модуля</span></h3><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Давайте рассмотрим пример генерации цен с некоторыми переопределёнными параметрами в Pandas DataFrame и отрисовку графика. Сохраните и запустите следующий python-скрипт:</p><div class="highlight highlight-source-python position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; overflow: auto !important; position: relative !important;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px; word-break: normal;"><span class="pl-k" style="box-sizing: border-box; color: var(--color-prettylights-syntax-keyword);">from</span> <span class="pl-s1" style="box-sizing: border-box;">pricegenerator</span>.<span class="pl-v" style="box-sizing: border-box; color: var(--color-prettylights-syntax-variable);">PriceGenerator</span> <span class="pl-k" style="box-sizing: border-box; color: var(--color-prettylights-syntax-keyword);">import</span> <span class="pl-v" style="box-sizing: border-box; color: var(--color-prettylights-syntax-variable);">PriceGenerator</span>, <span class="pl-s1" style="box-sizing: border-box;">uLogger</span>
<span class="pl-k" style="box-sizing: border-box; color: var(--color-prettylights-syntax-keyword);">from</span> <span class="pl-s1" style="box-sizing: border-box;">datetime</span> <span class="pl-k" style="box-sizing: border-box; color: var(--color-prettylights-syntax-keyword);">import</span> <span class="pl-s1" style="box-sizing: border-box;">datetime</span>, <span class="pl-s1" style="box-sizing: border-box;">timedelta</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Отключаем логирование, чтобы не мешалось:</span>
<span class="pl-s1" style="box-sizing: border-box;">uLogger</span>.<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">setLevel</span>(<span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">0</span>)
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># --- Инициализируем экземпляр класса генератора и настраиваем некоторые параметры:</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-v" style="box-sizing: border-box; color: var(--color-prettylights-syntax-variable);">PriceGenerator</span>()
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">precision</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">1</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># сколько знаков после запятой должно быть в сгенерированных ценах</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">ticker</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-s" style="box-sizing: border-box; color: var(--color-prettylights-syntax-string);">"MY_GENERATED_PRICES"</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># произвольное имя (тикер) генерируемых цен</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">timeframe</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">timedelta</span>(<span class="pl-s1" style="box-sizing: border-box;">days</span><span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span><span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">1</span>) <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># временной интервал между генерируемыми свечами, 1 час по умолчанию</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">timeStart</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-s1" style="box-sizing: border-box;">datetime</span>.<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">today</span>() <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># с какой даты начинать генерацию свечей, по умолчанию с текущего времени</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">horizon</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">60</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># сколько сгенерировать свечей, их должно быть не меньше 5-ти, по умолчанию 100</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">maxClose</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">16000</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># максимальная цена закрытия свечи во всей цепочке цен,</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># по умолчанию генерируется случайно в интервале (70, 90), это немного похоже на цены USDRUB</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">minClose</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">13800</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># минимальная цена закрытия свечи во всей цепочке цен,</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># по умолчанию генерируется случайно в интервале (60, 70), это немного похоже на цены USDRUB</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">initClose</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">14400</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># если цена указана, то она будет ценой close (как бы "предыдущей" свечи) и одновременно ценой open самой первой свечи в генерируемой цепочке.</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># None по умолчанию означает, что цена open первой свечи будет сгенерирована случайно в интервале (minClose, maxClose)</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">maxOutlier</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">500</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Максимальное значение для ценовых выбросов "хвостов" у свечей.</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># None по умолчанию означает, что выбросы будут не более чем на (maxClose - minClose) / 10</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">maxCandleBody</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">300</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Максимальное значение для размера тел свечей abs(open - close).</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># None по умолчанию означает, что тело свечи может быть не более чем 90% от размера максимального выброса: maxOutlier * 90%</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">maxVolume</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">400000</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># максимальное значение объёма торгов для одной свечи, по умолчанию берётся случайным образом из интервала (0, 100000)</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">upCandlesProb</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">0.46</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># вероятность того, что очередная генерируемая свеча будет вверх, 50% по умолчанию</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">outliersProb</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">0.11</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># вероятность того, что очередная генерируемая свеча будет иметь ценовой "выброс", 3% по умолчанию</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">trendDeviation</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">0.005</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># колебание цены close первой и последней свечей для определения тренда. "NO trend" если разница меньше этого значения, по умолчанию ±0.005 или ±0.5%.</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">zigzag</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">0.05</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># относительная разница между двумя точками ZigZag индикатора, 0.03 по умолчанию</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">_chartTitle</span> <span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span> <span class="pl-s" style="box-sizing: border-box; color: var(--color-prettylights-syntax-string);">""</span> <span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># произвольный заголовок графика, обычно генерируется автоматически</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Цены пока не сгенерированы и не загружены, проверим это:</span>
<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">print</span>(<span class="pl-s" style="box-sizing: border-box; color: var(--color-prettylights-syntax-string);">"Current prices:<span class="pl-cce" style="box-sizing: border-box;">\n</span>{}"</span>.<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">format</span>(<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">prices</span>))
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Запускаем генератор цен, при этом они будут сохранены</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># в переменной priceModel.prices в формате Pandas DataFrame:</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-v" style="box-sizing: border-box; color: var(--color-prettylights-syntax-variable);">Generate</span>()
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Убеждаемся, что цены сгенерированы:</span>
<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">print</span>(<span class="pl-s" style="box-sizing: border-box; color: var(--color-prettylights-syntax-string);">"Generated prices as Pandas DataFrame:<span class="pl-cce" style="box-sizing: border-box;">\n</span>{}"</span>.<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">format</span>(<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">prices</span>))
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Словарь с посчитанной статистикой сохраняется в переменную self.stat:</span>
<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">print</span>(<span class="pl-s" style="box-sizing: border-box; color: var(--color-prettylights-syntax-string);">"Dict with statistics:<span class="pl-cce" style="box-sizing: border-box;">\n</span>{}"</span>.<span class="pl-en" style="box-sizing: border-box; color: var(--color-prettylights-syntax-entity);">format</span>(<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-s1" style="box-sizing: border-box;">stat</span>))
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Сохраняем OHLCV-цены в .csv-файл</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-v" style="box-sizing: border-box; color: var(--color-prettylights-syntax-variable);">SaveToFile</span>(<span class="pl-s1" style="box-sizing: border-box;">fileName</span><span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span><span class="pl-s" style="box-sizing: border-box; color: var(--color-prettylights-syntax-string);">"test.csv"</span>)
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Сохраняем график цен в html-файл и сразу открываем его в браузере.</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Статистика в текстовом виде будет автоматически сохранена в markdown-файле с именем fileName + ".md".</span>
<span class="pl-s1" style="box-sizing: border-box;">priceModel</span>.<span class="pl-v" style="box-sizing: border-box; color: var(--color-prettylights-syntax-variable);">RenderBokeh</span>(<span class="pl-s1" style="box-sizing: border-box;">fileName</span><span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span><span class="pl-s" style="box-sizing: border-box; color: var(--color-prettylights-syntax-string);">"index.html"</span>, <span class="pl-s1" style="box-sizing: border-box;">viewInBrowser</span><span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">=</span><span class="pl-c1" style="box-sizing: border-box; color: var(--color-prettylights-syntax-constant);">True</span>)
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Вместо библиотеки Bokeh вы можете отрисовать цены на простом, не интерактивном графике,</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># через библиотеку Google Candlestick chart. Просто раскомментируйте строчки ниже.</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># Перед вызовом priceModel.RenderGoogle(), вы можете задать свой шаблон в переменной self.j2template</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># priceModel.j2template = "google_template_example.j2" # полный путь до шаблона или мультистроковая переменная с jinja2-шаблоном</span>
<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"># priceModel.RenderGoogle(fileName="index.html", viewInBrowser=True)</span></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">При запуске скрипта вы получите аналогичный вывод в консольный лог, три файла: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">test.csv</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">index.html</code> и <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">index.html.md</code>, а также html-файл с графиком цен, который будет сразу же открыт в браузере. Вы можете самостоятельно поэкспериментировать с параметрами класса <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; margin: 0px; padding: 0.2em 0.4em;">PriceGenerator()</code> для генерации цен подходящих под ваши условия тестирования.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px !important; margin-top: 0px;"><br /></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px !important; margin-top: 0px;"><br /></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px !important; margin-top: 0px;">Успехов вам в автоматизации и тестировании биржевой торговли! <b>;-)</b></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-18700986876353132542022-01-10T19:35:00.006+03:002022-10-02T20:25:30.570+03:00AVStockParser — модуль python для работы с сервисом Alpha Vantage и получения данных с биржи NASDAQ <p><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292f;"><b>AVStockParser</b></span></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://travis-ci.com/Tim55667757/AVStockParser" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="Build Status" data-canonical-src="https://travis-ci.com/Tim55667757/AVStockParser.svg?branch=master" src="https://camo.githubusercontent.com/8d712369a1bc0d3bdeb8167b518e5e427fe0bda0bf2adaae07844ada155d7c88/68747470733a2f2f7472617669732d63692e636f6d2f54696d35353636373735372f415653746f636b5061727365722e7376673f6272616e63683d6d6173746572" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://pypi.python.org/pypi/AVStockParser" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="pypi" data-canonical-src="https://img.shields.io/pypi/v/AVStockParser.svg" src="https://camo.githubusercontent.com/6bfcf0b606349d8cce98ccd692732326e3c5f53a0b3d8eab011a57c11150a4fc/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f415653746f636b5061727365722e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://github.com/Tim55667757/AVStockParser/blob/master/LICENSE" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="license" data-canonical-src="https://img.shields.io/pypi/l/AVStockParser.svg" src="https://camo.githubusercontent.com/04e00ca88cb59c8405867bde7e3b779eb7e411cd5c2b5f00a98133870e0134d9/68747470733a2f2f696d672e736869656c64732e696f2f707970692f6c2f415653746f636b5061727365722e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Ссылка на проект: <a href="https://github.com/Tim55667757/AVStockParser">https://github.com/Tim55667757/AVStockParser</a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Трейдерам необходимо получать исторические данные по акциям для дальнейшего анализа цен и построения графиков. Чаще всего эти данные платные или приходится тратить много времени и вручную загружать их со специальных сайтов.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Для автоматизации работы с историческими данными есть множество онлайн-сервисов, которые предоставляют API для этого бесплатно, но с некоторой задержкой. Например, <b>Alpha Vantage</b>. Основной источник данных для этого сервиса — биржа NASDAQ. Если вам нужна автоматизация работы с этой американской биржей и вы используете python, то далее расскажу, как это можно сделать с помощью Alpha Vantage API и библиотеки AVStockParser.<span></span></p><a name='more'></a><p></p><p></p><p dir="auto" style="background-color: white; box-sizing: border-box; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box;"><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji" style="color: #24292f;">Подробная документация по работе с Alpha Vantage API здесь: <a href="https://www.alphavantage.co/documentation/">https://www.alphavantage.co/documentation/</a></span></span></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><b><span style="box-sizing: border-box;">AVStockParser</span> </b>это простая библиотека, которую можно использовать как python-модуль или запускать из командной строки и получать данные от Alpha Vantage сервера с историей котировок произвольных инструментов по их тикеру. Причём не нужно разбираться в тонкостях API сервера, модуль всё сделает сам.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Модуль AVStockParser запрашивает историю цен по доступным инструментам (акциям и валютам) в формате .json с сайта <a href="http://www.alphavantage.co/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">www.alphavantage.co</a> и конвертирует их в Pandas dataframe или в .csv-файл, которые содержат OHLCV-свечи в каждой строке. Вы получаете таблицу, которая содержит колонки данных в следующей последовательности: "date", "time", "open", "high", "low", "close", "volume". Одна строка — это набор данных для построения одной "японской свечи" (candlestick). Дополнительно можно отобразить данные на простом интерактивном свечном графике.</p><p></p><h2 dir="auto" style="background-color: white; border-bottom: 1px solid var(--color-border-muted); box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><span style="font-size: x-large;">Как установить</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Проще всего использовать установку через PyPI:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip install avstockparser
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">После этого можно проверить установку командой:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="box-sizing: border-box; overflow: auto; position: relative; text-align: left;"><pre lang="commandline" style="border-radius: 6px; box-sizing: border-box; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; color: #24292f; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip show avstockparser</code></pre></div><h3 style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; text-align: left;"><span style="font-size: large;">Аутентификация</span></h3><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Сервис Alpha Vantage использует для аутентификации <b>апи-кей</b>. Запросить бесплатный ключ можно тут: <a href="https://www.alphavantage.co/support/#api-key" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">https://www.alphavantage.co/support/#api-key</a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><b>Апи-кей</b> — <b>это алфавитно-цифровой токен</b>. Этот токен необходимо отправлять на сервер с каждым запросом. Для этого, при работе с библиотекой AVStockParser, просто используйте ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--api-key "your token here"</code> или указывайте апи-кей при вызове метода: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">AVParseToPD(apiKey="your token here")</code>.</p><h2 dir="auto" style="background-color: white; border-bottom: 1px solid var(--color-border-muted); box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/AVStockParser/blob/master/README_RU.md#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F" id="user-content-примеры-использования" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg><span style="font-size: x-large;"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></span></a><span style="font-size: x-large;">Примеры использования</span></h2><h3 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/AVStockParser/blob/master/README_RU.md#%D0%B8%D0%B7-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D0%BE%D0%B9-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8" id="user-content-из-командной-строки" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Из командной строки</h3><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Внутренняя справка по ключам:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">avstockparser --help
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Вывод:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">Запуск: python AVStockParser.py [параметры] [одна или несколько команд]
Получение данных о ценах акций через сервис Alpha Vantage. Можно получить
и сохранить исторические данные по ценам акций в .csv-файл или в виде
Pandas dataframe. Примеры: https://tim55667757.github.io/AVStockParser
Возможные параметры командной строки:
-h, --help Показать эту подсказку и выйти
--api-key API_KEY Параметр (обязательный): апи-кей для сервиса Alpha Vantage.
Запросить ключ для бесплатного доступа можно тут:
https://www.alphavantage.co/support/#api-key
--ticker TICKER Параметр (обязательный): тикер акции, например,
'GOOGL' или 'YNDX'.
--output OUTPUT Параметр: полный путь до .csv-файла. По умолчанию None
означает, что будет получен только Pandas dataframe.
--period PERIOD Параметр: можно использовать значения 'TIME_SERIES_INTRADAY',
'TIME_SERIES_DAILY', 'TIME_SERIES_WEEKLY' или
'TIME_SERIES_MONTHLY'. По умолчанию: 'TIME_SERIES_INTRADAY',
что означает, что api вернёт внутридневную историю цен для
предопределённого интервала. Больше примеров здесь:
https://www.alphavantage.co/documentation/
--interval INTERVAL Параметр: '1min', '5min', '15min', '30min' или '60min'.
Интервал используется только для внутридневной истории цен
для ключа --period='TIME_SERIES_INTRADAY'. По умолчанию: '60min',
что означает, что api вернёт внутридневную историю цен
и каждая свеча будет иметь интервал в 60 минут.
--size SIZE Параметр: сколько исторических свечей нужно скачать.
Значения могут быть 'full' или 'compact'. Этот параметр
использует сервис AV для параметра запроса 'outputsize'.
По умолчанию: 'compact' означает, что api вернёт 100 свечей.
--retry RETRY Параметр: количество попыток подключения к сервису AV.
По умолчанию: 3.
--debug-level DEBUG_LEVEL
Параметр: уровень логирования для STDOUT,
например, 10 = DEBUG, 20 = INFO, 30 = WARNING,
40 = ERROR, 50 = CRITICAL.
--parse Команда: скачать историю цен как Pandas dataframe
или как .csv-файл (если ключ --output будет задан).
--render Команда: использовать библиотеку PriceGenerator для отрисовки
интерактивного графика цен после парсинга истории. Этот ключ
можно использовать только с ключом --parse.
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Давайте попробуем получить <b>дневные свечи по акциям Яндекса</b> (тикер <b>YNDX</b>) и сохранить их в файл YNDX1440.csv. Команда может выглядеть как-то так:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">avstockparser --debug-level 10 --api-key "your token here" --ticker YNDX --period TIME_SERIES_DAILY --size full --output YNDX1440.csv --parse
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В случае успеха вы должны получить вывод логов примерно следующего содержания:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">AVStockParser.py L:184 DEBUG [2020-12-25 01:03:13,459] Alpha Vantage data parser started: 2020-12-25 01:03:13
AVStockParser.py L:51 DEBUG [2020-12-25 01:03:13,459] Request to Alpha Vantage: [https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=YNDX&outputsize=full&apikey=***]
AVStockParser.py L:55 DEBUG [2020-12-25 01:03:13,459] Trying (1) to send request...
AVStockParser.py L:119 INFO [2020-12-25 01:03:15,013] It was received 2415 candlesticks data from Alpha Vantage service
AVStockParser.py L:120 INFO [2020-12-25 01:03:15,013] Showing last 3 rows with Time Zone: 'US/Eastern':
AVStockParser.py L:123 INFO [2020-12-25 01:03:15,018] date time open high low close volume
AVStockParser.py L:123 INFO [2020-12-25 01:03:15,018] 2412 2020.12.22 00:00 67.2800 67.4400 66.3000 67.1100 1002761
AVStockParser.py L:123 INFO [2020-12-25 01:03:15,018] 2413 2020.12.23 00:00 67.7300 68.7700 67.6400 67.6900 822039
AVStockParser.py L:123 INFO [2020-12-25 01:03:15,018] 2414 2020.12.24 00:00 68.1800 68.2900 67.1700 67.6500 359133
AVStockParser.py L:127 INFO [2020-12-25 01:03:15,027] Stock history saved to .csv-formatted file [./YNDX1440.csv]
AVStockParser.py L:229 DEBUG [2020-12-25 01:03:15,027] All Alpha Vantage data parser operations are finished success (summary code is 0).
AVStockParser.py L:234 DEBUG [2020-12-25 01:03:15,028] Alpha Vantage data parser work duration: 0:00:01.568581
AVStockParser.py L:235 DEBUG [2020-12-25 01:03:15,028] Alpha Vantage data parser finished: 2020-12-25 01:03:15
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Для консольного ключа <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--period</code> вы можете указывать значения: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TIME_SERIES_DAILY</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TIME_SERIES_WEEKLY</code> и <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TIME_SERIES_MONTHLY</code> для получения дневных, недельных и месячных свечей соответственно. По умолчанию используется значение <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">TIME_SERIES_INTRADAY</code>.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В следующем примере давайте попробуем получить <b>внутридневные часовые свечи по акциям 3M</b> (тикер <b>MMM</b>) и сохранить их в файл MMM60.csv. Команда может быть примерно такой:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">avstockparser --debug-level 10 --api-key "your token here" --ticker MMM --period TIME_SERIES_INTRADAY --interval 60min --size compact --output MMM60.csv --parse
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В случае успеха вы получите вывод, похожий на этот:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">AVStockParser.py L:184 DEBUG [2020-12-25 01:09:44,601] Alpha Vantage data parser started: 2020-12-25 01:09:44
AVStockParser.py L:51 DEBUG [2020-12-25 01:09:44,601] Request to Alpha Vantage: [https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MMM&interval=60min&outputsize=compact&apikey=***]
AVStockParser.py L:55 DEBUG [2020-12-25 01:09:44,601] Trying (1) to send request...
AVStockParser.py L:119 INFO [2020-12-25 01:09:45,542] It was received 100 candlesticks data from Alpha Vantage service
AVStockParser.py L:120 INFO [2020-12-25 01:09:45,542] Showing last 3 rows with Time Zone: 'US/Eastern':
AVStockParser.py L:123 INFO [2020-12-25 01:09:45,551] date time open high low close volume
AVStockParser.py L:123 INFO [2020-12-25 01:09:45,551] 97 2020.12.23 16:00 174.5700 175.0200 173.9550 174.0200 332340
AVStockParser.py L:123 INFO [2020-12-25 01:09:45,551] 98 2020.12.23 17:00 173.9900 173.9900 173.9600 173.9600 316682
AVStockParser.py L:123 INFO [2020-12-25 01:09:45,551] 99 2020.12.23 18:00 173.9900 173.9900 173.9900 173.9900 1410
AVStockParser.py L:127 INFO [2020-12-25 01:09:45,555] Stock history saved to .csv-formatted file [./MMM60.csv]
AVStockParser.py L:229 DEBUG [2020-12-25 01:09:45,555] All Alpha Vantage data parser operations are finished success (summary code is 0).
AVStockParser.py L:234 DEBUG [2020-12-25 01:09:45,555] Alpha Vantage data parser work duration: 0:00:00.953904
AVStockParser.py L:235 DEBUG [2020-12-25 01:09:45,555] Alpha Vantage data parser finished: 2020-12-25 01:09:45
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Файл ./MMM60.csv из этого примера будет содержать похожие данные по часовым свечам и столбцы: "date", "time", "open", "high", "low", "close", "volume":</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">2020.12.11,09:00,171.9100,171.9100,171.5500,171.8300,1663
2020.12.11,10:00,172.0100,173.6800,172.0100,173.5900,214065
2020.12.11,11:00,173.5800,173.9770,172.6700,173.0800,268294
...
2020.12.23,16:00,174.5700,175.0200,173.9550,174.0200,332340
2020.12.23,17:00,173.9900,173.9900,173.9600,173.9600,316682
2020.12.23,18:00,173.9900,173.9900,173.9900,173.9900,1410
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--size</code> может принимать значение <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">full</code> (Alpha Vantage сервис отправит всю доступную историческую информацию по свечам) или <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">compact</code> (будут отправлены только последние 100 свечей).</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--interval</code> используется только с ключом и значением <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--period TIME_SERIES_INTRADAY</code>. Интервалы для внутридневных свечей могут принимать значения: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">1min</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">5min</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">15min</code>, <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">30min</code> или <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">60min</code>.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Кроме того, вы можете построить интерактивный график цен (используя библиотеку <a href="https://github.com/Tim55667757/PriceGenerator" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">PriceGenerator</a>). Для этого укажите ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--render</code> после ключа <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--parse</code>:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">avstockparser --debug-level 10 --api-key "your token here" --ticker YNDX --period TIME_SERIES_DAILY --size compact --output YNDX1440.csv --parse --render
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">После выполнения команды выше вы получите три файла:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">YNDX1440.csv</code> — файл в формате .csv, который содержит цены (пример: <a href="https://github.com/Tim55667757/AVStockParser/blob/master/media/YNDX1440.csv" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">./media/YNDX1440.csv</a>);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">index.html</code> — график цен и статистику, отрисованные при помощи библиотеки Bokeh и сохранённые в .html-файл (пример: <a href="https://github.com/Tim55667757/AVStockParser/blob/master/media/index.html" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">./media/index.html</a>);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">index.html.md</code> — статистика в текстовом виде, сохранённая в маркдаун-формате (пример: <a href="https://github.com/Tim55667757/AVStockParser/blob/master/media/index.html.md" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">./media/index.html.md</a>).</li></ul><div class="separator" style="clear: both; text-align: center;"><a href="https://raw.githubusercontent.com/Tim55667757/AVStockParser/master/media/index.html.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="421" data-original-width="800" height="337" src="https://raw.githubusercontent.com/Tim55667757/AVStockParser/master/media/index.html.png" width="640" /></a></div><h3 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/AVStockParser/blob/master/README_RU.md#%D1%87%D0%B5%D1%80%D0%B5%D0%B7-%D0%B8%D0%BC%D0%BF%D0%BE%D1%80%D1%82-%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8F" id="user-content-через-импорт-модуля" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Через импорт модуля</h3><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Давайте рассмотрим один простой <b>пример запроса исторических данных по акциям IBM</b> и как их можно сохранить их в <b>Pandas dataframe</b>:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">from avstockparser.AVStockParser import AVParseToPD as Parser
# Запрашиваем исторические данные по свечам и сохраняем их в переменную Pandas dataframe.
# Если переменная output не указана, то метод AVParseToPD не будет сохранять текстовый файл,
# а только вернёт данные в формате Pandas dataframe.
df = Parser(
reqURL=r"https://www.alphavantage.co/query?",
apiKey="demo",
output=None,
ticker="IBM",
period="TIME_SERIES_INTRADAY",
interval="5min",
size="full",
retry=2,
)
print(df)
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">При запуске получим вывод, похожий на следующий:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">AVStockParser.py L:119 INFO [2020-12-25 01:49:51,612] It was received 2001 candlesticks data from Alpha Vantage service
AVStockParser.py L:120 INFO [2020-12-25 01:49:51,612] Showing last 3 rows with Time Zone: 'US/Eastern':
AVStockParser.py L:123 INFO [2020-12-25 01:49:51,616] date time open high low close volume
AVStockParser.py L:123 INFO [2020-12-25 01:49:51,616] 1998 2020.12.23 17:35 124.1000 124.1000 124.1000 124.1000 1571
AVStockParser.py L:123 INFO [2020-12-25 01:49:51,617] 1999 2020.12.23 18:45 124.0500 124.0500 124.0000 124.0000 278
AVStockParser.py L:123 INFO [2020-12-25 01:49:51,617] 2000 2020.12.23 20:00 123.9100 123.9100 123.9100 123.9100 225
date time open high low close volume
0 2020.11.25 06:50 124.3500 124.3500 124.2000 124.2000 1218
1 2020.11.25 07:05 124.2000 124.2000 124.2000 124.2000 150
2 2020.11.25 07:10 124.1000 124.1000 124.1000 124.1000 100
3 2020.11.25 07:35 124.0000 124.0000 124.0000 124.0000 510
4 2020.11.25 08:05 123.8201 124.2000 123.8200 123.8200 1414
... ... ... ... ... ... ... ...
1996 2020.12.23 17:05 123.9100 123.9100 123.9100 123.9100 100
1997 2020.12.23 17:20 123.9000 123.9000 123.9000 123.9000 1146
1998 2020.12.23 17:35 124.1000 124.1000 124.1000 124.1000 1571
1999 2020.12.23 18:45 124.0500 124.0500 124.0000 124.0000 278
2000 2020.12.23 20:00 123.9100 123.9100 123.9100 123.9100 225
[2001 rows x 7 columns]
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;">После этого переменную <code style="background-color: transparent; border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">df</code> вы можете передать в любую вашу любимую библиотеку (NumPy, SciPy, Matplotlib, TensorFlow, Keras, Pandas etc) и использовать для дальнейших манипуляций с данными.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;"><br /></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;"><br /></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;"><br /></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;">Успехов вам в автоматизации биржевой торговли! <b>;-)</b></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-3934961042605309602022-01-09T23:41:00.004+03:002022-10-02T20:25:54.099+03:00MT4ForexParser — модуль python для работы с файлами истории MetaTrader 4<p><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292f;"><b>MT4ForexParser</b></span></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://travis-ci.com/Tim55667757/MT4ForexParser" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="Build Status" data-canonical-src="https://travis-ci.com/Tim55667757/MT4ForexParser.svg?branch=master" src="https://camo.githubusercontent.com/9f584778692a73666eace3f2297e236b8064e59d408a3f001d45e30fdfb66e20/68747470733a2f2f7472617669732d63692e636f6d2f54696d35353636373735372f4d5434466f7265785061727365722e7376673f6272616e63683d6d6173746572" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://pypi.python.org/pypi/MT4ForexParser" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="pypi" data-canonical-src="https://img.shields.io/pypi/v/MT4ForexParser.svg" src="https://camo.githubusercontent.com/aaa505bc3666792f9b1005640c824eb9304da6a3daf5ce2ae068d911bc85ffff/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f4d5434466f7265785061727365722e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a> <a href="https://github.com/Tim55667757/MT4ForexParser/blob/master/LICENSE" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><img alt="license" data-canonical-src="https://img.shields.io/pypi/l/MT4ForexParser.svg" src="https://camo.githubusercontent.com/579f0d11dfa531fcafe6d073fedd817b8a41c060256df77b664c1fd22a2d315f/68747470733a2f2f696d672e736869656c64732e696f2f707970692f6c2f4d5434466f7265785061727365722e737667" style="background-color: var(--color-canvas-default); border-style: none; box-sizing: content-box; max-width: 100%;" /></a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Ссылка на проект: <a href="https://github.com/Tim55667757/MT4ForexParser">https://github.com/Tim55667757/MT4ForexParser</a></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">У всех трейдеров периодически возникает необходимость получить исторические данные по валютам Forex (или по акциям) для дальнейшего анализа цен и построения графиков. Чаще всего эти данные поставляются на платной основе, либо вам приходится тратить много времени на ручную выгрузку данных на специальных сайтах.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Однако большинство Forex брокеров работают с торговой платформой MetaTrader 4 и загружают туда данные <b>в специальном бинарном .hst-формате </b>для MetaTrader 4 (не в .csv). Этим можно воспользоваться и получить исторические свечи подключившись к серверу брокера в демо-режиме, который есть почти у всех брокеров. При этом сжатый бинарный .hst-файл будет скачан локально в рабочий каталог MetaTrader 4.<span></span></p><a name='more'></a><p></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Далее можно запустить <b>python-модуль mt4forexparser</b>, который умеет читать файлы формата .hst и сохранять их как текстовый .csv-файл или pandas dataframe. Вы получите таблицу, которая содержит колонки данных в следующей последовательности: "date", "time", "open", "high", "low", "close", "volume". Одна строка — это набор данных для построения одной "японской свечи" (candlestick).</p><h2 dir="auto" style="background-color: white; border-bottom: 1px solid var(--color-border-muted); box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><span style="font-size: x-large;">Как установить</span></h2><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Проще всего использовать установку через PyPI:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip install mt4forexparser
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">После этого можно проверить установку командой:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative; text-align: left;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">pip show mt4forexparser
</code></pre></div><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-muted); box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; text-align: left;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/MT4ForexParser/blob/master/README_RU.md#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F" id="user-content-примеры-использования" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg><span style="font-size: x-large;"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></span></a><span style="font-size: x-large;">Примеры использования</span></h2><h3 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/MT4ForexParser/blob/master/README_RU.md#%D0%B8%D0%B7-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D0%BE%D0%B9-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8" id="user-content-из-командной-строки" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Из командной строки</h3><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Внутренняя справка по ключам:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">mt4forexparser --help
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Вывод:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">Запуск: python MT4ForexParser.py [параметры] [одна или несколько команд]
Парсер бинарных файлов истории Metatrader 4. Умеет читать и сохранять историю цен в виде .csv-файла
или Pandas dataframe, а также отображать цены в виде интерактивного графика.
Смотрите примеры: https://tim55667757.github.io/MT4ForexParser
Возможные параметры командной строки:
-h, --help Показать эту подсказку и выйти
--mt4-history MT4_HISTORY
Параметр (обязательный): полный путь до файла истории цен
в формате Metatrader 4.
--output OUTPUT Параметр: полный путь до выходного .csvфайла. По умолчанию
None, при этом возвращается только Pandas dataframe.
--debug-level DEBUG_LEVEL
Параметр: уровень логирования для STDOUT,
например, 10 = DEBUG, 20 = INFO, 30 = WARNING,
40 = ERROR, 50 = CRITICAL.
--parse Команда: прочитать, распарсить и сохранить историю цен как
Pandas dataframe или .csv-файл (если задан ключ --output).
--render Команда: использовать библиотеку PriceGenerator для отрисовки
интерактивного графика цен после парсинга истории. Этот ключ
можно использовать только с ключом --parse.
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Поддерживаются две версии форматов файлов .hst: <b>400</b> и <b>401</b>, они определяются автоматически. Попробуйте проверить работу парсера через командную строку на двух приложенных файлах различного формата: <b>./tests/EURUSD240_old_format_400.hst</b> и <b>./tests/EURUSD240_new_format_401.hst</b>.</p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Команда запуска может быть такая:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">mt4forexparser --mt4-history ./tests/EURUSD240_old_format_400.hst --output ./tests/EURUSD240_old_format_400.csv --debug-level 10 --parse
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В случае успеха вы должны получить вывод логов примерно следующего содержания:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">MT4ForexParser.py L:118 DEBUG [2020-07-21 20:47:00,134] MT4 parser started: 2020-07-21 20:47:00
MT4ForexParser.py L:38 DEBUG [2020-07-21 20:47:00,134] MT4 history file: [./tests/EURUSD240_old_format_400.hst]
MT4ForexParser.py L:42 DEBUG [2020-07-21 20:47:00,171] MT4 history file format version: [400]
MT4ForexParser.py L:63 INFO [2020-07-21 20:47:00,334] It was read 5909 rows from file [./tests/EURUSD240_old_format_400.hst]
MT4ForexParser.py L:64 INFO [2020-07-21 20:47:00,334] Showing last 3 rows:
MT4ForexParser.py L:69 INFO [2020-07-21 20:47:00,339] date time open high low close volume
MT4ForexParser.py L:69 INFO [2020-07-21 20:47:00,339] 5906 2013.10.18 12:00 1.36918 1.37036 1.36690 1.36780 8193
MT4ForexParser.py L:69 INFO [2020-07-21 20:47:00,340] 5907 2013.10.18 16:00 1.36779 1.36993 1.36773 1.36795 6639
MT4ForexParser.py L:69 INFO [2020-07-21 20:47:00,340] 5908 2013.10.18 20:00 1.36793 1.36849 1.36765 1.36839 1955
MT4ForexParser.py L:73 INFO [2020-07-21 20:47:00,383] Forex history saved to .csv-formatted file [./tests/EURUSD240_old_format_400.csv]
MT4ForexParser.py L:148 DEBUG [2020-07-21 20:47:00,384] All MT4 parser operations are finished success (summary code is 0).
MT4ForexParser.py L:153 DEBUG [2020-07-21 20:47:00,384] MT4 parser work duration: 0:00:00.249747
MT4ForexParser.py L:154 DEBUG [2020-07-21 20:47:00,384] MT4 parser work finished: 2020-07-21 20:47:00
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">При этом вы получите .csv-файл ./tests/EURUSD240_old_format_400.csv следующего содержания (всего 5909 строк):</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">2009.12.21,00:00,1.4311,1.4347,1.4311,1.4342,5504
2009.12.21,04:00,1.4342,1.4357,1.4327,1.4334,5234
2009.12.21,08:00,1.4334,1.4342,1.428,1.4337,8366
...
2013.10.18,12:00,1.36918,1.37036,1.3669,1.3678,8193
2013.10.18,16:00,1.36779,1.36993,1.36773,1.36795,6639
2013.10.18,20:00,1.36793,1.36849,1.36765,1.36839,1955
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Аналогично для парсинга файла нового формата:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">mt4forexparser --mt4-history ./tests/EURUSD240_new_format_401.hst --output ./tests/EURUSD240_new_format_401.csv --debug-level 10 --parse
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В случае успеха вы получите примерно такой вывод логов:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">MT4ForexParser.py L:118 DEBUG [2020-07-21 20:55:42,594] MT4 parser started: 2020-07-21 20:55:42
MT4ForexParser.py L:38 DEBUG [2020-07-21 20:55:42,595] MT4 history file: [./tests/EURUSD240_new_format_401.hst]
MT4ForexParser.py L:42 DEBUG [2020-07-21 20:55:42,675] MT4 history file format version: [401]
MT4ForexParser.py L:63 INFO [2020-07-21 20:55:43,098] It was read 12969 rows from file [./tests/EURUSD240_new_format_401.hst]
MT4ForexParser.py L:64 INFO [2020-07-21 20:55:43,099] Showing last 3 rows:
MT4ForexParser.py L:69 INFO [2020-07-21 20:55:43,103] date time open high low close volume
MT4ForexParser.py L:69 INFO [2020-07-21 20:55:43,104] 12966 2019.07.08 08:00 1.12305 1.12339 1.12190 1.12310 8894
MT4ForexParser.py L:69 INFO [2020-07-21 20:55:43,104] 12967 2019.07.08 12:00 1.12309 1.12322 1.12123 1.12228 9257
MT4ForexParser.py L:69 INFO [2020-07-21 20:55:43,104] 12968 2019.07.08 16:00 1.12228 1.12240 1.12091 1.12153 7381
MT4ForexParser.py L:73 INFO [2020-07-21 20:55:43,187] Forex history saved to .csv-formatted file [./tests/EURUSD240_new_format_401.csv]
MT4ForexParser.py L:148 DEBUG [2020-07-21 20:55:43,188] All MT4 parser operations are finished success (summary code is 0).
MT4ForexParser.py L:153 DEBUG [2020-07-21 20:55:43,188] MT4 parser work duration: 0:00:00.594304
MT4ForexParser.py L:154 DEBUG [2020-07-21 20:55:43,189] MT4 parser work finished: 2020-07-21 20:55:43
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Файл ./tests/EURUSD240_new_format_401.csv будет полностью аналогичный и включать те же самые столбцы "date", "time", "open", "high", "low", "close", "volume" (всего 12969 строк):</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">2009.12.21,00:00,1.4311,1.4347,1.4311,1.4342,5504
2009.12.21,04:00,1.4342,1.4357,1.4327,1.4334,5234
2009.12.21,08:00,1.4334,1.4342,1.428,1.4337,8366
...
2019.07.08,08:00,1.12305,1.12339,1.1219,1.1231,8894
2019.07.08,12:00,1.12309,1.12322,1.12123,1.12228,9257
2019.07.08,16:00,1.12228,1.1224,1.12091,1.12153,7381
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Кроме того, вы можете построить <b>интерактивный график цен</b> (используя библиотеку <a href="https://github.com/Tim55667757/PriceGenerator" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;"><b>PriceGenerator</b></a>). Для этого укажите ключ <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--render</code> после ключа <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">--parse</code>:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre lang="commandline" style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">mt4forexparser --mt4-history ./tests/EURUSD240_new_format_401.hst --output test.csv --parse --render
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">После выполнения команды выше вы получите три файла:</p><ul dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">test.csv</code> — файл в формате .csv, который содержит цены (пример: <a href="https://github.com/Tim55667757/MT4ForexParser/blob/master/media/test.csv" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">./media/test.csv</a>);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">index.html</code> — график цен и статистику, отрисованные при помощи библиотеки Bokeh и сохранённые в .html-файл (пример: <a href="https://github.com/Tim55667757/MT4ForexParser/blob/master/media/index.html" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">./media/index.html</a>);</li><li style="box-sizing: border-box; margin-top: 0.25em;"><code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em;">index.html.md</code> — статистика в текстовом виде, сохранённая в маркдаун-формате (пример: <a href="https://github.com/Tim55667757/MT4ForexParser/blob/master/media/index.html.md" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">./media/index.html.md</a>).</li></ul><div class="separator" style="clear: both; text-align: center;"><a href="https://github.com/Tim55667757/MT4ForexParser/blob/master/media/index.html.png?raw=true" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="422" data-original-width="800" height="338" src="https://github.com/Tim55667757/MT4ForexParser/blob/master/media/index.html.png?raw=true" width="640" /></a></div><h3 dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/Tim55667757/MT4ForexParser/blob/master/README_RU.md#%D1%87%D0%B5%D1%80%D0%B5%D0%B7-%D0%B8%D0%BC%D0%BF%D0%BE%D1%80%D1%82-%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8F" id="user-content-через-импорт-модуля" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Через импорт модуля</h3><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Рассмотрим на примере парсинга файла истории нового формата (версии 401 для MetaTrader 4) ./tests/EURUSD240_new_format_401.hst:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">from mt4forexparser.MT4ForexParser import MT4ParseToPD as Parser
# Распарсим исторические свечи и сохраним данные в переменную типа pandas dataframe.
# Для сохранения свечей в файл можно указать переменную outputFile="./tests/EURUSD240_new_format_401.csv"
# Если переменная outputFile не будет указана, модуль вернёт только данные в формате pandas dataframe.
df = Parser(historyFile="./tests/EURUSD240_new_format_401.hst")
print(df) # выведем данные по свечам в формате pandas dataframe
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">При запуске получим полностью аналогичный вывод:</p><div class="snippet-clipboard-content position-relative overflow-auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; overflow: auto; position: relative;"><pre style="background-color: var(--color-canvas-subtle); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: transparent; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">...
>>> print(df)
date time open high low close volume
0 2009.12.21 00:00 1.43110 1.43470 1.43110 1.43420 5504
1 2009.12.21 04:00 1.43420 1.43570 1.43270 1.43340 5234
2 2009.12.21 08:00 1.43340 1.43420 1.42800 1.43370 8366
3 2009.12.21 12:00 1.43370 1.43710 1.43300 1.43330 8456
4 2009.12.21 16:00 1.43320 1.43350 1.42860 1.42940 8488
... ... ... ... ... ... ... ...
12964 2019.07.08 00:00 1.12230 1.12293 1.12192 1.12204 3455
12965 2019.07.08 04:00 1.12205 1.12307 1.12203 1.12307 4173
12966 2019.07.08 08:00 1.12305 1.12339 1.12190 1.12310 8894
12967 2019.07.08 12:00 1.12309 1.12322 1.12123 1.12228 9257
12968 2019.07.08 16:00 1.12228 1.12240 1.12091 1.12153 7381
</code></pre></div><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;"><br /></p><p dir="auto" style="background-color: white; box-sizing: border-box; color: #24292f; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;">Успехов вам в автоматизации биржевой торговли! <b>;-)</b></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-39681206817893780292021-12-20T14:08:00.006+03:002021-12-22T14:53:32.681+03:00Безопасная разработка: какую часть Sec занимает в DevSecOps<div class="tm-misprint-area" style="quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><div class="tm-misprint-area__wrapper" style="quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><article class="tm-article-presenter__content tm-article-presenter__content_narrow" style="box-sizing: border-box; padding: 16px 20px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><div class="tm-article-body" data-gallery-root="" lang="ru" style="box-sizing: border-box; padding-top: 16px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><div class="article-formatted-body article-formatted-body_version-2" id="post-content-body" style="color: #111111; font-size: 1rem; line-height: 1.56; overflow-wrap: break-word; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><div style="quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;" xmlns="http://www.w3.org/1999/xhtml"><p style="font-size: 1rem; line-height: 1.5rem; margin: 32px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh5oFzoyjBz5SMZEwzWuSmM9rmBUC8SdGnuQzgwEA-2dPcY9z_bVwBYsZvyMSL4XSgxP_QL9p4_ATbMBG8PndPcz8G49IbPnObt02cnSIIXkjKMytYS-hT1qNYeJvdD0dBu8DEwO9rkwXpJNkbkn7bk8Y_94fbWSvlwGAZ_UwXs7JQ4NurdU9dlIoWqLw=s1740" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="1080" data-original-width="1740" height="199" src="https://blogger.googleusercontent.com/img/a/AVvXsEh5oFzoyjBz5SMZEwzWuSmM9rmBUC8SdGnuQzgwEA-2dPcY9z_bVwBYsZvyMSL4XSgxP_QL9p4_ATbMBG8PndPcz8G49IbPnObt02cnSIIXkjKMytYS-hT1qNYeJvdD0dBu8DEwO9rkwXpJNkbkn7bk8Y_94fbWSvlwGAZ_UwXs7JQ4NurdU9dlIoWqLw=s320" width="320" /></a></div>Всем привет! На Хабре вышла новая статья по теме безопасной разработки и DevSecOps: "<a href="https://habr.com/ru/company/pt/blog/595955/" target="_blank">Безопасная разработка: какую часть Sec занимает в DevSecOps</a>". Сохраню тут копию.<span><a name='more'></a></span><p></p><p style="font-size: 1rem; line-height: 1.5rem; margin: 32px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Меня зовут <a href="https://www.linkedin.com/in/tgilmullin/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Тимур Гильмуллин</a>, я руководитель направления по построению процессов безопасной разработки в компании Positive Technologies. Раньше я работал в DevOps-отделе, где инженеры занимаются автоматизацией различных процессов и помогают программистам и тестировщикам. В числе прочего мы проводили работы, связанные с внедрением <a href="https://habr.com/ru/company/pt/blog/557142/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">инструментов безопасной разработки</a> в CI/CD-конвейер. В этой статье я рассмотрю концепцию безопасной разработки DevSecOps (или SecDevOps) в целом: разберемся, что это за концепция, что она дает бизнесу, разработчикам, инженерам DevOps и безопасникам, какие инструменты можно при этом использовать и насколько трудоемко их внедрение.</p><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 1.25rem; font-weight: 500; line-height: 1.625rem; margin: 56px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Про DevSecOps</h2><p style="font-size: 1rem; line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">По версии компании «Майкрософт», <a href="https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/secure/devsecops-controls" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">методология DevSecOps</a> подразумевает интеграцию процессов и внедрение инструментов безопасной разработки поверх уже выстроенных DevOps-процессов и работающих CI/CD-конвейеров.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Сами по себе идеи безопасной разработки и тестирования безопасности ПО не новы. Уже в конце 80-х годов в России существовали ГОСТы, например <a href="https://docs.cntd.ru/document/1200009135" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">ГОСТ 28195-89</a>, включающие в себя в том числе проверки на ошибки обслуживания, то есть нарушение порядка взаимодействия с программой со стороны пользователя, — фактически это были проверки безопасности. Аналогичные стандарты были и за рубежом. DevSecOps — это более современный подход к быстрой разработке надежного и безопасного продукта, учитывающий все последние технологические новинки в этой области.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Однако сами по себе процессы и безопасная разработка как сервис мало кого интересуют, важны лишь конечные результаты, к которым приводит внедрение идей и инструментов DevSecOps. К ним можно отнести:</p><ul style="margin-top: 32px; padding-inline-start: 32px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><li style="line-height: 1.5rem; margin: 0px 0px 6px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">быстрое и безопасное развертывание приложений в продакшн-окружении, то есть уменьшение времени time-to-market за счет автоматизации;</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">удешевление исправления ошибок и уязвимостей в ПО за счет их обнаружения на ранних этапах разработки;</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">снижение критических и неприемлемых рисков для вендора ПО, например, недопущение встраивания вредоносного кода в компоненты разрабатываемого продукта или защита инфраструктуры от атак типа <a href="https://en.wikipedia.org/wiki/Supply_chain_attack" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">supply chain</a>.</p></li></ul><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Альтернативой процессам DevSecOps можно назвать только отказ от этих идей и возвращение к <a href="https://habr.com/ru/company/pt/blog/552104/#:~:text=%D0%9A%D0%B0%D0%BA%20%D0%BC%D1%8B%20%D0%BF%D0%BE%D0%BD%D0%B8%D0%BC%D0%B0%D0%B5%D0%BC%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%83,%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D0%BD%D0%BE%D0%BC%20%D0%B4%D0%BB%D1%8F%20%D0%BD%D0%B8%D1%85%20%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%B5." style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">классическому подходу к разработке</a>. Напомню, как это было до использования гибких методологий разработки и DevOps. Программисты писали код и сами же его собирали, тестировщики тестировали то, что им отдали программисты, а дальше инженеры по эксплуатации вручную устанавливали это на «боевые» серверы. Добавьте сюда различные регламенты и противоречивые требования команды безопасников. А еще — распределение всех этих команд по разным городам и разным часовым поясам. Разработка могла затянуться на месяцы и даже годы. Сейчас мало кто захочет вернуться к тем временам. Чтобы решать такие проблемы, нужно объединить всех участников в едином и понятном для них процессе. Это могут помочь сделать инженеры и идеологи подходов DevSecOps.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Построить DevOps-процессы и наладить автоматизацию разработки — задача сама по себе уже достаточно сложная и трудоемкая. <a href="https://habr.com/ru/company/pt/blog/552104/#:~:text=%D0%9A%D0%B0%D0%BA%20%D0%B8%D0%B4%D0%B5%D1%82%20%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0%20%D0%BF%D0%BE%20%D0%BF%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF%D0%B0%D0%BC%20DevOps" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Типовой процесс разработки</a> включает в себя CI/CD-конвейер, который автоматизирует все этапы сборки продукта, деплой на тестовой инфраструктуре, проведение автотестов, продвижение продукта в релиз и его публикацию на серверах обновлений для дальнейшей доставки в инфраструктуру заказчика. Этот конвейер сопровождают на всех этапах DevOps-инженеры, к которым относятся инженеры по инфраструктуре и CI-инженеры. Они занимаются автоматизацией различных процессов разработки, помогают программистам и тестировщикам работать с продуктовыми конвейерами и инструментами автоматизации.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Security-часть необходимо внедрять в этот процесс комплексно, включая встраивание инструментов DevSecOps поверх конвейера разработки совместными усилиями инженеров IT, DevOps и специалистов-безопасников.</p><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 1.25rem; font-weight: 500; line-height: 1.625rem; margin: 56px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Про инструменты</h2><p style="font-size: 1rem; line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Инструменты, обеспечивающие безопасность инфраструктуры и каждого из этапов разработки, могут быть различными. Есть множество вендоров, предлагающих отдельные технические инструменты, но очень мало тех, кто предлагает решения под ключ, обеспечивающие защиту всех этапов разработки, и в этом есть определенная проблема.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Кроме того, недостает и технических решений, тех же сканеров кода, которыми программист мог бы пользоваться самостоятельно. Я считаю, что в этом вопросе разработчикам сканеров следует двигаться в сторону исправления уязвимостей «одной кнопкой», без привлечения так называемых security champions — специалистов-безопасников. Программисты вряд ли захотят, чтобы такие специалисты постоянно сидели около них и объясняли, как исправлять уязвимости. Это как если бы рядом с пользователями редактора Word сажали учительницу русского языка, которая бы объясняла, почему редактор подчеркнул ошибку и как ее исправить :) Но для этого сканер кода должен включать в себя достаточно обширную базу знаний по уязвимостям и типовые шаблоны их исправления для большинства языков программирования.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Хотелось бы отметить, что само по себе сканирование кода не дает результатов. Подход должен быть комплексным: сканирование должно быть встроено в CI/CD-процесс, должны быть настроены правила безопасности (<a href="https://habr.com/ru/company/pt/blog/557142/#:~:text=Security%20Gates%20%E2%80%94%20%D1%8D%D1%82%D0%BE%20%D0%BD%D0%B0%D0%B1%D0%BE%D1%80%20%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%20%D0%B4%D0%BB%D1%8F%20%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0%20%D1%81%D0%BA%D0%B0%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%2C%20%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5%20%D1%83%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D1%8E%D1%82%20CI%2D%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B5%2C%20%D0%BA%D0%B0%D0%BA%20%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BD%D0%B0%D0%B9%D0%B4%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5%20%D1%83%D1%8F%D0%B7%D0%B2%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8%20%D0%B8%20%D0%BA%D0%B0%D0%BA%20%D0%BD%D0%B0%20%D0%BD%D0%B8%D1%85%20%D1%80%D0%B5%D0%B0%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%3A%20%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D1%83%20%D0%B8%D0%BB%D0%B8%20%D0%BC%D0%B5%D1%80%D0%B4%D0%B6%2D%D1%80%D0%B5%D0%BA%D0%B2%D0%B5%D1%81%D1%82%20%D0%BB%D0%B8%D0%B1%D0%BE%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D1%82%D1%8C%20%D0%B2%20%D1%80%D0%B5%D0%B6%D0%B8%D0%BC%D0%B5%20%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F." style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">security gates</a>) для автоматической блокировки сборки в случае обнаружения уязвимостей, а разработчики — пользователи сканера — должны пройти обучение.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Насколько сложно внедрить в компании процесс безопасной разработки? На мой взгляд, трудоемкость внедрения инструментов DevSecOps в CI/CD зависит от множества факторов: от масштабов проекта, готовности инфраструктуры разработки, достаточной квалификации инженеров и принципиального желания самих разработчиков использовать внедряемые инструменты. <a href="https://habr.com/ru/company/pt/blog/557142/#:~:text=%D0%AF%20%D1%85%D0%BE%D1%87%D1%83%20%D0%BF%D0%BE%D0%B4%D1%87%D0%B5%D1%80%D0%BA%D0%BD%D1%83%D1%82%D1%8C,%D1%83%D0%B4%D0%BE%D0%B1%D0%B5%D0%BD%20%D0%B2%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Два последних фактора</a> я считаю наиболее важными. Инженеры и разработчики должны быть сами заинтересованы в использовании инструментов безопасной разработки, эти инструменты должны им нравиться, быть удобными и легко интегрироваться в CI/CD-конвейеры корпоративной разработки.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">В одной из наших прошлых статей мы <a href="https://habr.com/ru/company/pt/blog/557142/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">подробно рассказали</a> о внедрении анализатора исходного кода <a href="https://www.ptsecurity.com/ru-ru/products/ai/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PT Application Inspector</a> (комплексное решение SAST/DAST/IAST) в DevSecOps-процессы одного из наших продуктов и о том, с какими нюансами при этом столкнулись. Тогда это потребовало усилий двух CI-инженеров и одного инженера по инфраструктуре на протяжении нескольких месяцев работы, включая разработку архитектуры внедрения сканера. Но зато потом мы получили шаблоны и типовой процесс сканирования кода, тиражирование которых уже не занимает много времени. Все эти наработки, включая шаблоны сканирования, мы выложили в опенсорс-проект <a href="https://github.com/devopshq/dohq-ai-best-practices" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">dohq-ai-best-practices</a>.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Как же организовать процесс безопасной разработки? Во-первых, прежде чем выстраивать <a href="https://tproger.ru/articles/devops-among-developers/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">DevSecOps-процессы</a>, компания сначала должна построить DevOps-процессы. Для автоматизации процессов может использоваться любой CI/CD-конвейер, их достаточно много (GitLab CI/CD, GitHub Actions, TeamCity, Travis CI, Jenkins, CI платформы Microsoft Azure, AWS и Google).</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Во-вторых, необходимо на уровне CI/CD-конвейера обеспечить защиту каждого этапа разработки и развертывания ПО. Ведь, согласно <a href="https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/secure/innovation-security#secure-by-design-and-shifting-left" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">концепции shift left</a>, чем раньше будут найдены потенциальные уязвимости в коде и инфраструктуре, тем дешевле будет стоить исправление этих ошибок. А если они будут обнаружены только в продакшн-окружении у заказчика, их исправление может привести даже к переделке всей архитектуры приложения.</p><figure class="full-width" style="margin: 32px 0px 0px; quotes: "«" "»"; text-align: center; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><img alt="Использование продуктов Positive Technologies в качестве DevSecOps-инструментов на различных этапах CI/CD-конвейера" data-src="https://habrastorage.org/getpro/habr/upload_files/752/284/b7b/752284b7b051a078c5206a08e7f75beb.png" data-width="1400" height="920" src="https://habrastorage.org/r/w1560/getpro/habr/upload_files/752/284/b7b/752284b7b051a078c5206a08e7f75beb.png" style="border-style: none; color: #7e6e6f; cursor: pointer; font-size: 0.75rem; font-style: italic; height: auto; margin: 0px; max-width: 100%; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s; vertical-align: middle;" title="Использование продуктов Positive Technologies в качестве DevSecOps-инструментов на различных этапах CI/CD-конвейера" width="1400" /><figcaption style="color: #909090; font-size: 0.8125rem; line-height: 1.125rem; margin-top: 4px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s; white-space: pre-wrap;">Использование продуктов Positive Technologies в качестве DevSecOps-инструментов на различных этапах CI/CD-конвейера</figcaption></figure><p style="font-size: 1rem; line-height: 1.5rem; margin: 32px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Расположение SEC на схеме подразумевает, что security-процесс должен рассматриваться как непрерывный — так же, как и процессы разработки, деплоя, тестирования и доставки. То есть безопасность должна обеспечиваться соответствующими инструментами на каждом этапе технологического процесса.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">На этапах разработки и сборки продукта для этого могут использоваться различные сканеры кода (например, <a href="https://www.ptsecurity.com/ru-ru/products/ai/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PT Application Inspector</a>). После развертывания продукта в тестовой среде могут быть использованы сканеры black box (например, <a href="https://bbs.ptsecurity.com/ru" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PT BlackBox Scanner</a> в составе <a href="https://www.ptsecurity.com/ru-ru/products/mp8/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">MaxPatrol 8</a>), которые фактически имитируют внешний пентест приложения. И, наконец, после завершения всех тестов, исправления найденных уязвимостей и развертывания продукта в продакшн-окружении, он может быть защищен от хакерских атак межсетевым экраном (например, таким как <a href="https://www.ptsecurity.com/ru-ru/products/af/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PT Application Firewall</a>). Кстати, PT Application Firewall может защитить не только разрабатываемый продукт, но и вообще любые корпоративные приложения и сервисы, в том числе от <a href="https://ru.wikipedia.org/wiki/%D0%A3%D1%8F%D0%B7%D0%B2%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C_%D0%BD%D1%83%D0%BB%D0%B5%D0%B2%D0%BE%D0%B3%D0%BE_%D0%B4%D0%BD%D1%8F" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">0-day атак</a> (например, он из коробки <a href="https://www.ptsecurity.com/ru-ru/about/news/produkty-positive-technologies-vyyavlyayut-kriticheski-opasnuyu-uyazvimost-v-rasprostranennoj-biblioteke-log4j/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">умеет предотвращать</a> эксплуатацию критической уязвимости в <a href="https://www.opennet.ru/opennews/art.shtml?num=56319" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Apache Log4j 2</a>, затрагивающей большое число Java-проектов).</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Дальнейший контроль за инфраструктурой и развернутым продуктом может вестись более комплексными системами аудита ИБ и SIEM-системами, такими как <a href="https://www.ptsecurity.com/ru-ru/products/mpsiem/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">MaxPatrol SIEM</a>, системой управления уязвимостями <a href="https://www.ptsecurity.com/ru-ru/products/mp-vm/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">MaxPatrol VM</a>, а также системами контроля трафика по всей сети, где развернуто приложение, для предотвращения хакерских атак. Например, системой анализа трафика <a href="https://www.ptsecurity.com/ru-ru/products/network-attack-discovery/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PT Network Attack Discovery</a>, которая умеет выявлять техники <a href="https://mitre.ptsecurity.com/ru-RU/techniques" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">MITRE ATT&CK</a>. Дополнительно обеспечить безопасность серверов можно при помощи <a href="https://www.ptsecurity.com/ru-ru/products/sandbox/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PT Sandbox</a> — песочницы для выявления сложных атак с применением вредоносного ПО, или системы антивирусной защиты <a href="https://www.ptsecurity.com/ru-ru/products/multiscanner/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PT MultiScanner</a>.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">В-третьих, необходимо обеспечить безопасное развертывание всей инфраструктуры, виртуальной или «железной». Для этого используется множество инструментов и подходов, в том числе написание сценариев подготовки и развертывания инфраструктуры через SaltStack, Ansible, Kubernetes или OpenShift. О технологических новинках из мира построения безопасной инфраструктуры можно узнавать на различных ресурсах, например, в канале <a href="https://t.me/sec_devops" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">DevSecOps Wine</a>. Его автор, Денис Якимов, участвуя в одном исследовании нашей компании, <a href="https://www.ptsecurity.com/ru-ru/about/news/issledovanie-positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/#:~:text=%D0%94%D0%B5%D0%BD%D0%B8%D1%81%20%D0%AF%D0%BA%D0%B8%D0%BC%D0%BE%D0%B2%20%D0%BA%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D1%83%D0%B5%D1%82" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">подчеркнул</a> важность правильного выбора подходов DevSecOps: «<em style="quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">В погоне за маркетинговыми лозунгами shift left компании так увлеклись встраиванием сканеров в пайплайны, что забыли про не менее важную часть безопасности разработки — инфраструктуру и цепочку поставок</em>».</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://www.enterprisenetworkingplanet.com/security/a-guide-to-devsecops-what-is-it-and-why-is-it-required/#Switch_to_Immutable_Infrastructure" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Неизменяемая и версионированная инфраструктура</a> также важна, потому что DevOps-инженерам необходимо обеспечивать повторяемость сборок для одного и того же коммита в кодовой базе. Оркестрация контейнеров сборки помогает избежать досадных проблем, которые могут возникать при ручном конфигурировании инфраструктуры (например, как это было в недавнем <a href="https://www.bbc.com/russian/features-58807202" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">нашумевшем случае</a> с «Фейсбуком»). Не менее важна и защита самих контейнеров сборки — минимальный базовый образ и использование минимальных привилегий для запуска приложений внутри контейнера, использование систем аудита для контроля запущенных процессов и сетевой активности.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Ко всем перечисленным инструментам можно добавить следующие:</p><ul style="margin-top: 32px; padding-inline-start: 32px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><li style="line-height: 1.5rem; margin: 0px 0px 6px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">внедрение в пайплайны сборки автоматизированных тестов безопасности (функции безопасности должны тестироваться так же качественно, как и основная функциональность продукта);</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">автоматическая проверка сторонних зависимостей (например, с помощью <a href="https://owasp.org/www-project-dependency-check/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">OWASP Dependency-Check</a>);</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">внедрение ролевой модели доступа к ресурсам разрабатываемого продукта;</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">защита кодовой базы (например, <a href="https://docs.gitlab.com/ee/user/project/repository/gpg_signed_commits/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">подписывание коммитов</a> в хранилище и использование верификации коммитов);</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">цифровая подпись собранных компонентов (например, при помощи <a href="https://docs.microsoft.com/ru-ru/windows/win32/seccrypto/signtool" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">SignTool</a>) и ее проверка при формировании бандла (инсталлятора) продукта из этих компонентов.</p></li></ul><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">О безопасной разработке в части процессов и инструментов много было сказано <a href="https://www.ptsecurity.com/ru-ru/about/press/events/322706/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">на встрече Positive Tech Press Club</a> с экспертами в области DevOps, DevSecOps, AppSec и защиты инфраструктуры. Участники встречи рассказали о трендовых угрозах и примерах кибератак, которые стали возможны из-за брешей в исходном коде, а также обсудили, нужна ли компаниям безопасная разработка, как эксперты оценивают степень проникновения этого подхода в российский бизнес и какие результаты уже достигнуты.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Отдельной темой беседы стало обсуждение элементов DevSecOps и SSDL не только в плане технологий и инструментов, но и культуры безопасной разработки, подходов и принципов. Из важного стоит отметить, что мнения экспертов по поводу того, безопасность каких элементов процесса разработки необходимо обеспечить в первую очередь, разделились. Кто-то считает, что самое важное — защитить инфраструктуру разработки и эксплуатации, а другие, что инфраструктура вторична и что главное — это защитить само приложение и сделать безопасным код. То есть ключевые элементы DevSecOps — это безопасная инфраструктура для CI/CD-конвейера и процесс безопасной разработки, работающий поверх этой инфраструктуры.</p><blockquote style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-left: 4px solid rgb(84, 142, 170); margin: 32px 0px 12px; padding: 0px 12px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Если обобщить мнения экспертов, то можно дать следующую комплексную формулу: <span style="-webkit-font-smoothing: antialiased; font-weight: bolder; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">DevSecOps </span>= <span style="-webkit-font-smoothing: antialiased; font-weight: bolder; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">AppSec + SecDev + Infrastructure Security</span>. В каждом из этих трех направлений кибербезопасности нужно, конечно же, исходить из лучших его практик.</p></blockquote><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 1.25rem; font-weight: 500; line-height: 1.625rem; margin: 56px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Про культуру</h2><p style="font-size: 1rem; line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://youtu.be/xfIwn9ZiaZo?t=425" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">По мнению специалистов «Тинькофф»</a>, «безопасность как сервис» часто интерпретируется только в контексте предоставления шаблонов подключения WAF/SAST/DAST и прочих инструментов ИБ, которые могут быть легко встроены в CI/CD-конвейер через IaC (infrastructure as code). При этом каждый разработчик может сам встроить все проверки безопасности отдельными шагами в свой сборочный процесс. Но здесь есть проблемы, тормозящие внедрение культуры безопасной разработки, с которыми часто сталкиваются крупные компании:</p><ol style="margin-top: 32px; padding-inline-start: 32px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><li style="line-height: 1.5rem; margin: 0px 0px 6px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">До сих пор в компаниях не везде есть единый согласованный CI, под который нужно писать шаблоны. Часто бывает «зоопарк» технологий: одновременно могут использоваться TeamCity, GitLab CI/CD, TFS, Jenkins и самописные системы сборки.</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">До сих пор есть разработчики, которые собирают код руками и выкладывают артефакты сборки в хранилище, вперемешку с артефактами, собранными автоматически.</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Разработчики могут просто отключить шаги безопасности или не встраивать их в свой сборочный процесс, а у команды ИБ нет механизмов по своевременному выявлению таких ситуаций.</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Все инструментальные решения имеют свой воркфлоу по работе с уязвимостями. Где-то проставляются комментарии и статусы в трекере или в системе контроля версий, а где-то таких механизмов в принципе нет. У многих инструментов вообще нет UI.</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">У каждого решения есть своя консоль управления и, соответственно, свой набор доступов, который нужно предоставлять для разработчиков и безопасников. А это приводит к большему усложнению и без того сложных ролевых политик компании.</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Специалистов со стороны ИБ, как правило, всего несколько человек, а разработчиков сотни. Это приводит к классической проблеме «вас много, а я один», из-за чего разработчикам просто не хочется обращаться к безопасникам.</p></li></ol><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">В итоге для решения указанных проблем команды разработчиков из крупных компаний с большой разношерстной инфраструктурой разработки постепенно приходят к концепции предоставления безопасности не просто в виде шаблонов, а в виде полноценного внутрикорпоративного SaaS-решения — платформе DevSecOps/AppSec, или «безопасности под ключ».</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Тем не менее простое внедрение подходов и инструментов DevSecOps не приведет к одномоментной трансформации всей инфраструктуры компании в сторону большей безопасности. Здесь нет универсальных решений. Для успешного развития идей безопасной разработки в компании должны сложиться определенная культура разработки и тесное сотрудничество между безопасниками и различными группами инженеров. Однако многие компании по-прежнему ведут разработку, используя традиционные подходы, где инженеры по эксплуатации, разработчики и безопасники достаточно сильно изолированы друг от друга. Это <a href="https://www.ptsecurity.com/ru-ru/about/news/issledovanie-positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">подтверждается и нашим опросом</a> о состоянии безопасной разработки в компаниях — вендорах ПО.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Только треть опрошенных инженеров сообщили, что компании, в которых они работают, включили меры по обеспечению безопасности в цикл разработки ПО. А половина опрошенных готовы участвовать в DevSecOps-процессах, только если у них появится понимание, что этот подход сможет защитить разрабатываемые продукты от хакеров. Здесь я бы рекомендовал инженерам, разработчикам и руководителям разработки ПО принимать участие в различных профильных конференциях по кибербезопасности, хакатонах и киберучениях (например, <a href="https://standoff365.com/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">The Standoff</a> или <a href="https://www.phdays.com/ru/about/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">PHDays</a>), где они смогут приобрести необходимые знания и навыки, в том числе по безопасной разработке.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Руководителям компаний и подразделений разработки также стоит поощрять культуру сотрудничества между инженерами служб ИБ, ИТ, DevOps и самими разработчиками. DevSecOps-специалисты, которые им помогают, должны быть хорошо знакомы с процессами и методологиями разработки, принятыми в конкретной компании. Кроме того, они должны не только очень хорошо разбираться в вопросах безопасности, но и уметь донести свое видение до всех участников процесса разработки.</p><p style="font-size: 1rem; line-height: 1.5rem; margin: 24px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">DevSecOps — это не только про инструменты или конкретный набор технологий, но еще и про новое глобальное направление в компании. Для его развития нужен ответственный человек, который будет его идеологом, а также заинтересованные инженеры и программисты в командах. Понятно, что процессы разработки различаются в каждой компании, у всех есть своя специфика. Но, несмотря на все преимущества подходов безопасной разработки, многие компании все еще сомневаются в принятии DevSecOps. Как и DevOps, который когда-то изменил подходы к разработке ПО, идеи DevSecOps также требуют изменений в способе мышления. Современные компании должны понять, что ответственность за безопасность лежит на всех участниках процесса разработки, а не только на специалистах по информационной безопасности. Внедрить идеи DevSecOps будет непросто, но изменения того стоят.</p><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 1.25rem; font-weight: 500; line-height: 1.625rem; margin: 56px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Дополнительные материалы по теме DevOps и DevSecOps</h2><ul style="margin-top: 24px; padding-inline-start: 32px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><li style="line-height: 1.5rem; margin: 0px 0px 6px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://habr.com/ru/company/pt/blog/313616/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Личный опыт: как выглядит наша система Continuous Integration</a> (2016)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://habr.com/ru/company/pt/blog/343884/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Автоматизация процессов разработки: как мы в Positive Technologies внедряли идеи DevOps</a> (2017)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://forworktests.blogspot.com/2018/12/blog-post.html" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Моделирование производственных процессов в ИТ-компании</a> (2018)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://habr.com/ru/company/pt/blog/480754/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Управление хаосом: наводим порядок с помощью технологической карты</a> (2019)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://habr.com/ru/company/pt/blog/501766/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Личный опыт: как выстроить карьерный рост в отделе DevOps</a> (2020)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://habr.com/ru/company/pt/blog/534458/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">DevSecOps: как мы внедряли PT Application Inspector в наш продуктовый конвейер</a> (2020)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://habr.com/ru/company/pt/blog/557142/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">DevSecOps. PT Application Inspector в разработке ПО: блокировка релиза</a> (2021)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://habr.com/ru/company/pt/blog/552104/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Как работает команда DevOps в Positive Technologies</a> (2021)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://standoff365.com/phdays10/schedule/development/positive-technologies-experience-in-implementing-devsecops-tools/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Positive Technologies: опыт внедрения инструментов DevSecOps</a> (2021)</p></li><li style="line-height: 1.5rem; margin: 12px 0px 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a href="https://www.ptsecurity.com/ru-ru/about/press/events/322706/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Безопасная разработка: как жить в цифре, писать много кода и не стать жертвой хакеров</a> (2021)</p></li></ul><p style="font-size: 1rem; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Если вам интересна тема кибербезопасности и безопасной разработки, следите за нашими <a href="https://www.ptsecurity.com/ru-ru/research/webinar/" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">вебинарами</a> и новыми статьями в этом блоге. На этом пока все, ждем ваших вопросов в комментариях :)</p><hr style="border-bottom: 0px; border-image: initial; border-left-color: rgb(17, 17, 17); border-left-style: solid; border-right-color: rgb(17, 17, 17); border-right-style: solid; border-top-color: rgb(17, 17, 17); border-top-style: solid; box-sizing: initial; height: 0px; margin: 56px auto; max-width: 280px; overflow: visible; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;" /><div class="persona" persona="true" style="clear: both; margin: 24px 0px; min-height: 60px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><img class="image persona__image" data-src="https://habrastorage.org/getpro/habr/upload_files/244/d59/3f0/244d593f08d61168accbd551787da69a.jpg" persona="true" src="https://habrastorage.org/r/w1560/getpro/habr/upload_files/244/d59/3f0/244d593f08d61168accbd551787da69a.jpg" style="border-radius: 30px; border-style: none; color: #7e6e6f; cursor: pointer; float: left; font-size: 0.75rem; font-style: italic; height: 60px; margin: 0px 16px 0px 0px; max-width: 100%; object-fit: cover; overflow: hidden; position: relative; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s; vertical-align: middle; width: 60px;" /><h5 class="persona__heading" persona="true" style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 1rem; font-weight: 400; line-height: 1.5rem; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Тимур Гильмуллин</h5><p class="persona__text" persona="true" style="clear: none; color: #909090; font-size: 0.8125rem; line-height: 1.25rem; margin: 4px 0px 0px; overflow: hidden; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Руководитель направления по построению процессов безопасной разработки в Positive Technologies. Отвечал за разработку архитектуры и внедрение сканера кода PT Application Inspector в сборочный технологический процесс. Создатель опенсорс-проекта <a href="https://github.com/devopshq/dohq-ai-best-practices" style="color: #548eaa; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">dohq-ai-best-practices</a>.</p></div></div></div></div><div class="tm-article-presenter__meta" style="-webkit-font-smoothing: antialiased; box-sizing: border-box; color: #548eaa; font-size: 1rem; line-height: 28.8px; margin: 24px 0px; max-width: 780px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><div class="tm-separated-list tm-article-presenter__meta-list" style="quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><span class="tm-separated-list__title" style="color: #444444; font-weight: 700; margin-right: 4px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Теги:</span> <ul class="tm-separated-list__list" style="display: inline; list-style: none; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5Bdevops%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">devops</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5Bdevsecops%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">devsecops</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5B%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE%D1%81%D1%82%D1%8C%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">безопасность</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5Bcybersecurity%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">cybersecurity</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5B%D0%B8%D0%BD%D1%84%D1%80%D0%B0%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">инфраструктура</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5B%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">разработка</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5B%D0%B7%D0%B0%D1%89%D0%B8%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9%20%D0%BA%D0%BE%D0%B4%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">защищенный код</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5Bcontainers%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">containers</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5B%D1%83%D1%8F%D0%B7%D0%B2%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">уязвимости</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-tags-list__link" href="https://habr.com/ru/search/?target_type=posts&order=relevance&q=%5Bapplication%20security%5D" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">application security</a></li></ul></div><div class="tm-separated-list tm-article-presenter__meta-list" style="margin-top: 24px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><span class="tm-separated-list__title" style="color: #444444; font-weight: 700; margin-right: 4px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Хабы:</span> <ul class="tm-separated-list__list" style="display: inline; list-style: none; margin: 0px; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-hubs-list__link router-link-active" href="https://habr.com/ru/company/pt/blog/" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Блог компании Positive Technologies</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-hubs-list__link" href="https://habr.com/ru/hub/infosecurity/" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Информационная безопасность</a></li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-hubs-list__link" href="https://habr.com/ru/hub/sys_admin/" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Системное администрирование</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-hubs-list__link" href="https://habr.com/ru/hub/dev_management/" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">Управление разработкой</a> </li><li class="tm-separated-list__item" style="display: inline-block; padding: 0px; quotes: "«" "»"; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;"><a class="tm-hubs-list__link" href="https://habr.com/ru/hub/devops/" style="-webkit-font-smoothing: antialiased; color: #548eaa; display: inline-flex; font-size: 1rem; line-height: 1.75rem; quotes: "«" "»"; text-decoration-line: none; transition: opacity 0.2s ease-in-out 0s, color 0.2s ease-in-out 0s, text-decoration 0.2s ease-in-out 0s, background-color 0.2s ease-in-out 0s, -webkit-text-decoration 0.2s ease-in-out 0s;">DevOps</a></li></ul></div></div></article></div></div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-26470763470797475632021-10-12T20:24:00.001+03:002021-10-12T20:24:45.583+03:00Безопасная разработка: как жить в цифре, писать много кода и не стать жертвой хакеров<p>Хочу поделиться <a href="https://www.ptsecurity.com/ru-ru/about/press/events/322706/" target="_blank">ссылкой</a> на прошедшую 2 сентября 2021 года встречу пресс-клуба Positive Tech Press Club, на которых обсудили эволюцию угроз и технологий информационной безопасности. На встрече была затронута актуальная тема DevSecOps или безопасной разработки.</p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="406" src="https://www.youtube.com/embed/Txa22taohEw" width="488" youtube-src-id="Txa22taohEw"></iframe></div><p>Участники пресс-клуба рассказали о трендовых угрозах и примерах кибератак, виной которым послужили бреши в исходном коде ПО. Была дискуссия о том, нужна ли компаниям безопасная разработка, как эксперты оценивают степень проникновения этого подхода в российский бизнес и какие результаты уже достигнуты.</p><p>Отдельной темой беседы стало обсуждение элементов DevSecOps и SSDL1: не только в плане технологий, но и культуры разработки, подходов и принципов. Мероприятие прошло в формате круглого стола и собрало участников, которые смогли всесторонне осветить тему безопасной разработки – с точки зрения вендоров, компаний, имеющих собственные большие команды разработки, системных интеграторов и независимых экспертов.</p><span><a name='more'></a></span><p>На вопросы журналистов ответили: </p><p></p><ul style="text-align: left;"><li>Алексей Жуков, эксперт отдела систем защиты приложений Positive Technologies,</li><li>Тимур Гильмуллин, руководитель направления по построению процессов безопасной разработки центра исследований и разработки Positive Technologies,</li><li>Денис Якимов, независимый эксперт, создатель самого известного и крупнейшего телеграм-канала на тему DevSecOps,</li><li>Антон Гаврилов, руководитель направления DevSecOps центра информационной безопасности компании «Инфосистемы Джет».</li></ul><div><div class="article__content" style="-webkit-box-flex: 1; -webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; background-color: white; border: 0px; box-sizing: border-box; flex: 1 1 auto; font-family: Roboto, Arial, Helvetica, sans-serif; font-size: 16px; margin: 0px; outline: 0px; overflow: auto; padding: 0px; vertical-align: baseline; width: 820px;"><article style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; box-sizing: border-box; margin: 0px; overflow: hidden; padding: 0px;"><article style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; box-sizing: border-box; margin: 0px; overflow: hidden; padding: 0px;"><h4 style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-size: 18px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 26px; margin: 0px 0px 20px; outline: 0px; padding: 0px; vertical-align: baseline;">Больше подробностей в материалах пресс-конференции:</h4><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a href="https://www.ptsecurity.com/ru-ru/about/news/issledovanie-positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" target="_blank">Исследование Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку</a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a href="https://www.ptsecurity.com/upload/corporate/ru-ru/press/events/positive-tech-press-club-whitepaper-devsecops.pdf" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" target="_blank">Positive Tech Press Club. Безопасная разработка: как жить в цифре, писать много кода и не стать жертвой хакеров</a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a href="https://www.ptsecurity.com/upload/corporate/ru-ru/press/events/pt-devsecops-bio.pdf" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" target="_blank">Результаты опроса: что думают о безопасной разработке в российских компаниях</a></p><h4 style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-size: 18px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 26px; margin: 0px 0px 20px; outline: 0px; padding: 0px; vertical-align: baseline;">Публикации в СМИ</h4><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://ib-bank.ru/bisjournal/post/1655" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">BIS Journal, «Филология DevSecOps» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.cismag.news/post/%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5-%D1%87%D0%B5%D0%BC-%D0%B2-30-%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B5%D0%B2-%D0%B2-%D0%BE%D1%82%D0%B5%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F%D1%85-%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D1%8F%D1%8E%D1%82-%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D1%83%D1%8E-%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D1%83" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">CIS, «Более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://cio.ru/news/030921-Lish-v-30-otechestvennyh-kompaniy-primenyayut-DevSecOps" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">CIO, «Лишь в 30% отечественных компаний применяют DevSecOps» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.cnews.ru/news/line/2021-09-02_issledovanie_positive_technologies" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Cnews, «Исследование Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.crn.ru/news/detail.php?ID=156104" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">CRN, «Опрос Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://plusworld.ru/daily/cat-analytics/issledovanie-positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Журнал ПЛАС, «Исследование Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="http://www.itsz.ru/news/n225228/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">SPBIT, «Безопасная разработка: почему с DevSecOps все непросто» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://servernews.ru/1048181" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Servernews, «Более трети российских компаний придерживаются методологии безопасной разработки ПО» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="http://mskit.ru/news/n225228/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">MSKIT, «Безопасная разработка: почему с DevSecOps все непросто» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="http://nnit.ru/news/n225228/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">NNIT, «Безопасная разработка: почему с DevSecOps все непросто» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="http://www.itsz.ru/news/n225228/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">ITSZ, «Безопасная разработка: почему с DevSecOps все непросто» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://lionsharecitynews.ru/issledovanie-positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Львиная доля городских новостей, «Исследование Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.ptsecurity.com/ru-ru/about/news/issledovanie-positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Positive Technologies, «Исследование Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="http://www.mobilecomm.ru/bezopasnaya-razrabotka-po-v-rossijskih-kompaniyah" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Журнал Мобильные телекоммуникации, «Безопасная разработка ПО в российских компаниях» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.itrn.ru/news/detail.php?id=176255" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">ITRN, «Опрос Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.securitylab.ru/news/523982.php" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">SecurityLab, «PT: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://umnpro.com/novosti/issledovanie-positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Журнал Умное Производство, «Исследование Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="http://www.amulet-group.ru/news.htm?id=4793" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Амулет, «Технологическая сеть 75% промышленных компаний открыта для хакерских атак» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.anti-malware.ru/news/2021-09-03-114534/36840" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Anti-Malware, «Positive Technologies: в России DevSecOps применяют более трети айтишников» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://ib-bank.ru/bisjournal/post/1649" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">BIS Journal, «Обсуждение темы DevSecOps на сентябрьской встрече Positive Tech Press Club» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.allcio.ru/about/company.php" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">allCIO, «DevSecOps в отечественных компаниях» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.it-world.ru/news-company/releases/177925.html" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">it-world, «DevSecOps в отечественных компаниях» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.itsec.ru/news/issledovaniya-positive-technologies-bolee-chem-v-30-sluchayev-v-otechestvennih-kompaniyah-primenayut-bezopasnuyu-razrabotku?hstc=266615889.17ab01c71b5151185d12f498df90c3d0.1625038241513.1629963871683.1630933606135.7&hssc=266615889.1.1630933606135&hsfp=2824465531" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">ITSec, «Исследование Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.it-weekly.ru/news-company/releases/177925.html" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">it-weekly, «DevSecOps в отечественных компаниях» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="https://www.jetinfo.ru/news/positive-technologies-bolee-chem-v-30-sluchaev-v-otechestvennyh-kompaniyah-primenyayut-bezopasnuyu-razrabotku/" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">JETINFO, «Positive Technologies: более чем в 30% случаев в отечественных компаниях применяют безопасную разработку» </a></p><p style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #333333; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px 0px 20px; outline: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;"><a class="link link_new-window" href="http://delmoscow.ru/news/?cid=3fe6b80e&nid=f9e885f1" rel="nofollow noopener noreferrer" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important; border: 0px; box-sizing: border-box; color: #316eb9; cursor: pointer; display: inline-block; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) 0.3s; vertical-align: baseline;" target="_blank">Деловая Москва, «Более чем в 30% случаев в компаниях применяют безопасную разработку» </a></p></article></article></div></div><p></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-78138117045695443532021-06-04T23:25:00.007+03:002021-06-04T23:32:50.592+03:00Содержание коротких технических статей<p><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"" style="background-color: white; color: #24292e; font-size: 16px;"></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQhiQOLliujIJ9vDjv8uJQtLsgWiRXVhRCaeUgsqTarZQR6TDj16mNTnx0euWRIxElJhVcxdaV2x2YQ2cZJkF9JFy_7FLnd8v78VUc0-vxjhR3jLFao2qSxhmv9uR2aHYIWO1vL3U58UVX/s516/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="516" height="99" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQhiQOLliujIJ9vDjv8uJQtLsgWiRXVhRCaeUgsqTarZQR6TDj16mNTnx0euWRIxElJhVcxdaV2x2YQ2cZJkF9JFy_7FLnd8v78VUc0-vxjhR3jLFao2qSxhmv9uR2aHYIWO1vL3U58UVX/w99-h99/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" width="99" /></a></div><p></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Инженерам иногда приходится писать инструкции, короткие технические статьи, готовить рассказы для презентаций и воркшопов, с объяснением того или иного рекомендуемого решения. При подготовке таких рассказов и статей сразу возникают вопросы: о чем писать, сколько писать, что рассказать, а что опустить.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">У профессиональных писателей и редакторов есть шаблоны и заготовки текстов на различные темы. Попробуем <b><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/tech-articles.md" target="_blank">собрать здесь ссылки</a></b> на лучшие рекомендации в помощь тем, кто пишет технические статьи или рассказы.</p><span><a name='more'></a></span><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><br /></p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/tech-articles.md#%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%B0%D1%8F-%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0-%D0%B8%D0%B4%D0%B5%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE-%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE-%D1%80%D0%B0%D1%81%D1%81%D0%BA%D0%B0%D0%B7%D0%B0-%D0%B4%D0%BB%D1%8F-%D0%B2%D0%BE%D1%80%D0%BA%D1%88%D0%BE%D0%BF%D0%B0-%D0%B8%D0%BB%D0%B8-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8" id="user-content-возможная-структура-идеального-технического-рассказа-для-воркшопа-или-статьи" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Возможная структура "идеального" технического рассказа для воркшопа или статьи</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Конечно же ничего идеального не бывает, кроме "золотого сечения" и числа π :) Но следующие рекомендации могут вам пригодиться как для подготовки каркаса для технической статьи, так и для рассказа на воркшопе или вебинаре.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Каким может быть каркас (структура) технической статьи или рассказа:</p><ol style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Технические проблемы, которые будут разобраны или решены в статье (или в рассказе на воркшопе).</li><li style="box-sizing: border-box; margin-top: 0.25em;">Выбранные для решения инструменты, технологии или методики. На что опирались при выборе способов решения, какие метрики и целевые показатели для оценки итогов решения выбирали.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Описание того, как внедряли инструмент или реализовывали техническое решение. Расскажите о процессе решения, разработки инструмента, использовании технологии или методики.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Итоги внедрения: к чему пришли, оценка значений метрик и какая экономия получена.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Описание того, какие выявлены ограничения инструмента, технологии или методики в процессе решения.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Предложения, как можно улучшить и доработать предлагаемое решение в будущем.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Выводы, краткое резюме и основные мысли статьи или рассказа.</li></ol><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Приведём также один пример готовой структуры для написания вообще любой статьи (<a href="https://doitinbound.com/blog/posts-guides/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">взято отсюда</a>). Как пишет сам автор: "По ней можно написать пост, даже если вы считаете, что не умеете писать" :)</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://camo.githubusercontent.com/a5c8716493d40366147d0a0b9567d7796fb2b86b6ffab3de61ab268c3277bc36/687474703a2f2f646f6974696e626f756e642e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031382f30342f706f73742d6775696465732e706e67" rel="noopener noreferrer" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;" target="_blank"><img alt="article-structure" data-canonical-src="http://doitinbound.com/wp-content/uploads/2018/04/post-guides.png" src="https://camo.githubusercontent.com/a5c8716493d40366147d0a0b9567d7796fb2b86b6ffab3de61ab268c3277bc36/687474703a2f2f646f6974696e626f756e642e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031382f30342f706f73742d6775696465732e706e67" style="background-color: var(--color-bg-primary); border-style: none; box-sizing: content-box; max-width: 100%;" /></a></p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/tech-articles.md#%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D0%B5-%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8-%D0%B4%D0%BB%D1%8F-%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BA%D0%B8-%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85-%D1%81%D1%82%D0%B0%D1%82%D0%B5%D0%B9-%D0%B2%D0%BE%D1%80%D0%BA%D1%88%D0%BE%D0%BF%D0%BE%D0%B2-%D0%B8-%D1%80%D0%B0%D1%81%D1%81%D0%BA%D0%B0%D0%B7%D0%BE%D0%B2-%D1%81%D0%BE%D0%B2%D0%B5%D1%82%D1%8B-%D0%B8-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B" id="user-content-полезные-ссылки-для-подготовки-технических-статей-воркшопов-и-рассказов-советы-и-сервисы" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Полезные ссылки для подготовки технических статей, воркшопов и рассказов. Советы и сервисы</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Сервисы:</span></p><ol style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Сервис Главред: <a href="https://glvrd.ru/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">проверит стилистику и грамотность текста</a>.</li><li style="box-sizing: border-box; margin-top: 0.25em;">The Rules: "<a href="https://therules.ru/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">Правила русского языка. Проверка орфографии и пунктуации</a>".</li></ol><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Советы:</span></p><ol style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Как начать писать лучше? Главред: <a href="https://soviet.glvrd.ru/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">Советы и статьи о тексте, редактуре, информационном стиле и рекламе</a> (см. раздел для начинающих).</li><li style="box-sizing: border-box; margin-top: 0.25em;">Конечно же "<a href="https://letters.glvrd.ru/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">Новые правила деловой переписки</a>"</li><li style="box-sizing: border-box; margin-top: 0.25em;">Рекомендации по подготовке презентаций и как готовиться к докладу: "<a href="https://bizikov.ru/books/tochka-kontakta-prezentaciya/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">Точка контакта: презентация</a>".</li><li style="box-sizing: border-box; margin-top: 0.25em;">DO IT INBOUND: "<a href="https://doitinbound.com/blog/posts-guides/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">Готовая структура для разных типов статей</a>"</li><li style="box-sizing: border-box; margin-top: 0.25em;">"<a href="http://public-notice.ru/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">Как написать простое и понятное объявление</a>".</li><li style="box-sizing: border-box; margin-top: 0.25em;">Бюро: "<a href="https://bureau.ru/bb/soviet/20181104/" rel="nofollow" style="background-color: transparent; box-sizing: border-box; text-decoration-line: none;">Почему НЕ НАДО ПИСАТЬ КАПСОМ</a>" и как лучше.</li></ol>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-88480231299633613442021-06-03T14:10:00.002+03:002021-06-03T14:10:08.563+03:00Разбор полётов<p><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguh7cKrAOUcZiMNYEousK0DT6aHFE2Fz1cE6w_UefpVLEdak5HnFsYKnnG7KTVrKTpLkNPgEd3jLXfhytswj9lJghug0-9U3Zi-P7TeW55WGjE2z0hXDFjBMpOuGbx8Tt932Z1vecctZle/s516/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="516" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguh7cKrAOUcZiMNYEousK0DT6aHFE2Fz1cE6w_UefpVLEdak5HnFsYKnnG7KTVrKTpLkNPgEd3jLXfhytswj9lJghug0-9U3Zi-P7TeW55WGjE2z0hXDFjBMpOuGbx8Tt932Z1vecctZle/w166-h166/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" width="166" /></a></div>Как я говорил ранее, мы с коллегами, DevOps-инженерами, создали общедоступный репозиторий <a href="https://github.com/devopshq/dohq-doc-templates" style="background-color: #fefdfa; color: #0e2bd8; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px; text-decoration-line: none;" target="_blank"><b>dohq-doc-templates</b></a>, <span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;">где лежат </span><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;">шаблоны инженерной документации. Они нужны для упрощения сопровождения различных регламентных работ. Шаблоны были созданы в процессе повседневной работы наших инженеров и автоматизаторов. Они могут пригодиться и вашим инженерам, для разработки регламентов и внутренней технической документации.</span><p></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif">Сегодня расскажу про то, как мы ведём <b><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/debriefing.md" target="_blank">разбор полётов</a></b> по техническим происшествиям</span><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif">.</span></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif"><br /></span></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><span></span></p><a name='more'></a><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif"><br /></span><p></p><h1 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding-bottom: 0.3em;">Разбор полётов</h1><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">"Разборы полётов"</span> (дебрифинги, постмортемы и т.п.) — это инженерные документы, где чётко фиксируются:</p><ul style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">хронология проблем и событий, возникших в ходе эксплуатации инфраструктуры, конкретного сервиса или ПО,</li><li style="box-sizing: border-box; margin-top: 0.25em;">гипотезы причин возникновения проблем и инцидентов,</li><li style="box-sizing: border-box; margin-top: 0.25em;">планы работ по их устранению,</li><li style="box-sizing: border-box; margin-top: 0.25em;">рекомендации и шаги возможных улучшений, чтобы не допустить повторения проблем.</li></ul><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Разборы полётов используются инженерами для того, чтобы в будущем спокойно проанализировать событие, выявить слабые места инфраструктуры, продумать и зафиксировать в виде задач конкретные действия, или предусмотреть дополнительную автоматизацию и тестирование, чтобы проблема вновь не возникла.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Рекомендуется заранее подготовить шаблон документа для разбора полётов, чтобы во время активной работы над устранением проблемы ваши инженеры не тратили на него лишнее время. Далее рассмотрим пример, как может выглядеть такой шаблон, из каких блоков может состоять документ.</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/debriefing.md#i-%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BE%D0%BA" id="user-content-i-заголовок" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>I. Заголовок</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">В заголовке</span> странички с разбором полётов укажите начальную дату и запишите кратко: суть проблемы, сервис и количество часов простоя</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Проблема:</span> здесь более подробно опишите проблему, с какими сервисами она произошла, к чему это привело.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Основная причина:</span> здесь укажите основную причину, которая привела к проблеме.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Полезные ссылки и инструкции:</span> подготовьте для шаблона свой список полезных ссылок на внутренние документы и регламенты, чтобы во время работы над инцидентом инженер не тратил время на их поиски.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><em style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">Пример заполнения области заголовка:</span></em></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">2020-02-03 — Отказ инфраструктуры сборочных серверов из-за проблем с обновлением, простой ~4 часа</span></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Проблема:</span> после обновления ОС на сборочных серверах сборочная инфраструктура была недоступна ~4 часа.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Основная причина:</span> служба CI-агента не запустилась после перезагрузки. Обновление было проведено не по регламенту, не согласовано с продуктовыми командами, не был предусмотрен план обновления и отката.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Полезные ссылки и инструкции:</span></p><ul style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">System Operation Manual — что инженер по инфраструктуре должен сделать в первую очередь (в каждой компании свой регламент).</li><li style="box-sizing: border-box; margin-top: 0.25em;">Инструкции по снятию типовых показаний и метрик с исследуемых систем (в каждой компании своя специфика и свои метрики для критических показателей).</li></ul><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/debriefing.md#ii-%D1%85%D1%80%D0%BE%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%8F-%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC-%D0%B8-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D0%B9" id="user-content-ii-хронология-проблем-и-событий" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>II. Хронология проблем и событий</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Тут пишем простую последовательность событий, в свободной форме: что случилось, что произошло, что было сделано инженерами, к чему это привело, прикладываем переписку, логи и тексты оповещений. С сервисных ВМ нужно прикладывать логи аудита и значения метрик ОС. Хронологию проще всего вести в табличной форме.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><em style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">Пример заполнения хронологии:</span></em></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Хронология проблем и событий</span></p><table style="background-color: white; border-collapse: collapse; border-spacing: 0px; color: #24292e; display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; max-width: 100%; overflow: auto; width: max-content;"><thead style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">N</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Дата и время события</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Событие или проблема</th></tr></thead><tbody style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">1</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2020-06-17 12:00 MSK</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Производились работы по обновлению Windows Server на сборочных агентах</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2020-06-17 13:00 MSK</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">После обновления агенты не запустились из-за проблем с учёткой. Логи приложены.</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">3</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2020-06-17 13:30 MSK</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Оповестили разработчиков о проблеме. Служебное письмо приложено.</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">4</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2020-06-17 13:40 MSK</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Начали процедуры отката...</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2020-06-17 14:00 MSK</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">... прочие действия ... логи ... метрики ... служебная переписка ...</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">N</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2020-06-17 16:00 MSK</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Разослали оповещение о восстановлении сборочных пулов агентов. Копия приложена.</td></tr></tbody></table><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/debriefing.md#iii-%D0%B3%D0%B8%D0%BF%D0%BE%D1%82%D0%B5%D0%B7%D1%8B-%D0%BF%D1%80%D0%B8%D1%87%D0%B8%D0%BD-%D0%B2%D0%BE%D0%B7%D0%BD%D0%B8%D0%BA%D0%BD%D0%BE%D0%B2%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC" id="user-content-iii-гипотезы-причин-возникновения-проблем" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>III. Гипотезы причин возникновения проблем</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Если сходу причины проблем установить не удалось, фиксируются все возможные варианты и последовательно выполняется их проверка. Этот раздел можно изобразить также в виде обычной таблицы.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><em style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">Пример заполнения таблицы с гипотезами:</span></em></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Гипотезы причин возникновения проблем</span></p><table style="background-color: white; border-collapse: collapse; border-spacing: 0px; color: #24292e; display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; max-width: 100%; overflow: auto; width: max-content;"><thead style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">N</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Гипотеза</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Подтверждается или опровергнута</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Как проверяли гипотезу</th></tr></thead><tbody style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">1</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Перезатёрлись ключи авторизации</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">нет</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Зашли в админку, проверили ...</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Не запустилась служба агента</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">да</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Служба агента - был ручной запуск</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">... прочие варианты ...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr></tbody></table><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/debriefing.md#iv-%D0%BF%D0%BB%D0%B0%D0%BD-%D1%80%D0%B0%D0%B1%D0%BE%D1%82" id="user-content-iv-план-работ" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>IV. План работ</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Тут пишем запланированные виды работ для устранения причин проблемы. Если по какой-то причине её устранение затруднено, также сообщаем об этом.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><em style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">Пример заполнения плана работ:</span></em></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">План работ</span></p><table style="background-color: white; border-collapse: collapse; border-spacing: 0px; color: #24292e; display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; max-width: 100%; overflow: auto; width: max-content;"><thead style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">N</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Виды работ для устранения проблемы</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Ответственные</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Трудности и ограничения</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Выполнено</th></tr></thead><tbody style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">1</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Установить сервис на автозапуск</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Иванов И.И.</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">нет</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">да</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Поставить службу на мониторинг</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Петров П.П.</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">нужно настроить item-ы Zabbix-а</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">нет</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">... прочие работы ...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Сидоров С.С.</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">нет</td></tr></tbody></table><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/debriefing.md#v-%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5-%D1%83%D0%BB%D1%83%D1%87%D1%88%D0%B5%D0%BD%D0%B8%D1%8F" id="user-content-v-возможные-улучшения" style="background-color: transparent; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>V. Возможные улучшения</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В этом разделе описываем по шагам, какие действия нужно предпринять, чтобы избежать этой проблемы в будущем. Это могут быть как технические, так и улучшения существующих регламентов.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><em style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">Пример заполнения:</span></em></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="box-sizing: border-box; font-weight: 600;">Возможные улучшения</span></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif"></span></p><ol style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px !important; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">В сценарии установки CI-агентов добавить скрипты для автоматического включения сервиса при перезагрузке ОС.</li><li style="box-sizing: border-box; margin-top: 0.25em;">При начальной установке и настройке CI-агента сразу добавлять службу на мониторинг.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Написать регламенты обновления ОС и CI-агентов.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Внести в регламенты работ на инфраструктуре пункт согласования обновлений с продуктовыми командами.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Составить operational manual для задач обновления ОС и CI-агентов, включающий в себя план обновления и отката инфраструктуры.</li><li style="box-sizing: border-box; margin-top: 0.25em;">... прочие возможные улучшения ...</li></ol>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-27766120889142614922021-06-02T11:51:00.006+03:002021-06-02T11:53:49.552+03:00Анализ и планирование работ по долгосрочным задачам<span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdSri8VEwztewl5GoIXcvB9ORQYMGrfzDh6NjMW1LdOFzfN5-qoDCgsMZQ7iWrzwvCYYYuMJA7HyoSkXtl-fHjM4f2l5oWf3n0qQ-cwDmnfQi0bI5WFFaspUhD1OpV_UAyH4o5tmUwfn3U/s516/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="516" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdSri8VEwztewl5GoIXcvB9ORQYMGrfzDh6NjMW1LdOFzfN5-qoDCgsMZQ7iWrzwvCYYYuMJA7HyoSkXtl-fHjM4f2l5oWf3n0qQ-cwDmnfQi0bI5WFFaspUhD1OpV_UAyH4o5tmUwfn3U/w155-h155/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" width="155" /></a></div>В нашем общедоступном репозитории </span><a href="https://github.com/devopshq/dohq-doc-templates" style="background-color: #fefdfa; color: #0e2bd8; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; text-decoration-line: none;" target="_blank"><b>dohq-doc-templates</b></a><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333;"> лежат </span><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333;">шаблоны инженерной документации. Они нужны для упрощения сопровождения различных регламентных работ. Эти шаблоны были созданы в процессе повседневной работы DevOps-инженеров и автоматизаторов. Они могут пригодиться и вашим инженерам, для разработки регламентов и внутренней технической документации.</span><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif;"></p><p><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333;">Сегодня поговорим про <b><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/plan.md" target="_blank">а</a></b></span><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="color: #333333;"><b><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/plan.md" target="_blank">нализ и планирование работ по долгосрочным задачам</a></b></span><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333;">.</span> </p><p><br /></p><span><a name='more'></a></span><h1 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; margin: 0px 0px 16px; padding-bottom: 0.3em;">Анализ и планирование работ по долгосрочным задачам</h1><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Простые, типовые задачи обычно не требуют серьёзной аналитики и планирования. Их легче всего вести в трекере. Главное, что требуется по таким задачам — вовремя оповещать заказчиков, когда работы будут выполнены.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Когда идёт работа по долгосрочным, сложным и непонятным техническим задачам, в которой задействованы инженеры из разных команд, требуется дополнительная координация всех участников, разграничение этапов и зон ответственности. Для этого можно создать, например, общедоступную страничку в Confluence ("на вики"), добавить к ней всех участников, проанализировать задачу и представить этапы работ в таблице.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Конечно же, отдельные технические задачи нужно по-прежнему вести в командном трекере, но свести вместе всех заинтересованных в решении большой задачи и окинуть взглядом весь процесс проще всего на общей страничке и в табличном виде.</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/plan.md#%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD-%D0%BF%D0%BB%D0%B0%D0%BD%D0%B0-%D1%80%D0%B0%D0%B1%D0%BE%D1%82" id="user-content-шаблон-плана-работ" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Шаблон плана работ</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Ниже представлен возможный вид странички с планом работ по долгосрочной задаче. Выделенный <в скобках> текст нужно заменить на свои значения.</p><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/plan.md#%D0%BE%D0%B1%D1%89%D0%B8%D0%B5-%D1%81%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F" id="user-content-общие-сведения" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Общие сведения</h3><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Здесь собираем требования и пожелания от продуктовой команды <название команды> по задаче <краткое описание задачи>. Проведём аналитику и составим план работ.</p><ul style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Задача: <ссылка на задачу в трекере, если есть></li><li style="box-sizing: border-box; margin-top: 0.25em;">Заказчики (контакты от команды): <ссылки на людей из продуктовой команды, кого можно спрашивать по задаче></li><li style="box-sizing: border-box; margin-top: 0.25em;">Исполнители (контакты от DevOps): <кто исполнители или ответственные со стороны DevOps-инженеров></li></ul><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/plan.md#%D0%BA%D1%80%D0%B0%D1%82%D0%BA%D0%B0%D1%8F-%D1%81%D1%83%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8" id="user-content-краткая-суть-задачи" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Краткая суть задачи</h3><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><В свободной форме, со слов заказчика описываем требования, пожелания или ТЗ. Что они хотят получить в конце?></p><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/plan.md#%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7-%D1%82%D1%80%D0%B5%D0%B1%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B9" id="user-content-анализ-требований" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Анализ требований</h3><table style="background-color: white; border-collapse: collapse; border-spacing: 0px; color: #24292e; display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; max-width: 100%; overflow: auto; width: max-content;"><thead style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">N</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Требование по задаче</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Что есть для решения задачи</th></tr></thead><tbody style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">1</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><одна конкретная фича, которая требуется заказчикам></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Какие инструменты уже есть для решения, а что потребуется разработать/доработать?></td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><вторая фича></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Какие инструменты уже есть для решения, а что потребуется разработать/доработать?></td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">3</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><третья фича></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Какие инструменты уже есть для решения, а что потребуется разработать/доработать?></td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">4</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">5</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr></tbody></table><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/plan.md#%D0%BF%D0%BB%D0%B0%D0%BD-%D1%80%D0%B0%D0%B1%D0%BE%D1%82" id="user-content-план-работ" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>План работ</h3><table style="background-color: white; border-collapse: collapse; border-spacing: 0px; color: #24292e; display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px; max-width: 100%; overflow: auto; width: max-content;"><thead style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">N</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Этапы работ</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Планируемые объемы работ</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Фактические объёмы</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Планируемый ввод в эксплуатацию</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Статус</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Ответственный за реализацию от DevOps</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Координатор со стороны заказчика</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Ограничения или возможные проблемы. Комментарии</th></tr></thead><tbody style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">1</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Анализ требований</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по плану></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по факту></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><дата или месяц сдачи этапа></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Решено></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><исполнители от DevOps></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Кто будет проверять и принимать работу?></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">3</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><отдельный логический этап работ></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по плану></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по факту></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><дата или месяц сдачи этапа></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Не готово></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><исполнители от DevOps></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Кто будет проверять и принимать работу?></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Возникшие проблемы или ограничения для реализации этапа. Любые комментарии></td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">2</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><отдельный логический этап работ></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по плану></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по факту></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><дата или месяц сдачи этапа></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><В работе></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><исполнители от DevOps></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Кто будет проверять и принимать работу?></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Возникшие проблемы или ограничения для реализации этапа. Любые комментарии></td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">4</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><отдельный логический этап работ></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по плану></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по факту></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><дата или месяц сдачи этапа></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Решено></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><исполнители от DevOps></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Кто будет проверять и принимать работу?></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">5</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><отдельный логический этап работ></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по плану></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><трудочасы по факту></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><дата или месяц сдачи этапа></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Решено></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><исполнители от DevOps></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;"><Кто будет проверять и принимать работу?></td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">6</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">7</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">8</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">9</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">...</td></tr></tbody></table>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-1813212062065537762021-06-01T10:57:00.009+03:002021-06-01T11:08:39.791+03:00Технологическая карта производственного процесса<p><span style="background-color: #fefdfa;"></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMyvI16gI3eSNkvBBxBi6C_PC3qt2vjaqhCQ2MkqX1tH1p55z46_vpJJMGte1PYAM-CK7rIalAZIMcR9q0kqibJidCD6G-kuMHC70QWaq4vkJAXKqVN6pY3DQBfDILSosbj3RPnu3Sh6ML/s516/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="516" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMyvI16gI3eSNkvBBxBi6C_PC3qt2vjaqhCQ2MkqX1tH1p55z46_vpJJMGte1PYAM-CK7rIalAZIMcR9q0kqibJidCD6G-kuMHC70QWaq4vkJAXKqVN6pY3DQBfDILSosbj3RPnu3Sh6ML/w152-h152/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" width="152" /></a></div><span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-size: 16px;">Продолжаю выкладывать в общедоступный репозиторий </span><a href="https://github.com/devopshq/dohq-doc-templates" style="background-color: #fefdfa; color: #0e2bd8; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px; text-decoration-line: none;" target="_blank"><b>dohq-doc-templates</b></a> <span face="Arial, Tahoma, Helvetica, FreeSans, sans-serif" style="background-color: #fefdfa; color: #333333; font-size: 16px;">шаблоны инженерной документации. Она нужна для упрощения и сопровождения различных регламентных работ. Шаблоны были созданы в процессе повседневной работы DevOps-инженеров и автоматизаторов. Они могут пригодиться и вашим инженерам, для разработки регламентов и внутренней технической документации.</span><p></p><p style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"></p><div style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;">Сегодня познакомлю вас с понятием "<b><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md" target="_blank">технологической карты производственного процесса</a></b>".</div><span><a name='more'></a></span><div style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><br /></div><div style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><h1 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; margin: 0px 0px 16px; padding-bottom: 0.3em;">Технологическая карта производственного процесса</h1><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Более подробно про то, как мы пришли к пониманию необходимости использования технологической карты в DevOps процессах, можно почитать в статье на Хабре: "<a href="https://habr.com/ru/company/pt/blog/480754/" rel="nofollow" style="background-color: initial; box-sizing: border-box; text-decoration-line: none;">Управление хаосом: наводим порядок с помощью технологической карты</a>"</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D1%82%D0%B8%D0%BF%D0%BE%D0%B2%D1%8B%D0%B5-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8-%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D1%8D%D1%82%D0%B0%D0%BF%D1%8B-%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F-%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F-%D1%86%D0%B5%D0%BF%D0%BE%D1%87%D0%BA%D0%B0" id="user-content-типовые-задачи-производственные-этапы-производственная-технологическая-цепочка" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Типовые задачи, производственные этапы, производственная технологическая цепочка</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">В работе DevOps-инженеров быстро накапливается множество однотипных и рутинных операций. От заказчиков в основном приходят так называемые <span style="box-sizing: border-box; font-weight: 600;">типовые инженерные задачи</span>, решение которых уже автоматизировано полностью или частично, не вызывает трудностей у исполнителей и не требует значительных объемов работ. Вы можете сами проанализировать такие задачи и выделить отдельные категории работ, или <span style="box-sizing: border-box; font-weight: 600;">производственные этапы</span>, этапы разбить на неделимые логические шаги, а из нескольких этапов получится <span style="box-sizing: border-box; font-weight: 600;">производственная технологическая цепочка</span>.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;"><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/.media/typical_steps.png" rel="noopener noreferrer" style="background-color: initial; box-sizing: border-box; text-decoration-line: none;" target="_blank"><img alt="" src="https://github.com/devopshq/dohq-doc-templates/raw/master/.media/typical_steps.png" style="background-color: var(--color-bg-primary); border-style: none; box-sizing: initial; max-width: 100%;" /></a></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Простейший пример технологической цепочки — это этапы сборки, деплоя и тестирования каждого продукта компании. В свою очередь этап сборки может состоять из множества отдельных типовых шагов: выкачивание исходников из хранилища кода, скачивание и подготовка зависимостей и 3rd-party библиотек, юнит-тестирование и статический анализ кода, выполнение сборочного сценария, публикация артефактов в некоторое хранилище и, например, генерация релиз-нотов.</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D1%8D%D1%82%D0%B0%D0%BF%D0%BE%D0%B2" id="user-content-классификация-этапов" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Классификация этапов</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Начинать анализ любого рабочего процесса необходимо с классификации и детализации типовых шагов производственного конвейера. В каждой компании разработчике ПО обычно уже есть своя сложившаяся технологическая цепочка. Также в реальной разработке есть еще и вспомогательные этапы: мониторинг, сертификация продуктов, автоматизация рабочих процессов и другие.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Если взять все этапы и шаги, попытаться закодировать их тегами и развернуть в одну цепочку, то она получится очень длинной и непонятной, как «хвост питона». Вот пример тегов этапов из реального процесса:</p><div class="snippet-clipboard-content position-relative" style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; position: relative;"><pre lang="text" style="background-color: var(--color-bg-tertiary); border-radius: 6px; box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; font-size: 13.6px; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 16px;"><code style="background: initial; border-radius: 6px; border: 0px; box-sizing: border-box; display: inline; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; font-size: 13.6px; line-height: inherit; margin: 0px; overflow-wrap: normal; overflow: visible; padding: 0px; word-break: normal;">[Production] — [InfMonitoring] — [SourceCodeControl] — [Prepare] — [PrepareLinuxDocker] — [PrepareWinDocker] — [Build] — [PullSourceCode] — [PrepareDep] — [UnitTest] — [CodeCoverage] — [StaticAnalyze] — [BuildScenario] — [PushToSnapshot] — [ChangelogBuilder] — [Deploy] — [PrepareTestStand] — [PullTestCode] — [PrepareTestEnv] — [PullArtifact] — [DeployArtifact] — [Test] — [BVTTest] — [SmokeTest] — [FuncTest] — [LoadTest] — [IntegrityTest] — [DeliveryTest] — [MonitoringStands] — [TestManagement] — [Promote] — [QualityTag] — [MoveToRelease] — [License] — [Publish] — [PublishGUSFLUS] — [ControlVisibility] — [Install] — [LicenseActivation] — [RequestUpdates] — [PullUpdates] — [InitUpdates] — [PrepareEnv] — [InstallUpdates] — [Telemetry] — [Workflow] — [Communication] — [Certification] — [CISelfSufficiency]
</code></pre></div><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Это этапы сборки продуктов [Build], их деплоя на тестовые серверы [Deploy], тестирования [Test], продвижения сборок в релизные репозитории по итогам тестирования [Promote], генерации и публикации лицензий [License], публикации [Publish] на сервере обновлений и доставка с них до инфраструктуры заказчиков, инсталляция и обновление компонентов продуктов на инфраструктуре заказчика средствами Product Configuration Management [Install], а также сбор телеметрии [Telemetry] с установленных продуктов.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Кроме них можно выделить отдельные этапы: мониторинга состояния инфраструктуры [InfMonitoring], управления версиями исходного кода [SourceCodeControl], подготовки сборочного окружения [Prepare], управления проектами [Workflow], обеспечения команд средствами коммуникации [Communication], сертификации продуктов [Certification] и обеспечения самодостаточности CI-процессов [CISelfSufficiency] (например, независимости сборок от интернета).</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Десятки отдельных шагов можно даже не рассматривать, потому что они могут быть очень специфичными для каждой компании.</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F-%D0%BA%D0%B0%D1%80%D1%82%D0%B0" id="user-content-технологическая-карта" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Технологическая карта</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Будет гораздо легче понять и окинуть взглядом весь производственный процесс, если представить его в виде так называемой <span style="box-sizing: border-box; font-weight: 600;">технологической карты</span>. Это таблица, в которую по строкам записаны отдельные производственные этапы и декомпозированные шаги, а по столбцам — описание того, что делается на каждом этапе или шаге. Основной акцент стоит сделать на ресурсах, обеспечивающих каждый этап, и разграничении зон ответственности.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Карта — это своеобразный классификатор. Она отражает крупные технологические части производства продуктов. С помощью неё команде DevOps-инженеров будет легче взаимодействовать с разработчиками и совместно планировать внедрение новых этапов автоматизации, а также понимать, какие трудозатраты и ресурсы (человеческие и «железные») для этого потребуются.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Более коротко, технологическая карта — это обобщенная картина производственного процесса, где отражены четко классифицированные блоки с типовой функциональностью. <span style="box-sizing: border-box; font-weight: 600;">Самое главное: карта позволяет увидеть весь процесс целиком, крупными кусками с возможностью их детализации.</span></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">В каждой компании карта может выглядеть по своему. Например, вот так:</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;"><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/.media/tech-map.png" rel="noopener noreferrer" style="background-color: initial; box-sizing: border-box; text-decoration-line: none;" target="_blank"><img alt="" src="https://github.com/devopshq/dohq-doc-templates/raw/master/.media/tech-map.png" style="background-color: var(--color-bg-primary); border-style: none; box-sizing: initial; max-width: 100%;" /></a></p><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0-%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9-%D0%BA%D0%B0%D1%80%D1%82%D1%8B" id="user-content-структура-технологической-карты" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Структура технологической карты</h3><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Карта состоит из нескольких основных частей:</p><ol style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">Область заголовков — здесь находится общее описание карты, вводятся базовые понятия, определяются основные ресурсы и результаты производственного процесса.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Область общей информации — здесь можно управлять отображением данных по отдельным продуктам, привести сводку и статистику по реализованным этапам и шагам в целом по всем продуктам.</li><li style="box-sizing: border-box; margin-top: 0.25em;">Технологическая карта — табличное описание технологического процесса. На самой карте:<ul style="box-sizing: border-box; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">приводятся все этапы, шаги и их коды;</li><li style="box-sizing: border-box; margin-top: 0.25em;">даются краткое и полное описания этапов;</li><li style="box-sizing: border-box; margin-top: 0.25em;">указываются входные ресурсы и сервисы, используемые на каждом этапе;</li><li style="box-sizing: border-box; margin-top: 0.25em;">указываются результаты каждого этапа и отдельного шага;</li><li style="box-sizing: border-box; margin-top: 0.25em;">указывается зона ответственности по каждому этапу и шагу;</li><li style="box-sizing: border-box; margin-top: 0.25em;">определяются технические ресурсы, например HDD (SSD), RAM, vCPU, и человеко-часы, необходимые для поддержки работ на данном этапе, как на текущий момент — факт, так и в будущем — план;</li><li style="box-sizing: border-box; margin-top: 0.25em;">в ячейках карты для каждого продукта указывается, какие технологические этапы или шаги для него реализованы, планируются к внедрению, неактуальны или не реализованы.</li></ul></li></ol><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD-%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D1%8F-%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D1%8D%D1%82%D0%B0%D0%BF%D0%B0-%D0%B8%D0%BB%D0%B8-%D1%88%D0%B0%D0%B3%D0%B0" id="user-content-шаблон-описания-производственного-этапа-или-шага" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Шаблон описания производственного этапа или шага</h3><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Чтобы не усложнять технологическую карту, более подробное описание каждого этапа или шага производственного конвейера можно вынести в отдельные стандартизированные карточки. Выглядеть эти карточки могут так:</p><table style="background-color: white; border-collapse: collapse; border-spacing: 0px; color: #24292e; display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; max-width: 100%; overflow: auto; width: max-content;"><thead style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Элемент технологического конвейера</th><th style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Описание характеристики</th></tr></thead><tbody style="box-sizing: border-box;"><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Название или ключ:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Любое обозначение в виде [тега]</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Тип (этап или шаг):</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">— / этап / шаг</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Вид работы:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Короткое, в пару слов, описание видов работ выполняемых на этапе или шаге.</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Краткое описание:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Короткий дайджест того, что происходит на данном этапе или шаге.</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Подробное описание:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Подробное и детализированное описание этапа или шага технологического конвейера.</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Входные ресурсы:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Какими ресурсами обеспечен данный этап или шаг, что требуется на входе для возможности его полной реализации?</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Результаты:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Что получаем по итогу выполнения работ на данном этапе или шаге?</td></tr><tr style="background-color: var(--color-bg-tertiary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Зона ответственности и контакты:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Контакты ответственных за реализацию данного этапа или шага.</td></tr><tr style="background-color: var(--color-bg-primary); border-top: 1px solid var(--color-markdown-table-tr-border); box-sizing: border-box;"><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Ссылки на корп. стандарт:</td><td style="border: 1px solid var(--color-markdown-table-border); box-sizing: border-box; padding: 6px 13px;">Ссылки на инструкции и описания, скрипты реализации или стандартные инструменты, рекомендуемые DevOps-инженерами компании. Исполнителям должно быть понятно, по каким стандартам нужно реализовывать тот или иной этап и шаг.</td></tr></tbody></table><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD-%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9-%D0%BA%D0%B0%D1%80%D1%82%D1%8B" id="user-content-шаблон-технологической-карты" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Шаблон технологической карты</h3><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Табличку для техкарты можно создать в любом удобном для вас инструменте. Например, на скриншоте выше представлена карта, которую мы генерим для себя автоматически, в виде веб-странички (HTML + JS + CSS). Но для простоты можно использовать Excel-таблицы, этого вполне достаточно и более понятно большинству коллег.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Вы можете скачать пример технологической карты в Excel по ссылке: <a href="https://github.com/devopshq/dohq-doc-templates/blob/master/.media/TechnologicalMapExample.xlsx" style="background-color: initial; box-sizing: border-box; text-decoration-line: none;">TechnologicalMapExample.xlsx</a>. Данные по продуктам приведены в таблице только для примера. Если решите ей воспользоваться, вам нужно будет провести собственную аналитику по вашим продуктам и заполнить ячейки актуальными данными.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;"><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/.media/tech-map-excel.png" rel="noopener noreferrer" style="background-color: initial; box-sizing: border-box; text-decoration-line: none;" target="_blank"><img alt="" src="https://github.com/devopshq/dohq-doc-templates/raw/master/.media/tech-map-excel.png" style="background-color: var(--color-bg-primary); border-style: none; box-sizing: initial; max-width: 100%;" /></a></p><h3 style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D0%BF%D1%80%D0%B8%D0%BD%D1%8F%D1%82%D0%B8%D0%B5-%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B9-%D0%BD%D0%B0-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B5-%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9-%D0%BA%D0%B0%D1%80%D1%82%D1%8B" id="user-content-принятие-решений-на-основе-технологической-карты" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Принятие решений на основе технологической карты</h3><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px;">Изучив карту, возможно предпринять некоторые действия — в зависимости от роли сотрудника в компании (руководитель разработки, менеджер продукта, разработчик или тестировщик):</p><ul style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">понять, какие этапы отсутствуют в реальном продукте или проекте, и оценить необходимость их внедрения;</li><li style="box-sizing: border-box; margin-top: 0.25em;">разграничить зоны ответственности между несколькими отделами, если они работают над разными этапами;</li><li style="box-sizing: border-box; margin-top: 0.25em;">договориться о контрактах на входах и выходах этапов;</li><li style="box-sizing: border-box; margin-top: 0.25em;">интегрировать свой этап работ в общий процесс разработки;</li><li style="box-sizing: border-box; margin-top: 0.25em;">точнее оценить потребность в ресурсах, обеспечивающих каждый из этапов.</li></ul><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/techmap.md#%D1%80%D0%B5%D0%B7%D1%8E%D0%BC%D0%B8%D1%80%D1%83%D1%8F-%D0%B2%D1%81%D0%B5-%D0%B2%D1%8B%D1%88%D0%B5%D1%81%D0%BA%D0%B0%D0%B7%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5" id="user-content-резюмируя-все-вышесказанное" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Резюмируя все вышесказанное</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; margin-bottom: 0px; margin-top: 0px;">Технологическая карта универсальна, расширяема и легко поддерживается. Разрабатывать и сопровождать описание процессов в таком виде гораздо легче, чем в любых других процессных моделях. Кроме того, табличное описание проще для человека, привычней и лучше структурировано, чем, например, функциональная модель.</p></div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-66221655329909569122021-05-31T20:12:00.005+03:002021-06-01T10:54:26.232+03:00Карта компетенций инженеров DevOps<p><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkfM7Huc3rfAWDOVYrhaViv_nQHG3tcV1U5mpbLbxBc4PXDV5JIK3eUET8dLRD63SBUyrqdCYBWWo9p6xBnoqlNSrnCTvXjv95JmB5iHnzAwPbV4iyQ9v5I_Re3Izu6THO4FOLonLNoiCO/s516/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="516" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkfM7Huc3rfAWDOVYrhaViv_nQHG3tcV1U5mpbLbxBc4PXDV5JIK3eUET8dLRD63SBUyrqdCYBWWo9p6xBnoqlNSrnCTvXjv95JmB5iHnzAwPbV4iyQ9v5I_Re3Izu6THO4FOLonLNoiCO/w145-h145/PT_Op%2521DevOps%2521_sticker_30mm_preview.png" width="145" /></a></div>Мы с коллегами из PT решили создать общедоступный репозиторий <a href="https://github.com/devopshq/dohq-doc-templates" target="_blank"><b>dohq-doc-templates</b></a>, куда будем выкладывать шаблоны инженерной документации для упрощения и сопровождения различных регламентных работ. Они были созданы в процессе повседневной работы DevOps-инженеров и автоматизаторов. Шаблоны могут пригодиться и вашим инженерам, для разработки регламентов и внутренней технической документации.<p></p><div>Сегодня познакомлю вас с понятием "<b><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/competence.md" target="_blank">карты компетенций</a></b>" инженеров DevOps, что это такое и как ей пользоваться.</div><span><a name='more'></a></span><div><br /></div><div><h1 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; margin: 0px 0px 16px; padding-bottom: 0.3em;">Карта компетенций инженеров DevOps</h1><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Более подробно про то, как мы видим развитие инженеров DevOps, рост их компетенций: знаний, умений и навыков, можно почитать в статье на Хабре: "<a href="https://habr.com/ru/company/pt/blog/501766/" rel="nofollow" style="background-color: initial; box-sizing: border-box; text-decoration-line: none;">Личный опыт: как выстроить карьерный рост в отделе DevOps</a>"</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В этой инструкции расскажем, что такое "карта компетенций" и как её можно представить с учётом особенностей работы своего отдела.</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/competence.md#%D0%B7%D0%BD%D0%B0%D0%BD%D0%B8%D1%8F-%D1%83%D0%BC%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B8-%D0%BD%D0%B0%D0%B2%D1%8B%D0%BA%D0%B8" id="user-content-знания-умения-и-навыки" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Знания, умения и навыки</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Когда увеличивается количество продуктовых конвейеров, находящихся на поддержке инженеров DevOps, то растёт и развивается и сам отдел. Становится понятно, что по каждому направлению работ не получится описать однозначную роль и найти подходящего инженера на рынке труда. От инженеров часто ожидают наличия кросс-навыков.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">У каждого DevOps-отдела своя специфика работы. Например, очевидно, что команде не нужен мегаквалифицированный программист разработчик ПО для решения CI-задач, но тем не менее CI-инженер должен уметь программировать небольшие модули и скрипты на Python на приемлемом уровне. Точно также бывает не нужен мегаквалифицированный Linux-администратор, но команде DevOps всегда нужен человек с достаточными знаниями ОС Debian или Ubuntu, чтобы он сумел установить на них сборочные агенты GitLab CI, а еще лучше — автоматизировал эти работы через SaltStack, Ansible или другие инструменты.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Так что же должен уметь делать DevOps-инженер? Для начала определимся с понятиями, что такое знания, умения и навыки (сокращенно ЗУН) в общепринятом понимании.</p><ul style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">Знания</span> — это основные закономерности предметной области, позволяющие человеку решать конкретные производственные, научные и другие задачи, то есть факты, понятия, суждения, образы, взаимосвязи, оценки, правила, алгоритмы, эвристики, а также стратегии принятия решений в этой области. Знания — это также элементы информации, связанные между собой и с внешним миром.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">Умения</span> — под ними понимают освоенный человеком способ выполнения действия, обеспеченный некоторой совокупностью знаний. Умение выражается в способности осознанно применять знания на практике.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">Навыки</span> — это автоматизированные действия человека, которые вырабатываются в процессе сознательного выполнения определенных рабочих операций. То, что данное действие стало навыком, означает, что человек в результате упражнений приобрел возможность осуществлять рабочие операции, не делая это выполнение своей сознательной целью.</li></ul><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Если вы сумеете определить ЗУН более конкретно, применительно к разрабатываемым в вашей компании продуктам, то у вас получится общий список компетенций инженеров DevOps или <span style="box-sizing: border-box; font-weight: 600;">Карта компетенций</span>. Без овладения этими конкретными компетенциями у инженера не получится качественно работать в компании. Список может получиться очень длинным, но это не страшно, потому что необходимо учитывать специфику работы сразу по всем направлениям, технологиям, процессам и продуктам.</p><h2 style="background-color: white; border-bottom: 1px solid var(--color-border-secondary); box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;"><a aria-hidden="true" class="anchor" href="https://github.com/devopshq/dohq-doc-templates/blob/master/competence.md#%D0%BA%D0%B0%D1%80%D1%82%D0%B0-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B5%D1%82%D0%B5%D0%BD%D1%86%D0%B8%D0%B9" id="user-content-карта-компетенций" style="background-color: initial; box-sizing: border-box; float: left; line-height: 1; margin-left: -20px; padding-right: 4px; text-decoration-line: none;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z" fill-rule="evenodd"></path></svg></a>Карта компетенций</h2><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Карту компетенций проще всего представить в виде таблицы. В ней необходимо описать и классифицировать все требования к инженеру. Выглядеть она может, примерно, так:</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><a href="https://github.com/devopshq/dohq-doc-templates/blob/master/.media/competence_map_1_0.png" rel="noopener noreferrer" style="background-color: initial; box-sizing: border-box; text-decoration-line: none;" target="_blank"><img alt="" src="https://github.com/devopshq/dohq-doc-templates/raw/master/.media/competence_map_1_0.png" style="background-color: var(--color-bg-primary); border-style: none; box-sizing: initial; max-width: 100%;" /></a></p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Обозначения в таблице должностей сотрудников DevOps (в столбцах):</p><ul style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;">(<span style="box-sizing: border-box; font-weight: 600;">С</span>)тажёры, либо проходящие испытательный срок на должности младших инженеров или программистов</li><li style="box-sizing: border-box; margin-top: 0.25em;">(<span style="box-sizing: border-box; font-weight: 600;">М</span>)ладшие инженеры или программисты</li><li style="box-sizing: border-box; margin-top: 0.25em;">(<span style="box-sizing: border-box; font-weight: 600;">И</span>)нженеры или (<span style="box-sizing: border-box; font-weight: 600;">П</span>)рограммисты</li><li style="box-sizing: border-box; margin-top: 0.25em;">(<span style="box-sizing: border-box; font-weight: 600;">Ст</span>)аршие инженеры или программисты</li><li style="box-sizing: border-box; margin-top: 0.25em;">(<span style="box-sizing: border-box; font-weight: 600;">В</span>)едущие инженеры или программисты</li></ul><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Таблица разбивается на четыре крупные секции (по строкам):</p><ol style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">Описание общих компетенций</span> сотрудников DevOps-отдела, необходимые для успешного решения повседневных задач.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">Знания</span> — специфические, ориентированные на конкретный продукт знания инженеров DevOps.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">Умения</span> — способности применить знания на практике для решения продуктовых задач; умение работать с используемыми в компании инструментами и технологиями.</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">Навыки</span> — профессиональное владение используемыми в компании инструментами и технологиями; изученные и доведенные до автоматизма действия при решении типовых задач, не требующие особых усилий для их выполнения.</li></ol><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">В ячейках таблицы указываются <span style="box-sizing: border-box; font-weight: 600;">качественные оценки</span>: на каком уровне примерно должен владеть инженер той или иной компетенцией. <span style="box-sizing: border-box; font-weight: 600;">Условные целевые оценки</span> требований по компетенциям и ЗУН для сотрудников различных уровней могут быть, например, такие:</p><ul style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 600;">0</span> — нет знаний, умений и практических навыков по данному требованию, либо они не обязательны для данной должности</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">1</span> — есть теоретические знания по данному требованию и умение применить их на практике, возможно с помощью коллег или гуглинга</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">2</span> — сотрудник знает данную тему хорошо и самостоятельно применяет навыки при решении типовых задач</li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="box-sizing: border-box; font-weight: 600;">3</span> — сотрудник эксперт в данном вопросе и наработанные практические навыки может применить к решению любой задачи</li></ul><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;">Для лучшего отражения динамики, можно использовать промежуточные оценки, с шагами <span style="box-sizing: border-box; font-weight: 600;">+0.1</span>, <span style="box-sizing: border-box; font-weight: 600;">+0.5</span>. Все требования к определённой должности по умолчанию включают в себя все требования предыдущей должности.</p><p style="background-color: white; box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 0px; margin-top: 0px;">В каждой компании и в каждом отделе DevOps нужно составлять свою аналогичную таблицу, учитывая специфику работы. Здесь также конкретизируются инструменты и технологии, которые обычно очень абстрактно описывают в формальных должностных инструкциях.</p></div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-6030274600956382972021-05-26T13:23:00.000+03:002021-05-26T13:23:10.860+03:00DevSecOps. PT Application Inspector в разработке ПО: блокировка релиза<p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy8bLTBQW32lui39P-xyCUtlekWClNKEQbpjDItUBpc4NDQt7CrOqXt_jjL-VWr-YNcZJnFO5AFS1P877pwEVsdlizZ1nY26TljiH0TvwG7viMEVQSW9VEKBxWVDUCKJbVe1mn3B7Jtzle/s350/image.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="350" data-original-width="350" height="119" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy8bLTBQW32lui39P-xyCUtlekWClNKEQbpjDItUBpc4NDQt7CrOqXt_jjL-VWr-YNcZJnFO5AFS1P877pwEVsdlizZ1nY26TljiH0TvwG7viMEVQSW9VEKBxWVDUCKJbVe1mn3B7Jtzle/w119-h119/image.png" width="119" /></a></div><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;">Вышла новая обзорная статья на Хабре по одному из направлений в DevSecOps: про то, как разработчики используют анализатор кода PT Application Inspector в релизном цикле разработки своих продуктов.</span><p></p><p><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;">Оригинал статьи <a href="https://habr.com/ru/company/pt/blog/557142/" target="_blank">по ссылке</a>, копия под катом.</span></p><p><span></span></p><a name='more'></a><span style="background-color: #fefdfa; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 16px;"><br /></span><p></p><p style="background-color: white; clear: both; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px; line-height: 24px; margin: 32px 0px 0px;">Всем привет! Меня зовут Тимур Гильмуллин, я работаю в отделе технологий и процессов разработки Positive Technologies. Неформально нас называют DevOps-отделом, а наши ребята занимаются автоматизацией различных процессов и помогают программистам и тестировщикам работать с продуктовыми конвейерами.</p><p style="background-color: white; clear: both; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px; line-height: 24px; margin: 24px 0px 0px;"><a href="https://habr.com/ru/company/pt/blog/534458/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">В прошлой статье</a> мы с коллегами рассказали, как наши инженеры внедряли анализатор защищенности кода <a href="https://www.ptsecurity.com/ru-ru/products/ai/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">PT Application Inspector</a> в сборочные конвейеры продуктовых команд. Тогда мы предложили клиент-серверную архитектуру и методику внедрения анализатора в CI/CD-конвейер, чтобы максимально упростить работу инженерам по инфраструктуре и CI-инженерам. Если перед вашими инженерами стоит задача внедрения сканера PT Application Inspector — обязательно прочитайте прошлую статью.</p><p style="background-color: white; clear: both; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px; line-height: 24px; margin: 24px 0px 0px;">А из этой статьи вы узнаете:</p><ul style="background-color: white; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px; margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">как организованы DevSecOps-процессы в нашей компании, как построена архитектура размещения сканера PT Application Inspector в CI-конвейере и как изменилась схема типовой сборки при добавлении сканирования;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">что такое Security Gates, как группировать уязвимости по степени важности и как при помощи шаблонов сканирования настроить блокирование мердж-реквестов в GitLab;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">как программисты работают со сборочным конвейером, как патчат найденные уязвимости и что поменялось для них в процессе разработки после внедрения сканирования кода в сборки.</p></li></ul><div><div class="post__body post__body_full" style="background-color: white; clear: both; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 14px; margin-bottom: 24px; padding-top: 32px;"><div class="post__text post__text_v2" id="post-content-body" style="font-size: 16px; line-height: 1.56; overflow-wrap: break-word;"><h2 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Процессы DevSecOps в Positive Technologies</h2><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Начну с небольшого обзора концепции DevSecOps на примере схемы типового CI/CD-процесса в нашей компании. Так будет проще понять, какое место занимает сканер PT Application Inspector в этом процессе.</p><figure class="bordered full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="DevSecOps-конвейер в Positive Technologies: безопасный цикличный процесс разработки, сборки, развертывания, тестирования, продвижения, публикации, установки обновлений, сбора телеметрии и мониторинга" height="700" src="https://habrastorage.org/getpro/habr/upload_files/286/e6f/aee/286e6faee5628dbaf784506cff73d431.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="DevSecOps-конвейер в Positive Technologies: безопасный цикличный процесс разработки, сборки, развертывания, тестирования, продвижения, публикации, установки обновлений, сбора телеметрии и мониторинга" width="1050" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">DevSecOps-конвейер в Positive Technologies: безопасный цикличный процесс разработки, сборки, развертывания, тестирования, продвижения, публикации, установки обновлений, сбора телеметрии и мониторинга</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Общие CI/CD-шаги для всех продуктов остаются неизменными. Разработчик пишет код фичи или исправляет найденные ошибки (Developing), делает git-коммит, после чего запускается автоматическая сборка в GitLab CI (Unit-Testing + Building). Далее происходит автоматическое развертывание на тестовые серверы (Deploying) и выполняются функциональное и прочие виды автотестирования (Functional Testing). Затем сборка продвигается в релизный репозиторий на Artifactory (Promoting), после чего компоненты и инсталляторы публикуются на корпоративный сервер обновлений GUS и происходит их автоматическое распространение через FLUS-серверы в интернете (Publishing GUS/FLUS). После этого на инфраструктуре заказчиков выполняется установка или обновление продукта (Installing/Updating). За установленным продуктом ведется наблюдение и сбор метрик (Collecting telemetry), его сервисы мониторятся (Monitoring) и собирается обратная связь от пользователей (User's feedback). Затем процесс разработки повторяется.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">На схеме выше я предлагаю рассматривать Security-процесс так же непрерывно, как и процессы разработки, развертывания, тестирования и доставки. Безопасность нужно обеспечивать соответствующими инструментами на каждом этапе производственного конвейера. В частности, все изменения в коде должны проверяться на наличие потенциальных уязвимостей и ошибок. Решение нашей компании, сканер <a href="https://www.ptsecurity.com/ru-ru/products/ai/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">PT Application Inspector</a>, позволяет проводить анализ исполняемого кода — как статический, так и динамический и интерактивный. Помимо этого продукта у нас в CI/CD-конвейере используются и другие решения, например система выявления инцидентов ИБ <a href="https://www.ptsecurity.com/ru-ru/products/mpsiem/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">MaxPatrol.SIEM</a> и межсетевой экран уровня веб-приложений <a href="https://www.ptsecurity.com/ru-ru/products/af/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">PT Application Firewall</a>.</p><blockquote style="background: 0px 0px; border-left: 4px solid rgb(84, 142, 170); box-sizing: border-box; clear: both; margin: 32px 0px 0px; padding: 12px 24px;"><p style="clear: both; line-height: 24px; margin: 0px;"><em style="margin-top: 0px;">Я хочу подчеркнуть, что концепцию DevSecOps, то есть непрерывный и безопасный процесс разработки, можно развивать в компании, только опираясь на инициативу и интерес самих разработчиков. Если руководство закупит какие-то инструменты и «спустит их сверху вниз» — ничего не выйдет. Разработчики должны быть сами заинтересованы в инструменте, он должен им нравиться, а также быть удобен в использовании.</em></p></blockquote><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Как PT Application Inspector внедряли в Positive Technologies</h3><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Теперь расскажу, как внедрение сканера происходило у нас. Сначала появились заинтересованные программисты из разных команд, которые хотели автоматизировать проверку своего кода, а затем к ним подключились DevOps-инженеры, которым было интересно попробовать внедрить новый инструмент в сборки. Они провели эксперименты и сделали пилот на одном из проектов. В итоге это вылилось в инициативу по развитию направления DevSecOps внутри всего сборочного конвейера Positive Technologies.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">В рамках этой инициативы нам было нужно разработать для DevSecOps-специалистов, CI-инженеров и в первую очередь для программистов компании методику использования PT Application Inspector в разработке ПО, а также определить метрики, которые критичны для сборочного процесса. Такая методика необходима для понимания того, как разработчики должны использовать сканер, на какие найденные уязвимости обращать внимание и как эти уязвимости должны влиять на выпуск релиза или даже блокировать его; как работать с ветками и мердж-реквестами, а также как DevSecOps-специалисты должны выстраивать инфраструктуру безопасной разработки и внедрять PT Application Inspector с нуля в производственные процессы.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Мы преследовали несколько внутренних целей:</p><ol style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Внедрить SAST/DAST/IAST-решение в сборочный CI-конвейер всех продуктов, что позволит находить уязвимости в коде на ранних стадиях разработки (реализовать концепцию shift-left).</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Использовать анализатор защищенности для сертификации продуктов компании — все сертифицирующие лаборатории требуют отчет по статическому анализу кода. До этого нам приходилось использовать сторонние продукты.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Дать возможность команде продуктовой разработки PT Application Inspector обкатать свои решения на «домашнем полигоне», выяснить потребности «живых» программистов — основных пользователей сканера и CI-инженеров — основных внедренцев продукта в сборочный конвейер, а также скорректировать планы разработки инструмента в зависимости от полученной обратной связи.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Продолжить развитие направления DevSecOps внутри продуктового конвейера компании. PT Application Inspector относится к общей схеме DevSecOps, это один из удобных инструментов для CI/CD-конвейера. Мы хотели дать внутренним разработчикам в Positive Technologies действительно удобный инструмент, которым бы они сами хотели пользоваться, который упростил бы и облегчил их работу.</p></li></ol><h2 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Архитектура PT Application Inspector в CI-конвейере</h2><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Сканер PT Application Inspector в CI-инфраструктуре" height="552" src="https://habrastorage.org/getpro/habr/upload_files/a2d/316/bb7/a2d316bb77492a6548c3fbec3702e037.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Сканер PT Application Inspector в CI-инфраструктуре" width="923" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Сканер PT Application Inspector в CI-инфраструктуре</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Легенда:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">DevOps.BuildAgent — сборочный агент</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Docker.Linux.AISA.Latest/TAG — все докер-образы клиента AISA, доступные по тегу</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">AI.Agent — агент сканирования</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">AI.Server — сервер PT Application Inspector</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">DevOps.GitLab — хранилище кода</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">DevOps.GitLab-CI — CI-система</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">DevOps.Artifactory — хранилище артефактов сборок и сторонних компонентов</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Docker.Registry — хранилище докер-образов</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Docker.Linux.AISA — артефакт сборки клиента AISA (рабочий докер-образ с клиентом)</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">AI.Shell Agent — клиент AISA, запущенный внутри докер-контейнера, работающий с API сервера PT Application Inspector</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">BuildAgent.Console — системная консоль сборочного агента</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">WorkingDirectory — рабочий каталог на сборочном сервере, где лежит исходный код, который будет отправлен на сканирование</p></li></ul><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Коротко напомню, какую мы выбрали <a href="https://habr.com/ru/company/pt/blog/534458/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">архитектуру</a>. Сервер и агенты сканирования PT Application Inspector размещены на отдельных виртуальных машинах. Запуск задания сканирования осуществляется в отдельных шагах на сборочных агентах GitLab CI. Исходный код из проекта на GitLab сначала выгружается на сборочный агент в рабочую директорию сборки, а затем передается для анализа через консольный клиент AISA на сервер и далее на агенты сканирования.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">AISA — это аббревиатура от Application Inspector Shell Agent. Этот клиент умеет работать с API сервера PT Application Inspector. AISA запускается в отдельном докер-контейнере, который является своеобразной «оберткой» для клиента.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Докер-образы с AISA собираются CI-конфигурациями, которые поддерживают CI-инженеры нашего DevOps-отдела. После сборки образы выкладываются в docker registry на Artifactory. Благодаря поставке докер-образами сборочная инфраструктура компании не зависит от разработки клиента AISA.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Мы определили основные шаги <span style="font-weight: bolder; margin-top: 0px;">методики внедрения</span> сканера в существующие CI-процессы. Вот они:</p><ol style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Подготовка серверной части:</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● установка и настройка сервера PT Application Inspector;</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● установка и настройка агентов сканирования.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Подготовка клиентской части:</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● организация релизного CI-цикла для клиента AISA (поставка докер-образом).</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Подготовка проекта сканирования:</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● на стороне сервера;</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● через клиент AISA.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Работа с CI-системами:</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● шаблоны сканирования в GitLab CI;</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● метараннеры TeamCity;</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">● прочие средства (работа с CLI AISA).</p></li></ol><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Чтобы внедрить PT Application Inspector по этой методике в конвейер одного продукта и поддерживать его работу, потребуются силы одного-двух CI-инженеров средней квалификации.</p><h2 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Сборочный процесс с использованием PT Application Inspector</h2><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Наши продукты — многокомпонентные, есть в них и сторонние компоненты. Из компонентов, продвинутых по результатам тестов в релиз и допущенных на интеграцию, собирается бандл (инсталлятор) продукта. Процесс сборки любого продукта максимально шаблонизирован, а его типовые шаги выглядят, как показано на схеме. На одном из шагов в сборке код передается на анализ на сервер через консольный клиент AISA. Напомню, что мы рекомендовали встраивать анализ кода непосредственно в сборочные шаблоны, чтобы было проще тиражировать процесс.</p><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Типовые шаги процесса продуктовой сборки" height="700" src="https://habrastorage.org/getpro/habr/upload_files/030/f77/203/030f77203cd4e529fc8523085b891d35.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Типовые шаги процесса продуктовой сборки" width="1665" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Типовые шаги процесса продуктовой сборки</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Как изменился алгоритм типовой сборки с учетом новых шагов сканирования:</p><ol style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Сборочный агент в момент старта сборки запрашивает исходный код проекта на GitLab.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Исходный код проекта скачивается на сборочный агент.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Запускается скрипт build-on-server, и начинают выполняться по порядку шаги сборки. Этот скрипт — точка входа для разделения логики сборки и ее внедрения в CI-конвейер. Скрипт build-on-server пишут разработчики, так как знают логику компиляции своего продукта, а CI-инженеры вызывают его в шагах сборки в своей CI-системе.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">В параллельном с основной сборкой режиме запускается легковесный клиент AISA. Он использует конфигурационный файл с настройками сканирования.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Код передается на сервер сканирования.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Сервер распределяет код между агентами сканирования, на которых запускается процесс анализа.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Выполняется сканирование кода проекта. Сканирование никак не мешает основному сборочному процессу, так как выполняется на отдельных серверах.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Результаты анализа сохраняются в базе данных на сервере сканирования.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">AISA-клиент получает результаты сканирования со стороны сервера, и они становятся доступны в сборочном пайплайне.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Выполняется проверка правил Security Gates. Результатом проверки является значение Code Quality Status — это 0, если все условия правил выполняются, и 1, если одно или больше условий не выполняются.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Если Code Quality Status равен 0, тогда считается, что пайплайны сборки и сканирования завершились успешно. При значении 1 сборка может быть остановлена, а в логи — добавлены соответствующие записи о проблемах с безопасностью кода.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Артефакт сборки публикуется в хранилище на Artifactory. К артефакту могут быть добавлены некоторые метки качества.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Специальный бот публикует отчет по сканированию и результаты проверки правил Security Gates в пайплайне на GitLab CI и в мердж-реквесте GitLab. Команде разработки отправляется уведомление об успешной сборке, к которому прикладываются результаты сканирования.</p></li></ol><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Что мы улучшили в этом процессе:</p><ol style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Раньше мы предлагали запускать сканирование на том же агенте, где идет сборка. Сейчас научились запускать сканирование в параллельном режиме, вынесли шаги отправки кода через AISA и шаги сканирования в отдельный пайплайн GitLab CI.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Раньше приходилось запускать сканирование, ждать отчета по его результатам и лишь потом запускать сборку и публикацию артефакта — либо отправлять код на сервер PT Application Inspector и через некоторое время, заранее неизвестное, возвращаться туда и смотреть результаты. Но сейчас появились штатные механизмы GitLab CI, и мы вынесли сканирование в так называемые <a href="https://docs.gitlab.com/ee/ci/multi_project_pipelines.html" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">downstream pipelines</a>, или дочерние пайплайны. Теперь сканирование запускается всегда, на каждую сборку, параллельно самой сборке и не мешая ее ходу.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Добавили бота, который оповещает письмом или в чат о завершении сканирования, умеет добавлять отчеты прямо в мердж-реквесты GitLab, но, самое главное, понимает формат отчета сканера и может блокировать мердж-реквест на основании заданных правил, так называемых Security Gates (по аналогии с Code Quality Gates от SonarQube).</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Разработчикам теперь доступно несколько вариантов работы с ветками в git. В зависимости от того, релизная это ветка или фича-ветка, можно использовать различные наборы правил блокировки мердж-реквеста либо только информировать о потенциальных уязвимостях.</p></li></ol><h2 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Security Gates: правила и группировки</h2><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Итак, что мы предлагаем для обеспечения непрерывной безопасной разработки, что такое Security Gates и как они используются для блокировки мердж-реквестов в GitLab.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;"><span style="font-weight: bolder; margin-top: 0px;">Security Gates</span> — это набор правил для проекта сканирования, которые указывают CI-системе, как группировать найденные уязвимости и как на них реагировать: блокировать сборку или мердж-реквест либо работать в режиме информирования.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">В качестве дополнительной меры в сборочных конфигурациях можно настроить «бан» собранного артефакта в Artifactory — переименовывать его с суффиксом -BANNED после сканирования, если будет найдено слишком много уязвимостей, не проходящих ограничения Security Gates.</p><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Пример описания правил Security Gates в файле aisa-codequality.settings.yaml" height="308" src="https://habrastorage.org/getpro/habr/upload_files/007/6c6/073/0076c60730e7f9cfbb6cce328f8e30b2.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Пример описания правил Security Gates в файле aisa-codequality.settings.yaml" width="841" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Пример описания правил Security Gates в файле aisa-codequality.settings.yaml</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Сами правила описываются в обычном yaml-файле, состоящем из двух разделов:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;"><span style="font-weight: bolder; margin-top: 0px;">threats mapping </span>— отвечает за маппинг и соответствие терминологии критичности проблем кода самого GitLab (имена ключей) и терминологии критичности уязвимостей PT Application Inspector (значения ключей). Кроме того, для удобства работы в этом разделе можно сгруппировать уязвимости по типу. Например, сказать, чтобы GitLab сгруппировал уязвимости уровней Potential, Low, Medium от сканера и отображал их в группе проблем Info.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;"><span style="font-weight: bolder; margin-top: 0px;">security gates </span>— в этой секции задается количество уязвимостей для каждой конкретной группы критичности. Если сканер найдет в коде указанное число или больше уязвимостей, то мердж-реквест или сборка будут заблокированы. Если задать значение ноль, проверка количества для соответствующей группы выполняться не будет. Если нули заданы для всех групп, то сканирование фактически будет вестись в режиме информирования.</p></li></ul><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Правила Security Gates в обоих разделах должны быть согласованы со специалистами по информационной безопасности в компании. На время разработки фич в отдельных ветках эти правила могут быть смягчены, чтобы не мешать быстрой разработке. Но в момент влития кода в релизные ветки обязательно должны использоваться максимально жесткие правила.</p><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Пример «портянки» сообщений от SonarQube в треде мердж-реквеста GitLab" height="932" src="https://habrastorage.org/getpro/habr/upload_files/7e5/739/7a2/7e57397a2943641ccae5f256a61ac7df.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Пример «портянки» сообщений от SonarQube в треде мердж-реквеста GitLab" width="1960" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Пример «портянки» сообщений от SonarQube в треде мердж-реквеста GitLab</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">В качестве основы для интеграции сканера кода мы решили взять вариант интеграции известного продукта SonarQube через штатный механизм GitLab — codequality. Мы посмотрели, как он внедряет свои сообщения в мердж-реквест, и спросили наших разработчиков, насколько им это удобно. Оказалось, что большинству такая «портянка» сообщений в треде мешает, особенно когда приходится работать с legacy-кодом, для которого замечаний бывает очень много. Кроме того, открывается страничка с сотнями сообщений небыстро.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Поэтому, когда мы работали над внедрением нашего сканера в сборочные процессы, то решили сразу позаботиться об удобстве программистов и сделать более удобное отображение рекомендаций по безопасности, в одном треде мердж-реквеста. Этот тред обновляется автоматически с помощью специального бота, написанного нашими CI-инженерами для интеграции AISA с GitLab CI.</p><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Security Gates: проверки</h3><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Пример треда мердж-реквеста в GitLab, не заблокированного ботом, так как правила Security Gates выполняются" height="603" src="https://habrastorage.org/getpro/habr/upload_files/c22/a81/50d/c22a8150d258b5f9b71961dd0b7be35c.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Пример треда мердж-реквеста в GitLab, не заблокированного ботом, так как правила Security Gates выполняются" width="763" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Пример треда мердж-реквеста в GitLab, не заблокированного ботом, так как правила Security Gates выполняются</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Если уязвимости найдены, но проходят условия Security Gates, то в сборке специальный шаг Code Quality Status выставляется в значение 0 (Passed). В этом случае мердж-реквест не будет заблокирован, а в треде на GitLab программист увидит комментарий от бота с перечислением найденных (некритичных для данного набора правил) уязвимостей. Прямо в треде он сможет посмотреть, что это за уязвимости, либо перейти по ссылкам к полному HTML-отчету или в сборку на GitLab CI или TeamCity, если сборка была инициирована там.</p><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Пример треда мердж-реквеста в GitLab, заблокированного ботом, так как нарушено правило Security Gates: «major-проблем (Medium-уязвимостей от сканера) — не более двух»" height="1035" src="https://habrastorage.org/getpro/habr/upload_files/1cf/fb3/127/1cffb312785d6f9a239f3d829d216334.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Пример треда мердж-реквеста в GitLab, заблокированного ботом, так как нарушено правило Security Gates: «major-проблем (Medium-уязвимостей от сканера) — не более двух»" width="760" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Пример треда мердж-реквеста в GitLab, заблокированного ботом, так как нарушено правило Security Gates: «major-проблем (Medium-уязвимостей от сканера) — не более двух»</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Во втором случае, то есть если уязвимости найдены и не проходят условия Security Gates, — значение Code Quality Status выставляется в 1 (Failed) и мердж-реквест блокируется путем добавления ключевого слова Draft в его заголовок.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">В комментариях от бота, кроме всей прочей информации, указывается причина блокировки, то есть текущий набор правил Security Gates для ветки, где идет сборка.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">При каждом сканировании бот обновляет один и тот же тред на страничке мердж-реквеста: все уязвимости удобно группируются и отображаются в одном месте.</p><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Пример интеграции отчета от сканера в сборки на TeamCity" height="955" src="https://habrastorage.org/getpro/habr/upload_files/a73/f1d/51c/a73f1d51ce723a961dfc25f4b05755c7.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Пример интеграции отчета от сканера в сборки на TeamCity" width="1561" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Пример интеграции отчета от сканера в сборки на TeamCity</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">В сборки на TeamCity сканирование кода добавляется аналогичным образом через скрипты-«метараннеры», которые разработаны специально для использования с AISA-клиентом. HTML-отчет по сканированию возможно прикрепить штатными средствами TeamCity, разместив его на отдельной вкладке (Tab reports), которая настраивается внутри проекта с конфигурацией.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Самое главное, что из сборок на TeamCity можно точно так же пробросить информацию о найденных уязвимостях в мердж-реквесты в GitLab.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Теперь перейдем к тому, как работают правила Security Gates и как результат их проверки — Code Quality Status — блокирует выпуск наших релизов.</p><h2 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Security Gates: три режима работы</h2><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Мы спросили у наших разработчиков, какой бы они хотели видеть интеграцию сканера PT Application Inspector с их сборками. Их основное пожелание состояло в том, чтобы он не мешал оперативной разработке фич и не требовалось бы долгое ожидание скана и сборок. В идеале, чтобы сканирование вообще не мешало сборкам. Именно для этого мы решили запускать его в <a href="https://docs.gitlab.com/ee/ci/multi_project_pipelines.html" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">параллельном пайплайне</a> на GitLab CI.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Наши CI-инженеры разработали три типа шаблонов сканирования, каждый для своего типа веток. В фича-ветках мы храним шаблоны, которые сканируют в режиме информирования. При влитии в мастер или релизные ветки мы используем на выбор шаблон с блокировкой или самый строгий шаблон.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;"><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWHDT3-IPjO005zYXdiqGV3laJa0M8MOlci_fsBVM0-WtKmQpPnJSUHXl2TrWD2nKtwsGISaecdHz0aoiyqMnMqa3Aav7ldkuRSGbCGFR8s7SF4R-4xL6pqiTubvStqGZrwKAiIV0s4JRX/s1920/24_SecurityGates_spec_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1080" data-original-width="1920" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWHDT3-IPjO005zYXdiqGV3laJa0M8MOlci_fsBVM0-WtKmQpPnJSUHXl2TrWD2nKtwsGISaecdHz0aoiyqMnMqa3Aav7ldkuRSGbCGFR8s7SF4R-4xL6pqiTubvStqGZrwKAiIV0s4JRX/w640-h360/24_SecurityGates_spec_2.png" width="640" /></a></div><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Основные отличия в работе шаблонов сканирования</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Основные отличия шаблонов — в их влиянии на сборку и в глубине интеграции сканирования со сборочным пайплайном. Например, самый строгий режим сканирования при непрохождении правил Security Gates одновременно блокирует и мердж-реквест, и сам сборочный пайплайн.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Все шаблоны кастомизируются, и при настройке сборочного процесса в специальном файле конфигурации <a href="https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">.gitlab-ci.yml</a> можно выбрать различные варианты работы со сканером.</p><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Security Gates: Information mode</h3><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Схема пайплайна сборки со сканированием в режиме информирования" height="593" src="https://habrastorage.org/getpro/habr/upload_files/d43/28d/111/d4328d1118bb37171914bea71b0c3a68.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Схема пайплайна сборки со сканированием в режиме информирования" width="1646" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Схема пайплайна сборки со сканированием в режиме информирования</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Давайте посмотрим на шаги типового пайплайна сборки на GitLab CI, в которой использовался шаблон для работы сканера в информационном режиме (AI Information Mode).</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Для примера, пусть сама сборка состоит из типовых шагов:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">юнит-тестирование кода (Unit tests);</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">сборка или компиляция (Build);</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">публикация собранного артефакта сборки в некоторое хранилище (Upload to registry).</p></li></ul><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">В GitLab CI в файл gitlab-ci.yml можно импортировать любые другие шаблоны через команду <a href="https://docs.gitlab.com/ee/ci/yaml/includes.html" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">include</a>. При подключении шаблона сканирования к основным шагам пайплайна сборки добавляются дополнительные:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">запуск в параллельном режиме внешнего пайплайна сканирования (Start AI Scan);</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">отправка кода на сервер и запуск сканирования через AISA (AI-Scanning);</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">в случае любых проблем с инфраструктурой сканирования — отправка информации об этом на мониторинг (Send info);</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">по окончании сканирования — отправка отчета о найденных уязвимостях со сканирующего сервера в AISA и его добавление к пайплайну основной сборки (AI Scan Report);</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">проверка правил Security Gates, добавление результата проверки — Code Quality Status (0, Passed / 1, Failed) — к основному пайплайну;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">отправка оповещения о результатах сканирования и сборки на почту или в чат (Send emails).</p></li></ul><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Важно отметить, что в информационном режиме сканирования результаты проверок не блокируют сборочный пайплайн и мердж-реквест.</p><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Security Gates: Lock mode</h3><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Схема пайплайна сборки со сканированием в режиме блокирования мердж-реквеста" height="593" src="https://habrastorage.org/getpro/habr/upload_files/000/ef4/ef1/000ef4ef13943d58d10f8343ceb26324.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Схема пайплайна сборки со сканированием в режиме блокирования мердж-реквеста" width="1646" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Схема пайплайна сборки со сканированием в режиме блокирования мердж-реквеста</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Следующая схема (AI Lock Mode) — чуть более строгая. Она подключается к основной сборке аналогично, через включение (include) шаблона сканирования, и добавляет все те же самые шаги, что и в режиме информирования.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Основные отличия этой схемы от предыдущей в том, что в основной пайплайн сборки пробрасывается дополнительный статус: ожидание отчета по сканированию (running). Кроме того, в случае непрохождения правил Security Gates мердж-реквест GitLab в этой схеме может быть заблокирован. Основной сборочный процесс при этом не блокируется, и сборка может создавать и публиковать артефакты.</p><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Security Gates: Strictest mode</h3><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Схема пайплайна со сканированием в режиме блокирования мердж-реквеста и самой сборки" height="593" src="https://habrastorage.org/getpro/habr/upload_files/e81/193/cfc/e81193cfc7ea9b4d31ca2da96958bb18.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Схема пайплайна со сканированием в режиме блокирования мердж-реквеста и самой сборки" width="1646" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Схема пайплайна со сканированием в режиме блокирования мердж-реквеста и самой сборки</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">И, наконец, третья схема (AI Strictest Mode) — максимально строгая. Кроме шагов, описанных в предыдущих схемах, в дочерний пайплайн добавляется новый шаг, разрешающий или запрещающий публикацию сборочного артефакта (Approve build). Таким образом, если будут обнаружены уязвимости, не проходящие проверки Security Gates, то будут заблокированы и основной сборочный пайплайн, и мердж-реквест. Дополнительно мердж-реквест может быть переведен в статус черновика (Draft).</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Далее расскажу, в каких случаях мы применяем разные шаблоны.</p><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Работа с ветками git для разных режимов Security Gates</h3><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">В разработке у нас используется классический git-flow для работы с ветками:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">master — ветка для стабильного кода;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">develop — ветка для основной разработки и стабилизации кода из влитых фича-веток;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">feature — в продуктовых командах работа идет параллельно над множеством фич во множестве таких веток;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">release — у наших продуктов может быть одновременно несколько поддерживаемых релизов, поэтому используется несколько релизных веток.</p></li></ul><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">При запуске сборки или мердж-реквеста из конкретной ветки вызывается тот шаблон сканирования, который лежит в этой ветке. Приведу примеры режимов работы сканера, которые можно использовать при мердж-реквестах из различного типа веток.</p><figure class="full-width " style="line-height: 0; margin: 32px 0px 0px; padding: 0px; text-align: center;"><img alt="Схема классического git-flow и рекомендуемые шаблоны для различных веток" height="825" src="https://habrastorage.org/getpro/habr/upload_files/13c/9a7/af1/13c9a7af15cd56412c782bc18138f5c3.png" style="border: 0px; height: auto; margin: 0px; max-width: 100%;" title="Схема классического git-flow и рекомендуемые шаблоны для различных веток" width="1732" /><figcaption style="color: #909090; font-size: 13px; line-height: 18px; margin-top: 4px;">Схема классического git-flow и рекомендуемые шаблоны для различных веток</figcaption></figure><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Мы рекомендуем:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">В feature-ветках хранить и использовать шаблон сканирования в информационном режиме (Information mode). Тогда при мердж-реквестах между feature-ветками и при влитии в ветку develop само сканирование никак не будет влиять на сборочный процесс и разработка будет идти быстро. Однако при этом разработчики все равно получают максимально подробные отчеты и рекомендации от сканера PT Application Inspector.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">В develop-ветке хранить и использовать самый строгий шаблон (Strictest mode), а также настраивать в нем самые строгие правила Security Gates. В этой ветке важно стабилизировать код и избавиться от всех возможных уязвимостей перед его влитием в релизные ветки. Этот шаблон пресечет любые попытки мерджа уязвимого кода в релиз, заблокирует мердж-реквесты и сами сборочные пайплайны, не даст опубликовать артефакт с уязвимостью в хранилище.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">В release-ветках допустимо хранить менее строгий шаблон (Lock mode) и использовать его при мердж-реквестах в master, так как большая часть уязвимостей уже будет закрыта на этапе стабилизации в develop.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">В master-ветке можно использовать сканирование в информационном режиме (Information mode), так как в этой ветке лежит стабильный, протестированный и проверенный код релизов, а значит, можно минимизировать проверки.</p></li></ul><h2 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Демонстрация: Security Gates и мердж-реквесты</h2><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">В апреле 2021 г. мы провели <a href="https://www.youtube.com/watch?v=tibEECBTWqo&t=22s" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">вебинар</a> для программистов и DevSecOps-инженеров. На нем мы показали, как шаблоны сканирования и правила Security Gates функционируют вживую, как наши программисты работают с реальными проектами, делают мердж-реквесты с поиском уязвимостей в коде через Application Inspector и как исправляют найденные ошибки.</p><iframe allowfullscreen="true" class="embed_video embed__content" height="459" id="609cd0ecd0e17eb5ff4723d6" src="https://embedd.srv.habr.com/iframe/609cd0ecd0e17eb5ff4723d6" style="border-style: initial; border-width: 0px; clear: both; margin: 32px 0px 4px; max-width: 100%; width: 780px;"></iframe><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Open Source dohq-ai-best-practices</h3><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Все наработки для GitLab CI и TeamCity, схемы и рабочие шаблоны сканирования для PT Application Inspector мы выложили в Open Source в проект <a href="https://github.com/devopshq/dohq-ai-best-practices" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">dohq-ai-best-practices</a> под свободной MIT-лицензией. Там вы найдете:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Подробное <a href="https://github.com/devopshq/dohq-ai-best-practices/blob/master/README.md" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">описание и схемы</a> для рекомендуемой нами методики внедрения сканера PT Application Inspector в CI.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;"><a href="https://github.com/devopshq/dohq-ai-best-practices/tree/master/AIE_Server_installation" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Скрипты инсталляции</a> для упрощения настройки серверной части PT Application Inspector.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;"><a href="https://github.com/devopshq/dohq-ai-best-practices/tree/master/AISA_Docker" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Dockerfile</a> для сборки AISA-клиента под Windows и Linux.</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">Шаблоны <a href="https://github.com/devopshq/dohq-ai-best-practices/tree/master/GitLab_templates" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">типовых пайплайнов</a> для GitLab CI и <a href="https://github.com/devopshq/dohq-ai-best-practices/tree/master/TeamCity_meta-runners" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">метараннеры</a> для TeamCity с возможностью блокирования мердж-реквестов и работающие в параллельном режиме с основной сборкой.</p></li></ul><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Что еще почитать по теме DevOps</h3><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">По мере развития нашего CI мы делились идеями и наработками в корпоративном блоге на Хабре:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">«<a href="https://habr.com/ru/company/pt/blog/313616/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Личный опыт: как выглядит наша система Continuous Integration</a>» (2016)</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">«<a href="https://habr.com/ru/company/pt/blog/343884/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Автоматизация процессов разработки: как мы в Positive Technologies внедряли идеи DevOps</a>» (2017)</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">«<a href="https://forworktests.blogspot.com/2018/12/blog-post.html" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Моделирование производственных процессов в ИТ-компании</a>» (2018)</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">«<a href="https://habr.com/ru/company/pt/blog/480754/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Управление хаосом: наводим порядок с помощью технологической карты</a>» (2019)</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">«<a href="https://habr.com/ru/company/pt/blog/501766/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Личный опыт: как выстроить карьерный рост в отделе DevOps</a>» (2020)</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">«<a href="https://habr.com/ru/company/pt/blog/534458/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">DevSecOps: как мы внедряли PT Application Inspector в наш продуктовый конвейер</a>» (2020)</p></li><li style="line-height: 24px; margin: 12px 0px 0px; padding: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">«<a href="https://habr.com/ru/company/pt/blog/552104/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Как работает команда DevOps в Positive Technologies</a>» (2021)</p></li></ul><p style="clear: both; line-height: 24px; margin: 32px 0px 0px;">Если вас интересует тема кибербезопасности, следите за нашими <a href="https://www.ptsecurity.com/ru-ru/research/webinar/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">вебинарами</a> и новыми статьями <a href="https://habr.com/ru/company/pt/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">в блоге компании</a>. А на этом пока все. Ждем ваших вопросов в комментариях :)</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;"><span style="font-weight: bolder; margin-top: 0px;">Автор статьи</span>: <a href="https://www.linkedin.com/in/tgilmullin/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Тимур Гильмуллин</a> — заместитель руководителя отдела технологий и процессов разработки в Positive Technologies. Отвечал за разработку архитектуры и методики внедрения PT Application Inspector в сборочные техпроцессы со стороны DevOps-команды, а также подготовку проекта Open Source.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;"><span style="font-weight: bolder; margin-top: 0px;">Технический эксперт: </span><a href="https://www.linkedin.com/in/dmitry-ragulin-756a5215a/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Дима Рагулин</a> — CI-инженер отдела технологий и процессов разработки. Отвечал за подготовку архитектуры и скриптов для интеграции PT Application Inspector с CI-системами и подготовку проекта Open Source.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Развивать идеи DevSecOps в большой компании невозможно без коллектива высококлассных специалистов. Выражаю огромную благодарность нашим коллегам: <a href="https://www.linkedin.com/in/antstas/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">Стасу Антонову</a>, <a href="https://www.linkedin.com/in/anton-volodchenko-59170769/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Антону Володченко</a>, <a href="https://www.linkedin.com/in/oleg-machalov-60420b124/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Олегу Мачалову</a> и <a href="https://www.linkedin.com/in/aleksandr-khudyshkin-0956b71aa/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Саше Худышкину</a> за оперативную техническую помощь по вопросам внедрения, разработки и использования сканера PT Application Inspector, <a href="https://www.linkedin.com/in/vicryzhkov/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Вите Рыжкову</a> и <a href="https://www.linkedin.com/in/alexey-zhukov-2031bb8b/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Алексею Жукову</a> за экспертизу и помощь с подготовкой вебинаров, всем инженерам нашего отдела DevOps Positive Technologies за техническое сопровождение сервиса PT Application Inspector и помощь с его внедрением в компании, а также всем разработчикам сканера за прекрасный продукт :)</p></div></div><dl class="post__tags" style="align-items: baseline; background-color: white; clear: both; color: #333333; display: flex; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 14px; justify-content: flex-start; margin: 24px 0px;"></dl></div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-33901421869917455762021-04-21T22:31:00.000+03:002021-04-21T22:31:09.567+03:00Как работает команда DevOps в Positive Technologies<div><div class="separator" style="clear: both; text-align: center;"><a href="https://hsto.org/getpro/habr/upload_files/0fd/9f4/77f/0fd9f477f6dc00903ace5950dd4317f8.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="533" data-original-width="800" height="427" src="https://hsto.org/getpro/habr/upload_files/0fd/9f4/77f/0fd9f477f6dc00903ace5950dd4317f8.jpg" width="640" /></a></div></div><div><br /></div><div><span style="background-color: white; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px;">Всем привет! Меня зовут Тимур Гильмуллин, я работаю в отделе технологий и процессов разработки Positive Technologies. Внутри компании нас неформально называют DevOps-отделом. Мы занимаемся автоматизацией внутренних процессов и помогаем разработчикам и тестировщикам. В прошлой статье я уже писал, </span><a href="https://habr.com/ru/company/pt/blog/501766/" style="background-color: white; color: #548eaa; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px; margin-top: 0px; text-decoration-line: none;">как выстроен карьерный рост</a><span style="background-color: white; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px;"> у инженеров, а сегодня хочу рассказать про «внутреннюю кухню» — о том, что делают DevOps-инженеры у нас в компании. Вы узнаете, что лежит в основе идей DevOps, какие плюсы дает бизнесу работа по принципам DevOps и как при этом изменяется процесс разработки.</span></div><div><span><a name='more'></a></span></div><div><span style="background-color: white; color: #333333; font-family: "Fira Sans", sans-serif; font-size: 22px;"><br /></span></div><div><span style="background-color: white; color: #333333; font-family: "Fira Sans", sans-serif; font-size: 22px;"><br /></span></div><div><span style="background-color: white; color: #333333; font-family: "Fira Sans", sans-serif; font-size: 22px;">Как мы понимаем идеи DevOps</span></div><div><div class="post__body post__body_full" style="background-color: white; clear: both; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 14px; margin-bottom: 24px; padding-top: 32px;"><div class="post__text post__text_v2" id="post-content-body" style="font-size: 16px; line-height: 1.56; overflow-wrap: break-word;"><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Мы не претендуем на идеальную реализацию всех идей DevOps, для этого есть специализированные компании и гуру в этой области, а у нас в Позитиве своя специфика разработки в области ИБ и свои процессы автоматизации.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Как мы понимаем работу по принципам DevOps и в чем их ключевые отличия от классического подхода к разработке? Для начала разберемся, как когда-то шла разработка ПО не только в нашей компании, а в целом в отрасли.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Команда программистов (Dev) писала код и сама делала его сборку, команда тестировщиков (QA/QC) тестировала то, что им отдали программисты, а далее команда администраторов (IT) вручную устанавливала это на «боевые» серверы. Обычные проблемы такого подхода: «<em style="margin-top: 0px;">Я код написал, сохранил, дальше не моя задача!</em>», «<em>Я баг протестировал в старой версии, а новую мне никто не давал!</em>», «<em>Я ваше приложение установил, оно не работает, что с ним делать, я не знаю, спрашивайте разработчиков!</em>». А если это была распределенная команда с сотрудниками в разных часовых поясах, то при таком подходе разработка затягивалась на месяцы и годы. Чтобы решить эти проблемы, нужно было объединить всех участников в едином и понятном для них процессе.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Понятие Development Operations (или DevOps) включает в себя не только инструменты разработки и сервисы, но также методики и лучшие практики их использования. Иногда бывает, что даже на уровне руководителей разработки звучат мнения: «<em style="margin-top: 0px;">Пусть ваши DevOps-инженеры просто настроят нам деплой (или CI)!</em>» или «<em>А вот в других компаниях DevOps-инженеры занимаются <подставить нужное>, вы тоже должны делать это!</em>». Это говорит о том, что работу DevOps-инженеров часто понимают как смешение различных ролей. Инженеры, работающие по принципам DevOps, помогают «подружить» между собой всех, кто участвует в процессе разработки ПО, и объединить их совместный труд в рамках общего производственного конвейера. Они смотрят на все процессы «сверху», при этом направления работ у таких инженеров динамически меняются и подстраиваются под реальность продуктовой разработки, чтобы предлагать наиболее подходящие решения под конкретные задачи.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Вот пример подобной гибкости из нашего опыта. В последние два года к поддержке направлений Dev и Ops для наших DevOps-инженеров добавились работы по внедрению инструментов безопасной разработки в уже существующие сборочные CI-конвейеры, то есть мы занялись развитием Sec-направления. Об этом мы подробно рассказывали в статье о том, <a href="https://habr.com/ru/company/pt/blog/534458/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">как внедряли анализатор кода PT Application Inspector</a> в продуктовый конвейер: для этого пришлось разработать методику и выстроить архитектуру решения, развернуть серверную и клиентскую части, разработать скрипты для работы с API <a href="https://www.ptsecurity.com/ru-ru/products/ai/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">PT AI</a> и шаблоны сканирования для интеграции с CI (их можно найти в <a href="https://github.com/devopshq/dohq-ai-best-practices" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">опенсорсе</a>). Как сейчас работает PT AI в сборочном конвейере, мы показали <a href="https://www.ptsecurity.com/ru-ru/research/webinar/devsecops-vnedrenie-v-produktovyj-konvejer-i-ehkspluataciya-pt-application-inspector/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">на вебинаре</a>.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Были в моей практике и нетривиальные инженерные задачи, например нужно было помочь тестировщикам нашего веб-сканера автоматически отсеивать false-позитивы найденных уязвимостей для одного из <a href="https://habr.com/ru/company/pt/blog/187636/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">этапов тестирования</a>. Для этого пришлось создать полноценную <a href="https://habr.com/ru/company/pt/blog/246197/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">математическую модель</a> и внедрить в CI <a href="https://habr.com/ru/company/pt/blog/274241/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">нейро-нечеткий классификатор</a> собственной разработки. Также мы внедряли <a href="https://habr.com/ru/company/pt/blog/204224/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">систему нагрузочного тестирования</a> на базе Яндекс.Танк, когда это еще не стало мейнстримом :) Но такие задачи достаточно редки, и они не совсем типичны для работы DevOps-инженера.</p><blockquote style="background: 0px 0px; border-left: 4px solid rgb(84, 142, 170); box-sizing: border-box; clear: both; margin: 32px 0px 0px; padding: 12px 24px;"><p style="clear: both; line-height: 24px; margin: 0px;">Я предлагаю сравнивать DevOps-инженеров с инженерами-технологами на обычном производстве: такие специалисты решают не только задачи своей роли, но и видят весь производственный конвейер целиком. Они понимают, как результаты работы на отдельном этапе будут использованы далее, как их объединить в общую производственную цепочку, как и какие инструменты и технологии лучше использовать на каждом этапе.</p></blockquote><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Плюсы, которые дает бизнесу работа по принципам DevOps</h3><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Рассмотрим некоторые требования современного бизнеса к ПО. К ним относят высокую скорость разработки и развертывания новых версий программ, надежный механизм контроля внесения изменений в код, минимизацию дефектов приложений, максимизацию стабильности в эксплуатации, простоту масштабирования. Идеально, если все это будет с минимальными трудозатратами и издержками, а также удастся избежать неограниченного расширения штата сотрудников.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Положительное влияние на бизнес от внедрения идей DevOps в компании может оказать работа по принципу DevOps as a service. В крупных компаниях, которые могут себе это позволить, выделенная команда DevOps-инженеров построит весь технологический конвейер из определенного набора сервисов, регламентирует и автоматизирует все процессы разработки, проконтролирует технологические этапы и шаги разработки, тестирования и развертывания, сохранит и распространит технологические знания внутри компании.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Важно для бизнеса и то, что в итоге DevOps-инженеры могут уменьшить общую стоимость и издержки производства ПО за счет шаблонизации типовых, надежных и проверенных решений и их тиражирования по всем продуктовым командам.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">В нашей компании примеров внедрения автоматизации уже очень много. Но главной задачей было объяснить людям, зачем им нужна эта автоматизация. Проще всего, когда техническая задача сразу идет от бизнеса: когда у людей, приносящих деньги компании, есть четкое понимание того, что, как и когда нужно сделать или оптимизировать. Подробнее о том, какие плюсы для бизнеса приносит внедрение идей DevOps, мы писали в статьях о наших <a href="https://habr.com/ru/company/pt/blog/310584/" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">первых шагах в DevOps</a>, о том, как мы пытались <a href="https://habr.com/ru/company/pt/blog/313616/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">построить свой CI-конвейер</a>, и о том, к чему в итоге пришли в <a href="https://habr.com/ru/company/pt/blog/343884/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">автоматизации CI/CD-процессов</a>. А также в статье о том, как научились выделять типовые шаги производственного конвейера, планировать их внедрение и тиражирование при помощи <a href="https://habr.com/ru/company/pt/blog/480754/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">технологической карты</a>.</p><h4 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 18px; font-weight: 500; line-height: 26px; margin: 32px 0px 0px;">Какие проблемы разработки может помочь решить DevOps-команда</h4><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Как я отметил ранее, одна из основных задач DevOps-инженера — упрощение взаимодействия между командами разработки (Dev) и эксплуатации (Ops, обычно эту роль выполняет IT-подразделение). Они могут сделать совместный труд разработчиков и IT-инженеров более эффективным и продуктивным, обеспечивая обмен информацией и технологиями между ними.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Вообще DevOps-инженеры должны стремиться к тому, чтобы IT-специалисты понимали процессы разработки и тестирования и вовлекались в них, а разработчики и тестировщики — понимали процессы развертывания и эксплуатации разрабатываемого ПО и тоже вовлекались в эту работу. Такой подход позволит избежать «детских» проблем взаимодействия между разными подразделениями, как в классическом подходе к разработке, который я описал в начале статьи.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Работать DevOps-инженеры могут как по сервисной модели, решая поступающие запросы от разработчиков и тестировщиков, помогая им интегрироваться с существующими сервисами разработки, так и проактивно, проводя аналитику существующих процессов, выявляя узкие места в разработке ПО и предлагая варианты и инструменты для решения проблем.</p><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Как идет разработка по принципам DevOps</h3><h4 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 18px; font-weight: 500; line-height: 26px; margin: 32px 0px 0px;">Основные шаги</h4><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Процесс разработки сильно зависит от специфики работы каждой конкретной компании. У нас в Positive Technologies, являющейся вендором программных продуктов в сфере информационной безопасности, все решения от DevOps-инженеров — типовые, масштабируемые и построены на шаблонах. Для всех CI/CD-проектов общие шаги остаются неизменными: разработчик делает git-коммит и запускается автоматическая сборка в GitLab CI (building) — далее запускается автоматическое развертывание на тестовые серверы (deploying) — выполняются функциональное и прочие виды автотестирования (testing) — сборка продвигается в релизный репозиторий на Artifactory (promoting) — публикация компонентов и инсталляторов на корпоративный сервер обновлений GUS (publishing) — распространение через FUS-серверы в интернете (delivering) — установка или обновление продукта на инфраструктуре заказчиков (installing/updating).</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">На каждом шаге DevOps-инженеры помогают разработчикам и тестировщикам решать множество конкретных технических задач, например:</p><ul style="margin: 32px 0px 0px; padding: 0px 0px 0px 32px;"><li style="line-height: 24px; margin-top: 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">подготовить и настроить проекты в GitLab для хранения кода и конфигураций;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">подготовить пулы сборочных серверов;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">разработать сборочные конфигурации, используя типовые шаблоны;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">сохранить артефакты сборки (компоненты и инсталляторы) в репозитории на Artifactory;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">создать сценарии автоматического развертывания тестового окружения на виртуальных машинах;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">разработать конфигурации для развертывания компонент и инсталляторов на тестовых серверах;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">помочь тестировщикам с подготовкой тестовых конфигураций и запуском в них тестовых сценариев;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">продвинуть сборку, то есть переместить ее в хранилище успешно протестированных артефактов;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">опубликовать сборку на корпоративном Update-сервере;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">помочь с написанием сценариев для развертывания сборки на «боевом» сервере;</p></li><li style="line-height: 24px; margin: 12px 0px 0px; position: relative;"><p style="clear: both; line-height: 24px; margin: 0px;">помочь с техническими деталями лицензирования и сбора телеметрии от установленных продуктов.</p></li></ul><h4 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 18px; font-weight: 500; line-height: 26px; margin: 32px 0px 0px;">Инструменты для поддержки автоматизации</h4><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Как правило, инструменты для автоматизации разработки выбираются из потребностей решаемых задач. У нас за 7 лет эволюции CI/CD-конвейера сложилась устойчивая связка из трех базовых сервисов, предоставляемых для разработчиков и тестировщиков по умолчанию: GitLab как хранилище кода, GitLab CI для реализации CI/CD вместе с пулами сборочных агентов и Artifactory как хранилище собранных компонент и инсталляторов, а также кеширующий прокси для внешних репозиториев различного типа.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Разработчики пишут в основном на C++, C# и Python. Тестировщики пишут SaltStack или Ansible сценарии для подготовки тестового окружения, используют py.test, Selenium, RobotFramework, Яндекс.Танк, JMeter и собственные фреймворки для реализации различных видов тестов. Отчеты по тестам публикуются в сервисах TestRail или Allure.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Для работы с внешними заказчиками используется набор сервисов Supply Lab собственной разработки: GUS-сервер для публикации успешно протестированных релизов инсталляторов и пакетов обновлений, FUS-серверы для автоматической доставки релизов и License-сервер для работы с лицензиями. Подготовка окружения и развертывание продуктов компании на конечных серверах заказчиков производится либо самописными инсталляторами, либо также с использованием сценариев на SaltStack или Ansible.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Для ведения проектной работы мы предоставляем командам трекеры на выбор: TFS, YouTrack или Jira. Организовать связанную работу всех перечисленных сервисов, трекеров и интегрировать в них результаты труда продуктовых команд — также задача наших DevOps-инженеров.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Большая часть шагов CI/CD-конвейера и все задействованные сервисы разработки контролируются в системе мониторинга Zabbix. При любом сбое наши инженеры быстро локализуют проблему и исправляют ошибки. Чтобы избежать повторения проблем, мы создаем и ведем странички так называемых <a href="https://github.com/devopshq/dohq-doc-templates/blob/master/debriefing.md" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">разборов полетов</a>.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">Кроме того, наши DevOps-инженеры используют опенсорс-решения и сами пишут небольшие инструменты для интеграции с сервисами разработки (проект <a href="https://github.com/devopshq" style="background-color: transparent; color: #548eaa; margin-top: 0px; text-decoration-line: none;">DevOpsHQ</a> в GitHub).</p><h3 style="-webkit-font-smoothing: antialiased; clear: both; font-family: "Fira Sans", sans-serif; font-size: 22px; font-weight: 500; line-height: 32px; margin: 32px 0px 0px;">Итоги</h3><p style="clear: both; line-height: 24px; margin: 12px 0px 0px;">Несмотря на то, что работодатели часто представляют DevOps-инженера как некоего мастера-универсала, который и серверы настроит, и CI/CD на них, и с мониторингом разберется, а также инструменты интеграции разработает как профессиональный программист, на практике его роль сильно зависит от специфики задач, которые поставлены перед конкретной продуктовой командой.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;">DevOps-инженер, конечно, может обладать широким кругозором в различных системах CI/CD и инфраструктуре, но также он может быть и узким специалистом (например, отлично разбираться только в мониторинге или сборе телеметрии от установленных продуктов). Как правило, в отдел инженеров, внедряющих идеи DevOps, выделяют нескольких специалистов из различных технических областей. И вот тогда они вместе как отдел представляют собой того самого «мастера-универсала», который так необходим для развития продуктовой разработки.</p><p style="clear: both; line-height: 24px; margin: 24px 0px 0px;"><em style="margin-top: 0px;">Автор</em>: <a href="https://www.linkedin.com/in/tgilmullin/" style="background-color: transparent; color: #548eaa; text-decoration-line: none;">Тимур Гильмуллин</a>, заместитель руководителя отдела технологий и процессов разработки в Positive Technologies</p></div></div></div><div>Это копия недавно опубликованной статьи на Хабре про то, <a href="https://habr.com/ru/company/pt/blog/552104/" target="_blank">как работает наша DevOps команда</a>.</div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-20020332891520116542020-12-22T18:55:00.002+03:002021-05-26T13:10:51.799+03:00DevSecOps: как мы внедряли PT Application Inspector в наш продуктовый конвейер<p></p><div class="separator" style="clear: both; text-align: left;"><div class="separator" style="clear: both; text-align: left;"><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIGtGFYb89z5GOT_VNvqtDQzpOo1PycqBe4k_j5CFkXEzW2zJqYm6Pj3t0cgnMkJHYiOBdKnmRsREKbA02zWDHhOMk7MLgfO6x47ptxFMpEdgXBagE8IpvsJPLLGRchsT0eWdGLyHb-qkC/" style="margin-left: 1em; margin-right: 1em;"><img alt="PT AI" data-original-height="350" data-original-width="350" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIGtGFYb89z5GOT_VNvqtDQzpOo1PycqBe4k_j5CFkXEzW2zJqYm6Pj3t0cgnMkJHYiOBdKnmRsREKbA02zWDHhOMk7MLgfO6x47ptxFMpEdgXBagE8IpvsJPLLGRchsT0eWdGLyHb-qkC/w105-h105/image.png" width="105" /></a></div><div class="separator" style="clear: both; text-align: left;"><br /></div>Вышла новая обзорная статья на Хабре по одному из направлений в DevSecOps: про то, как мы внедряли анализатор кода PT Application Inspector в корпоративный сборочный конвейер.</div></div><p></p><p>Первоисточник: <a href="https://habr.com/ru/company/pt/blog/534458/" target="_blank">статья на Хабре</a>. Копия под катом.<span><br /></span></p><span><a name='more'></a></span><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6QXo0ZIxIWqjBr9AK6lVd_eB6SIPjDa6ghx2b3MQ1Qt5Vt4AcRyzjKPY1sUPugeokmBGKaRmdRiRoc05fOvbFYgw6ChjL3LenSLW0kjY3dL5Rm8tgZgd-azB4VsREIOjG7p6rbC8SeEti/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="463" data-original-width="718" height="412" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6QXo0ZIxIWqjBr9AK6lVd_eB6SIPjDa6ghx2b3MQ1Qt5Vt4AcRyzjKPY1sUPugeokmBGKaRmdRiRoc05fOvbFYgw6ChjL3LenSLW0kjY3dL5Rm8tgZgd-azB4VsREIOjG7p6rbC8SeEti/w640-h412/image.png" width="640" /></a></div><br /><p class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i style="mso-bidi-font-style: normal;"><span lang="ru">Изображение: </span></i><span lang="ru"><a href="https://www.ptsecurity.com/ru-ru/products/ai/"><i style="mso-bidi-font-style: normal;"><span style="color: #1155cc;">ptsecurity.com</span></i></a><i style="mso-bidi-font-style: normal;"><o:p></o:p></i></span></p>
<p class="MsoNormal"><span lang="ru">Привет! Меня зовут Тимур Гильмуллин, я работаю
в отделе технологий и процессов разработки Positive Technologies. Неформально
наш отдел называют DevOps-отделом, мы занимаемся автоматизацией различных
процессов и помогаем разработчикам и тестировщикам в нашей компании.<o:p></o:p></span></p><p class="MsoNormal"><span lang="ru">Я и мой коллега Дима Рагулин хотим рассказать,
как инженеры нашего отдела внедряли сканер кода <a href="https://www.ptsecurity.com/ru-ru/products/ai/"><span style="color: #1155cc;">PT
Application Inspector</span></a> (PT AI) в сборочные процессы продуктовых
команд внутри компании. Отмечу, что статья про архитектуру и интеграцию PT AI в
CI, а не про работу с этим инструментом и не про поиск уязвимостей. Подробнее о
функциональных возможностях PT AI вы можете узнать из <a href="https://www.ptsecurity.com/ru-ru/research/webinar/pt-application-inspector-obzor-novoy-versii-i-roadmap/"><span style="color: #1155cc;">вебинара</span></a>.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Статья состоит из двух частей. В первой части
расскажем, какое место PT AI занимает в наших технологических цепочках, дадим
рекомендации по возможной архитектуре его внедрения в CI-конвейер. Это будет
полезно DevOps-архитекторам и специалистам по внедрению решений в области
безопасной разработки (DevSecOps). Вторая часть посвящена практическому
внедрению PT AI в наш корпоративный CI-конвейер: в ней мы поделимся наработками
своих шаблонов и скриптов, а также покажем, как можно подключить сканирование
через PT AI в пару строчек кода. Это может быть интересно инженерам, перед
которыми встали вопросы внедрения PT AI внутри уже сложившихся инфраструктуры и
процессов разработки.<o:p></o:p></span></p>
<h2 style="text-align: left;"><span style="font-size: x-large;">PT Application Inspector в технологическом конвейере</span></h2><div style="text-align: left;"> </div><h1><a name="_waorc766aeni"></a></h1>
<h3 style="margin-top: 8pt; text-align: left;"><span lang="ru">Чем
занимаются DevOps-инженеры в Positive Technologies</span></h3><h2 style="margin-top: 8pt;"><a name="_j8r4xmlyxp6w"></a></h2>
<p class="MsoNormal"><span lang="ru">Понятие DevOps включает в себя не только
инструменты и сервисы разработки, но также методологии и лучшие практики их
использования. Positive Technologies уже 18 лет разрабатывает продукты в
области ИБ, а наш DevOps-отдел помогает анализировать, классифицировать и
автоматизировать отдельные этапы разработки. Кроме того, мы шаблонизируем и
тиражируем решения отдела в продуктовые команды.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Если обобщить, то мы поддерживаем весь
CI/CD-конвейер от коммита строчки кода разработчиками до публикации готовых
продуктов и лицензий на серверах обновлений и контролируем их доставку до
инфраструктуры заказчиков. Также мы собираем и агрегируем знания о CI/CD конвейере всех продуктов
компании, делимся своими наработками и лучшими DevOps-практиками с командами.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Сейчас в отделе работает 15 инженеров. Мы
работаем по сервисной модели и решаем заявки внутренних пользователей — 500++
разработчиков и тестировщиков компании. Ведём проактивную разработку и
улучшение наших инструментов, исследуем, внедряем и развиваем полезные для
разработки сервисы. Один из таких полезных сервисов — PT Application Inspector,
о котором пойдёт речь в статье.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Наши продуктовые CI/CD-процессы технологически
построены на нескольких взаимосвязанных системах:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l0 level1 lfo10; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">GitLab (хранилище кода), где
размещено более 9.5K сборочных проектов;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l0 level1 lfo10; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">GitLab CI (основная CI-система),
где выполняется более 2.7M сборок в год;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l0 level1 lfo10; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Artifactory (в качестве хранилища
бинарных компонент), где хранится более 8.2Tb артефактов;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l0 level1 lfo10; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Сборочные агенты, сгруппированные
по high, med и low пулам, в зависимости от требований к ресурсам. В пулах
используется более 40 общедоступных виртуальных машин, размещённых во
внутрикорпоративном облаке vSphere.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">На базе этих систем уже в 2014 году был
построен типовой CI-процесс, мы разработали скрипты для интеграции сборок
любого типа и на любых языках программирования с корпоративной CI-системой,
сделали сборочный конвейер для десятка продуктов компании.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">По мере развития CI мы делились наработками в
опенсорсе, на митапах и конференциях. Об этом мы писали в <a href="https://habr.com/ru/users/ptsecurity/posts/"><span style="color: #1155cc;">корпоративном
блоге</span></a> на Хабре:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l1 level1 lfo2; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">"<a href="https://habr.com/ru/company/pt/blog/313616/"><span style="color: #1155cc;">Личный
опыт: как выглядит наша система Continuous Integration</span></a>" (2016).<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l1 level1 lfo2; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">"<a href="https://habr.com/ru/company/pt/blog/343884/"><span style="color: #1155cc;">Автоматизация
процессов разработки: как мы в Positive Technologies внедряли идеи DevOps</span></a>"
(2017).<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l1 level1 lfo2; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">"<a href="https://forworktests.blogspot.com/2018/12/blog-post.html"><span style="color: #1155cc;">Моделирование производственных процессов в ИТ-компании</span></a>"
(2018).<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l1 level1 lfo2; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">"<a href="https://habr.com/ru/company/pt/blog/480754/"><span style="color: #1155cc;">Управление
хаосом: наводим порядок с помощью технологической карты</span></a>"
(2019).</span></p><p class="MsoNormal" style="margin-left: 36pt; mso-list: l1 level1 lfo2; text-indent: -18pt;"><span lang="ru"><br /></span></p>
<h3 style="text-align: left;"><span lang="ru">Польза</span><span lang="EN-US"> PT Application Inspector </span><span lang="ru">для</span><span lang="EN-US"> DevSecOps-</span><span lang="ru">направления</span></h3><h2><a name="_52w13686ha7q"></a></h2>
<p class="MsoNormal"><span lang="ru"><a href="https://www.ptsecurity.com/ru-ru/products/ai/"><span style="color: #1155cc;">PT
Application Inspector</span></a> — инструмент для выявления уязвимостей и ошибок
в приложениях, поддерживающий процесс безопасной разработки. PT AI использует
статические, динамические и интерактивные методы (SAST, DAST и IAST), а по
результатам анализа формирует безопасные эксплойты для ручной проверки наличия
уязвимостей.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">PT AI позволяет ИБ-специалистам выявлять и
подтверждать уязвимости и признаки НДВ, например, закладок, оставленных в
исходном коде разработчиками или хакерами, а разработчикам — ускорить
исправление кода на ранних стадиях разработки.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Список поддерживаемых языков для сканирования:
java, php, c#, vb, objective-c, c++, sql, swift, python, javascript, go,
kotlin.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">С недавних пор наш отдел помогает развивать в
компании идеи DevSecOps. Методологии DevSecOps подразумевают обеспечение
безопасной разработки на всех технологических этапах и шагах производственного
CI/CD-конвейера. При этом контроль безопасности и разработка осуществляются
параллельно, а инструменты, обеспечивающие безопасность, рекомендуется внедрять
непосредственно в CI/CD-конвейер.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkh7rxWVyPSWatttkb27fZGxhwcToBUKX_KjLCG264lIP0w1muVAnHJN6swf-hAJ9MYnwxmmThD_TeBxWKlSfrrH7kZro7w7tOL5Xm-_wx7QfXArcLR46eMMjeJtloIr9P-EZS9KpJnXVA/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="481" data-original-width="718" height="428" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkh7rxWVyPSWatttkb27fZGxhwcToBUKX_KjLCG264lIP0w1muVAnHJN6swf-hAJ9MYnwxmmThD_TeBxWKlSfrrH7kZro7w7tOL5Xm-_wx7QfXArcLR46eMMjeJtloIr9P-EZS9KpJnXVA/w640-h428/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru">Ключевые элементы DevSecOps.
Изображение: </span></i><span lang="ru"><a href="https://swordfishsecurity.ru/"><i><span style="color: #1155cc;">swordfishsecurity.ru</span></i></a><i><o:p></o:p></i></span></p>
<p class="MsoNormal"><span lang="ru">Анализатор кода PT Application Inspector выявляет уязвимости на ранних стадиях разработки.
Именно поэтому он хорошо ложится на идеи DevSecOps и мы воспользовались им на
одном из этапов сборки продуктов. Инструмент гарантирует нам, что на продакшн
попадут только релизы без уязвимостей.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Кроме того, PT AI помогает нашим инженерам в
решении и других технических задач:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l4 level1 lfo1; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Прохождение сертификаций.
Проведение анализа кода на самых ранних стадиях жизненного цикла разработки ПО
позволяет снизить риски ошибок при прохождении в испытательных лабораториях
сертификаций продуктов компании.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l4 level1 lfo1; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Оценка качества кода. В PT AI
реализован не только поиск уязвимостей в коде, но и анализ его качества,
например, использование устаревших и неподдерживаемых функций или пустые
обработчики исключений.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l4 level1 lfo1; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Поиск уязвимостей в исходном коде
для различных языков. Анализатор поддерживает более десятка языков
программирования и позволяет выявлять уязвимости с учётом особенностей
используемых фреймворков и 3rd-party библиотек.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l4 level1 lfo1; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Автоматическое блокирование
выпуска уязвимых компонент. Использование PT AI в режиме Security Gate позволяет
задавать правила для анализа и блокирования сборок продукта или его компонент
при несоответствии результатов сканирования этим правилам.<o:p></o:p></span></p><p class="MsoNormal" style="margin-left: 36pt; mso-list: l4 level1 lfo1; text-indent: -18pt;"><span lang="ru"><br /></span></p>
<h3 style="margin-top: 8pt; text-align: left;"><span lang="ru">Релизная
схема</span> сборок с продвижениями</h3><h2 style="margin-top: 8pt;"><a name="_77vjjvei2jfb"></a></h2>
<p class="MsoNormal"><span lang="ru">Глобальная цель от внедрения идей DevOps в
нашей компании — последовательное снижение себестоимости производства и
сопровождения продуктов в количественных показателях (человеко-часах или
машино-часах, CPU, RAM, Disk). Самый простой и очевидный способ такого снижения
— минимизировать затраты на выполнение задач и тиражирование решений на всех
этапах производства. Мы унифицировали все CI-проекты, создав так называемую
релизную схему сборок с продвижениями, которая сейчас используется для всех
продуктов компании.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIPOg1KKNIGxwuX3z4Tzv0JA1CYsf5jb_wefQXkSQpk4MmFePmiyXAK_Gjn2B5fmE5w4EpzOy0Kmd3py3fV8JsrnqXKYDUPh-uL-Qxtnnlr2_E2ULC8gqZrFGKolbou62IE2cknH823ptk/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="499" data-original-width="718" height="444" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIPOg1KKNIGxwuX3z4Tzv0JA1CYsf5jb_wefQXkSQpk4MmFePmiyXAK_Gjn2B5fmE5w4EpzOy0Kmd3py3fV8JsrnqXKYDUPh-uL-Qxtnnlr2_E2ULC8gqZrFGKolbou62IE2cknH823ptk/w640-h444/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru">Общая</span></i><i><span lang="EN-US"> IDEF0-</span><span lang="ru">схема</span></i><i><span lang="EN-US"> CI/CD-</span><span lang="ru">конвейера</span></i><i><span lang="ru"> </span><span lang="ru">в</span></i><i><span lang="EN-US"> Positive Technologies<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru">Производственный конвейер в компании за многие
годы усложнился и сейчас состоит из десятков отдельных технологических этапов.
Если упростить и обобщить текущую релизную схему, то она включает в себя:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l9 level1 lfo3; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">кроссплатформенную сборку
продукта;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l9 level1 lfo3; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">деплой на тестовые стенды;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l9 level1 lfo3; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">выполнение функциональных и иных
тестов;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l9 level1 lfo3; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">продвижение протестированных
сборок в релизные репозитории на Artifactory;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l9 level1 lfo3; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">публикацию релизных сборок на
сервере обновлений GUS;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l9 level1 lfo3; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">доставку сборок и обновлений при
помощи FUS-серверов;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l9 level1 lfo3; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">запуск инсталляции или обновления
продукта на инфраструктуре заказчиков.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Перед нами встала задача: внедрить в уже
имеющиеся и сложившиеся сборочные процессы новый этап сканирования кода при
помощи PT Application Inspector. Совместно с DevOps-инженерами, разработчиками
PT AI и внутренними пользователями сканера кода — разработчиками из других
продуктов — мы рассматривали несколько вариантов его "врезки" в
CI-процессы релизной схемы:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l6 level1 lfo5; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">выполнять сканирование кода только
протестированных компонент перед их продвижением в релизный репозиторий (перед
этапом Promoting);<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l6 level1 lfo5; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">выполнять сканирование кода релизных
компонент перед их публикацией на серверах обновлений (перед Publishing);<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l6 level1 lfo5; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">сделать сканирование кода как один
из видов приёмочных тестов (внутри Testing);<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l6 level1 lfo5; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">запускать сканирование кода до
выполнения шага компиляции компоненты на этапе сборки (внутри Building, первым
шагом);<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l6 level1 lfo5; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">запускать сканирование кода после
компиляции компоненты, перед выкладкой артефакта в хранилище (внутри Building,
перед сохранением в Artifactory).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Каждый из этих вариантов имел плюсы и минусы.
Например, сканируя код перед продвижением компоненты в релиз можно было
минимизировать нагрузку на сканирующий сервер за счёт уменьшения количества
сканов. Однако мы решили запускать сканирование кода до выполнения шага
компиляции компоненты на этапе сборки. Этот вариант позволял достаточно легко
внедрить шаг сканирования прямо в шаблоны сборочных конфигураций и быстро
тиражировать это решение, что важно для CI-инженеров.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Мы написали несколько скриптов для запуска
сканирования и сохранили их в DevOps-Tools (это внутренние инструменты, которые
всегда доступны на сборочных агентах), а также подготовили для разработчиков
несколько шаблонов типовых задач (job) для GitLab CI, с примерами
параметризации и запуска этих скриптов.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Таким образом, мы избавили разработку от
необходимости обращаться в DevOps с заявками по этим вопросам. Программисты
сами могут подключить шаги сканирования в сборках новых компонент по нашей
инструкции.<o:p></o:p></span></p><p class="MsoNormal"><span lang="ru"><br /></span></p>
<h3 style="text-align: left;"><span lang="ru">Архитектура</span><span lang="ru"> </span><span lang="ru">размещения</span><span lang="EN-US"> PT Application Inspector Enterprise
Server<o:p></o:p></span></h3><h2><a name="_lpz4cery90jy"></a></h2>
<p class="MsoNormal"><span lang="ru">Кроме вопроса, на каком этапе техпроцесса
запускать сканирование кода, мы рассматривали различные архитектурные решения
по размещению серверной части PT AI внутри сборочной инфраструктуры. Было
несколько вариантов развернуть AIE-сервер:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l2 level1 lfo8; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">на каждом сборочном CI-агенте в
хостовой ОС, а запускать проверку кодовой базы во время сборки прямо на этом
агенте;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l2 level1 lfo8; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">в базовых докер-контейнерах,
которые предоставляют CI-инженеры для сборок, и запускать сканирование из этих
контейнеров;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l2 level1 lfo8; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">на отдельной виртуальной машине,
передавать на сервер исходный код со сборочного агента во время сборки,
проверять код удалённо и возвращать в сборку статус сканирования.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Плюсы первого и второго варианта, что
сканирующий сервис сразу доступен на любом CI-агенте, не нужно долго передавать
код и ждать запуск и результаты сканирования. Однако мы отказались от них, так
как на инженеров по инфраструктуре тогда бы легло множество задач по обновлению
серверов AIE во всех базовых докер-контейнерах и их мониторинг. Кроме того,
серверную часть AIE на данный момент возможно установить и запустить только на
Windows Server, а у наших продуктовых команд есть и Linux-сборки.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">На схеме представлен третий вариант, на
котором мы остановились.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM8c3cvCRzCVy211YUMDS5pGID6eMc31H0SlGHSYOyvmXikL50Fm6MtzffTX7s1R44efniZ-FQNB852OI32rYiILW8lEFxNeuCbyVuJMXcSmZ7D9dEfGGlbuRycnmWexkQ15LyJDZNxEGR/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="488" data-original-width="718" height="434" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM8c3cvCRzCVy211YUMDS5pGID6eMc31H0SlGHSYOyvmXikL50Fm6MtzffTX7s1R44efniZ-FQNB852OI32rYiILW8lEFxNeuCbyVuJMXcSmZ7D9dEfGGlbuRycnmWexkQ15LyJDZNxEGR/w640-h434/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Архитектура
размещения AIE Server относительно билд-агента<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru">Мы развернули серверную часть AIE (на схеме
обозначено как Server.AIE.Agent) и сканирующие агенты на отдельных виртуальных
машинах.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Исходный код (source code) из проекта на
GitLab (DevOps.GitLab) сначала выгружается на сборочный агент
(DevOps.BuildAgent) в рабочую директорию сборки (workingDirectory), а затем
передаётся для анализа на сервер AIE через специальный консольный клиент
Application Inspector Shell Agent или AISA (AIE.LightweightClient). Клиент
умеет работать с API сервера AIE. AISA запускается в отдельном докер-контейнере
(Docker.Windows/Linux.AISA-client), который является своеобразной
"обёрткой" над клиентом.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Возможности передать код на AIE-сервер
напрямую из GitLab-проекта, без физического копирования со сборочного агента
("стрелочка" от source code к AIE.Server), в текущей версии нет, но в
будущих версиях AISA разработчики обещают такую возможность.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Докер-образы с AISA собираются специальными
конфигурациями (DevOps.GitLab-CI), которые поддерживают CI-инженеры
DevOps-отдела. После сборки образы выкладываются в docker registry на
Artifactory (Docker.Registry). Для их подготовки мы организовали релизный цикл
и приёмочное тестирование.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Благодаря поставке докер-образами сборочная
инфраструктура компании не зависит от разработки самого клиента AISA.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Плюсы архитектуры:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l5 level1 lfo4; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Минимальные трудозатраты инженеров
группы инфраструктуры на развёртывание, эксплуатацию и обновление сервера AIE,
в отличие от двух других вариантов.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l5 level1 lfo4; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Требуется настройка мониторинга
только для сервера AIE и сканирующих агентов, то есть небольшого количества ВМ.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l5 level1 lfo4; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Наличие API: команды для передачи
кода на сканирование унифицированы через легковесный клиент AISA и в будущем не
придётся перенастраивать сотни сборочных конфигураций в случае изменения
контрактов в новых версиях AIE-сервера.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l5 level1 lfo4; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">По аналогичному принципу (передача
кода на анализ во внешние сервисы) работают все облачные сканеры кода,
например, Codacy и SonarQube. Хотя есть и GitLab, который использует
интегрированное серверное решение для своего Code Quality сервиса.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l5 level1 lfo4; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">В предлагаемой архитектуре можно
отделить анализ кодовой базы от сборочного процесса.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Минусы архитектуры:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l11 level1 lfo11; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Чуть более сложное внедрение
анализатора кода в сборочный процесс, за счёт дополнительных шагов настройки
сборки и проекта сканирования. Здесь требуется разработка скриптов интеграции с
CI-системами и шаблонов для запуска сканирования. Это немного сложнее, чем в
случае, когда AIE-сервер и агент сканирования расположены на самом билд-агенте.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l11 level1 lfo11; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Потенциально может возникнуть
больше проблем со сборками, за счёт добавления нового внешнего сервиса в
сборочный конвейер.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l11 level1 lfo11; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Возможно значительное увеличение
ожидания сборок в очереди, пока идёт сканирование на AIE-сервере.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l11 level1 lfo11; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Трудно спрогнозировать требования
по железу для масштабирования и обеспечения сканирований для десятков тысяч
сборок в день.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">На момент внедрения PT AI в наш сборочный
конвейер, плюсы указанной архитектуры значительно перевесили минусы.<o:p></o:p></span></p><p class="MsoNormal"><span lang="ru"><br /></span></p>
<h3 style="text-align: left;"><span lang="ru">Обновлённый сборочный процесс с
использованием PT AI</span></h3><h2><a name="_69kv6asemoox"></a></h2>
<p class="MsoNormal"><span lang="ru">Мы определились, что будем запускать
сканирование кода до выполнения шага компиляции компонент на этапе сборки.
Сервер AIE в нашей инфраструктуре будет размещён на отдельной виртуальной
машине, а запуском сканирования и передачей кода на анализ будет заниматься
консольный клиент AISA, "обёрнутый" в докер.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">В качестве основной CI-системы мы используем
GitLab CI, а все технологические шаги и этапы реализуем в виде шаблонов в
файлах <a href="https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html"><span style="color: #1155cc; font-family: "Courier New"; mso-fareast-font-family: "Courier New";">.gitlab-ci.yml</span></a>. На схеме представлен обновлённый
CI-процесс, который мы тиражируем внутри компании, с учётом новых шагов
сканирования.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGR2x5P5BTdkyEMoTMiA9gG8qPrQwZvLlvmPSAel5vZhubrJmQQU5_Yxw5LOzuQa8tYyakVVqkEMn5VX2ooGTpTYL2_zT4vz4GdwtlFCeN-OMnfzChI9SB7V28x-dQQA_SKx9ljPHiUzM/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="277" data-original-width="718" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGR2x5P5BTdkyEMoTMiA9gG8qPrQwZvLlvmPSAel5vZhubrJmQQU5_Yxw5LOzuQa8tYyakVVqkEMn5VX2ooGTpTYL2_zT4vz4GdwtlFCeN-OMnfzChI9SB7V28x-dQQA_SKx9ljPHiUzM/w640-h246/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Шаги
сборочного процесса с использованием PT AI<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru">Детализация шагов сборочного процесса с
использованием PT AI:<o:p></o:p></span></p>
<ol start="1" style="margin-top: 0cm;" type="1">
<li class="MsoNormal"><span lang="ru">Сборка,
запущенная на билд-агенте, запрашивает исходный код из GitLab.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">Исходный
код скачивается на билд-агент в рабочую директорию сборки.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">Запускается
так называемый build-on-server сборочный скрипт (bash или batch), который
реализует логику разработчиков и все шаги сборки компоненты. Это точка
входа для отделения логики сборки от её исполнения в CI-конвейере.
Разработчики пишут build-on-server скрипт, так как лучше знают детали компиляции
своего продукта, а CI-инженеры вызывают его в шагах сборки в CI-системе.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">Отдельным
шагом запускается докер и легковесный консольный клиент AISA, которому
передаются все необходимые параметры для выполнения сканирования: имя
проекта на сервере AIE, язык программирования, путь до локального каталога
на сборочном сервере с исходным кодом и, при необходимости, некоторые
другие параметры.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">AISA-клиент
стартует и выполняется физическое копирование на сервер AIE исходного кода
собираемой компоненты. Как уже отмечалось — это временное решение.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">Сейчас
этого шага нет, но уже в ближайшем будущем на шаге 5, вместо физического
копирования исходников со сборочного агента, AISA будет передавать на
сервер AIE некий ключ (имя проекта и ветка, либо конкретный hash коммита),
однозначно идентифицирующий проверяемый код. Либо сам сервер AIE будет
интегрирован с GitLab-сервером и будет знать, где лежит исходный код
проекта и все его ветки. Это позволит избежать лишних манипуляций с
копированием кода.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">AIE-сервер
получает код и запускается сканирующий агент для его анализа. Здесь есть
варианты: либо дождаться окончания сканирования и сразу получить отчёт в
сборке, либо не ждать результаты, продолжить выполнение остальных
сборочных шагов, а результаты посмотреть позднее на сервере через
веб-приложение.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">В любом
случае нужно дождаться кодов возврата (exit code) от сервера. Если
передача исходного кода на сервер или само сканирование завершились с
ошибкой, он вернёт ненулевой код. Далее логика сборки зависит от
реализации CI-инженером и требований к процессу от разработчиков: если
очень важно получить результаты анализа кода, например, для релизных
сборок, то в случае любых ошибок можно сразу фейлить сборку. Для
нерелизных сборок любые ошибки от AIE-сервера можно игнорировать и продолжать
обычную сборку компоненты.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">Если все
предыдущие шаги окончились успешно, то запускается стандартное модульное
юнит-тестирование и продолжают выполняться оставшиеся шаги, заложенные в
логику сборки.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">Если все
шаги сборки окончились успехом, то скомпилированный бинарь выгружается на
Artifactory.<o:p></o:p></span></li>
<li class="MsoNormal"><span lang="ru">Артефакт
публикуется на Artifactory в соответствующем продуктовом
snapshot-репозитории и сохраняется для последующего деплоя на тестовый
стенд, выполнения тестирования и остальных типовых этапов схемы сборки с
продвижениями, рассмотренной ранее.<o:p></o:p></span></li>
</ol><div><br /></div>
<h3 style="text-align: left;"><span lang="ru">Основные этапы методики внедрения
PT AI в CI</span></h3><h2 style="text-align: left;"><a name="_raagn1j81tle"></a></h2>
<p class="MsoNormal"><span lang="ru">Для упрощения работы CI-инженеров мы
подготовили небольшой список рекомендаций по внедрению и технической
эксплуатации серверной, клиентской и CI частей PT AI. Эти рекомендации можно
представить в виде шагов простой методики: подготавливаем серверную часть,
организуем релизный цикл для клиента AISA, подготавливаем проект сканирования
для AIE-сервера и начинаем работать со сканами в CI-системах.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYb4aiT9zfnUABV3tQEIsgCaPWWYkgty92yCBU_rUdO7kGTC0sm556gY3DRp-DHtnC_fDvp9l13IYUBaLE8EsmwOMUxlQjEMDgQ2O9t5PmcVB6wBB-UCO4GlGGB8cS_b-jPt595lbzWaD6/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="355" data-original-width="718" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYb4aiT9zfnUABV3tQEIsgCaPWWYkgty92yCBU_rUdO7kGTC0sm556gY3DRp-DHtnC_fDvp9l13IYUBaLE8EsmwOMUxlQjEMDgQ2O9t5PmcVB6wBB-UCO4GlGGB8cS_b-jPt595lbzWaD6/w640-h316/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Основные
этапы методики внедрения PT AI в CI<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru">Первая рекомендация, на которую стоит обратить
внимание: серверную часть Application Inspector Enterprise нужно разместить на
отдельной виртуальной машине. Это упростит её настройку, обновление и
мониторинг, чем если бы сканирующий сервер устанавливался на каждом сборочном
агенте, либо подтягивался туда докер-образом. В отличие от клиента AISA,
"оборачиваемого" в докер, с сервером мы так не делаем. По крайней
мере до тех пор, пока AIE-сервер не будет официально поставляться как
докер-образ.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Вторая рекомендация: поставляемые бинари
клиента AISA необходимо "обернуть" в докер-образы, версионировать их
и настроить релизный цикл с тестированием в вашей CI-системе. Это значительно
упростит CI-инженерам распространение AISA-клиента по сборочной инфраструктуре
и не придётся каждый раз устанавливать клиентскую часть на все сборочные агенты
— образ будет подтягиваться из docker registry по запросу во время сборок. А
также, при необходимости, можно будет быстро откатиться на предыдущие версии
AISA простой заменой тега latest для докер-образа.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Все это было сделано для того, чтобы чётко
отделить инфраструктурную часть PT AI от процесса разработки и сборки
продуктов. Наши CI-инженеры отвечают за сборочную инфраструктуру,
инфраструктуру сканирования и интеграцию с ней сборок, а разработчики должны
иметь простую возможность подключить свой код на анализ, работать только с
получаемыми от PT AI результатами и повышать безопасность и качество кода.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Далее рассмотрим техническую часть внедрения
PT Application Inspector в сборочный CI-конвейер и тиражирование нашего решения
со сканированием кода по продуктовым командам.<o:p></o:p></span></p><p class="MsoNormal"><span lang="ru"><br /></span></p>
<h2 style="text-align: left;"><span style="font-size: x-large;">Компоненты решения: сервер, клиент и интеграция с GitLab CI</span></h2><p style="text-align: left;"> </p><h3 style="text-align: left;"><span lang="ru">Серверная</span><span lang="ru"> </span><span lang="ru">часть</span><span lang="EN-US"> PT Application Inspector Enterprise<o:p></o:p></span></h3><h2 style="text-align: left;"><a name="_98yp5pee9xhd"></a></h2>
<p class="MsoNormal"><span lang="ru">PT Application Inspector Enterprise Server —
это сервис под Windows, который является агрегатором для сканируемого исходного
кода. Анализ кода выполняется на специальных агентах сканирования (workers),
которые получают задания от сервера аналогично, как и в CI-системах TeamCity,
GitLab CI или Jenkins. Настройки проектов сканирования хранятся на сервере.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Для упрощения работы с серверной частью в
нашем опенсорсе есть <a href="https://github.com/devopshq/dohq-ai-best-practices/tree/master/AIE_Server_installation"><span style="color: #1155cc;">установочный скрипт</span></a>. После установки доступ к
сервису осуществляется через веб-интерфейс или через специальный софт
Application Inspector Viewer.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVAH50UdfgbKppY5Nn6eLFlx87gQ0lRZwJIpOO19Q3B4TlanZqgkalgFmzyAi9ZgxAC9yRhd_Xk0oAydSCWOAabMpD7QzCmH4-UIE2xQW8MxR6y3KxyVmFD8WXaBWkF1EOGcDLYJJUvHXU/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="295" data-original-width="718" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVAH50UdfgbKppY5Nn6eLFlx87gQ0lRZwJIpOO19Q3B4TlanZqgkalgFmzyAi9ZgxAC9yRhd_Xk0oAydSCWOAabMpD7QzCmH4-UIE2xQW8MxR6y3KxyVmFD8WXaBWkF1EOGcDLYJJUvHXU/w640-h262/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Скриншот</span></i><i><span lang="ru" style="color: #333333; mso-ansi-language: EN-US;"> </span><span lang="ru" style="color: #333333;">веб</span></i><i><span lang="EN-US" style="color: #333333; mso-ansi-language: EN-US;">-</span><span lang="ru" style="color: #333333;">интерфейса</span></i><i><span lang="EN-US" style="color: #333333; mso-ansi-language: EN-US;"> PT Application Inspector Enterprise Server.<br />
</span><span lang="ru" style="color: #333333;">Вкладка со статистикой</span></i><span lang="ru" style="color: #333333;"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru" style="color: #333333;">Рекомендуемые на данный
момент характеристики сервера и агента представлены в таблице (они могут
измениться для новых версий и лучше смотреть официальную документацию).<o:p></o:p></span></p>
<table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="border-collapse: collapse; border: none; mso-border-alt: solid #B7B7B7 1.0pt; mso-border-insideh: 1.0pt solid #B7B7B7; mso-border-insidev: 1.0pt solid #B7B7B7; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-table-layout-alt: fixed; mso-yfti-tbllook: 1536; width: 718px;">
<tbody><tr style="height: 22pt; mso-yfti-firstrow: yes; mso-yfti-irow: 0;">
<td rowspan="6" style="background: rgb(153, 153, 153); border: 1pt solid rgb(183, 183, 183); height: 22pt; padding: 5pt; width: 150.75pt;" valign="top" width="201">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 10pt; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><b><span lang="ru" style="color: #333333; font-size: 10pt;"> </span></b></p>
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 10pt; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><b><span lang="ru" style="color: #333333; font-size: 10pt;"> </span></b></p>
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 10pt; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><b><span lang="ru" style="color: #333333; font-size: 10pt;">PT AI Enterprise Server<o:p></o:p></span></b></p>
</td>
<td style="border-left: none; border: 1pt solid rgb(183, 183, 183); height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">Процессор Intel
Core i7 с частотой 3,2 ГГц или аналоги<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 1;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">От 8 ГБ оперативной
памяти<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 2;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">От 200 ГБ на
жестком диске<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 3;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">Сетевой адаптер от
10 Мбит/с<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 4;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">64-разрядная версия
Windows Server 2012 R2 и выше<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 5;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">Средство
автоматизации Windows PowerShell версии 5.0 и выше<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 6;">
<td rowspan="4" style="background: rgb(153, 153, 153); border-top: none; border: 1pt solid rgb(183, 183, 183); height: 22pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 150.75pt;" valign="top" width="201">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 10pt; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><b><span lang="ru" style="color: #333333; font-size: 10pt;"> </span></b></p>
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 10pt; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><b><span lang="ru" style="color: #333333; font-size: 10pt;">PT AI Enterprise Agent<o:p></o:p></span></b></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">Процессор Intel
Core i7 с частотой 3,2 ГГц или аналоги<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 7;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">От 8 ГБ оперативной
памяти<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 8;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">Сетевой адаптер от
10 Мбит/с<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 22pt; mso-yfti-irow: 9; mso-yfti-lastrow: yes;">
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 22pt; mso-border-left-alt: solid #B7B7B7 1.0pt; mso-border-top-alt: solid #B7B7B7 1.0pt; padding: 5pt; width: 387.75pt;" valign="top" width="517">
<p class="MsoNormal" style="border: none; line-height: normal; margin-top: 0cm; mso-border-shadow: yes; mso-padding-alt: 31.0pt 31.0pt 31.0pt 31.0pt; mso-pagination: none;"><span lang="ru" style="color: #333333; font-size: 10pt;">Браузер: Microsoft
Edge, Mozilla Firefox 46 и выше, Google Chrome 50 и выше<o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p style="text-align: left;"><span lang="ru"> </span></p><h3 style="text-align: left;"><span lang="ru">Релизный CI-цикл для AISA-клиента</span></h3><h2><a name="_cdbjed1pakk2"></a></h2>
<p class="MsoNormal"><span lang="ru">Относительно нашей сборочной инфраструктуры
клиент AISA, который разрабатывает команда PT AI, является 3rd-party — внешним
инструментом. Поэтому, прежде чем начать его использовать в CI-конвейере и
ничего не поломать при этом, мы организовали для него стандартный <a href="https://github.com/devopshq/dohq-ai-best-practices#%D1%86%D0%B8%D0%BA%D0%BB-%D1%80%D0%B5%D0%BB%D0%B8%D0%B7%D0%BD%D0%BE%D0%B9-%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B8-application-inspector-shell-agent-%D0%B2-docker"><span style="color: #1155cc;">релизный цикл сборки в докере</span></a>, интеграционное
тестирование на сборочной инфраструктуре и продвижение в релиз. После
тестирования клиент возможно использовать в сборках других продуктов.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxbQYKZN2DsKzeK5ovBzjszUeKNialLs0PAaEl3z-Gr35SL2bIg5TlDVJb0wocmEVdgQvEw91hjeVOW2iH2g1qJJsjTwToUnzwKVFQYTo3OmDE4DhqItOIo2pOwOmFvf8l4aG4p0l552pv/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="775" data-original-width="718" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxbQYKZN2DsKzeK5ovBzjszUeKNialLs0PAaEl3z-Gr35SL2bIg5TlDVJb0wocmEVdgQvEw91hjeVOW2iH2g1qJJsjTwToUnzwKVFQYTo3OmDE4DhqItOIo2pOwOmFvf8l4aG4p0l552pv/w592-h640/image.png" width="592" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Алгоритм
реализации CI-схемы для сборки AISA-клиента в Docker</span></i><span lang="ru" style="color: #333333;"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Первый этап релизного цикла для AISA включает
в себя одновременную сборку двух докер-образов под Linux и Windows, установку в
них новой версии клиента AISA и выкладку образов в корпоративный docker
registry на Artifactory. В качестве тега для докер-образов мы используем
текущую версию клиента AISA и дополнительный билд-номер сборки докера.
Например, 3.6.1.4931-7 означает, что используется седьмая сборка докер-образа,
внутри которого установлена версия AISA 3.6.1.4931.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Второй этап — маркировка докер-образов тегом
latest. Для нас это означает, что образы можно "продвинуть"
(promoting) из snapshot-репозитория в release-репозиторий и начать использовать
в общем корпоративном сборочном конвейере. Но до того необходимо успешно пройти
третий этап приёмочного тестирования, где проверяется возможность сделать
docker pull образов из docker registry, тестируются различные способы запуска
клиента внутри докера и насколько корректно он взаимодействует с текущей
версией AIE-сервера. После тестирования докер-образы маркируются
дополнительными атрибутами, с так называемыми метками качества, и уже потом их
можно "продвигать" в релиз.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">После продвижения докер-образы с новой версией
клиента AISA доступны для использования в сборках продуктов. Клиент
предназначен для того, чтобы отправлять исходный код на сервер AIE, а также он
может создавать и настраивать на сервере проекты сканирования и получать по ним
отчёты. Кроме клиента мы добавляем в докер различные <a href="https://github.com/devopshq/dohq-ai-best-practices#%D1%83%D1%82%D0%B8%D0%BB%D0%B8%D1%82%D1%8B-%D0%B8-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F"><span style="color: #1155cc;">вспомогательные утилиты</span></a>.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCTuS5pFbaPp_QOL_Bi_gKZo04zYx_9BO9OpJ-ncwEcJsx9hsp1gPTolrV7EF34vMxQIxIZzowhuRhk6eZsA3ygIFxM79iL22gm-AXN1PMXVi1bZD9YtYN7NBWrQkU2WHwIGbJ0nHHhla_/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="69" data-original-width="718" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCTuS5pFbaPp_QOL_Bi_gKZo04zYx_9BO9OpJ-ncwEcJsx9hsp1gPTolrV7EF34vMxQIxIZzowhuRhk6eZsA3ygIFxM79iL22gm-AXN1PMXVi1bZD9YtYN7NBWrQkU2WHwIGbJ0nHHhla_/w640-h62/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Скриншот
с примером запуска AISA-клиента в консоли<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru" style="color: #333333;">В таблице приведены
примеры аргументов: ключей и значений для запуска AISA (они также могут
измениться в новых версиях и лучше смотреть официальную документацию).<o:p></o:p></span></p>
<table border="0" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="border-collapse: collapse; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-table-layout-alt: fixed; mso-yfti-tbllook: 1536; width: 719px;">
<tbody><tr style="height: 35.25pt; mso-yfti-firstrow: yes; mso-yfti-irow: 0;">
<td style="background: rgb(153, 153, 153); border: 1pt solid rgb(183, 183, 183); height: 35.25pt; mso-border-alt: solid #B7B7B7 .75pt; padding: 5pt 11pt 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 10pt;"><b><span lang="ru" style="font-size: 10pt;">Параметр
запуска<o:p></o:p></span></b></p>
</td>
<td style="background: rgb(153, 153, 153); border-left: none; border: 1pt solid rgb(183, 183, 183); height: 35.25pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; padding: 5pt 11pt 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 10pt;"><b><span lang="ru" style="font-size: 10pt;">Описание<o:p></o:p></span></b></p>
</td>
<td style="background: rgb(153, 153, 153); border-left: none; border: 1pt solid rgb(183, 183, 183); height: 35.25pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; padding: 5pt 11pt 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 10pt;"><b><span lang="ru" style="font-size: 10pt;">Обязательный
параметр?<o:p></o:p></span></b></p>
</td>
</tr>
<tr style="height: 33pt; mso-yfti-irow: 1;">
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); height: 33pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--project-name<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 33pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Название проекта (регистронезависимо), который надо
просканировать. Проект должен быть создан на сервере AIE на момент запуска
сканирования.<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Пример значения: </span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">DevOps_Sandbox</span><span lang="ru" style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 33pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Да, при отсутствии ключа<br /></span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--project-settings-file<o:p></o:p></span></p>
</td>
</tr>
<tr>
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--project-settings-file<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Путь к файлу с настройками проекта<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Пример: </span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">Test.aiproj</span><span lang="ru" style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Да, при отсутствии ключа<br /></span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--project-name<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 20.25pt; mso-yfti-irow: 3;">
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); height: 20.25pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--policies-path<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 20.25pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Путь к файлу с описанием политик.<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Пример значения: </span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">./policy.json</span><span lang="ru" style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 20.25pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Нет<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 20.35pt; mso-yfti-irow: 4;">
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); height: 20.35pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--scan-target<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 20.35pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Путь к каталогу или файлу приложения для
сканирования.<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Пример значения: </span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">source/folder</span><span lang="ru" style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 20.35pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Да<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 29.35pt; mso-yfti-irow: 5;">
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); height: 29.35pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--reports-folder<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 29.35pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Путь к каталогу, куда будут сохранены файлы отчетов.<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Пример значения: </span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">.ptai</span><span lang="ru" style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 29.35pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Нет<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 35.1pt; mso-yfti-irow: 6;">
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); height: 35.1pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--reports<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 35.1pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Типы отчетов, создаваемых по окончании сканирования.
Может принимать одно или несколько значений через запятую: HTML, PDF, JSON,
WAF<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Пример значения: </span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">"HTML,JSON"</span><span lang="ru" style="font-size: 10pt;"><o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 35.1pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Нет<o:p></o:p></span></p>
</td>
</tr>
<tr style="height: 15.75pt; mso-yfti-irow: 7;">
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); height: 15.75pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--no-wait<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 15.75pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Отключает ожидание результатов сканирования,
значительно сокращает время работы<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; height: 15.75pt; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Нет<o:p></o:p></span></p>
</td>
</tr>
<tr>
<td style="border-top: none; border: 1pt solid rgb(183, 183, 183); mso-border-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 156.75pt;" valign="top" width="209">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--scan-off<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 228pt;" valign="top" width="304">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Отключает сканирование на AIE сервере, используется
для создания проекта (в паре с аргументом
</span><span lang="ru" style="font-family: "Courier New"; font-size: 10pt; mso-fareast-font-family: "Courier New";">--project-settings-file</span><span lang="ru" style="font-size: 10pt;">)<o:p></o:p></span></p>
</td>
<td style="border-bottom: 1pt solid rgb(183, 183, 183); border-left: none; border-right: 1pt solid rgb(183, 183, 183); border-top: none; mso-border-alt: solid #B7B7B7 .75pt; mso-border-left-alt: solid #B7B7B7 .75pt; mso-border-top-alt: solid #B7B7B7 .75pt; padding: 5pt 8pt; width: 154.5pt;" valign="top" width="206">
<p class="MsoNormal" style="line-height: normal; margin-top: 3pt;"><span lang="ru" style="font-size: 10pt;">Нет<o:p></o:p></span></p>
</td>
</tr>
</tbody></table>
<p style="text-align: left;"><span lang="ru"> </span></p><h3 style="text-align: left;"><span lang="ru">Внедрение PT AI в GitLab CI</span></h3><h2><a name="_tj11691kocfg"></a></h2>
<p class="MsoNormal"><span lang="ru">Мы показали архитектуру размещения AIE-сервера
и шаги изменённого сборочного процесса, с учётом новых шагов сканирования. Этот
процесс не зависит от CI-системы. Однако для простоты рассмотрим его пошаговую
реализацию <a href="https://github.com/devopshq/dohq-ai-best-practices#%D1%82%D0%B8%D0%BF%D0%BE%D0%B2%D1%8B%D0%B5-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BE%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B8-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%BE%D0%B2-%D0%BD%D0%B0-%D1%81%D0%BA%D0%B0%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%B2-aie"><span style="color: #1155cc;">на примере шаблонов GitLab CI</span></a>.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcdfieMLaeKVgbuX50h8LoJ73Ovksf4_-bYUnU_2qk3qhSdCIw3XCXPbfVP5QYVXBuQ7QRtPV_eaPLYWBBElu5mKzwLPWIMgveJ7SakSL3WO5h_2FSrsO2N7fzVA6ScFY8pQ_8mcgjdQit/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="927" data-original-width="718" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcdfieMLaeKVgbuX50h8LoJ73Ovksf4_-bYUnU_2qk3qhSdCIw3XCXPbfVP5QYVXBuQ7QRtPV_eaPLYWBBElu5mKzwLPWIMgveJ7SakSL3WO5h_2FSrsO2N7fzVA6ScFY8pQ_8mcgjdQit/w496-h640/image.png" width="496" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Алгоритм
сборочного процесса в GitLab CI с учётом шагов сканирования через AISA</span></i><span lang="ru" style="color: #333333;"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Сборочные шаги в GitLab CI описываются
отдельными задачами (job) в специальном файле <a href="https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html"><span style="color: #1155cc; font-family: "Courier New"; mso-fareast-font-family: "Courier New";">.gitlab-ci.yml</span></a>. При запуске задачи на сканирование
сначала происходит загрузка исходного кода на CI-агент. Затем, в зависимости от
операционной системы, скачивается Linux или Windows докер-образ с клиентом
AISA.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Для генерации проекта сканирования у нас
используется утилита <a href="https://github.com/devopshq/dohq-ai-best-practices#aisa-set-settings"><span style="color: #1155cc; font-family: "Courier New"; mso-fareast-font-family: "Courier New";">aisa-set-settings</span></a>. Она создаёт специальный файл </span><span lang="ru" style="font-family: "Courier New"; mso-fareast-font-family: "Courier New";">.aiproj</span><span lang="ru"> с настройками проекта, которые AISA отправляет на сервер. Запуск
утилиты не основная операция, поэтому мы разместили её в секции </span><span lang="ru" style="font-family: "Courier New"; mso-fareast-font-family: "Courier New";">before_script</span><span lang="ru">.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Основная секция начинается с запуска утилиты <a href="https://github.com/devopshq/dohq-ai-best-practices#aisa"><span style="color: #1155cc; font-family: "Courier New"; mso-fareast-font-family: "Courier New";">aisa</span></a> и передачи ей необходимых параметров. В случае,
если проект на AIE-сервере был заранее создан, можно использовать ключ </span><span lang="ru" style="font-family: "Courier New"; mso-fareast-font-family: "Courier New";">--project-name</span><span lang="ru"> для отправки исходного кода сразу в него. Если проект не существует,
что чаще всего и бывает, то нужно использовать ключ </span><span lang="ru" style="font-family: "Courier New"; mso-fareast-font-family: "Courier New";">--project-settings-file</span><span lang="ru"> с указанием имени файла настроек проекта. AISA создаст проект на
сервере и код начнёт сканироваться. При повторном запуске настройки обновятся.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Информация о ходе сканирования попадает в лог
сборки и получить отчёт возможно в виде артефакта нужного формата, например
HTML и JSON. Если не нужно ждать полного завершения скана, можно
воспользоваться ключом </span><span lang="ru" style="font-family: "Courier New"; mso-fareast-font-family: "Courier New";">--no-wait</span><span lang="ru">, с
помощью которого работа AISA будет завершена сразу же после отправки исходников
на сервер. Отчёты при этом получены не будут, но их всегда можно посмотреть
через веб-клиент на AIE-сервере.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzV6Yub8Q5B1OfGYh4Uc1PSJsx4W3QGgjXHkrFo897vn0gEp1DqNEiRC6YhZuJT7HGGK00_Ld11enD3qiyiRaJdFENwjoO_EtyfQRvWIE6tSyBnUrD8HvHewW-oPUCktxdjpSAVGYsh7Me/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="554" data-original-width="650" height="545" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzV6Yub8Q5B1OfGYh4Uc1PSJsx4W3QGgjXHkrFo897vn0gEp1DqNEiRC6YhZuJT7HGGK00_Ld11enD3qiyiRaJdFENwjoO_EtyfQRvWIE6tSyBnUrD8HvHewW-oPUCktxdjpSAVGYsh7Me/w640-h545/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Пример
шаблона сканирования для GitLab CI с реализацией описанного выше алгоритма<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru">Остаётся вопрос с местом хранения файлов для
настройки проектов сканирования. Их можно подготовить заранее и хранить в
продуктовых git-репозиториях. Но для себя мы выбрали способ, который предлагаем
и вам, — всегда генерировать файл с настройками через утилиту </span><span lang="ru" style="font-family: "Courier New"; mso-fareast-font-family: "Courier New";">aisa-set-settings</span><span lang="ru">. В таком случае потребность в хранении файла отпадает и становится
проще тиражировать шаги сканирования в сборочные шаблоны команд.<i><span style="color: #333333;"><o:p></o:p></span></i></span></p>
<p class="MsoNormal"><span lang="ru">Мы разделяем шаблоны сканирования на две
категории — базовые типовые и продуктовые. Они очень похожи, но несут в себе
различную функциональность.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Базовые типовые шаблоны сканирования — стандартные,
редко изменяемые, их сопровождают CI-инженеры. Эти шаблоны можно быстро и легко
подключить в любых сборочных шаблонах. Они имеют минимальные настройки для
начала сканирования кода.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQSab8RD0x9DTLZ6QCeL25CQEc1pIBwkm9ONoYAws3PbCmDcLMJxA9y3hjjwGEZEz7b4fKS7rES7pVOzkOf9QVSqL4nzRYA39K-yMyE7wA_4afRh_feubRBTlX9JHeGUgfEIHogaMS-aVp/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="256" data-original-width="718" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQSab8RD0x9DTLZ6QCeL25CQEc1pIBwkm9ONoYAws3PbCmDcLMJxA9y3hjjwGEZEz7b4fKS7rES7pVOzkOf9QVSqL4nzRYA39K-yMyE7wA_4afRh_feubRBTlX9JHeGUgfEIHogaMS-aVp/w640-h228/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Примеры
шаблонов: для существующего проекта (слева) и для проекта, который будет создан
при запуске сканирования (справа)<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru">Продуктовые шаблоны сканирования создаются под
нужды конкретной команды разработчиков. Настройки в них можно кастомизировать:
указать действия после получения отчёта, например, отправить его по почте или
сохранить в хранилище для дальнейшего анализа, запустить внешнюю утилиту <a href="https://github.com/devopshq/dohq-ai-best-practices#aisa-codequality"><span style="color: #1155cc; font-family: "Courier New"; mso-fareast-font-family: "Courier New";">aisa-codequality</span></a></span><span lang="ru" style="font-family: "Courier New"; mso-fareast-font-family: "Courier New";"> </span><span lang="ru">и экспортировать отчёт в мерж-реквест для GitLab или выполнить любые
другие сценарии разработчиков.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie8C4x8JxUphqOeCND5676T17StXJlDyON1LbrzkdR2FGdP9KqspUDCYK-mZfb_eBhDl-uNH1IhHGQVyE4imA5sq4A8Z_6BuTpUpP6nB30QXLvrXE2nXC1jV9t4fm14ZTqDLfCnlURJsRC/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="575" data-original-width="626" height="589" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie8C4x8JxUphqOeCND5676T17StXJlDyON1LbrzkdR2FGdP9KqspUDCYK-mZfb_eBhDl-uNH1IhHGQVyE4imA5sq4A8Z_6BuTpUpP6nB30QXLvrXE2nXC1jV9t4fm14ZTqDLfCnlURJsRC/w640-h589/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Пример
кастомного продуктового шаблона<o:p></o:p></span></i></p>
<p class="MsoNormal"><span lang="ru">На следующем скриншоте можно увидеть ключевое
решение, ради которого всё и затевалось, — <b>тиражирование
шаблонов сканирования в продуктовые шаблоны "в пару строчек кода"</b>.
Здесь указана достаточно простая конструкция: в сборочном проекте подключаем
через <a href="https://docs.gitlab.com/ee/ci/yaml/includes.html"><span style="color: #1155cc; font-family: "Courier New"; mso-fareast-font-family: "Courier New";">include</span></a> ссылку на шаблон сканирования и задаём
необходимые переменные, в частности, основной язык программирования.
Подключаемый шаблон должен находиться в публичном репозитории на GitLab.<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0DScJowMPGnWhReQTamDBpr-0Mf2zvB4P5LCUsycOfuJDL6GCmLdQbqULkQDRe6yjRaU1pHbOHGGxl3j4IogQdBJ8hIbnpQOlV1sLlBtoeb3eC3jwfzNm_cMrtyn2q4SzApla36XaKCBg/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="313" data-original-width="718" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0DScJowMPGnWhReQTamDBpr-0Mf2zvB4P5LCUsycOfuJDL6GCmLdQbqULkQDRe6yjRaU1pHbOHGGxl3j4IogQdBJ8hIbnpQOlV1sLlBtoeb3eC3jwfzNm_cMrtyn2q4SzApla36XaKCBg/w640-h278/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Пример
подключения шаблона сканирования в проекты на GitLab CI</span></i></p><p class="MsoNormal">Сам процесс сканирования и получения отчетов от PT AI не требует от наших разработчиков понимания того, как работает инфраструктура сканирования и PT Application Inspector. CI-инженер или сами программисты вставляют одну строчку кода — "а дальше оно само".</p><p class="MsoNormal">Для интеграции PT AI с CI-системой TeamCity
можно использовать так называемые <a href="https://forworktests.blogspot.com/2014/06/teamcity.html"><span style="color: #1155cc;">метараннеры</span></a>. Примеры разработанных нами <a href="https://github.com/devopshq/dohq-ai-best-practices/tree/master/TeamCity_meta-runners"><span style="color: #1155cc;">метараннеров под Linux и Windows</span></a> при помощи
python-скрипта выкачивают нужный докер-образ с клиентом AISA и он запускается с
заданными аргументами.</p>
<p class="MsoNormal" style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwEolxaMDa23oV9jMeXP07IFDIGEzNOQLvwhBUvLFyDtdOF2fqzPSMCdMXaFrq6KyYaHmxQKHVOlyjl1GbukXyERwaTwLEx9W3tAJjS9t4ywvquExG24Y0u2gP4pAOtnPr6o25HvmNv2Jw/" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="552" data-original-width="718" height="492" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwEolxaMDa23oV9jMeXP07IFDIGEzNOQLvwhBUvLFyDtdOF2fqzPSMCdMXaFrq6KyYaHmxQKHVOlyjl1GbukXyERwaTwLEx9W3tAJjS9t4ywvquExG24Y0u2gP4pAOtnPr6o25HvmNv2Jw/w640-h492/image.png" width="640" /></a></div><p></p>
<p align="center" class="MsoNormal" style="margin-top: 0cm; text-align: center;"><i><span lang="ru" style="color: #333333;">Пример
интерфейса TeamCity-метараннера для запуска сканирования под Linux</span></i><span lang="ru"><o:p></o:p></span></p>
<h2 style="text-align: left;"><span style="font-size: x-large;">Open Source dohq-ai-best-practices</span></h2><p class="MsoNormal"><span lang="ru">Всю документацию, схемы и наработки для CI мы
выложили в опенсорс в проект <a href="https://github.com/devopshq/dohq-ai-best-practices"><span style="color: #1155cc;">dohq-ai-best-practices</span></a> под свободной
MIT-лицензией.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Там вы найдёте:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l10 level1 lfo6; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">подробное описание и схемы для
рекомендуемой методики внедрения PT AI в CI;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l10 level1 lfo6; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">скрипты инсталляции и рекомендации
по настройке серверной части PT Application Inspector Enterprise;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l10 level1 lfo6; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">примеры dockerfile для сборки
AISA-клиента под Windows и Linux;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l10 level1 lfo6; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">примеры шаблонов для шагов запуска
сканирования кода через AISA:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 72pt; mso-list: l10 level2 lfo6; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US" style="color: #333333; font-size: 10.5pt; line-height: 130%; mso-ansi-language: EN-US;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="EN-US">job-</span><span lang="ru">ы</span><span lang="ru"> </span><span lang="ru">для</span><span lang="EN-US"> GitLab CI,<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 72pt; mso-list: l10 level2 lfo6; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">метараннеры для TeamCity,<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 72pt; mso-list: l10 level2 lfo6; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru" style="color: #333333; font-size: 10.5pt; line-height: 130%;">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">команды для работы с CLI AISA.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Этим опенсорс-проектом мы хотели обобщить все
знания и навыки наших DevOps-инженеров, полученные при внедрении и эксплуатации
PT Application Inspector внутри компании, а также дать рекомендации, как можно
упростить внедрение сканера кода в сборочные процессы, построенные на базе
любой CI-системы. Ваши инженеры могут без ограничений воспользоваться этими
наработками.<o:p></o:p></span></p><p class="MsoNormal"><span lang="ru"><br /></span></p>
<h3 style="text-align: left;"><span lang="ru">Вебинар</span></h3><h2><a name="_qx65iathp1r2"></a></h2>
<p class="MsoNormal"><span lang="ru">В начале декабря 2020 наша компания проводила <a href="https://www.ptsecurity.com/ru-ru/research/webinar/devsecops-vnedrenie-v-produktovyj-konvejer-i-ehkspluataciya-pt-application-inspector/"><span style="color: #1155cc;">вебинар</span></a> для CI-инженеров, инженеров по
инфраструктуре и специалистов DevSecOps по теме внедрения PT Application
Inspector. <span>Мы <a href="https://youtu.be/DIJKIpQ4UXw?t=6" target="_blank">рассказали</a></span><a href="https://youtu.be/DIJKIpQ4UXw?t=6" target="_blank"> и показали, как развернуть и
эксплуатировать PT AI в сборочном конвейере</a> с учетом особенностей корпоративной
инфраструктуры (можно посмотреть только <span>демонстрацию
решения</span> на 39:45).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Из него вы узнаете: что умеет PT Application
Inspector "из коробки", о способах его интеграции в процессы
разработки, в том числе, как подготовить серверную часть Application Inspector
Enterprise и как удобно настроить взаимодействие с сервером при помощи
клиентской утилиты AISA. На вебинаре даны рекомендации для DevSecOps-инженеров
по работе с AIE-сервером и AISA. Особенно полезно это будет тем инженерам,
которые уже внедряют PT Application Inspector в сложившиеся инфраструктуру и
процессы разработки в своей компании.</span></p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="406" src="https://www.youtube.com/embed/DIJKIpQ4UXw" width="489" youtube-src-id="DIJKIpQ4UXw"></iframe></div><h3 style="text-align: left;"><span lang="ru">Ссылки</span></h3><h2><a name="_1rpp46xa9h5r"></a></h2>
<p class="MsoNormal"><span lang="ru">Упоминаемые в статье ссылки:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l7 level1 lfo7; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">PT Application Inspector
Анализатор и сканер кода для поиска уязвимостей:<br />
<a href="https://www.ptsecurity.com/ru-ru/products/ai/"><span style="color: #1155cc;">ptsecurity.com/ru-ru/products/ai/</span></a><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l7 level1 lfo7; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru">Записи вебинаров Positive
Technologies:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 72pt; mso-list: l7 level2 lfo7; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span lang="ru">про</span><span lang="ru"> </span><span lang="ru">инструмент</span><span lang="EN-US"> PT
Application Inspector:<br />
</span><span lang="ru"><a href="https://www.ptsecurity.com/ru-ru/research/webinar/pt-application-inspector-obzor-novoy-versii-i-roadmap/"><span lang="EN-US" style="color: #1155cc; mso-ansi-language: EN-US;">ptsecurity.com/ru-ru/research/webinar/pt-application-inspector-obzor-novoy-versii-i-roadmap/</span></a></span><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 72pt; mso-list: l7 level2 lfo7; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span lang="ru">про</span><span lang="ru"> </span><span lang="ru">внедрение</span><span lang="EN-US"> PT
Application Inspector </span><span lang="ru">в</span><span lang="ru"> </span><span lang="EN-US">CI-</span><span lang="ru">процессы</span><span lang="EN-US">:<br />
</span><span lang="ru"><a href="https://www.ptsecurity.com/ru-ru/research/webinar/devsecops-vnedrenie-v-produktovyj-konvejer-i-ehkspluataciya-pt-application-inspector/"><span lang="EN-US" style="color: #1155cc; mso-ansi-language: EN-US;">ptsecurity.com/ru-ru/research/webinar/devsecops-vnedrenie-v-produktovyj-konvejer-i-ehkspluataciya-pt-application-inspector/</span></a></span><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l7 level1 lfo7; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span lang="ru">Опенсорс</span><span lang="ru"> </span><span lang="ru">с</span><span lang="ru"> </span><span lang="ru">методикой</span><span lang="ru"> </span><span lang="ru">внедрения</span><span lang="ru"> </span><span lang="ru">и</span><span lang="ru"> </span><span lang="ru">примерами</span><span lang="ru"> </span><span lang="ru">скриптов</span><span lang="ru"> </span><span lang="ru">и</span><span lang="ru"> </span><span lang="ru">шаблонов</span><span lang="ru"> </span><span lang="ru">для</span><span lang="EN-US"> GitLab CI:<br />
</span><span lang="ru"><span lang="EN-US" style="color: #1155cc; mso-ansi-language: EN-US;"><a href="https://github.com/devopshq/dohq-ai-best-practices">github.com/devopshq/dohq-ai-best-practices</a></span></span><span lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin-left: 36pt; mso-list: l7 level1 lfo7; text-indent: -18pt;"><span lang="ru"><br /></span></p>
<h3 style="text-align: left;"><span lang="ru">Итоги</span></h3><h2><a name="_xg5dulijllua"></a></h2>
<p class="MsoNormal"><span lang="ru">Итак, мы
рассказали о нашем первом опыте эксплуатации PT Application Inspector и
его внедрении в реальный сборочный процесс. Также мы предложили максимально
упрощённую <a href="https://github.com/devopshq/dohq-ai-best-practices#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%B8%D0%BA%D0%B0-%D0%B2%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D1%8F-pt-ai-%D0%B2-ci"><span style="color: #1155cc;">архитектуру и методику внедрения PT AI в CI</span></a>.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Основные рекомендации на данный момент
заключаются в том, чтобы "обернуть" клиента AISA в докер-образ,
разместить серверную часть Application Inspector Enterprise на отдельной
виртуальной машине и добавить в свой сборочный проект шаблоны для запуска
сканирования кода через AISA-клиент. Подключать проекты на сканирование при
этом возможно в пару строчек кода. Один-два CI-инженера средней квалификации
смогут разобраться, что к чему в нашей методике, и повторить аналогичный
процесс в своей компании. <a href="https://youtu.be/Qg-SmDpMSQ4?t=2385"><span style="color: #1155cc;">Демо</span></a>, показанное на вебинаре, это то, как
работает PT AI на данный момент в CI-конвейере у нас в компании.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru">Конечно, всё рассказать в одной статье
невозможно. В следующих статьях покажем, как именно и какие результаты
сканирования и найденные уязвимости блокируют выпуск наших релизов, а также как
разработчики работают с PT Application Inspector.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ru"> </span></p>
<p class="MsoNormal"><b><span lang="ru">Авторы
статьи</span></b><span lang="ru">,<b> </b>разработчики
архитектуры, методики и скриптов интеграции для PT AI:<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l3 level1 lfo9; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru"><a href="https://www.linkedin.com/in/tgilmullin/"><span style="color: #1155cc;">Тимур
Гильмуллин</span></a> — заместитель руководителя отдела технологий и процессов
разработки в Positive Technologies,<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 36pt; mso-list: l3 level1 lfo9; text-indent: -18pt;"><!--[if !supportLists]--><span lang="ru">●<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span lang="ru"><a href="https://www.linkedin.com/in/dmitry-ragulin-756a5215a/"><span style="color: #1155cc;">Дмитрий Рагулин</span></a> — CI-инженер отдела технологий
и процессов разработки.</span></p><p></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-74393255251819128162020-09-01T18:24:00.002+03:002020-09-03T17:37:49.515+03:00Чем занимается DevOps-инженер в команде современных разработчиков<p></p><p class="MsoNormal" style="mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-align: justify;"><span face="" style="font-size: 14pt;">Вышла
моя новая статья в журнале TProger. В ней я рассказал о роли DevOps-инженера,
чего мы добились в нашей компании, используя принципы DevOps, и немного про
инструментарий. Только личный опыт.<o:p></o:p></span></p><p class="MsoNormal" style="mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-align: justify;"><span face="" style="font-size: 14pt;">Ключевая
мысль статьи:<o:p></o:p></span></p><p class="MsoNormal" style="mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-align: justify;">
</p><p class="MsoNormal"><span face="" style="font-size: 14pt;"></span></p><blockquote>«<i>В
отличие от классических сисадминов мы не работаем по шаблонам и инструкциям
24×7×365, мы не техподдержка, в наши обязанности не входят поддержка «железной»
части инфраструктуры и круглосуточное обеспечение работоспособности серверов. Я
предлагаю считать DevOps-инженеров современными инженерами-технологами в
производстве ПО. Такие специалисты квалифицированно решают не только задачи
своей роли, но и видят весь производственный конвейер целиком, понимают, как
результаты их работы будут использованы далее и интегрированы в общую
производственную цепочку.</i>»</blockquote><o:p></o:p><p></p><p class="MsoNormal"><span style="font-size: 14pt;"></span></p><o:p></o:p><p></p>
<p style="text-align: justify;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"><span></span></span></p><a name='more'></a><p style="text-align: justify;"><span face="" style="font-size: 15pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">Говоря о DevOps-инженерах, важно охватить весь спектр решаемых ими
задач. Вообще сам термин «DevOps-инженер» следует использовать только с
привязкой к конкретной предметной области, иначе получится как с
программистами: говорят «он работает программистом», а подразумевают под этим и
веб-дизaйнера, и специалиста по базам данных, и программиста C++. Для меня
DevOps — это набор методологий, лучших практик, технологий и инструментов
разработки ПО. Инженер, работающий по принципам DevOps, может обладать широким
кругозором в различных направлениях: continuous integration, continuous
delivery, build, deploy, test, </span><span face="" lang="" style="font-size: 15pt; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">SCM</span><span face="" style="font-size: 15pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">,
infrastructure, monitoring, но может быть и узкоспециализированным
специалистом, например только в области мониторинга или сбора телеметрии от
продуктов.<o:p></o:p></span></p><p></p>
<h1 style="text-align: justify;"><span face=""><span style="font-size: x-large;">О роли
DevOps-инженера</span></span></h1>
<p style="text-align: justify;"><span face="" style="font-size: 14pt;">Роль DevOps-инженера сильно зависит от специфики
задач, решаемых конкретной командой. Если команда занимается разработкой
веб-приложений, то скорее всего, ей потребуется инженер по деплою продуктов на
staging- и production-серверы. Если команда — это специалисты по тестированию
ПО, то DevOps-инженер может заниматься у них инфраструктурными задачами,
например помогать с развертыванием виртуальных стендов для тестирования и
доставкой тестируемого приложения и тестов на эти стенды. Если это SCM-команда,
занимающаяся развертыванием ПО в инфраструктуре конечного заказчика,
DevOps-инженеры могут взять на себя задачи, связанные с доставкой компонентов
продукта до серверов заказчика, а также заняться разработкой сценариев
развертывания ПО, мониторингом продукта и сбором телеметрии.</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;">Для
примера, специфика работы нашей компании, вендора в области <a href="https://www.ptsecurity.com/ru-ru/products/" target="_blank">инновационных
решений информационной безопасности</a>, накладывает на наш отдел автоматизации
(неформально называемый DevOps-отделом) обязанность поддерживать работу всего
конвейера производства ПО и сопутствующую инфраструктуру, начиная от сборки
отдельных компонентов и инсталляторов продуктов до их отправки на тестирование
и доставки на серверы обновлений и затем в инфраструктуру
заказчиков. Несмотря на огромный объем технических задач, с ними
справляются полтора десятка человек, при этом количество разработчиков в
R&D, с которыми мы работаем, — несколько сотен.</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;">DevOps
в современном IT уже давно выделился в самостоятельную инженерную дисциплину —
очень динамичную и технологичную. Ключевым принципом для DevOps-инженеров
является принцип DevOps as a service. Мы должны оперативно приносить новые
технологии нашим разработчикам и тестировщикам и поддерживать работу старых,
проверенных временем сервисов. Кроме того, мы делаем труд разработчиков более
комфортным, эффективным и продуктивным. Также мы разрабатываем внутренние
вспомогательные инструменты, регламентируем и автоматизируем процессы
разработки, сохраняем и распространяем технологические знания внутри компании,
проводим технические воркшопы, митапы и делаем еще много всего полезного.</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;">В
отличие от классических сисадминов мы не работаем по шаблонам и инструкциям 24×7×365,
мы не техподдержка, в наши обязанности не входят поддержка «железной» части
инфраструктуры и круглосуточное обеспечение работоспособности серверов. Я
предлагаю считать DevOps-инженеров современными инженерами-технологами в
производстве ПО. Такие специалисты квалифицированно решают не только задачи
своей роли, но и видят весь производственный конвейер целиком, понимают, как
результаты их работы будут использованы далее и интегрированы в общую
производственную цепочку.</span><span face="" style="text-align: left;"> </span></p>
<h1 style="text-align: left;"><span face=""><span style="font-size: x-large;">Чего мы
добились, используя принципы DevOps</span></span></h1>
<p class="MsoNormal"><span face="" style="font-size: 14pt;">Основное, чего мы добились для бизнеса, работая по
принципам DevOps, — это тиражируемость технологических решений. В</span><span face="" style="color: #222222; font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">се решения, которые мы предоставляем, типовые, масштабируемые и
построены на шаблонах. Для всех проектов общая концепция процесса CI/CD
остается неизменной: выполняются </span><span face="" style="font-size: 14pt;">коммит в git и
автоматическая сборка (building) — деплой на тестовые серверы (deploying) —
функциональное и прочие виды автотестирования (testing) — продвижение сборки в
стабильные (promoting) — публикация на GUS (publishing) — распространение через
FUS на инфраструктуре заказчика (delivering) — установка или обновление
продукта на серверах </span><span face="" style="color: #222222; font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">(installing & updating)</span><span face="" style="font-size: 14pt;">.</span><span face="" style="mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"><o:p></o:p></span></p>
<p align="center" style="text-align: center;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"><o:p></o:p></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY9-lCI8bS7NkrwhftPAQthCzx158-oPbJPDCZo-2_wvXVesmZqrldNVqFFzcp0KOiZqygTVSkXdIOvxkj5ftn7yHNvyWZkAia9VE9zd4HHS5Wp-8Wd8CmT_6YSz59xKSNmay615MKb4f1/s1600/devops_main_process.png" style="margin-left: 1em; margin-right: 1em;"><img alt="IDEF0-схема типового процесса CI/CD" border="0" data-original-height="1131" data-original-width="1600" height="452" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY9-lCI8bS7NkrwhftPAQthCzx158-oPbJPDCZo-2_wvXVesmZqrldNVqFFzcp0KOiZqygTVSkXdIOvxkj5ftn7yHNvyWZkAia9VE9zd4HHS5Wp-8Wd8CmT_6YSz59xKSNmay615MKb4f1/w640-h452/devops_main_process.png" title="IDEF0-схема типового процесса CI/CD" width="640" /></a></div><p></p>
<p align="center" style="text-align: center;"><i><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">IDEF0-схема типового процесса CI/CD<o:p></o:p></span></i></p>
<p style="text-align: justify;"><span face="" style="font-size: 14pt;">На каждом из этапов наш отдел помогает разработчи</span><span face="" style="color: #222222; font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">кам и тестировщикам решить конкретные технические задачи:</span></p><ul type="disc">
<li class="MsoNormal" style="mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 36.0pt; text-align: justify;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: "Times New Roman"; mso-hansi-theme-font: minor-latin;">обеспечить хранение кода в системе
GitLab (выделить им проект);<o:p></o:p></span></li>
<li class="MsoNormal" style="mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 36.0pt; text-align: justify;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: "Times New Roman"; mso-hansi-theme-font: minor-latin;">разработать сборочную
конфигурацию на базе одного из типовых шаблонов и обеспечить хранение
собранных артефактов в системе Artifactory;<o:p></o:p></span></li>
<li class="MsoNormal" style="mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 36.0pt; text-align: justify;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: "Times New Roman"; mso-hansi-theme-font: minor-latin;">реализовать конфигурации для
деплоя артефактов на серверах тестировщиков и помочь им с подготовкой
тестовых конфигураций;<o:p></o:p></span></li>
<li class="MsoNormal" style="mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 36.0pt; text-align: justify;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: "Times New Roman"; mso-hansi-theme-font: minor-latin;">в случае успешного
тестирования — продвинуть сборку, то есть переместить ее в хранилище
протестированных артефактов в Artifactory, для чего также создается
специальная конфигурация;<o:p></o:p></span></li>
<li class="MsoNormal" style="mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 36.0pt; text-align: justify;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: "Times New Roman"; mso-hansi-theme-font: minor-latin;">при необходимости опубликовать
сборку на корпоративном сервере Global Update, откуда она будет автоматически
распространена на FUS-серверы для заказчиков;<o:p></o:p></span></li>
<li class="MsoNormal" style="mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 36.0pt; text-align: justify;"><span face="" style="font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: "Times New Roman"; mso-hansi-theme-font: minor-latin;">при помощи скриптов на базе
SaltStack развернуть сборку на конкретном сервере.<o:p></o:p></span></li>
</ul><p class="MsoListParagraphCxSpFirst" style="mso-add-space: auto; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-align: justify; text-indent: -18pt;"><!--[if !supportLists]--></p><p style="text-align: justify;">
</p><ul type="disc"><o:p><o:p><o:p><o:p><o:p>
</o:p></o:p></o:p></o:p></o:p></ul><p style="text-align: justify;"><span face="" style="color: #222222; font-size: 14pt; mso-ascii-theme-font: minor-latin; mso-bidi-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">Каждый
этап контролируется через систему мониторинга Zabbix. Когда возникает сбой,
разработчики пишут нам заявку, мы локализуем и исправляем проблему.</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;">О
первых шагах нашей команды в DevOps, о том, с какими проблемами мы столкнулись,
как выстраивали процесс CI/CD и к чему пришли в итоге, можно почитать в статьях
на Хабре:</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="margin-left: 36pt; mso-list: l0 level1 lfo1; text-align: justify; text-indent: -18pt;"><!--[if !supportLists]--><span style="font-family: Symbol; font-size: 14pt;">·<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span face="" style="font-size: 14pt;"><a href="https://habr.com/ru/company/pt/blog/310584/" target="_blank">Миссия выполнима: как развить DevOps в компании со множеством проектов</a>,</span><span style="font-size: 13.5pt;"><o:p></o:p></span></p><p style="margin-left: 36pt; mso-list: l1 level1 lfo2; text-align: justify; text-indent: -18pt;"><!--[if !supportLists]--><span style="font-family: Symbol; font-size: 14pt;">·<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span face="" style="font-size: 14pt;"><a href="https://habr.com/ru/company/pt/blog/313616/" target="_blank">Личный опыт: как выглядит наша система Continuous Integration</a>,</span><span style="font-size: 13.5pt;"><o:p></o:p></span></p><p style="margin-left: 36pt; mso-list: l1 level1 lfo2; text-align: justify; text-indent: -18pt;"><!--[if !supportLists]--><span style="font-family: Symbol; font-size: 14pt;">·<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span face="" style="font-size: 14pt;"><a href="https://habr.com/ru/company/pt/blog/343884/" target="_blank">Автоматизация процессов разработки: как мы в Positive Technologies внедряли идеи DevOps</a>.</span></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;">Если
они вас заинтересуют как инженеров, можете прочитать подробнее, как мы выделяли
и классифицировали типовые шаги и этапы производственного конвейера в нашей
компании, а затем пришли к технологической карте производственного процесса —
простому, но мощному аналитическому инструменту для управления проектами. Об
этом написано в статье «<a href="https://habr.com/ru/company/pt/blog/480754/">Управление
хаосом: наводим порядок с помощью технологической карты</a>». Если вы тимлид
команды автоматизаторов, то вам также может быть интересна статья «<a href="https://habr.com/ru/company/pt/blog/501766/">Личный
опыт: как выстроить карьерный рост в отделе DevOps</a>».</span><span face="" style="text-align: left;"> </span></p>
<h1 style="text-align: left;"><span face=""><span style="font-size: x-large;">Какие
инструменты DevOps-инженеры используют в работе</span></span></h1>
<p style="text-align: justify;"><span face="" style="font-size: 14pt;">Применяемый DevOps-инженерами инструментарий должен
подбираться в зависимости от решаемых задач, не стоит жестко их ограничивать.
Кроме того, любой набор инструментов автоматизации сейчас устаревает слишком
быстро и за пару лет может полностью измениться. В этом плане мне нравятся
гибкие roadmaps развития в профессии, которые предлагаются opensource-сообществом,
в том числе с перечислением актуальных на данный момент инструментов. Например,
есть <a href="https://roadmap.sh/devops">roadmap
для DevOps-инженеров</a> и <a href="https://github.com/orsanawwad/awesome-roadmaps">roadmap
для разработчиков</a>.</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;">Если
сказать чуть более абстрактно, без привязки к решаемым задачам, то
DevOps-инженер должен владеть как минимум одним высокоуровневым языком
программирования (Python, Java, Go, C++, C# или любым
другим), понимать основы разработки и тестирования ПО. Понимать, как работают
операционные системы Windows и Linux и их основные концепции: треды и процессы,
разграничение доступа, сокеты, модель OSI, устройства ввода-вывода, память
и устройства хранения данных; понимать, как работает виртуализация. Также
потребуются навыки работы с терминалом ОС, умение писать batch- и bash-скрипты.
Будет совсем не лишним знакомство с направлением infrastructure as code
(инфраструктура как код): контейнеризацией (например, с помощью Docker и Docker Compose),
написанием сценариев развертывания окружения (например, посредством Salt или
Ansible), оркестрацией (Kubernetes), а также со всем, что касается мониторинга
инфраструктуры (например, Zabbix, Grafana или Prometheus). Для продуктовой
разработки также очень важны навыки работы с системами CI/CD, например
TeamCity, Gitlab CI, Travis CI, Jenkins и Azure DevOps. Кроме того, важно
умение работать с виртуальной инфраструктурой и облаками, например с vSphere,
Azure, AWS или Google Cloud.</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;">Важно
не останавливаться на достигнутом: современные технологии требуют постоянного
совершенствования навыков и постоянного изучения новых подходов к решению
инженерных задач.</span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p style="text-align: justify;"><span face="" style="font-size: 14pt;"> </span><span face="" style="font-size: 13.5pt;"><o:p></o:p></span></p><p><span face="" style="font-size: 14pt;">Автор: Тимур
Гильмуллин, заместитель руководителя отдела технологий и процессов разработки <a href="https://www.ptsecurity.com/ru-ru/" target="_blank">Positive
Technologies</a></span><span face="" style="font-size: 13.5pt;"></span><o:p></o:p></p><p><span face="" style="font-size: 14pt;">Оригинал статьи в
журнале TProger: <a href="https://tproger.ru/articles/devops-among-developers/">https://tproger.ru/articles/devops-among-developers/</a></span><span face=""> </span></p><p></p>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.comtag:blogger.com,1999:blog-5253197049947532203.post-2512147678580270132020-08-11T14:09:00.000+03:002020-08-11T14:09:09.587+03:00Aptly. Как организовать контроль пакетов из внешних репозиториев и делегировать управление в продуктовые команды<font face="arial">Всем привет! Решил отрепостить и сюда тоже нашу совместную с коллегами из Positive Technologies Сашей Паздниковым и Никитой Драчёвым статью про Aptly: будет полезной тех-лидам от разработки. Оригинал размещён на Хабре <a href="https://habr.com/ru/company/pt/blog/513958/" target="_blank">по ссылке</a>.</font><div><br /></div><div><span style="background-color: white; color: #222222; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px;">Сейчас многие компании работают без возможности прямого управления составом пакетов внешних репозиториев, даже если применяют зеркалирование, проксирование и кэширование. Это приводит к тому, что окружение выполнения постоянно меняется, в частности состав докер-образов меняется чаще, чем требуется производству.</span><br style="background-color: white; color: #222222; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; color: #222222; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 16px;">Возможны ситуации, когда в состав разрабатываемого продукта могут попадать нежелательные изменения, которые содержатся во внешних зависимостях. Это особенно актуально во время сертификации продукта. Как следствие — затягивание сертификаций, сбои ночных тестов и интеграционного тестирования, поломки on-premise production (производственной среды, расположенной на собственных ресурсах организации) при накатывании хотфикса и прочее. В новой статье мы описали подход, который позволит избежать таких проблем.</span></div><div><span><a name='more'></a></span><div class="post__body post__body_full" style="background-color: white; clear: both; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 14px; margin-bottom: 24px; padding-top: 32px;"><div class="post__text post__text-html post__text_v1" data-io-article-url="https://habr.com/ru/company/pt/blog/513958/" id="post-content-body" style="color: #222222; font-size: 16px; line-height: 1.56; margin-right: -5px; overflow-wrap: break-word; padding-right: 5px;"><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 0px; padding: 0px;">Чего мы хотели добиться</h2><br />Прежде чем приступать к описанию подхода, пара слов о задачах, которые мы хотели решить:<br /><br /><ul style="margin: 0px 0px 0px 34px; padding: 0px;"><li style="line-height: 1.6; padding: 0px 0px 9px;">Получить полный контроль над составом внешних пакетов в релизе (предсказуемость).</li><li style="line-height: 1.6; padding: 9px 0px;">Зафиксировать составы внешних репозиториев для быстрой выкатки хотфиксов с минимальным дополнительным тестированием (скорость).</li><li style="line-height: 1.6; padding: 9px 0px;">Обеспечить продуктовые стенды QA повторяемым предсказуемым фиксированным окружением (повторяемость).</li><li style="line-height: 1.6; padding: 9px 0px;">Независимость от наличия внешнего канала связи (автономность).</li><li style="line-height: 1.6; padding: 9px 0px;">Моментальное переключение на официальные репозитории при аварии (отказоустойчивость).</li><li style="line-height: 1.6; padding: 9px 0px;">Гарантированная проверка ключей внешних репозиториев в сборочных конвейерах (доверие).</li><li style="line-height: 1.6; padding: 9px 0px 0px;">И самое главное, передать управление и контроль над составом внешних пакетов в руки продуктовых команд и релиз-менеджеров (самоуправление).</li></ul><br /><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 0px; padding: 0px;">Анализ жизненного цикла feature-сборок</h2><br />Наш подход решает задачу фиксации состава внешних репозиториев на конкретную дату, под релиз или фичу. Следующая схема наглядно показывает управление жизненным циклом релиза, feature-сборки и хотфикса.<br /><br />Для примера возьмем условный репозиторий Debian Stretch. Данный подход применим и для репозиториев Docker, SaltStack и т. п. На временной шкале зафиксировали три среза на даты T1, T2 и T3.<br /><br /><img height="246" src="https://habrastorage.org/webt/i3/ni/fu/i3nifuk8oxs5ve0sbxmkpp-7mki.png" style="border-style: none; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="534" /><br /><div class="scrollable-table" style="overflow-x: auto;"><table style="border-collapse: collapse; border: 1px solid rgb(213, 221, 223); margin: 1.5em 0px; width: 780px;"><thead><tr><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"></th><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">T1</span></th><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">T2</span></th><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">T3</span></th></tr></thead><tbody><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">stretch</span></td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200305</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200420</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200615</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Feature1</span></td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200304</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200304</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200501</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Feature2</span></td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200304</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200304</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200601</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Feature3</span></td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200301</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200406</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200406</td></tr></tbody></table></div><br />Мы свели в таблицу состав внешнего репозитория Debian Stretch для сборки дистрибутивов Feature1, Feature2 и Feature3. Из таблицы видно, что состав внешнего репозитория контролируется каждой веткой независимо. Мы приняли соглашение для себя фиксировать ветку master для Debian Stretch ежедневно и давать метки каждому срезу в формате YYYYMMDD, например 2020304 для среза на 4 марта 2020 года. Итого в таблице приведены используемые для дистрибутива в каждой ветке срезы внешнего репозитория в трех разных моментах времени и состав в мастере для Debian Stretch. Команда для каждой фичи или для каждого релиза обновляет состав внешних репозиториев по своему усмотрению и согласно своему циклу разработки.<br /><br />На примере Feature1: продуктовая команда приступает к разработке новой фичи и фиксирует в конфигурационных файлах состав внешнего репозитория на дату 20200228 (см. на схеме выше).<br /><br /><span style="font-weight: bolder;">Переключаем на 20200228</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-20200228 stretch main contrib non-free</code><br /><br />В процессе разработки в связи с появлением новых пакетов возникает необходимость обновить пакетную базу до даты 20200304. Переключаем рабочий репозиторий на нужную дату.<br /><br /><span style="font-weight: bolder;">Переключаем на 20200304</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-20200304 stretch main contrib non-free</code><br /><br />Далее происходит еще одно переключение пакетной базы на дату 20200501.<br /><br /><span style="font-weight: bolder;">Переключаем на 20200501</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-20200501 stretch main contrib non-free</code><br /><br />Если теперь мы проведем временные срезы, то увидим, что в моменты времени T1 и Т2 разработка Feature1 идет на пакетной базе, «замороженной» 4 марта 2020 года. А в срезе T3 разработка идет уже на новой пакетной базе за 1 мая 2020 года.<br /><br /><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 0px; padding: 0px;">Продуктовое мультирелизное управление зависимостями</h2><br />Теперь рассмотрим управление зависимостями нескольких активных релизов продукта. На поддержке представлены три релиза 2.5, 2.6 и 2.7.<br /><br />В таблице мы видим соответствие релизов и дат, на которые сделан слепок репозитория. В ней показано, какой срез состава внешнего репозитория использовался для построения конкретной версии дистрибутива.<br /><br /><img height="174" src="https://habrastorage.org/webt/ix/67/ef/ix67efppfkyokvv2vxfxnwmtouy.png" style="border-style: none; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="534" /><br /><div class="scrollable-table" style="overflow-x: auto;"><table style="border-collapse: collapse; border: 1px solid rgb(213, 221, 223); margin: 1.5em 0px; width: 780px;"><thead><tr><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Релиз</span></th><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Состав</span></th></tr></thead><tbody><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">2.5.128, 2.5.135, 2.5.207</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200301</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">2.6.201, 2.6.215, 2.6.315</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200301</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">2.7.210, 2.7.217, 2.7.305</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200404</td></tr></tbody></table></div><br />Вместо именования срезов по датам YYYYMMDD мы также используем именование тегами в формате <ProjectName.ReleaseVersion> (название_релиза.версия_релиза продукта, например name.2.2) или <ProjectName-FeatureNumber> (добавляем номер фичи, например 3).<br /><br /><span style="font-weight: bolder;">Снапшот для 2.5 по состоянию на 20200301</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-projectname-2.5 stretch main contrib non-free # 20200301</code><br /><br />Таким образом в процессе разработки релиза 2.5 команда фиксирует состав зависимых репозиториев на дату 20200301. Где-то в апреле команда начинает новый релиз 2.6 и решает использовать состав пакетов внешнего репозитория от 2.5. Создаем новый снапшот для 2.6 из снапшота для 2.5. В будущем составы репозиториев для релизов 2.5 и 2.6 могут легко разойтись. Мы сделали для 2.6 свой тег debian-stretch-projectname-2.6.<br /><br /><span style="font-weight: bolder;">Снапшот для 2.6 по состоянию на 20200301</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-projectname-2.6 stretch main contrib non-free # 20200301</code><br /><br />В случае релиза 2.7 команда может начать разработку с ветки master — ежедневного снапшота оригинального репозитория.<br /><br /><span style="font-weight: bolder;">Снапшот для 2.7 по состоянию на 20200404</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-projectname-2.7 stretch main contrib non-free # 20200404</code><br /><br /><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 0px; padding: 0px;">Мультипродуктовое управление зависимостями</h2><br />Рассмотрим мультипродуктовое управление зависимостями на примере двух продуктов с разными релизными циклами и своими продуктовыми командами: Stealth и Infiniti.<br /><br /><img height="166" src="https://habrastorage.org/webt/lz/gx/f9/lzgxf9lbhhmc8tio-lhakchtxha.png" style="border-style: none; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="534" /><br /><br />Прокомментируем таблицу, что и когда происходит.<br /><div class="scrollable-table" style="overflow-x: auto;"><table style="border-collapse: collapse; border: 1px solid rgb(213, 221, 223); margin: 1.5em 0px; width: 780px;"><thead><tr><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Продукт</span></th><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Релиз</span></th><th style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;"><span style="font-weight: bolder;">Состав</span></th></tr></thead><tbody><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">stealth2.2</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">r2.2.124</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200301</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">stealth2.2</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">r2.2.131, r2.2.162</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200305</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">infiniti4.0</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">r4.0.235, r4.0.241</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200303</td></tr><tr><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">infiniti4.0</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">r4.0.250</td><td style="border: 1px solid rgb(213, 221, 223); line-height: 1.5; padding: 6px 12px 9px; vertical-align: top;">20200308</td></tr></tbody></table></div><br />1. Пусть с 1 марта 2020 года стартовала разработка версии 2.2 проекта Stealth, для этого был создан снапшот состава пакетной базы на текущую дату. Выпуск релиза 2.2.124 выполнен с пакетной базой внешнего репозитория от 20200301.<br /><br /><span style="font-weight: bolder;">Stealth 2.2</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-stealth-2.2 stretch main contrib non-free # 20200301</code><br /><br />2. Пятого числа производится обновление пакетной базы. Рабочий репозиторий debian-stretch-stealth-2.2 одномоментно переключается на нужную дату, выпуск релизов 2.2.131 и 2.2.162 выполнен с составом пакетов внешнего репозитория от 20200305. <span style="font-weight: bolder;">Без дополнительных манипуляций в окружении все 100500 микросервисов продукта одномоментно получили в сборочном конвейере новое окружение 20200305</span>.<br /><br /><span style="font-weight: bolder;">Stealth 2.2</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-stealth-2.2 stretch main contrib non-free # 20200305</code><br /><br />3. Параллельно третьего числа стартует разработка проекта Infiniti версии 4.0 и для нее создается срез состава репозитория на дату 20200303. Версии 4.0.235 и 4.0.241 выпускаются с составом пакетов внешнего репозитория на 20200303.<br /><br /><span style="font-weight: bolder;">Infiniti 4.0</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-infiniti-4.0 stretch main contrib non-free # 20200303</code><br /><br />4. После выпуска версии 4.0.241 команда решает обновить состав репозитория до 20200308 и выпустить новый релиз с новым составом внешних пакетов. Версия 4.0.250 выходит с составом пакетов на 20200308.<br /><br /><span style="font-weight: bolder;">Infiniti 4.0</span><br /><code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;">deb http://repository.co/debian-stretch-infiniti-4.0 stretch main contrib non-free # 20200308</code><br /><br />Два варианта переключения между состояниями репозиториев позволяют выбрать удобный для процесса разработки подход. В первом случае мы переключаемся в нужное состояние путем указания снапшота репозиториев на конкретную дату. Во втором случае для многокомпонентных продуктов используем именованный срез и двигаем его на нужную дату. Такой механизм обеспечивает единовременное переключение среза во всех 100500 компонентах продукта.<br /><br />Управление срезами каждого внешнего репозитория мы ведем в отдельном Docker-контейнере, поэтому в любой момент можем переключить конкретный репозиторий на скачивание с внешней сети в случае каких-то аварий.<br /><br /><span style="font-weight: bolder;">Скачать список всех репозиториев</span><br /><br /><pre style="font-family: monospace, monospace; font-size: 1em; margin-bottom: 0px; margin-top: 0px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="bash hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-comment" style="color: #a0a1a7; font-style: italic;"># For example</span>
curl repository.co/info/sources.list | grep $(lsb_release -cs) > /etc/apt/sources.list</code></pre><br /><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 0px; padding: 0px;">Автоматическое создание срезов внешних репозиториев</h2><br />Обновление репозиториев происходит каждую ночь по планировщику GitLab. При добавлении нового репозитория изменения автоматически применяются на сервере.<br /><br /><img src="https://habrastorage.org/webt/jv/kb/ca/jvkbca0q4mirfcd9v5y7z9cqzcy.png" style="border-style: none; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" /><br /><br />В момент фиксации нового среза внешнего репозитория проверяется его сертификат, если он отличается от сохраненного у нас, то обновления не происходит, а нам поступает сообщение об ошибке.<br /><br /><h2 style="-webkit-font-smoothing: antialiased; font-family: "Fira Sans", sans-serif; font-size: 24px; font-weight: 500; line-height: 32px; margin: 0px; padding: 0px;">Итоги</h2><br /><ol style="margin: 0px 0px 0px 34px; padding: 0px;"><li style="line-height: 1.6; padding: 0px 0px 9px;">Подготовка новой версии дистрибутива к сертификации больше не является головной болью. На период сертификации мы фиксируем состав дистрибутива, и если нужно что-то пофиксить оперативно, то с большой вероятностью в выпущенном хотфиксе не будет ошибок из-за изменения окружения.</li><li style="line-height: 1.6; padding: 9px 0px;">Все feature-сборки получают управляемое состояние внешних репозиториев.</li><li style="line-height: 1.6; padding: 9px 0px;">Ускоряются выкатка хотфиксов и проверка через QA с предсказуемым, быстрым и успешным результатом.</li><li style="line-height: 1.6; padding: 9px 0px;">Feature-стенды получают после развертывания заранее определенную, неизменяемую среду выполнения.</li><li style="line-height: 1.6; padding: 9px 0px 0px;">Продуктовые команды получили полностью самостоятельный контроль над составом внешних репозиториев для любых задач.</li></ol><br />Отметим, что у Debian есть официальный ресурс <a href="https://snapshot.debian.org/" style="background-color: transparent; color: #992298; text-decoration-line: none;">snapshot.debian.org</a> с ежедневными срезами и большой глубиной хранения. Для определенных задач этого достаточно.<br /><br />Благодарим Сергея Смирнова и сообщество за прекрасный инструмент для управления составом внешних репозиториев Aptly. От нас — небольшой вклад в лучшие практики использования этого полезного инструмента в производственных конвейерах.<br /><br />В следующих статьях расскажем про связку Aptly + Simple-CDD для подготовки ISO-образов дистрибутивов, делегирование управления внешними зависимостями в продуктовые команды и проблемы применения Aptly в процессе управления внешними зависимостями.<br /><br /><span style="font-weight: bolder;">Авторы</span>: <a href="https://www.linkedin.com/in/whatnik/" style="background-color: transparent; color: #992298; text-decoration-line: none;">Никита Драчёв</a>, <a href="https://www.linkedin.com/in/alexander-pazdnikov-90a98a71/" style="background-color: transparent; color: #992298; text-decoration-line: none;">Александр Паздников</a>, <a href="https://www.linkedin.com/in/tgilmullin/" style="background-color: transparent; color: #992298; text-decoration-line: none;">Тимур Гильмуллин</a></div><div><br /></div></div><dl class="post__tags" style="align-items: baseline; background-color: white; clear: both; color: #333333; display: flex; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; font-size: 14px; justify-content: flex-start; margin: 24px 0px;"></dl></div>Тимур Гильмуллинhttp://www.blogger.com/profile/05942690986593926514noreply@blogger.com