async function waitForVariable(variableName, timeout = 5000) { const startTime = Date.now(); while (typeof window[variableName] === 'undefined') { if (Date.now() - startTime > timeout) { throw new Error(`Variable '${variableName}' not defined within ${timeout}ms`); } await new Promise(resolve => setTimeout(resolve, 100)); } console.log(`Variable '${variableName}' is now defined.`); } async function update_tv(data_dict) { window.data.push({ time: data_dict.timestamp, value: data_dict.value }); window.data_b.push({ time: data_dict.timestamp_b, value: data_dict.value_b }); window.data_c.push({ time: data_dict.timestamp_c, value: data_dict.value_c }); window.data_tgt.push({ time: data_dict.timestamp_c, value: data_dict.target }); window.lineSeries.update({ time: data_dict.timestamp, value: data_dict.value }); window.lineSeries_b.update({ time: data_dict.timestamp_b, value: data_dict.value_b }); window.lineSeries_c.update({ time: data_dict.timestamp_c, value: data_dict.value_c }); window.lineSeries_tgt.update({ time: data_dict.timestamp_c, value: data_dict.target }); // midPriceLine.applyOptions({ // price: data_dict.mid_px, // color: '#c78228', // lineWidth: 3, // lineStyle: LightweightCharts.LineStyle.Dashed, // axisLabelVisible: true, // }); window.chart.timeScale().scrollToRealTime(); // const currentRange = window.chart.timeScale().getVisibleLogicalRange(); // window.chart.timeScale().fitContent(); // window.chart.timeScale().setVisibleLogicalRange(currentRange); const MAX_DATA_POINTS = data_dict.LOOKBACK_RT_TV_MAX_POINTS; if (window.lineSeries.data().length > MAX_DATA_POINTS) { window.lineSeries.setData(lineSeries.data().slice(-MAX_DATA_POINTS)); } if (window.lineSeries_b.data().length > MAX_DATA_POINTS) { window.lineSeries_b.setData(lineSeries_b.data().slice(-MAX_DATA_POINTS)); } if (window.lineSeries_c.data().length > MAX_DATA_POINTS) { window.lineSeries_c.setData(lineSeries_c.data().slice(-MAX_DATA_POINTS)); } if (window.lineSeries_tgt.data().length > MAX_DATA_POINTS) { window.lineSeries_tgt.setData(lineSeries_tgt.data().slice(-MAX_DATA_POINTS)); } }; async function create_tv() { window.chart = LightweightCharts.createChart(document.getElementById('tv'), { autoSize: true, toolbox: true, timeScale: { timeVisible: true, // Shows HH:mm on x-axis secondsVisible: true // Optional: show seconds }, rightPriceScale: { visible: true, autoScale: true }, leftPriceScale: { visible: true }, layout: { background: { type: 'solid', color: '#222' }, textColor: '#DDD', }, grid: { vertLines: { color: '#e1e1e1', // Set vertical line color visible: true, style: 2, // 0: Solid, 1: Dashed, 2: Dotted, 3: LargeDashed, 4: SparseDotted }, horzLines: { color: '#e1e1e1', // Set horizontal line color visible: true, style: 2, }, }, crosshair: { mode: LightweightCharts.CrosshairMode.Normal }, } ); window.lineSeries = chart.addSeries(LightweightCharts.LineSeries, { color: '#94fcdf', priceScaleId: 'right' // topColor: '#94fcdf', // bottomColor: 'rgba(112, 171, 249, 0.28)', // invertFilledArea: false }); window.lineSeries_b = chart.addSeries(LightweightCharts.LineSeries, { color: '#dd7525', priceScaleId: 'right' // topColor: '#94fcdf', // bottomColor: 'rgba(112, 171, 249, 0.28)', // invertFilledArea: false }); window.lineSeries_c = chart.addSeries(LightweightCharts.LineSeries, { color: '#ea0707', priceScaleId: 'left', autoscaleInfoProvider: () => ({ priceRange: { minValue: 0.0, maxValue: 1.0 } }) // topColor: '#94fcdf', // bottomColor: 'rgba(112, 171, 249, 0.28)', // invertFilledArea: false }); window.lineSeries_tgt = chart.addSeries(LightweightCharts.LineSeries, { color: '#ffffff', priceScaleId: 'right', lineStyle: LightweightCharts.LineStyle.Dashed // topColor: '#94fcdf', // bottomColor: 'rgba(112, 171, 249, 0.28)', // invertFilledArea: false }); // window.midPriceLine_Config = { // price: 0, // color: '#c78228', // lineWidth: 3, // lineStyle: LightweightCharts.LineStyle.Dashed, // axisLabelVisible: false, // }; // window.midPriceLine = window.lineSeries.createPriceLine(midPriceLine_Config); window.data = []; window.data_b = []; window.data_c = []; window.data_tgt = []; window.lineSeries.setData(window.data); window.lineSeries_b.setData(window.data_b); window.lineSeries_c.setData(window.data_c); window.lineSeries_tgt.setData(window.data_tgt); // Create and style the tooltip html element const container = document.getElementById('tv'); window.toolTipWidth = 200; const toolTip = document.createElement('div'); toolTip.style = `width: ${window.toolTipWidth}px; height: 100%; position: absolute; display: none; padding: 8px; box-sizing: border-box; font-size: 12px; text-align: left; z-index: 1000; top: 12px; left: 12px; pointer-events: none; border-radius: 4px 4px 0px 0px; border-bottom: none; box-shadow: 0 2px 5px 0 rgba(117, 134, 150, 0.45);font-family: -apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;`; toolTip.style.background = `rgba(${'0, 0, 0'}, 0.25)`; toolTip.style.color = 'white'; toolTip.style.borderColor = 'rgba( 239, 83, 80, 1)'; container.appendChild(toolTip); // update tooltip window.chart.subscribeCrosshairMove(async param => { if ( param.point === undefined || !param.time || param.point.x < 0 || param.point.x > container.clientWidth || param.point.y < 0 || param.point.y > container.clientHeight ) { toolTip.style.display = 'none'; } else { // toolTip.style.height = '100%'; toolTip.style.alignContent = 'center'; const dateStr = new Date(param.time*1000).toISOString(); let data = await param.seriesData.get(window.lineSeries); if (data === undefined) { data = {} data.value = 0 console.log('data is UNDEFINED, SETTING TO 0') }; let data_b = await param.seriesData.get(window.lineSeries_b); if (data_b === undefined) { data_b = {} data_b.value = 0 console.log('data is UNDEFINED, SETTING TO 0') }; const value_px = data.value const value_px_b = window.data_b.value const value_px_c = window.data_c.value const value_px_tgt = window.data_tgt.value toolTip.style.display = 'block'; //
// Atwater Trading //
toolTip.innerHTML = `
Chainlink: ${Math.round(100 * value_px) / 100} Binance: ${Math.round(100 * value_px_b) / 100}
${dateStr}
`; let left = param.point.x; // relative to timeScale const timeScaleWidth = chart.timeScale().width(); const priceScaleWidth = chart.priceScale('left').width(); const halfTooltipWidth = toolTipWidth / 2; left += priceScaleWidth - halfTooltipWidth; left = Math.min(left, priceScaleWidth + timeScaleWidth - toolTipWidth); left = Math.max(left, priceScaleWidth); toolTip.style.left = left + 'px'; toolTip.style.top = 0 + 'px'; } }); window.chart.timeScale().fitContent(); console.log("TV Created!") };