Electron, React, SQLite를 사용해 데스크톱 트레이딩 저널을 만든 방법

발행: (2026년 4월 4일 PM 11:39 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

위에 제공된 Source 링크 아래에 번역하고자 하는 전체 텍스트를 붙여 주시면, 해당 내용을 한국어로 번역해 드리겠습니다.
(코드 블록, URL, 마크다운 형식 및 기술 용어는 그대로 유지됩니다.)

개요

지난 주에 나는 Aurafy라는 데스크톱 앱을 출시했습니다. 이 앱은 선물 트레이더를 위한 거래 저널이며 완전히 로컬에서 실행됩니다—클라우드도 없고, 계정도 없으며, 구독도 없습니다. 민감한 금융 데이터를 다루는 도구에 대해 “로컬‑first” 접근 방식이 과소평가되고 있기 때문에 그 뒤에 있는 기술적 결정을 공유하고 싶었습니다.

아키텍처

앱은 세 부분으로 구성된 모노레포입니다:

Server

  • Express.js + better‑sqlite3
  • Electron 메인 프로세스 내부에서 실행됩니다 (자식 프로세스 생성이 없으며, 시작 시간을 2초 이하로 단축합니다)
  • WAL 모드의 SQLite가 모든 영속성을 처리합니다
  • 모든 쓰기는 synchronous = FULL을 사용하여 내구성을 보장합니다

Client

  • React, Vite, Tailwind CSS, Recharts
  • localhost를 통해 Express 서버와 통신하는 표준 SPA
  • TanStack Query가 데이터 가져오기와 캐싱을 담당합니다

Electron Wrapper

  • 메인 프로세스가 인‑프로세스로 Express 서버를 시작하고, localhost를 가리키는 BrowserWindow를 열며, 화면 녹화 권한 및 플로팅 카메라 창과 같은 네이티브 기능을 처리합니다.

데이터 저장 및 보안

거래 데이터(P&L, 계좌 규모, 실수)는 매우 민감합니다. SQLite를 사용하면 모든 것이 다음 위치에 저장됩니다:

~/Library/Application Support/aurafy/data/journal.db
  • 사용자는 파일을 직접 백업, 이동 또는 삭제할 수 있습니다.
  • API 키, OAuth 흐름, 로그인 프롬프트가 없습니다.
  • 트레이드‑오프: 장치 간 동기화가 없으며, 이는 트레이더들이 보통 책상에서 저널링하기 때문에 문제가 되지 않았습니다.

내장 화면 녹화기

핵심 기능은 트레이딩 세션을 나중에 검토할 수 있도록 녹화하는 것으로, 운동선수가 경기 영상을 보는 방식과 유사합니다.

  • Electron의 desktopCapturer API가 화면 캡처를 제공합니다.

  • 마이크 입력을 위해 getUserMedia와 결합합니다.

  • 오디오 스트림은 Web Audio API를 사용해 믹싱한 뒤 MediaRecorder에 전달합니다.

  • 카메라 오버레이는 별도의 BrowserWindow에서 다음 옵션으로 실행됩니다:

    {
      transparent: true,
      alwaysOnTop: true,
      frame: false
    }

    이는 Loom의 카메라 버블처럼 모든 앱 위에 떠 있습니다. HTML은 웹캠 피드를 표시하는 요소를 포함한 간단한 원형 로 구성됩니다.

CSV Import from Trading Platforms

트레이더들은 TradovateNinjaTrader와 같은 플랫폼에서 데이터를 CSV 파일로 내보냅니다. 각 플랫폼은 열 이름, 날짜 형식, 그리고 계약명(예: MNQM6 vs. MNQ 06-26)이 서로 다릅니다.

제가 만든 파서는 다음을 수행합니다:

  1. 자동 감지: 열 헤더를 확인하여 플랫폼을 식별합니다.
  2. 정규화: 정규식으로 계약 월 코드를 제거하여 상품명을 표준화합니다.
  3. 매칭: 틱 사이즈와 포인트 값이 포함된 로컬 상품 테이블에 연결합니다.
  4. 페어링: 진입/청산 실행을 짝지어 P&L을 계산합니다.

수입 흐름은 다음과 같습니다:

Drop CSV → preview detected trades → confirm

수동 매핑이 필요하지 않습니다.

성능 최적화

  • In‑process server: 첫 번째 버전은 Express를 위해 Node 자식 프로세스를 생성했으며, 시작 시간이 3 초 이상 늘어나고 macOS 코드‑서명 문제를 일으켰습니다 (OS가 이를 두 개의 별도 앱으로 인식). require()를 사용해 Electron 메인 프로세스 내에서 Express를 실행하면 두 문제 모두 해결됩니다.
  • SQLite WAL mode: WAL이 없으면 쓰기가 읽기를 차단합니다. journal_mode = WALsynchronous = FULL을 사용하면 쓰기 중에도 동시 읽기가 가능하고, 충돌 시 내구성이 보장됩니다.

Auto‑update Challenges

electron-updater는 GitHub에 초안 릴리스를 생성하는데, 수동으로 게시하기 전까지 404 오류가 반환됩니다. macOS와 Windows 빌드가 모두 완료된 후 릴리스를 자동으로 게시하는 CI 단계를 추가했습니다.

Development Gotchas

  • ELECTRON_RUN_AS_NODE: 이 환경 변수가 설정되어 있으면(일부 개발 환경에서 흔함), Electron이 일반 Node.js처럼 실행되고 require('electron')이 모듈이 아니라 문자열을 반환합니다. 이 때문에 몇 시간씩 디버깅을 해야 했습니다.

Availability

Aurafy는 무료이며 에서 사용할 수 있습니다. 코드는 선물 계약(ES, NQ, CL, MES, MNQ)을 적절한 포인트 값과 틱 사이즈로 처리합니다.

질문

Electron + Express + SQLite 아키텍처 패턴에 관심이 있으시면, 댓글에 자유롭게 질문을 남겨 주세요.

0 조회
Back to Blog

관련 글

더 보기 »