본문 바로가기
경제 금융 포털사이트 경제 금융 포털사이트

CSV vs Parquet 틱 데이터 백테스팅 속도는 파일 형식에서 얼마나 달라질까?

금알남 읽는 시간 약 14분
ai thumbnail minimal CSV vs Parquet 틱 데이터 백테스팅 속도 1789701669

틱 데이터 백테스트가 느리다면 전략 코드만 최적화하기 전에 저장 파일부터 확인해보는 것이 좋습니다. CSV와 Parquet는 단순히 확장자가 다른 것이 아니라 데이터를 읽고 선택하는 방식 자체가 다릅니다. 아래 글에 백테스팅 관점에서 두 형식을 어떻게 비교하면 되는지 정리했습니다.

틱 데이터 백테스트가 느린데 정말 코드가 문제일까?

파이썬으로 틱 데이터 백테스트를 돌리다 보면 이상한 상황을 만날 때가 있습니다.

전략 로직은 생각보다 단순합니다.

그런데 데이터를 불러오는 단계부터 오래 걸립니다.

종목을 하나 추가했을 뿐인데 실행 시간이 크게 늘고, 기간을 몇 개월 더 늘렸더니 메모리 사용량도 급격하게 올라갑니다.

이때 대부분은 먼저 Pandas 코드나 반복문을 의심합니다.

물론 그것도 확인해야 합니다.

하지만 원본 틱 데이터를 매번 CSV로 읽고 있다면 먼저 파일 형식을 살펴볼 필요가 있습니다.

예를 들어 백테스트에서 실제 필요한 컬럼이

  • timestamp
  • price
  • volume
  • side

정도라고 해보겠습니다.

그런데 원본 CSV에 15개 컬럼이 들어 있다면 어떻게 될까요?

일반적인 CSV 처리에서는 파일을 읽고 문자열을 해석하면서 필요한 데이터 구조로 변환하는 과정이 필요합니다.

그리고 실제 전략에서는 사용하지 않는 데이터까지 함께 처리하는 구조가 만들어질 수 있습니다.

틱 데이터가 작다면 문제가 크게 느껴지지 않습니다.

하지만 데이터가 수천만 행 이상으로 커지고, 같은 데이터를 전략 변경 때마다 반복해서 읽기 시작하면 이야기가 달라집니다.

그래서 대규모 시계열 데이터를 다룰 때는 전략 코드뿐 아니라

데이터 저장 포맷 자체도 백테스트 시스템의 일부

라고 생각하는 것이 좋습니다.

CSV와 Parquet는 무엇이 다른가?

CSV는 매우 단순하고 범용적인 형식입니다.

사람이 직접 열어볼 수 있고, 대부분의 분석 프로그램에서 쉽게 읽을 수 있다는 장점이 있습니다.

데이터를 주고받거나 원본 파일을 보관할 때도 편합니다.

반면 Parquet은 분석용 데이터 처리에 초점을 둔 컬럼형 저장 포맷입니다.

Apache Arrow 공식 문서는 Parquet을 데이터 분석 시스템에서 활용되는 표준화된 오픈소스 컬럼형 저장 형식으로 설명합니다.

이 차이는 틱 데이터에서 꽤 중요합니다.

쉽게 비유해보겠습니다.

CSV가

“한 줄에 있는 정보를 순서대로 읽어가는 장부”

에 가깝다면,

Parquet은

“같은 종류의 데이터를 컬럼별로 효율적으로 관리하는 분석용 저장 구조”

에 가깝습니다.

특히 Parquet은 필요한 컬럼만 선택해서 읽을 수 있습니다.

Apache Arrow 문서에서도 Parquet 파일에서 일부 컬럼만 읽는 것이 컬럼형 구조 덕분에 전체 파일을 읽는 것보다 훨씬 효율적일 수 있다고 설명합니다.

예를 들어 틱 데이터에

timestamp
symbol
price
volume
bid
ask
exchange
condition
sequence

가 저장돼 있는데,

현재 전략에서는

timestamp
price
volume

만 사용한다고 해보겠습니다.

CSV vs Parquet 틱 데이터 백테스팅 속도는 파일 형식에서 얼마나 달라질까?

이 경우 전체 컬럼을 매번 처리하기보다 필요한 컬럼만 읽는 구조를 만들 수 있습니다.

Pandas 역시 현재 read_parquet()에서 columnsfilters 등의 옵션을 지원합니다. 즉 Pandas를 그대로 사용하면서 저장 형식만 Parquet으로 바꾸는 방법도 충분히 검토할 수 있습니다.

여기서 중요한 포인트가 하나 있습니다.

Parquet을 쓰기 위해 Pandas를 버릴 필요는 없습니다.

Pandas와 Parquet은 서로 경쟁하는 개념이 아닙니다.

Pandas는 데이터를 처리하는 도구이고,

Parquet은 데이터를 저장하는 형식입니다.

둘은 함께 사용할 수 있습니다.

틱 데이터에서는 왜 Parquet의 장점이 더 커질까?

틱 데이터 백테스팅에서는 같은 데이터를 반복해서 사용하는 일이 많습니다.

오늘 전략 A를 돌립니다.

조건을 조금 바꿔 전략 B를 돌립니다.

다음에는 수수료 조건을 바꿉니다.

그다음에는 다른 종목을 테스트합니다.

즉 원본 데이터를 한 번 읽고 끝나는 것이 아닙니다.

연구를 반복할수록 같은 데이터에 계속 접근하게 됩니다.

이때 Parquet의 장점이 나타날 수 있습니다.

첫 번째는 필요한 컬럼만 읽을 수 있다는 점입니다.

두 번째는 조건에 따라 필요 없는 데이터 읽기를 줄일 수 있다는 점입니다.

DuckDB는 Parquet을 직접 조회하면서 projection pushdown을 이용해 쿼리에 필요한 컬럼만 읽고, filter pushdown을 이용해 조건에 맞지 않는 데이터 일부를 파일 스캔 단계에서 건너뛸 수 있습니다.

예를 들어 전체 틱 데이터 중

특정 종목
특정 거래일
특정 시간대

만 분석한다고 생각해보겠습니다.

전체 데이터를 먼저 메모리에 올리고 나중에 필터링하는 것보다 필요한 데이터만 먼저 가져오는 구조가 효율적일 수 있습니다.

Polars에서도 비슷한 접근이 가능합니다.

scan_parquet()을 사용하면 데이터를 즉시 전부 읽는 대신 LazyFrame을 만들고, 쿼리 최적화 과정에서 predicate와 projection을 파일 스캔 단계까지 내려보낼 수 있습니다. Polars 공식 문서에서는 이 방식이 성능 향상과 메모리 사용량 감소에 도움이 될 수 있다고 설명합니다.

그래서 틱 데이터에서는 단순히

CSV → Parquet

한 단계만 보는 것보다

CSV + Pandas
Parquet + Pandas
Parquet + Polars
Parquet + DuckDB

처럼 조합을 비교해보는 것이 더 의미가 있습니다.

다만 여기서 주의해야 합니다.

“Parquet이면 무조건 몇 배 빨라진다”

같은 식으로 생각해서는 안 됩니다.

성능 차이는

  • SSD 또는 HDD
  • CPU
  • 메모리
  • 데이터 크기
  • 컬럼 수
  • 파일 압축 방식
  • 파일 개수
  • row group 크기
  • 읽는 컬럼의 비율
  • 필터 조건

등에 따라 달라질 수 있습니다.

DuckDB 공식 문서 역시 Parquet 데이터셋의 파일 수, 개별 파일 크기, 압축 알고리즘과 row group 크기 등이 성능에 큰 영향을 줄 수 있다고 안내하고 있습니다.

따라서 인터넷의 벤치마크 숫자를 그대로 자신의 시스템에 대입하기보다는 직접 비교하는 것이 가장 정확합니다.

