Финансовые графики для вашего приложения


    Поиск нужных графиков отнимает время и несет много вопросов. Сегодня хочу поделиться своим опытом в выборе финансовых графиков, для экономии вашего времени и сил.


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


    Привет, Хабр!


    Было необходимо подключить графики к приложению. По итогу пользуюсь 3 вариантами, о которых мы поговорим в статье. Все они бесплатные для коммерческого и не коммерческого использования. Два из них open source lightweight-charts, trading-vue-js (на Vuejs) и один проприетарный сharting_library.


    Продолжение статьи: "Подключение и настройка графиков TradingView"


    English version.


    Введение


    Каждый график решает свою задачу. Это кажется банальным, при этом переодически наблюдаю картину как из "жигулей" пытаются сделать "спорткар". Начнем с обзора и сравнения.


    Библиотеки


    lightweight-charts


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


    Тот, кто знаком с графиками платформы TradingView увидит лайт-версию классических графиков.



    Из "коробки" доступны графики: line, area, бары, свечи и гистограмма. Графики можно комбинировать. Есть возможность выводить сделки, выставлять ордера и много дополнительных настроек. Есть CDN версия и пакет для Nodejs.


    Пример подключения:


    $ npm install lightweight-charts

    import { createChart } from 'lightweight-charts';
    
    const chart = createChart(document.body, { width: 400, height: 300 });
    const lineSeries = chart.addLineSeries();
    lineSeries.setData([
        { time: '2019-04-11', value: 80.01 },
        { time: '2019-04-12', value: 96.63 },
        { time: '2019-04-13', value: 76.64 },
        { time: '2019-04-14', value: 81.89 },
    ]);

    Демо: https://ru.tradingview.com/lightweight-charts/
    Документация: https://github.com/tradingview/lightweight-charts/blob/master/docs/README.md
    Лицензия: Apache License, Version 2.0
    Версия на момент статьи: 3.1.5
    Комьюнити: https://discord.com/invite/E6UthXZ


    сharting_library


    Классический график TradingView, которым можно пользоваться бесплатно. Этот вариант используется на большинстве бирж и в самом сервисе TV. Он подходит, если требуется из "коробки" использовать мощный функционал с техническим анализом для своего приложения.



    Библиотека закрытая. Получение доступа проходит в несколько этапов:


    1. Заполнение заявки на сайте и ожидание ответа (от двух недель)
    2. Подписание договора
    3. Получение доступа к репозиторию на GitHub

    При желании, можно подключить виджет с ограниченными настройками.


    Главным минусом является ограниченность API, нельзя масштабировать. С технической стороной возникает много вопросов, поэтому это — тема для отдельной статьи.


    сharting_library я использую в своем приложении для торгового терминала. Выглядит "дорого-богато" и знакомо пользователям.


    Демо: https://charting-library.tradingview.com/
    Документация: https://github.com/tradingview/charting_library/wiki (если нет доступа будет 404 ошибка)
    Комьюнити: https://discord.com/invite/E6UthXZ


    TradingVue


    Достаточно молодой проект, на котором делают действительно крутые графики. Визуально они похожи на классический TradingView, с отличиями в лицензии (MIT), полной кастомизацией и простым API. На этих графиках можно рисовать все, что захотите. Высокая скорость обработки данных 20ms для 1000 свечей. Доступен скриптовый язык — JavaScript, есть песочница. Библиотека написана на Vuejs, поэтому тем, кто знаком с фреймворком, все будет понятно.


    Цитата разработчика:


    Если вы создаете софт для торговли — эта библиотека для вас. Если вы хотите создавать собственные индикаторы и мыслите шире — эта библиотека для вас. И если вам не хватает юзабилити TradingView.com в других библиотеках с открытым исходным кодом — вы определенно попали в нужное место!


    Минусом является небольшое количество плагинов для расширения функционала. В рамках библиотеки они называются overlays. Доступные расширения tvjs-overlays.


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



    Пример подключения:


    npm i trading-vue-js

    <template>
    <trading-vue :data="this.$data"></trading-vue>
    </template>
    
    <script>
    
    import TradingVue from 'trading-vue-js'
    
    export default {
        name: 'app',
        components: { TradingVue },
        data() {
            return {
                ohlcv: [
                    [ 1551128400000, 33,  37.1, 14,  14,  196 ], // [timestamp, open, high, low, close, volume],
                    [ 1551132000000, 13.7, 30, 6.6,  30,  206 ],
                    [ 1551135600000, 29.9, 33, 21.3, 21.8, 74 ],
                    [ 1551139200000, 21.7, 25.9, 18, 24,  140 ],
                    [ 1551142800000, 24.1, 24.1, 24, 24.1, 29 ],
                ]
            }
        }
    }
    
    </script>

    Демо и playground
    Документация
    Лицензия: MIT
    Комьюнити


    Заключение


    Если вам интересно разобрать техническую сторону и "подводные камни" для charting_library и TradingVue поддержите статью или напишите, что не так.


    При наличие опыта использования одной или нескольких библиотек отпишитесь в комментариях, будет интересно узнать ваше мнение :)


    Продолжение статьи: "Подключение и настройка графиков TradingView"


    Спасибо за внимание!

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 13

      +2
      Большое спасибо! Отличня публикация. Есть опыт работы с amcharts, и, коротко говоря, они не годятся для финансовых графиков. А то, что в статье — прямо очень завораживает.
        0

        Попробуйте HighStock, от авторов HighCharts, спец версия для финансовых графиков, странно что автор не рассмотрел этот вариант

          0

          HighCharts не добавил из-за лицензии. Бесплатная только для не коммерческого использования.

        +2
        У TradingView высокий порог входа.для того чтоб запустить график надо писать код сразу на бэкэнде и на фронтэнде. причем конфигурация происходит на обоих концах. Лажаешь с какимто параметром и библиотека начинает валится в самых неожиданных местах. Особенно доставляет сообщение в консоли «it shouldn't have happened».

        В адаптере который идет в примере идет совершенно ненужный пинг понг данными. сначала отсылается конфиг потом время потом данные по символу(причем несколько раз так и не получилось победить хотя есть еще идейка) и только потом история свечей. Хотя можно было это одним пакетом отсылать. Наверное сделано для наглядности Это все можно переписать конечно но график грузится медленно.

        Эта библиотека может делать скрины графика но отсылает его в виде json с data. собрать это в картинку можно, но не для новичка.

        Есть возможность написать индикаторы для графика но тут свои особенности. Например обход свечей идет от старой к новой хотя в терминале MT4 наоборот. так же нет возможности получить значения следующих свечей. Изза того что функция индикатора применяется к каждой свече то при возникновении ошибки в индикаторе в консоли огромная стена повторяющихся ошибок. Ах да. документации по написанию индикаторов практически нет несмотря на то что эти кастомные индикаторы доступны уже года 3. Есть куцая страничка с 3 примерами индикаторов и куча issues на гитхабе.
        Эти индикаторы можно разрабатывать на встроеном скриптовом языке pinescript прям на сайте tradingview. Очень удобно.пишешь скрипт и сразу видишь результат на графике. Раньше была возможность отправить pinescript в поддержку а они присылали скомпилированный вариант. Сейчас очень помогают эти скомпилированные скрипты в написании немного нестандартных вещей. судя по задержке там человек переписывал вручную и видно его это достало поэтому потом эту лавочку прикрыли. Но какой-то магией все же pinescript в браузере научились компилировать в яваскрипт. ведь в браузере индикатор показывается. Странная ситуация.
        Как говорит саппорт времени на документацию нет. Денег на то чтоб нанять человека похоже тоже нет. бедная компания что с нее взять.
        Когда ручками переписываешь pinescript то из 70 строк pinescript получается 1000 строк яваскрипта. большая часть это манифест который описывает мета вещи типа используемые виды линий, настройки итд.
        Pinescript содержит много вспогательных функция для работы с данными и только малую часть из них перенесли в обьект PIneJs который доступен в индикаторах. Причем некоторых важных нет. и не особо похоже что со временем растет количество доступных методов.
        Также в эти индикаторы приходит время свечи в utc и нет возможности получить время в таймзоне графика. то есть вот надо вам нарисовать вертикальную линию на свече вторника 00:00 то будь добр ручками посчитай на какой свече это должно произойти

        На графике можно переключать вид свечей. среди них есть ренко. Алгоритм расчета ренко есть в открытом доступе но почему то этот вид доступен только на сайте tradingview а в библиотеке нет. Саппорт ничего определенного не говорит. Ну а что скажешь если алгоритм в библиотеке отличается от стандартного какими то странными подвывертами типа перерасчета коэффициентов на каждой новой свечи. ТО есть пришла новая свеча на ренко и график может поменятся до неузнаваемости. Когда попробовали сэмулировать ренко расчетами на сервере клиенты сильно возмущались что ренко на tradingview отличается от нашего ренко. и их не убеждали наши заверения что у нас правильный алгоритм а у них нет. У парня который пытался подобрать алгоритм чтоб было похоже как на tradingview сильно бомбило. А я уже привычный.

        Немного напрягает что основной график на странице tradingview.com/chart ушел по фичам на несколько версий вперед от библиотеки в репе. ПОтом приходят недовольные клиенты и обвиняют тебя в рукожопости " не ну на tradingview же есть почему вы не можете также сделать".

        Есть возможность сохранять состояние графика но это состояние очень многословное. Если пользователь немного поработал на графике то JSON может весить больше мегабайта (1,12 мб весит самый большой из 45 тысяч сохраненок). Представляете да как загибаются мобилы пытаясь его прожевать?

        Саппорт на гитхабе хочет помочь и сильно старается. особенно с написанием индикаторов.
          0

          Спасибо за развернутый отзыв.


          Для charting_library пишу пост в формате "книга рецептов". Вы можете в комментариях или в телеграм\лс рассказать про свои сложности и решения к ним, а я добавлю с вашим авторством :)

            +1
            В адаптере который идет в примере идет совершенно ненужный пинг понг данными. сначала отсылается конфиг потом время потом данные по символу(причем несколько раз так и не получилось победить хотя есть еще идейка) и только потом история свечей. Хотя можно было это одним пакетом отсылать. Наверное сделано для наглядности Это все можно переписать конечно но график грузится медленно.

            Адаптер, который идёт "в пакете" это исключительно пример реализации JS-API датафида, и лично я бы не советовал его использовать, если вам нужен свой датафид со своими особенностями. Это пример, его стоит рассматривать как референс для реализации. Если интересует реальный пример с реальным сервисом, можно глянуть этот туториал, там используется вебсокет для получения данных и никаких пинг-понгов.


            Опять же, то, какие методы charting_library требует реализовать обусловенно её особенностями, и никто не заставляет делать всё именно так и строго в той последовательности, в которой приходят запрос. Вы можете спокойно делать на сервер 1 запрос на получение сразу всего, а как только данные придут и библиотека их запросит — возвращать из кэша. В этом и плюс наличия собственного адаптера данных.


            Эта библиотека может делать скрины графика но отсылает его в виде json с data. собрать это в картинку можно, но не для новичка.

            Тут согласен, серверные скриншоты сделаны достаточно сложно, и даже доки на это нет. Но кажется совсем недавно была добавлена возможность делать целиком клиентские скриншоты — вам возвращается HTMLCanvasElement, с которым можно делать что угодно (копировать данные в буфер, выгружать на сервер картинку и так далее).


            Есть возможность написать индикаторы для графика но тут свои особенности. Например обход свечей идет от старой к новой хотя в терминале MT4 наоборот.

            Думаю это обусловленно тем, как работают в большинстве своём индикаторы и в принципе какой-то расчет данных — всегда идёт из истории в настоящее (к примеру для рассчета MA нужно накапливать данные на последние N баров, чтобы правильно рассчитать следующий бар).


            так же нет возможности получить значения следующих свечей.

            Такая функция есть (но не сказать, что это будет сильно просто, как и всё с индикаторами), но из-за бага так сделать не получится, к сожалению. Надеюсь он будет исправлен в ближайшее время (судя по всему на сказать, что это популярная фича, но я согласен, что она имеет место быть). В том же PineScript кажется такое в принципе невозможно сделать (поправьте меня, если не так), не слышал чтобы жаловались на это (могу ошибаться). Но еще раз отмечу, что я понимаю и согласен с тем, что это штука должна быть.


            Изза того что функция индикатора применяется к каждой свече то при возникновении ошибки в индикаторе в консоли огромная стена повторяющихся ошибок. Ах да. документации по написанию индикаторов практически нет несмотря на то что эти кастомные индикаторы доступны уже года 3. Есть куцая страничка с 3 примерами индикаторов и куча issues на гитхабе.

            Согласен. В скором времени мы добавим чуть больше примеров и описания на вики касательно кастомных индикаторов (уже в процессе), но текущая ситуация примерно такая, как вы описали.


            Но какой-то магией все же pinescript в браузере научились компилировать в яваскрипт. ведь в браузере индикатор показывается. Странная ситуация.

            А можно тут чуть подробнее, пожалуйста? Не очень понял, что вы имеете ввиду.


            Когда ручками переписываешь pinescript то из 70 строк pinescript получается 1000 строк яваскрипта. большая часть это манифест который описывает мета вещи типа используемые виды линий, настройки итд.
            Pinescript содержит много вспогательных функция для работы с данными и только малую часть из них перенесли в обьект PIneJs который доступен в индикаторах. Причем некоторых важных нет. и не особо похоже что со временем растет количество доступных методов.

            Могу лишь сказать, что разработке кастомных индикаторов с всевозможными примерами и описанием всего и принципов работы можно посвятить целый отдельный проект и несколько выделенных человек, которые будут им заниматься. Это огромный кусок, который сходу невозможно покрыть документацией. На данный момент в вики описаны самые частые примеры (например как отобразить ваши собственные данные на чарте, рассчитанные на сервере). Как я отмечал выше, в процессе проработки еще несколько примеров и описание/особенности их работы.


            Как говорит саппорт времени на документацию нет. Денег на то чтоб нанять человека похоже тоже нет. бедная компания что с нее взять.

            Я бы не был так категоричен. Не всегда вопросы можно "залить баблом", есть еще обратная сторона — кадры и их поиск. Если вы сами хотите этим заниматься или знаете человека, который хотел бы этим заняться — можете писать мне в лс.


            Также в эти индикаторы приходит время свечи в utc и нет возможности получить время в таймзоне графика. то есть вот надо вам нарисовать вертикальную линию на свече вторника 00:00 то будь добр ручками посчитай на какой свече это должно произойти

            По своему опыту могу сказать, что вероятно это не то, что вы хотите сделать на графике. Работа с таймзонами достаточно сложна и тут очень много нюансов. Касательно вашего примера — вы действительно хотите нарисовать вертикальную линию на 00:00 вторника таймзоны, которую пользователь выбрал? Т.е. если он будет менять таймзону, то эта линия будет смещаться? Вы прям по дню хотите отображать, или по границе торговой сессии? Что она тогда отображает? Вероятно это нужно делать не в индикаторе, а дровингом и постоянно двигать при смене таймзоны. Индикаторы считаются на данных серии, и там действительно нет таймзоны чарта, т.к. таймзона чарта влияет исключительно на отображение данных (меняются тикмарки на временной шкале), и никак не влияет на рассчет (мне кажется было бы странно, если бы да).


            На графике можно переключать вид свечей. среди них есть ренко. Алгоритм расчета ренко есть в открытом доступе но почему то этот вид доступен только на сайте tradingview а в библиотеке нет. Саппорт ничего определенного не говорит. Ну а что скажешь если алгоритм в библиотеке отличается от стандартного какими то странными подвывертами типа перерасчета коэффициентов на каждой новой свечи. ТО есть пришла новая свеча на ренко и график может поменятся до неузнаваемости. Когда попробовали сэмулировать ренко расчетами на сервере клиенты сильно возмущались что ренко на tradingview отличается от нашего ренко. и их не убеждали наши заверения что у нас правильный алгоритм а у них нет. У парня который пытался подобрать алгоритм чтоб было похоже как на tradingview сильно бомбило. А я уже привычный.

            Рассчет Ренко (и некоторых других типов японских чартов) в общем случае невозможно сделать на клиенте (если я ничего не путаю), т.к. это это потребует всех тиковых данных за всю историю торговли инструмента. Это может быть очень много данных. Почему так? Потому что такова суть алгоритма: каждый "кирпич" должен в себе содержать выбранный boxsize изменения цены, если вдруг в истории появляется (читай догружается) новый бар, то нужно всё заново пересчитать, и график действительно может измениться до неузнаваемости. Именно поэтому в библиотеке такое поведение — как только догружается новый исторический бар(ы), библиотека заново всё перерассчитывает.


            Немного напрягает что основной график на странице tradingview.com/chart ушел по фичам на несколько версий вперед от библиотеки в репе.

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


            Есть возможность сохранять состояние графика но это состояние очень многословное. Если пользователь немного поработал на графике то JSON может весить больше мегабайта (1,12 мб весит самый большой из 45 тысяч сохраненок). Представляете да как загибаются мобилы пытаясь его прожевать?

            1мб для чарта это не сказать что очень много (бывает и сильно больше), если пользователь нарисовал по паре сотен дровингов на 3-4 символах. Мобильники такое переваривают нормально. В теории можно придумать новый способ сохранения, чтобы эти 2мб данных загружать постепенно, но представляете насколько сложно его будет реализовать, в добавок к тому, что вы выше описали? Я не думаю, что система получится сильно простой и каждый, кто захочет воспользоваться сохранением чартов, будет готов реализовывать очень хитрый механизм сохранения.
            Но в любом случае мы об этом знаем и думаем над решением, надеюсь что-нибудь да придумаем.


            Резюмируя, хочу сказать спасибо за ваш очень подробный отзыв. Видно, что вы достаточно хорошо и вероятно долго знакомы с charting_library и знаете про её особенности.

              0
              Про компиляцию pinescript в браузере я имел ввиду что на странице www.tradingview.com/chart есть pine editor в котором можно писать pinescript код и который очевидно компилируется в яваскрипт после нажатия кнопки add to chart перед тем как добавится на график.

              насчет расчета ренко я не совсем уверен потому-что занимался только отображением данных а не их расчетом. но нет возможности хотя бы создать вид ренко то есть чтоб свечи вплотную прилегали углами. да и алгоритм расчета у вас нестандартный. Интересно с чем это связано.

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

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

              Кстати я регулярно сталкиваюсь с тем что в обьекте полученном из widget.save() есть данные относящиеся к другому символу. ТО есть представьте что вы загружаете этот обьект и загружается график для символа FXCM:EURUSD:H1 на этом графике появляются всякие нарисованные обьекты прям как перед сохранением. Потом вы переходите на символ FXCM:GBPJPY:D1 и на нем тоже какието обьекты есть. и вот если поискать FXCM:GBPJPY:D1 в обьекте для FXCM:EURUSD:H1 то они находятся Хотя казалось бы widget.save() должен вернуть обьект которые относится только к текущему символу а не ко всем загруженным ранее. Я все не теряю надежды отловить этот баг чтоб описать его на гитхабе но пока безуспешно.

              Я регулярно возвращаюсь к документации проекта и постоянно отмечаю новые фичи введенные в проект. радует что проект развивается. Конкурентов особых нет поэтому работаем с тем что есть.
                0
                Про компиляцию pinescript в браузере я имел ввиду что на странице www.tradingview.com/chart есть pine editor в котором можно писать pinescript код и который очевидно компилируется в яваскрипт после нажатия кнопки add to chart перед тем как добавится на график.

                Нет, это не так. Все индикаторы на www.tradingview.com исполняются на сервере, на клиенте только отображение.


                да и алгоритм расчета у вас нестандартный

                Тут всё таки хотелось бы больше конкретики. Насколько я помню, алгоритм самый обычный, ничего не стандартного.


                Да нет как раз именно это я и хотел сделать. НАрисовать прямоугольники на свечах понедельника.

                Т.е. если у нас есть 3 бара 2020-03-01T20:00:00.000Z, 2020-03-02T00:00:00.000Z и 2020-03-02T04:00:00.000Z, то если у пользователя таймзона со смещением -4, то нужно отобразить на первом баре, далее если пользователь поменяет таймзону на тз со смещением 0, линия должна быть на втором баре, и если на тз со смещением +4, то на последнем? А можете привести пример, для чего именно такое нужно? Мне правда интересно понять юскейс.


                Хотя казалось бы widget.save() должен вернуть обьект которые относится только к текущему символу а не ко всем загруженным ранее.

                widget.save() возвращает весь стейт лейаута всех чартов в нем, в том числе все дровинги на всех символах, т.к. если пользователь затем его откроет, он не должен потерять их.

                  0
                  Пользователь просил индикатор который подсвечивает свечи понедельника. Это нужно было для последующего анализа. ТАймзона менялась только при инициализации графика. Дальше пользователь уже работал с установленной. Сначала таймзона была московской и приходилось обозначать свечи которые находятся в промежутке 00-24 по москве. потом польщователь попросил поменять таймзону на нью-йоркскую и пришлось поправить индикатор чтоб подсвечивало свечи в промежутке 00-24 по нью-йорку.
                  Сейчас код выглядит
                                  if (
                                      (current_day === 0 && current_time_hours >= 24 - difference_to_UTC) ||
                                      (current_day === 1 && current_time_hours < 24 - difference_to_UTC)
                                  ) {


                  Мне кажется будет лучше если наряду с функцией
                  PineJS.Std.time(this._context)
                  будет функция типа
                  PineJS.Std.localTime(this._context)
                  
                  которая возвращает время по таймзоне графика.

                  Насчет widget.save() мне кажется логичным что пользователь сохраняет текущий символ с нарисованными обьектами. то что заодно сохраняются объекты на всех символах на которых он раньше был это не интуитивно. Во всяком случае я проверил выбоолчно таблицу с сохранеными лэйаутами и в основном пользователи используют как называие для лэйаута название текущего символа
            +1
            Хорошая статья, спасибо!
              0
              несколько вещей, которые бесят с TV charting_library: обязательство показывать лого, вертикальный скроллинг, фуллскрин на ios, и общий вес виджета. Ну и невозможность отрисовывать позиции. В остальном, чарты TV — лучшие в мире (в своем классе) из доступных бесплатно. Платных конкурентов много и есть лучше.
                0
                Например из платных конкурентов лучше?
                  0
                  Ну, например chartiq

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое