콘텐츠로 건너뛰기

10-1. 차트 고도화: 이동평균선 및 반감기 차트 구현

  • 기준

주식이나 코인 투자자들이 차트를 볼 때 가장 먼저 추가하는 대표적인 지표가 무엇일까요? 바로 이동평균선(Moving Average)입니다. 그리고 비트코인 투자자들에게 나침반 역할을 하는 가장 핵심적인 이벤트는 반감기(Halving)입니다.

단순히 시세 캔들만 덩그러니 놓인 차트는 시장의 대세 흐름을 읽기에 부족합니다. 차트에 기술적 지표인 이동평균선을 부드럽게 얹어 흐름을 읽게 하고, 반감기라는 특수 이벤트를 수직선으로 표시하여 시계열적인 가격 변동 패턴을 한눈에 추적할 수 있도록 차트를 한 단계 고도화해 보겠습니다.

이동평균선(SMA/EMA)의 원리와 필요성

이동평균선은 일정 기간 동안의 가격 평균값을 선으로 연결하여 시세의 흐름(추세)을 직관적으로 보여주는 지표입니다.

  1. 단순 이동평균선(SMA – Simple Moving Average): 지정된 기간(예: 20일, 50일, 120일) 동안의 종가를 산술평균한 선입니다. 모든 거래일에 동일한 가중치를 두어 장기 추세를 파악할 때 유리합니다.
  2. 지수 이동평균선(EMA – Exponential Moving Average): 최근 거래일에 더 높은 가중치를 주어 계산하는 방식입니다. 최근 가격 변동에 더 민감하게 반응하므로 급격한 추세 전환을 빠르게 감지해야 하는 단기 매매에 유용합니다.

비트코인 반감기(Halving) 시각화의 가치

비트코인은 약 4년마다 블록 채굴 보상이 절반으로 줄어드는 ‘반감기’를 겪습니다. 역사적으로 비트코인은 반감기를 거친 후 공급 쇼크로 인해 강력한 불장(Bull Market)을 만들어왔습니다. 차트의 X축(날짜)에 반감기 라인을 수직선(plotLines)으로 그어주는 것만으로도, 과거 반감기 이후 가격이 어떻게 우상향했는지 역사적 흐름을 완벽하게 투영해 줄 수 있습니다.

🤖 실전! 이동평균선 및 반감기 차트 구현(2-17)

🧠 이번 실습은 Highcharts Stock 라이브러리를 활용하여 기존 캔들스틱 차트에 20일, 50일 단순 이동평균선(SMA)을 동적으로 계산하여 추가하고, 비트코인의 주요 반감기 일정들을 차트 내 수직 점선으로 시각화하는 과정입니다.

사전작업

Highcharts의 plotLines 기능을 이용하면 특정 날짜의 타임스탬프 위치에 선을 쉽게 그릴 수 있습니다. 또한, 기술적 지표 계산 모듈을 설치하거나 React 단에서 배열 데이터를 활용해 직접 이동평균을 구해서 새로운 Series로 추가할 수 있습니다. 여기서는 외부 라이브러리 추가 없이 데이터 연산 성능을 최적화하여 캔들과 이동평균을 동시에 그리는 방식을 적용합니다.

✨ 사용자의 의도(Vibe)

기존 HighChartGUI.tsx를 업그레이드하거나 신규 컴포넌트를 생성하여 이동평균선과 반감기 수직선이 표시되도록 해줘.

  1. 파일명: frontend/src/components/charts/highchart/HighChartAdvanced.tsx
  2. 기능 1: 캔들스틱 데이터 배열을 기반으로 20일, 50일 이동평균선(SMA) 데이터를 자바스크립트로 계산하여 종가 캔들 위에 선 차트(Series)로 함께 그려줘.
  3. 기능 2: 비트코인 주요 반감기 날짜(1차: 2012-11-28, 2차: 2016-07-09, 3차: 2020-05-11, 4차: 2024-04-20)의 타임스탬프 위치에 빨간색 점선으로 수직선(plotLines)과 텍스트 라벨(“Halving”)을 xAxis에 표시해줘.
  4. 기능 3: 모바일 환경에서도 가독성이 유지되도록 내비게이터(Navigator)와 범위 선택기(Range Selector)가 정상적으로 표시되도록 해줘.

💻 AI가 생성한 코드 (Syntax) 및 결과

  1. frontend/src/components/charts/highchart/HighChartAdvanced.tsx
"use client";  import React, { useEffect, useRef } from "react"; import Highcharts from "highcharts/highstock"; import HighchartsReact from "highcharts-react-official";  // 이동평균선(SMA) 계산 함수
function calculateSMA(data: [number, number, number, number, number, number][], period: number): [number, number][] {   const sma: [number, number][] = [];   for (let i = period - 1; i < data.length; i++) {     let sum = 0;     for (let j = 0; j < period; j++) {       sum += data[i - j][4]; // 종가(Close) 합산     }     sma.push([data[i][0], sum / period]);   }
return sma; }  interface HighChartAdvancedProps {   data: [number, number, number, number, number, number][]; // [time, open, high, low, close, volume]   symbol: string; }  export default
function HighChartAdvanced({ data, symbol }: HighChartAdvancedProps) {   const chartComponentRef = useRef<HighchartsReact.RefObject>(null);    const sma20 = calculateSMA(data, 20);   const sma50 = calculateSMA(data, 50);    // 반감기 날짜 설정 (UTC 타임스탬프 변환)   const halvingDates = [     { date: "2012-11-28", label: "1st Halving" },     { date: "2016-07-09", label: "2nd Halving" },     { date: "2020-05-11", label: "3rd Halving" },     { date: "2024-04-20", label: "4th Halving" }   ];    const plotLines = halvingDates.map(h => ({     value: new Date(h.date).getTime(),     color: "#FF4D4D",     dashStyle: "Dash" as const,     width: 1.5,     label: {       text: h.label,       style: { color: "#FF4D4D", fontSize: "10px", fontWeight: "bold" },       y: 20     }   }));    const options: Highcharts.Options = {     title: { text: `${symbol} Advanced Chart` },     xAxis: {       type: "datetime",       plotLines: plotLines     },     yAxis: [{       title: { text: "Price" },       height: "70%",       lineWidth: 2     }, {       title: { text: "Volume" },       top: "75%",       height: "25%",       offset: 0,       lineWidth: 2     }],     series: [       {         type: "candlestick",         name: symbol,         data: data,         yAxis: 0       },       {         type: "line",         name: "SMA 20",         data: sma20,         color: "#22C55E",         lineWidth: 1.5,         marker: { enabled: false }       },       {         type: "line",         name: "SMA 50",         data: sma50,         color: "#3B82F6",         lineWidth: 1.5,         marker: { enabled: false }       }     ]   };
return (     <div className="w-full bg-white dark:bg-gray-800 p-4 rounded-xl shadow-md">       <HighchartsReact         highcharts={Highcharts}         constructorType={"stockChart"}         options={options}         ref={chartComponentRef}       />     </div>   ); }
  1. 리빌드 후 차트를 실행하면, 기존 캔들 위에 20일선(초록)과 50일선(파랑)이 부드럽게 그려집니다. 또한 비트코인 차트를 로드해 과거 기간으로 줌 아웃하면 반감기 날짜마다 세로 점선이 선명하게 나타납니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다