제대로 비교하려면 이렇게 테스트해보자

저라면 CSV와 Parquet을 비교할 때 단순히 파일 열리는 시간 하나만 재지 않습니다.

동일한 원본 틱 데이터로 테스트 조건을 맞춥니다.

그리고 아래처럼 단계별로 측정합니다.

  1. 전체 데이터 로딩 시간
  2. 필요한 컬럼만 읽는 시간
  3. 특정 날짜 필터링 시간
  4. 특정 종목 필터링 시간
  5. 파일에서 DataFrame이 만들어질 때까지의 시간
  6. 메모리 사용량
  7. 실제 전략까지 포함한 전체 백테스트 시간

여기서 상당히 중요한 것이 마지막 항목입니다.

파일 로딩 속도가 크게 개선돼도 전체 백테스트에서 이벤트 시뮬레이션이 대부분의 시간을 차지한다면 전체 체감 속도는 생각보다 작을 수 있습니다.

반대로 전략 계산 자체는 빠른데 데이터 로딩을 매번 오래 기다리고 있었다면 파일 포맷 변경의 효과를 크게 체감할 수도 있습니다.

그래서 성능 측정은 다음처럼 구분하는 것이 좋습니다.

데이터 로딩 시간

전처리 시간

시그널 계산 시간

주문·체결 시뮬레이션 시간

전체 실행 시간

그리고 한 번만 실행해서 판단하지 않는 편이 좋습니다.

OS 파일 캐시 등의 영향을 받을 수 있으므로 여러 번 실행하면서 첫 실행과 이후 실행을 구분해 기록하는 방법이 좋습니다.

또 CSV에서 Parquet으로 바꾼 뒤에는 속도만 보면 안 됩니다.

반드시 결과값도 확인해야 합니다.

특히 틱 데이터에서는 다음 항목을 확인해야 합니다.

  • timestamp 정밀도가 유지되는가?
  • timezone 정보가 동일한가?
  • 가격과 수량의 dtype이 변경되지 않았는가?
  • 결측치 처리가 달라지지 않았는가?
  • 동일 timestamp의 데이터 순서가 보존되는가?
  • 최종 매매 결과가 기존 데이터와 동일한가?

파일을 바꿨는데 백테스트 결과까지 달라진다면 단순한 저장 포맷 변경으로 볼 수 없습니다.

속도와 데이터 무결성을 같이 확인해야 합니다.

그렇다면 CSV를 버리고 전부 Parquet으로 바꿔야 할까?

꼭 그렇게 할 필요는 없습니다.

CSV에도 분명한 장점이 있습니다.

원본 데이터 확인이 쉽고, 다른 프로그램과 데이터를 주고받기도 편합니다.

그래서 데이터 파이프라인을 구축할 때는 역할을 나누는 방법이 좋습니다.

예를 들면 이런 구조입니다.

1단계. 원본 데이터

CSV 또는 공급처에서 받은 원본 형식을 그대로 보관합니다.

2단계. 정제 과정

timestamp, dtype, 이상값, 중복 데이터를 확인합니다.

3단계. 분석용 데이터

정제한 데이터를 Parquet으로 변환해 저장합니다.

4단계. 백테스팅

Pandas, Polars, DuckDB 등으로 필요한 데이터만 읽습니다.

이렇게 하면 원본 데이터는 그대로 보존하면서 실제 연구에서는 분석에 적합한 구조를 사용할 수 있습니다.

데이터가 장기간 누적된다면 partitioning도 생각해볼 수 있습니다.

Apache Arrow는 여러 Parquet 파일을 연도와 월 등의 디렉터리 구조로 나누는 partitioned dataset 방식을 지원합니다.

틱 데이터라면 데이터 규모와 사용 패턴에 따라

연도

거래일
종목

등을 기준으로 나누는 방식을 검토할 수 있습니다.

다만 너무 잘게 파일을 나누면 작은 파일이 과도하게 많아지는 문제도 생길 수 있으므로 무조건 잘게 쪼개는 것이 좋은 것은 아닙니다.

