본문으로 건너뛰기
-
✨ 즐거움이 가득한 흥인 연구소 💡-> 지금 바로가기
로고 다크모드 로고 흥인 (heung-in)

✨ AI와 코딩으로 일상과 업무의 해답을 직접 만드는 공간🛠️

로고 다크모드 로고 흥인 (heung-in)

✨ AI와 코딩으로 일상과 업무의 해답을 직접 만드는 공간🛠️

  • 흥인이란
    • 운영자 소개 (About Us)
    • 개인정보처리방침 (Privacy Policy)
    • 문의하기 (Contact Us)
  • 🛠️내 손으로 만든 웹 툴 (계산기/분석기)
  • 📚 AI 자동화 & 프롬프트 가이드
  • 🌐 1인 마이크로 SaaS & 수익화
  • 흥인이란
    • 운영자 소개 (About Us)
    • 개인정보처리방침 (Privacy Policy)
    • 문의하기 (Contact Us)
  • 🛠️내 손으로 만든 웹 툴 (계산기/분석기)
  • 📚 AI 자동화 & 프롬프트 가이드
  • 🌐 1인 마이크로 SaaS & 수익화
닫기

검색

로고 다크모드 로고 흥인 (heung-in)

✨ AI와 코딩으로 일상과 업무의 해답을 직접 만드는 공간🛠️

로고 다크모드 로고 흥인 (heung-in)

✨ AI와 코딩으로 일상과 업무의 해답을 직접 만드는 공간🛠️

  • 흥인이란
    • 운영자 소개 (About Us)
    • 개인정보처리방침 (Privacy Policy)
    • 문의하기 (Contact Us)
  • 🛠️내 손으로 만든 웹 툴 (계산기/분석기)
  • 📚 AI 자동화 & 프롬프트 가이드
  • 🌐 1인 마이크로 SaaS & 수익화
  • 흥인이란
    • 운영자 소개 (About Us)
    • 개인정보처리방침 (Privacy Policy)
    • 문의하기 (Contact Us)
  • 🛠️내 손으로 만든 웹 툴 (계산기/분석기)
  • 📚 AI 자동화 & 프롬프트 가이드
  • 🌐 1인 마이크로 SaaS & 수익화
닫기

검색

🛠️내 손으로 만든 웹 툴 (계산기/분석기)

나스닥·코스피·환율·금리, 이제 창 하나로 다 봅니다 [2편] 기술 구현과 트러블슈팅

사진
By youn3345
2026년 08월 07일 3 Min Read
0

지난 [1편]에서는 마켓 브리핑 대시보드를 왜, 무엇을 넣어 만들었는지 다뤘습니다. 이번 편에서는 실제 구현 방식과, 만들면서 가장 애먹었던 문제를 코드와 함께 기록합니다.

Table of Contents

Toggle
  • 1. 왜 서버 대신 구글 앱스 스크립트(GAS)를 선택했나
  • 2. 데이터는 어디서 가져오나 — Yahoo Finance 비공식 API
  • 3. 60초 캐싱으로 API 호출 최소화
  • 4. 히스토리 저장 — 구글 시트를 데이터베이스처럼
  • 5. 가장 애먹었던 문제 — 날짜가 하루씩 밀리는 버그
    • 증상
    • 첫 번째 가설 (틀림)
    • 진짜 원인
    • 해결 방법
  • 6. 하나 더 — 응답이 예전 버전처럼 보이는 문제
  • 7. 마무리하며

1. 왜 서버 대신 구글 앱스 스크립트(GAS)를 선택했나

지금까지 만든 계산기들은 대부분 제 서버(CentOS + Apache)에 HTML 파일을 직접 올리는 방식이었습니다. 그런데 이 방식은 예전에 한글 인코딩이 깨지는 문제로 상당히 고생했던 이력이 있습니다. Apache가 응답 헤더에 잘못된 charset을 붙이거나, 로컬에서 메모장으로 파일을 열었다가 복사하면서 텍스트 자체가 오염되는 등, 원인을 하나씩 추적하는 데 꽤 시간을 썼습니다.

이번엔 그 문제를 아예 피해가기로 했습니다. Google Apps Script(GAS) 웹앱으로 만들면, 구글 서버가 응답 헤더의 charset을 항상 정확하게 처리해주기 때문에 이런 인코딩 문제가 원천적으로 발생하지 않습니다. 실제로 예전에 만든 주식 기울기 분석기와 레버리지 시뮬레이터도 GAS 기반이었는데, 그때는 인코딩 문제를 한 번도 겪지 않았던 게 이번 선택의 근거가 됐습니다.

2. 데이터는 어디서 가져오나 — Yahoo Finance 비공식 API

19개 지표(나스닥부터 비트코인까지) 전부 Yahoo Finance의 v8/finance/chart 엔드포인트로 가져옵니다.

var chartUrl = 'https://query1.finance.yahoo.com/v8/finance/chart/' + encodeURIComponent(ticker);
var chartRes = UrlFetchApp.fetch(chartUrl, {
  headers: { 'User-Agent': 'Mozilla/5.0' },
  muteHttpExceptions: true
});
var chartData = JSON.parse(chartRes.getContentText());
var meta = chartData.chart.result[0].meta;
var price = meta.regularMarketPrice;

처음엔 여러 종목을 한 번에 조회할 수 있는 v7/finance/quote 엔드포인트를 썼는데, 이게 최근 인증(crumb) 정책이 강화돼서 로그인 세션 없이 호출하면 401 에러가 나더군요. 인증이 필요 없는 v8/finance/chart로 바꾸고, 대신 티커 하나하나를 개별 호출하는 방식으로 우회했습니다.

3. 60초 캐싱으로 API 호출 최소화

방문자가 몰릴 때마다 Yahoo에 매번 새로 요청하면 비효율적이고, 과도한 호출은 차단당할 위험도 있습니다. 그래서 CacheService로 60초간 결과를 캐싱했습니다.

function getMarketData() {
  var cache = CacheService.getScriptCache();
  var cached = cache.get('marketData');
  if (cached) {
    return cached; // 캐시가 있으면 외부 호출 없이 바로 반환
  }
  // ... Yahoo Finance 호출 ...
  cache.put('marketData', payload, 60);
  return payload;
}

이러면 같은 1분 안에 방문자가 100명이 들어와도, 실제 Yahoo 호출은 딱 1번만 발생합니다.

4. 히스토리 저장 — 구글 시트를 데이터베이스처럼

7일치 추이 그래프를 그리려면 과거 데이터가 필요한데, CacheService는 최대 6시간까지만 보관되는 임시 저장소라 부적합합니다. 그래서 스크립트가 처음 실행될 때 구글 시트를 자동으로 생성해서, 여기에 매일 장 마감 데이터를 한 줄씩 기록하도록 만들었습니다.

function getHistorySheet_() {
  var props = PropertiesService.getScriptProperties();
  var sheetId = props.getProperty('HISTORY_SHEET_ID');
  var ss;
  if (sheetId) {
    try { ss = SpreadsheetApp.openById(sheetId); } catch (e) { ss = null; }
  }
  if (!ss) {
    ss = SpreadsheetApp.create('마켓 대시보드 - 일별 기록');
    props.setProperty('HISTORY_SHEET_ID', ss.getId());
    // ... 헤더 행 생성 ...
  }
  return ss.getSheetByName('History');
}

매일 자동으로 기록되도록, Apps Script의 시간 기반 트리거(매일 1회 실행)에 saveDailySnapshot 함수를 등록해뒀습니다.

5. 가장 애먹었던 문제 — 날짜가 하루씩 밀리는 버그

여기서부터가 이번 프로젝트에서 가장 오래 씨름한 부분입니다.

증상

구글 시트에는 분명 “2026-07-24″라고 정확히 저장돼 있는데, 화면에 그려지는 그래프에는 “07-23″으로 하루가 밀려서 표시되고 있었습니다. 코드를 아무리 다시 봐도 로직상 문제가 없어 보였습니다.

첫 번째 가설 (틀림)

처음엔 “완전한 데이터가 있는 날을 잘못 판단하고 있나?”를 의심해서, 데이터 필터링 로직을 여러 번 고쳤습니다. 하지만 문제는 그대로였습니다.

진짜 원인

