[JavaScript, Node.JS] Подключение и настройка TradingView графиков
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Если Вы — фрилансер или CTO финансового проекта, рано или позно Вы столкнетесь с вопросом подключения графиков, я сэкономлю Вам минимум сутки работы. Те, кто уже используют эту библиотеку, возможно, найдут что-то новое.
Статья будет в формате "книги рецептов" с open source решениями для криптовалютной биржи Binance и Forex.
Привет, Хабр!
У библиотеки TradingView (charting_library) высокий порог входа, при этом менее популярной она не стала из-за того, что используется на одноименном сервисе TradingView.com. Решил сделать "книгу рецептов" с ответами на основные вопросы.
Эта статья продолжение поста: "Финансовые графики для вашего приложения".
Cook book
Контент буду дополнять по мере появляния новых сложностей. Если у Вас есть вопросы и Вы не нашли ответы в статье, пишите в комментариях, будем разбираться вместе :)
В статье буду указывать ссылки на документацию. Если, при переходе по ссылке, у Вас открывается 404 страница, это означает, что у Вас нет доступа.
Лицензия
Можно использовать бесплатно в коммерческих и некоммерческих целях. Самый главный критерий — сохранность логотипа компании на графиках.
При запросе доступа к графикам обязательно указывать конечный домен, где они будут использоваться. При реализации одного из проектов мы подключали Forex-дату к графику, все настроили и запустили. За 2-й месяц заказчик данные Forex не проплатил, из-за этого графики полностью не загружались и отсутствовал логотип. После сложившейся ситуации проверяющий связался с заказчиком последством эл.почты с вопросами для разъяснения ситуации.
Получение доступа
У библиотеки закрытый доступ на GitHub, чтобы его получить необходимо:
- Заполнить заявку на сайте
- Подписать договор
- Получить доступ к репозиторию на GitHub
Мой опыт получения доступа
Спустя примерно 4 недели после заполнения заявки мне прислали договор для подписания. Через 3 дня после подписания открыли доступ к библиотеке. Судя по отзывам, период получения доступа плавает и точных сроков нет.
Не отображается график, даже с тестовыми данными
Для решения нужно подключить виджет и глобально указать доступ к бибилиотеке.
Подключение виджета
// для Nodejs
import { widget } from '../public/charting_library/charting_library.min'
const widget = new widget({ <options> })
Доступ к библиотеке
Указать глобальный путь к папке charting_library в опциях виджета library_path: '/charting_library/'
Глобальный путь будет отличаться от используемых модулей. В моем случае используется Vuejs с указанием в vue.config.js => publicPath: '/'. Структура папок: /public/index.html, /public/charting_library/ и настройки виджета, которые указаны выше.
Документация
Подключение данных
В базовом варианте используются тестовые данные. Далее необходимо подключить свой провайдер данных, используя одно из двух решений: JS API или UDF. Напрямую "скормить" массив данных не получится. Мы расмотрим JSAPI, UDF подключается аналогично, с отличием в указании конечной точки на сервере, откуда будет получать данные.
- JS API — подключение на стороне клиента
- UDF — подключение на серверной части
Основное отличие JSAPI от UDF, в отсутствии возможности для UDF добавить WebSocket подключение. При указании конечной точки на сервере, вы выставляете интервал для каждого запроса: datafeed: new Datafeeds.UDFCompatibleDatafeed('http://localhost:3000/datafeed', 1000)
Документация
TradingView JS API adapter
Чтобы настроить адаптер, нужно понимать, что каждый хук выполняется последовательно и для отладки лучше добавить вывод в консоль информации о запуске хука console.log('[<название хука>]: Method call').
Последовательность запуска: onReady => resolveSymbol => getBars => subscribeBars => unsubscribeBars.
Если вы меняете таймфрейм, символ, вызывается хук unsubscribeBars, который обращается к вашей функции, которая сбрасывает WebSocket подключение с провайдером данных. Если вы не используете subscribeBars, то и unsubscribeBars вам не нужен. getServerTime хук не обязательный, но если вам требуется использовать время сервера, подключайте его.
Если провайдер данных не отдает объемы, то можете указать в хуке resolveSymbol — has_no_volume: true.
export default {
// Инициализация настроек, должна отдаваться АСИНХРОННО
onReady: (callback) => {
console.log('[onReady]: Method call');
// setTimeout(() => callback(<объект с настройками>))
},
/*
// Не требуется, если не используете поиск
searchSymbols: (userInput, exchange, symbolType, onResultReadyCallback) => {
console.log('[searchSymbols]: Method call');
},
*/
// получение данных о конкретном символе
resolveSymbol: (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
console.log('[resolveSymbol]: Method call', symbolName);
// onSymbolResolvedCallback({ ..., has_no_volume: true})
},
// получение исторических данные для конкретного символа
getBars: (symbolInfo, interval, from, to, onHistoryCallback, onErrorCallback, firstDataRequest) => {
console.log('[getBars] Method call', symbolInfo, interval)
console.log('[getBars] First request', firstDataRequest)
},
// подписка на обновления WebSocket
subscribeBars: (symbolInfo, interval, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
console.log('[subscribeBars]: Method call with subscribeUID:', subscribeUID);
},
// вызывается для отписки от стрима
unsubscribeBars: (subscriberUID) => {
console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID);
},
getServerTime: (callback) => {}
};
Иногда провайдер данных не позволяет запрашивать данные напрямую с клиента, например биржа Binance, поэтому запрос можно прокидывать через прокси.
Документация JS API | Рабочий пример
TradingView UDF adapter
UDF адаптер актуален, когда данные запрашиваются со своего сервера. В конструкторе клиента нужно указать datafeed: new Datafeeds.UDFCompatibleDatafeed('http://localhost:3000/datafeed', 1000)
// пример оформления плагина для **Fastify**
// main.js
const app = Fastify()
app.register(import('./modules/tradingview'), {})
// tradingview.js
const plugin = async (app, options) => {
// проверяем работу конечной точки
app.get('/', (req, res) => {
res.code(200).header('Content-Type', 'text/plain')
.send('Welcome to UDF Adapter for TradingView. See ./config for more details.')
})
// время сервера
app.get('/time', (req, res) => {
console.log('[time]: Method call')
const time = Math.floor(Date.now() / 1000) // In seconds
res.code(200).header('Content-Type', 'text/plain').send(time.toString())
})
// аналог onReady
// https://github.com/tradingview/charting_library/wiki/UDF#data-feed-configuration-data
app.get('/config', (req, res) => {
console.log('[config]: Method call')
})
// вызывается если: supports_group_request: true & supports_search: false
app.get('/symbol_info', async (req, res) => {
console.log('[symbol_info]: Method call')
})
// вызывается если: supports_group_request: false & supports_search: true
app.get('/symbols', async (req, res) => {
console.log('[symbol_info]: Method call')
const symbol = await getSymbols(req.query.symbol)
return symbol
})
// аналог getBars, запрашивает исторических данные
app.get('/history', async (req, res) => {
console.log('[history]: Method call')
})
}
Документация UDF
JS API getBars хук вызывается много раз
Так бывает, когда не хватает данных и библиотека самостоятельно пытается "догрузить" информацию. В хуке getBars есть параметр firstDataRequest, который возвращает булевское значение true\false, используйте его. Возвращает true только при загрузке маркета.
getBars: (symbolInfo, interval, from, to, onHistoryCallback, onErrorCallback, firstDataRequest) => {
console.log('[getBars] Method call', symbolInfo, interval)
console.log('[getBars] First request', firstDataRequest)
if (firstDataRequest) {
console.log('do something')
}
},
У моего провайдера нет WebSocket подключения
Не обязательно использовать UDF провайдер, если нет стрима. Интервал запросов задать не получится для JS API адаптера, но это не мешает нам добавить setInterval в subscribeBars и отдавать данные для обновления.
subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
console.log('[subscribeBars]: Method call with subscribeUID:', subscribeUID)
window.interval = setInterval(function () {
getLastKline(symbolInfo.ticker, resolution).then(kline => onRealtimeCallback(kline))
}, 1000 * 60) // 60s update interval
unsubscribeBars: (subscriberUID) => {
console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID)
clearInterval(window.interval)
console.log('[unsubscribeBars]: cleared')
},
},
Рабочий пример
Кастомизация дизайна
По умолчанию доступны две темы: theme: "Light" || "Dark". Также можно использовать собственные цветовые решение. Со временем столкнетесь с проблемой, когда цвета поменялись везде, кроме header_widget (верхний блок с кнопками поиска, сравнения и пр.), его нужно менять через .css.
В опциях виджета нужно указать: custom_css_url: '/tradingview.css', где / — абсолютный путь от вашего index.html. С контентом:
.chart-controls-bar {
border-top: none !important;
}
.chart-page, .group-wWM3zP_M- {
background: transparent !important;
}
.pane-separator {
display: none !important;
}
Документация
Сохрание данных
Возможно понадобится сохранять "рисовалки".
Save\Load методы
Самый простой вариант, который можно использовать, если не планируется рисовать много на графиках. Простой, потому что можете вызвать объект со всеми данными графика widget.save(cb => this.setOverlay(cb)) и сохранить там, где будет удобно.
Рабочий пример
Save\Load adapter
Похож на UDF adapter. На сервере поднимаете конечные точки для сохранения\загрузки данных.
Документация
У меня что-то не работает, делаю все по документации
Реальный кейс, обратился фрилансер с проектом, проект был старый, он его переписывал. По итогу просто была старая версия библиотеки. Проверяйте версию.
Другая ситуация, когда пытаются вызвать методы у еще незагруженного графика, отслеживайте состояние через onChartReady. Если нет под капотом реактивности, чтобы отследить загрузку графика, используйте паттерн Observer.
widget.onChartReady(function() {
// It's now safe to call any other methods of the widget
});
Графики бибилиотеки отличаются от версий на сайте TradingView.com
Да, это нормально.
Как добавить ордера на график
После добавления ордера на график, нет доступа массиву, поэтому необходимо самостоятельно отслеживать ордера. Поделюсь своим решением оформленное в формате миксина для Vuejs, суть будет понятна.
import orders from '../../../multiblock/orders/mixin'
import createOrder from './createOrder'
import openOrders from './openOrders'
import trades from './trades'
export default {
mixins: [orders, createOrder, openOrders, trades],
data: () => ({
lines: new Map()
}),
watch: {
onChartReady(val) {
if (val) {
//* Uncomment: Testing price line
// this.line({ id: 'test', price: 0.021, quantity: 100 })
}
},
},
methods: {
// Line: open orders
positionLine(data) {
this.line(data)
.onCancel(() => {
this.deleteLine(data.id)
this.$bus.$emit('market-orders-deleteOrder', data.id)
})
.onMove(() => this.$bus.$emit('market-orders-updateOrder', { id: data.id, price: this.lines.get(data.id).getPrice() }))
},
// Line: order mobule ('price', 'stopPrice')
orderLine({ id = 'price', ...data }) {
this.line({ id, ...data })
.onMove(() => {
// Set new value on draging
this.$store.commit('setMarketOrder', { [id]: this.lines.get(id).getPrice() })
})
.onCancel(() => {
// Delete price line & set price = 0
this.deleteLine(id)
this.$store.commit('setMarketOrder', { [id]: 0 }) // set 0 value in vuex storage
})
},
line({ id = 'price', text = 'Price', color = '#ff9f0a', price, quantity, fontColor = '#fff', lineStyle = 2, lineLength = 25 }) {
if (this.lines.has(id)) this.deleteLine(id)
// Creating line from scratch
const widget = this.widget.chart().createOrderLine()
.setText(text)
.setPrice(price)
.setQuantity(quantity)
.onModify(res => res) // Need for dragging
// Customize color
.setLineColor(color)
.setBodyTextColor(fontColor)
.setBodyBorderColor(color)
.setBodyBackgroundColor(color)
.setQuantityBorderColor(color)
.setQuantityTextColor(fontColor)
.setQuantityBackgroundColor(color)
.setCancelButtonBorderColor(color)
.setCancelButtonBackgroundColor(color)
.setCancelButtonIconColor(fontColor)
.setLineLength(lineLength) // Margin right 25%
.setLineStyle(lineStyle)
this.lines.set(id, widget)
return widget // return for orderLine func()
},
deleteLine(id) {
this.lines.get(id).remove()
this.lines.delete(id)
},
deleteLines() {
this.lines.forEach((value, key) => this.deleteLine(key))
}
}
}
Документация
Как добавить формы на график
Добавлять можно исключительно предложенные библитекой формы, которые используются в тулбаре. Это необходимо, когда нужно вывести информацию на график.
Документация | Список доступных форм
Хочу использовать PineScript
charting_library не поддерживает такой функционал.
Хочу добавить свой индикатор
Посмотрите в сторону Custom Studies
Хочу использовать несколько графиков в одном окне
В бесплатной версии charting_library такой функционал отсутствует. При необходимости можно своими силами это сделать HTML+CSS.
Open source
- tradingview-jsapi-binance — подключенная биржа Binance c JS API адаптером и WebSocket стримом
- tradingview-jsapi-forex — данные Forex для JS API адаптера. Ежеминутное обновлением данных без WebSocket с Save\Load методами
Заключение
Статья будет дополняться. Если есть кейс с проблемой — решением, пишите, дополню статью с указанием авторства. Возможно вопросы и пожелания, пишите в комментариях, будет интересно услышать Ваше мнение :)
Спасибо за внимание!
===========
Источник:
habr.com
===========
Похожие новости:
- [ReactJS, JavaScript] React 17: Ничего нового? (перевод)
- [JavaScript, Node.JS] Выбираем финансовые графики для своего приложения
- [Разработка веб-сайтов, CSS, JavaScript, HTML, Accessibility] Делаем модальные окна для сайта. Заботимся об удобстве и доступности
- Проект Genode опубликовал выпуск ОС общего назначения Sculpt 20.08
- [JavaScript, Google Chrome, Node.JS, Браузеры, Локализация продуктов] Intl.Segmenter: сегментация Юникода в JavaScript (перевод)
- [JavaScript, Node.JS, ReactJS, Клиентская оптимизация] Перфоманс фронтенда как современное искусство: графики, код, кулстори
- [JavaScript, Node.JS, Программирование, Разработка веб-сайтов] Web Cryptography API: пример использования
- [JavaScript, TypeScript, SvelteJS] Svelte <3 TypeScript (перевод)
- [DevOps, Kubernetes, Интервью, Серверное администрирование] Команда поддержки систем хранения данных Bloomberg полагается на открытый исходный код и SDS (перевод)
- Прекращение разработки библиотеки Moment.js, имеющей 12 млн загрузок в неделю
Теги для поиска: #_javascript, #_node.js, #_tradingview, #_charting_library, #_jsapi, #_udf, #_javascript, #_node, #_finansovye_grafiki (финансовые графики), #_binance, #_forex, #_javascript, #_node.js
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 17:00
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Если Вы — фрилансер или CTO финансового проекта, рано или позно Вы столкнетесь с вопросом подключения графиков, я сэкономлю Вам минимум сутки работы. Те, кто уже используют эту библиотеку, возможно, найдут что-то новое. Статья будет в формате "книги рецептов" с open source решениями для криптовалютной биржи Binance и Forex. Привет, Хабр! У библиотеки TradingView (charting_library) высокий порог входа, при этом менее популярной она не стала из-за того, что используется на одноименном сервисе TradingView.com. Решил сделать "книгу рецептов" с ответами на основные вопросы. Эта статья продолжение поста: "Финансовые графики для вашего приложения". Cook book Контент буду дополнять по мере появляния новых сложностей. Если у Вас есть вопросы и Вы не нашли ответы в статье, пишите в комментариях, будем разбираться вместе :) В статье буду указывать ссылки на документацию. Если, при переходе по ссылке, у Вас открывается 404 страница, это означает, что у Вас нет доступа. Лицензия Можно использовать бесплатно в коммерческих и некоммерческих целях. Самый главный критерий — сохранность логотипа компании на графиках. При запросе доступа к графикам обязательно указывать конечный домен, где они будут использоваться. При реализации одного из проектов мы подключали Forex-дату к графику, все настроили и запустили. За 2-й месяц заказчик данные Forex не проплатил, из-за этого графики полностью не загружались и отсутствовал логотип. После сложившейся ситуации проверяющий связался с заказчиком последством эл.почты с вопросами для разъяснения ситуации. Получение доступа У библиотеки закрытый доступ на GitHub, чтобы его получить необходимо:
Мой опыт получения доступа Спустя примерно 4 недели после заполнения заявки мне прислали договор для подписания. Через 3 дня после подписания открыли доступ к библиотеке. Судя по отзывам, период получения доступа плавает и точных сроков нет. Не отображается график, даже с тестовыми данными Для решения нужно подключить виджет и глобально указать доступ к бибилиотеке. Подключение виджета // для Nodejs
import { widget } from '../public/charting_library/charting_library.min' const widget = new widget({ <options> }) Доступ к библиотеке Указать глобальный путь к папке charting_library в опциях виджета library_path: '/charting_library/' Глобальный путь будет отличаться от используемых модулей. В моем случае используется Vuejs с указанием в vue.config.js => publicPath: '/'. Структура папок: /public/index.html, /public/charting_library/ и настройки виджета, которые указаны выше. Документация Подключение данных В базовом варианте используются тестовые данные. Далее необходимо подключить свой провайдер данных, используя одно из двух решений: JS API или UDF. Напрямую "скормить" массив данных не получится. Мы расмотрим JSAPI, UDF подключается аналогично, с отличием в указании конечной точки на сервере, откуда будет получать данные.
Основное отличие JSAPI от UDF, в отсутствии возможности для UDF добавить WebSocket подключение. При указании конечной точки на сервере, вы выставляете интервал для каждого запроса: datafeed: new Datafeeds.UDFCompatibleDatafeed('http://localhost:3000/datafeed', 1000) Документация TradingView JS API adapter Чтобы настроить адаптер, нужно понимать, что каждый хук выполняется последовательно и для отладки лучше добавить вывод в консоль информации о запуске хука console.log('[<название хука>]: Method call'). Последовательность запуска: onReady => resolveSymbol => getBars => subscribeBars => unsubscribeBars. Если вы меняете таймфрейм, символ, вызывается хук unsubscribeBars, который обращается к вашей функции, которая сбрасывает WebSocket подключение с провайдером данных. Если вы не используете subscribeBars, то и unsubscribeBars вам не нужен. getServerTime хук не обязательный, но если вам требуется использовать время сервера, подключайте его. Если провайдер данных не отдает объемы, то можете указать в хуке resolveSymbol — has_no_volume: true. export default {
// Инициализация настроек, должна отдаваться АСИНХРОННО onReady: (callback) => { console.log('[onReady]: Method call'); // setTimeout(() => callback(<объект с настройками>)) }, /* // Не требуется, если не используете поиск searchSymbols: (userInput, exchange, symbolType, onResultReadyCallback) => { console.log('[searchSymbols]: Method call'); }, */ // получение данных о конкретном символе resolveSymbol: (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => { console.log('[resolveSymbol]: Method call', symbolName); // onSymbolResolvedCallback({ ..., has_no_volume: true}) }, // получение исторических данные для конкретного символа getBars: (symbolInfo, interval, from, to, onHistoryCallback, onErrorCallback, firstDataRequest) => { console.log('[getBars] Method call', symbolInfo, interval) console.log('[getBars] First request', firstDataRequest) }, // подписка на обновления WebSocket subscribeBars: (symbolInfo, interval, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => { console.log('[subscribeBars]: Method call with subscribeUID:', subscribeUID); }, // вызывается для отписки от стрима unsubscribeBars: (subscriberUID) => { console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID); }, getServerTime: (callback) => {} }; Иногда провайдер данных не позволяет запрашивать данные напрямую с клиента, например биржа Binance, поэтому запрос можно прокидывать через прокси. Документация JS API | Рабочий пример TradingView UDF adapter UDF адаптер актуален, когда данные запрашиваются со своего сервера. В конструкторе клиента нужно указать datafeed: new Datafeeds.UDFCompatibleDatafeed('http://localhost:3000/datafeed', 1000) // пример оформления плагина для **Fastify**
// main.js const app = Fastify() app.register(import('./modules/tradingview'), {}) // tradingview.js const plugin = async (app, options) => { // проверяем работу конечной точки app.get('/', (req, res) => { res.code(200).header('Content-Type', 'text/plain') .send('Welcome to UDF Adapter for TradingView. See ./config for more details.') }) // время сервера app.get('/time', (req, res) => { console.log('[time]: Method call') const time = Math.floor(Date.now() / 1000) // In seconds res.code(200).header('Content-Type', 'text/plain').send(time.toString()) }) // аналог onReady // https://github.com/tradingview/charting_library/wiki/UDF#data-feed-configuration-data app.get('/config', (req, res) => { console.log('[config]: Method call') }) // вызывается если: supports_group_request: true & supports_search: false app.get('/symbol_info', async (req, res) => { console.log('[symbol_info]: Method call') }) // вызывается если: supports_group_request: false & supports_search: true app.get('/symbols', async (req, res) => { console.log('[symbol_info]: Method call') const symbol = await getSymbols(req.query.symbol) return symbol }) // аналог getBars, запрашивает исторических данные app.get('/history', async (req, res) => { console.log('[history]: Method call') }) } Документация UDF JS API getBars хук вызывается много раз Так бывает, когда не хватает данных и библиотека самостоятельно пытается "догрузить" информацию. В хуке getBars есть параметр firstDataRequest, который возвращает булевское значение true\false, используйте его. Возвращает true только при загрузке маркета. getBars: (symbolInfo, interval, from, to, onHistoryCallback, onErrorCallback, firstDataRequest) => {
console.log('[getBars] Method call', symbolInfo, interval) console.log('[getBars] First request', firstDataRequest) if (firstDataRequest) { console.log('do something') } }, У моего провайдера нет WebSocket подключения Не обязательно использовать UDF провайдер, если нет стрима. Интервал запросов задать не получится для JS API адаптера, но это не мешает нам добавить setInterval в subscribeBars и отдавать данные для обновления. subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
console.log('[subscribeBars]: Method call with subscribeUID:', subscribeUID) window.interval = setInterval(function () { getLastKline(symbolInfo.ticker, resolution).then(kline => onRealtimeCallback(kline)) }, 1000 * 60) // 60s update interval unsubscribeBars: (subscriberUID) => { console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID) clearInterval(window.interval) console.log('[unsubscribeBars]: cleared') }, }, Рабочий пример Кастомизация дизайна По умолчанию доступны две темы: theme: "Light" || "Dark". Также можно использовать собственные цветовые решение. Со временем столкнетесь с проблемой, когда цвета поменялись везде, кроме header_widget (верхний блок с кнопками поиска, сравнения и пр.), его нужно менять через .css. В опциях виджета нужно указать: custom_css_url: '/tradingview.css', где / — абсолютный путь от вашего index.html. С контентом: .chart-controls-bar {
border-top: none !important; } .chart-page, .group-wWM3zP_M- { background: transparent !important; } .pane-separator { display: none !important; } Документация Сохрание данных Возможно понадобится сохранять "рисовалки". Save\Load методы Самый простой вариант, который можно использовать, если не планируется рисовать много на графиках. Простой, потому что можете вызвать объект со всеми данными графика widget.save(cb => this.setOverlay(cb)) и сохранить там, где будет удобно. Рабочий пример Save\Load adapter Похож на UDF adapter. На сервере поднимаете конечные точки для сохранения\загрузки данных. Документация У меня что-то не работает, делаю все по документации Реальный кейс, обратился фрилансер с проектом, проект был старый, он его переписывал. По итогу просто была старая версия библиотеки. Проверяйте версию. Другая ситуация, когда пытаются вызвать методы у еще незагруженного графика, отслеживайте состояние через onChartReady. Если нет под капотом реактивности, чтобы отследить загрузку графика, используйте паттерн Observer. widget.onChartReady(function() {
// It's now safe to call any other methods of the widget }); Графики бибилиотеки отличаются от версий на сайте TradingView.com Да, это нормально. Как добавить ордера на график После добавления ордера на график, нет доступа массиву, поэтому необходимо самостоятельно отслеживать ордера. Поделюсь своим решением оформленное в формате миксина для Vuejs, суть будет понятна. import orders from '../../../multiblock/orders/mixin'
import createOrder from './createOrder' import openOrders from './openOrders' import trades from './trades' export default { mixins: [orders, createOrder, openOrders, trades], data: () => ({ lines: new Map() }), watch: { onChartReady(val) { if (val) { //* Uncomment: Testing price line // this.line({ id: 'test', price: 0.021, quantity: 100 }) } }, }, methods: { // Line: open orders positionLine(data) { this.line(data) .onCancel(() => { this.deleteLine(data.id) this.$bus.$emit('market-orders-deleteOrder', data.id) }) .onMove(() => this.$bus.$emit('market-orders-updateOrder', { id: data.id, price: this.lines.get(data.id).getPrice() })) }, // Line: order mobule ('price', 'stopPrice') orderLine({ id = 'price', ...data }) { this.line({ id, ...data }) .onMove(() => { // Set new value on draging this.$store.commit('setMarketOrder', { [id]: this.lines.get(id).getPrice() }) }) .onCancel(() => { // Delete price line & set price = 0 this.deleteLine(id) this.$store.commit('setMarketOrder', { [id]: 0 }) // set 0 value in vuex storage }) }, line({ id = 'price', text = 'Price', color = '#ff9f0a', price, quantity, fontColor = '#fff', lineStyle = 2, lineLength = 25 }) { if (this.lines.has(id)) this.deleteLine(id) // Creating line from scratch const widget = this.widget.chart().createOrderLine() .setText(text) .setPrice(price) .setQuantity(quantity) .onModify(res => res) // Need for dragging // Customize color .setLineColor(color) .setBodyTextColor(fontColor) .setBodyBorderColor(color) .setBodyBackgroundColor(color) .setQuantityBorderColor(color) .setQuantityTextColor(fontColor) .setQuantityBackgroundColor(color) .setCancelButtonBorderColor(color) .setCancelButtonBackgroundColor(color) .setCancelButtonIconColor(fontColor) .setLineLength(lineLength) // Margin right 25% .setLineStyle(lineStyle) this.lines.set(id, widget) return widget // return for orderLine func() }, deleteLine(id) { this.lines.get(id).remove() this.lines.delete(id) }, deleteLines() { this.lines.forEach((value, key) => this.deleteLine(key)) } } } Документация Как добавить формы на график Добавлять можно исключительно предложенные библитекой формы, которые используются в тулбаре. Это необходимо, когда нужно вывести информацию на график. Документация | Список доступных форм Хочу использовать PineScript charting_library не поддерживает такой функционал. Хочу добавить свой индикатор Посмотрите в сторону Custom Studies Хочу использовать несколько графиков в одном окне В бесплатной версии charting_library такой функционал отсутствует. При необходимости можно своими силами это сделать HTML+CSS. Open source
Заключение Статья будет дополняться. Если есть кейс с проблемой — решением, пишите, дополню статью с указанием авторства. Возможно вопросы и пожелания, пишите в комментариях, будет интересно услышать Ваше мнение :) Спасибо за внимание! =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 17:00
Часовой пояс: UTC + 5