결국 핵심은 하나입니다.

백테스팅에서 데이터를 어떻게 사용할 것인가를 기준으로 저장 구조를 설계해야 합니다.

CSV와 Parquet 중 어느 것이 절대적으로 더 좋은가를 묻기보다 이렇게 질문하는 편이 좋습니다.

“나는 매번 데이터 전체를 읽는가?”

“실제로 사용하는 컬럼은 몇 개인가?”

“특정 날짜나 종목만 반복적으로 조회하는가?”

“파일을 읽는 시간이 전체 백테스트에서 얼마나 큰 비중을 차지하는가?”

여기에 답하면 Parquet을 적용할 가치가 있는지 훨씬 명확해집니다.

특히 틱 데이터처럼 데이터량이 빠르게 커지는 환경이라면 전략 로직을 최적화하기 전에 저장 방식과 읽기 구조를 한 번 점검해볼 필요가 있습니다.

좋은 백테스트 시스템은 단순히 계산이 빠른 시스템이 아닙니다.

데이터를 필요한 만큼만 읽고, 같은 데이터를 반복해서 효율적으로 재사용하며, 결과의 재현성까지 유지할 수 있는 시스템​이 더 중요합니다.

Q1. Pandas를 사용하는데 Parquet을 쓸 수 있나요?

가능합니다. Pandas는 read_parquet()to_parquet()을 제공하며 PyArrow 등의 엔진을 이용해 Parquet 파일을 읽고 저장할 수 있습니다. 따라서 기존 Pandas 코드를 모두 Polars로 변경하지 않고도 저장 포맷부터 개선해볼 수 있습니다.

Q2. CSV를 Parquet으로 바꾸면 항상 빨라지나요?

항상 그렇다고 단정할 수 없습니다. 파일 크기, 컬럼 수, 읽는 방식, 압축, 저장장치와 연산 구조 등에 따라 결과가 달라집니다. 특히 파일 전체의 모든 컬럼을 항상 사용하는 작업이라면 필요한 일부 컬럼만 조회하는 작업과 체감 차이가 다를 수 있습니다.

Q3. 틱 데이터는 어떻게 저장하는 것이 좋을까요?

원본은 별도로 보관하고 정제된 분석용 데이터를 Parquet으로 관리하는 방식을 검토할 수 있습니다. 데이터 규모가 크다면 날짜나 종목 기준 partitioning도 고려할 수 있지만 실제 조회 패턴과 파일 수를 함께 봐야 합니다.

자료 출처

  • Apache Arrow 공식 문서, Reading and Writing Apache Parquet Format
  • pandas 공식 문서, pandas.read_parquet
  • DuckDB 공식 문서, Reading and Querying Parquet Files
  • Polars 공식 문서, Parquet 및 scan_parquet()
  • Apache Arrow 공식 문서, Partitioned Parquet Datasets

※ 본 글에서 설명한 성능 차이는 특정 환경에서 동일하게 재현된다는 의미가 아닙니다. CPU, 메모리, 저장장치, 데이터 크기, 라이브러리 버전과 코드 구조에 따라 결과는 달라질 수 있으므로 실제 데이터로 별도 테스트하는 것이 좋습니다.

※ 본 글은 파이썬 데이터 처리 및 백테스팅 시스템 구축에 관한 기술 정보 제공을 목적으로 합니다. 특정 투자전략, 금융상품 또는 투자 성과를 추천하거나 수익을 보장하는 내용이 아닙니다.

※ 금융상품 또는 투자 관련 내용을 실제 상담·광고 목적으로 활용하는 경우에는 해당 업무의 등록 범위와 금융소비자보호 관련 표시·광고 기준을 별도로 확인해야 합니다. 등록번호·심의번호 등이 필요한 업종이라면 실제 등록정보와 승인된 문구로 교체한 뒤 사용하시기 바랍니다.

금알남

금알남
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.