구글 시트는 "2026-07-24" 같은 텍스트를 셀에 입력하면, 스프레드시트 계정의 기본 시간대(한국 시간, Asia/Seoul) 자정을 나타내는 날짜 객체로 자동 변환해버립니다. 그런데 이걸 다시 읽어올 때, 제 코드는 미국 동부 시간(America/New_York) 기준으로 재해석하고 있었습니다. 한국 자정을 미국 동부 시간으로 환산하면 13시간 차이 때문에 전날로 계산돼버리는 것이었습니다.

// 문제가 됐던 코드
Utilities.formatDate(dateObject, 'America/New_York', 'yyyy-MM-dd')
// 한국 자정(2026-07-24 00:00 KST) → 미국 동부 시간으로 환산하면 2026-07-23 11:00 EDT
// 그래서 "07-24"가 "07-23"으로 표시됨

해결 방법

날짜를 아예 구글 시트가 자동 변환하지 못하도록, 텍스트로 강제 고정 저장하는 방식으로 바꿨습니다. 셀 값 앞에 작은따옴표를 붙이면 시트가 이를 날짜가 아닌 순수 텍스트로 취급합니다.

sheet.appendRow([
  "'" + dateStr, // 작은따옴표로 텍스트 강제 → 시트가 날짜 객체로 자동 변환하지 못하게 함
  // ... 나머지 지표 값들
]);

이렇게 하니 애초에 “시간대 재해석”이라는 단계 자체가 필요 없어져서, 문제가 근본적으로 해결됐습니다.

6. 하나 더 — 응답이 예전 버전처럼 보이는 문제

이번 프로젝트에서 또 하나 배운 게 있습니다. 코드를 분명히 고쳤는데 화면 결과가 안 바뀌는 상황이 반복됐는데, 원인은 Apps Script의 “새 버전으로 배포”를 빼먹은 것이었습니다. 코드를 저장하는 것과, 웹앱에 실제로 반영되게 배포하는 것은 별개의 단계입니다. 이 둘을 헷갈리면 “코드는 맞는데 결과가 이상한” 상황을 계속 마주하게 되니, 다음엔 결과가 이상하면 가장 먼저 배포 버전부터 확인하는 습관을 들이기로 했습니다.

7. 마무리하며

이번 작업에서 가장 크게 배운 건, 문제가 안 풀릴 때 “가장 그럴듯해 보이는 원인”보다 “가장 최근에 실제로 무엇을 했는지”를 먼저 되짚어봐야 한다는 점이었습니다. 날짜 버그도, 처음엔 복잡한 로직 문제라고 의심했지만 실제로는 “시간대를 잘못 지정한 한 줄”이 원인이었습니다. 코드를 아무리 고쳐도 안 풀리는 문제라면, 코드 바깥의 가정 자체를 의심해보는 게 오히려 빠른 길이라는 걸 다시 확인한 프로젝트였습니다.

무료로 직접 사용해보고 싶으시다면 [1편]에 링크해둔 대시보드를 확인해보세요.

Tags:

GAS 웹앱 배포Yahoo Finance API구글 앱스 스크립트 주식구글시트 날짜 버그
사진
작성자

youn3345

Follow Me
다른 기사
Previous

나스닥·코스피·환율·금리, 이제 창 하나로 다 봅니다 [1편] 기획과 사용법

Next

연봉만 넣으면 끝? 진짜 정확한 실수령액 계산기 만들었습니다 [1편]

댓글 없음! 첫 댓글을 남겨보세요.

답글 남기기 응답 취소

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

최신 글

  • 청년미래적금 조건 총정리, 계산기로 직접 확인해보세요 [2편] 개발기
  • 청년미래적금 조건 총정리, 계산기로 직접 확인해보세요 [1편]
  • 사회초년생 월급관리, 첫 월급부터 이렇게 나눠보세요 [2편] 구현기
  • 사회초년생 월급관리, 첫 월급부터 이렇게 나눠보세요 [1편]
  • 연봉만 넣으면 끝? 진짜 정확한 실수령액 계산기 만들었습니다 [2편] 계산 로직 구현기

카테고리

  • 🌐 1인 마이크로 SaaS & 수익화
  • 📚 AI 자동화 & 프롬프트 가이드
  • 🛠️내 손으로 만든 웹 툴 (계산기/분석기)

    흥인 이란?

    • 개인정보처리방침 (Privacy Policy)
    • 문의하기 (Contact Us)
    • 운영자 소개 (About Us)

    Copyright 2026 — 흥인 (heung-in). All rights reserved.