HTML + Javascript를 이용하여 브라우저에 아래와 같은 캔들 차트를 그려보자.

* 차트 예시 실행해보기 → Draw chart exam (sparrow-lee.github.io)

 

Draw chart exam

 

sparrow-lee.github.io

위 예시 데이터는 비트코인 4시간봉 데이터를 업비트에서 Rest API로 가져와서 그린 것으로 실시간 데이터를 가져온 것이다. 업비트에서 오픈으로 제공하고 있고 별도 auth나 secret key가 필요하진 않다.

 

분(Minute) 캔들 (upbit.com)

 

Open API | 업비트 개발자 센터

 

docs.upbit.com

 

    async function getBitPrice({count, market, unit, name}) {
        let url = `https://api.upbit.com/v1/candles/minutes/${unit}?market=${market}&count=${count}`;
        const response = await fetch(url);
        const prices = await response.json();

 

cdn에 올려서 제공하는 라이브러리 스크립트를 가져다 쓸 수 있다.

 

Plotly.newPlot('chartDiv', data, layout);
// javascript에서 데이터, 레이아웃 및 그려질 div id를 넘겨주면 그려준다

 

 

※ 아래는 전체 코드

 

<html lang="ko">
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>
    <meta charset="utf-8" />
    <title>Draw chart exam</title>
    <script src="https://cdn.plot.ly/plotly-2.27.0.min.js" charset="utf-8"></script>
    <script>
        async function onLoad() {
            console.log('onLoad')
            let market = 'KRW-BTC';
            let unit = '240';
            let name = '비트코인';
            let res = await getBitPrice({count: 100, market, unit, name});
            drawChart(res.trace, res.info);
        }


        async function getBitPrice({count, market, unit, name}) {
            let url = `https://api.upbit.com/v1/candles/minutes/${unit}?market=${market}&count=${count}`;
            const response = await fetch(url);
            const prices = await response.json();
            console.log(prices);

            let pricesSorted = prices.sort((a, b) => a.timestamp - b.timestamp);    // 시간순으로 정렬

            let x = [];
            let high = [];
            let low = [];
            let open = [];
            let close = [];

            let info = {};
            // 차트 그릴 때, 최소, 최대값 range를 설정하기 위해.
            lowest_price = pricesSorted[0].low_price;
            highest_price = pricesSorted[0].high_price;
            pricesSorted.forEach((p) => {
                x.push(p.candle_date_time_kst);
                high.push(p.high_price);
                low.push(p.low_price);
                open.push(p.opening_price);
                close.push(p.trade_price);

                lowest_price = lowest_price > p.low_price ? p.low_price : lowest_price;
                highest_price = highest_price < p.high_price ? p.high_price : highest_price;
            })

            info = {
                lowest_price,
                highest_price,
                market,
                name
            }

            // 차트 그릴 때 필요로 하는 정보들. 캔들값을 배열로.
            let trace = {
                x,
                high,
                low,
                open,
                close,
                decreasing: {line: {color: 'blue'}},
                increasing: {line: {color: 'red'}},
                line: {color: 'rgba(31,119,180,1)'},
                type: 'candlestick', 
                xaxis: 'x', 
                yaxis: 'y'
            }
            console.log(info);
            console.log('>> getBitPrice done')
            return {trace, info};
        }

        function drawChart(trace, info) {
            var data = [trace];
                
            var layout = {
                dragmode: 'zoom', 
                margin: {
                    r: 10, 
                    t: 25, 
                    b: 40, 
                    l: 60
                }, 
                showlegend: false, 
                xaxis: {
                    autorange: true, 
                    domain: [0, 1], 
                    //range: ['2017-01-03 12:00', '2017-02-15 12:00'], 
                    range: [trace.x[0], trace.x[trace.x.length - 1]],
                    rangeslider: {range: [trace.x[0], trace.x[trace.x.length - 1]]}, 
                    title: info.name + ' / ' + info.market, 
                    type: 'date',
                    rangeslider: {
                        visible: false
                    }
                }, 
                yaxis: {
                    autorange: true, 
                    domain: [0, 1], 
                    range: [info.lowest_price * 0.95, info.highest_price * 1.05], 
                    type: 'linear'
                }
            };
                
            Plotly.newPlot('chartDiv', data, layout);
            console.log('>> drawChart done')
        }
    </script>
</head>
<body onload="onLoad()">
    <div id="chartDiv" style="width:100%;height:500px;"></div>
</body>
</html>

 

 

실시간으로 데이터를 가져온 뒤 그려주는 것이어서, async - await를 잘 써주자.

setTimeout 같은걸 이용하면 실시간 업데이트해서 캔들을 보여주는것도 가능할 거 같다.

Github 소스코드 참고

exam-codes-public/javascript/draw-chart.html at main · sparrow-lee/exam-codes-public (github.com)

 

 

 

 

+ Recent posts