2022.11.16 - [Python, API] - 백테스트의 속도 개선
백테스트의 속도개선
일전에 포스팅한 내용대로 백테스트 프로그램의 개선 작업을 거의 완료했다. 2022.11.13 - [Python, API] - DataFrame의 Loop속도 비교 (iloc, iat, iterrows, itertuples) [AS-IS] Df.iat 함수를 사용해서 Loop를 생성한다
toniteifly.tistory.com
어느 정도 완성된 줄 알았는데 몇 가지 문제가 생겨서 해결하는데 꽤 많은 시간이 걸렸다.
1. 메모리 부족 문제
해외선물 쪽에 바뀐 코드를 적용하다가 CPU가 사용률이 100%가 나오지도 않고 속도도 너무 안 나와서 봤더니 32기가인 메모리 사용량이 100%를 찍고 있었다.
파이썬을 써온지 그리 오래된 건 아니지만 그동안 한 번도 메모리 사용량에 대해서 고민해볼 일이 없었다. 그런데 몇십만 행의 시세 자료를 DataFrame에 올렸다가 Loop 하는 과정에서 그 DataFrame보다 더 큰 Dictionary가 생성된다. 이 과정에서 메모리 소요가 기존 프로그램의 구조와 비교해보면 거의 2~3배로 크게 늘어났다. 여기에다가 30개쯤 Multiprocessing을 돌리면 32기가의 메모리를 100% 사용하고도 모자라게 되는 황당한 상황이 생겨버렸다.
전체 Loop를 돌고 그 즉시 DataFrame을 메모리에서 삭제하고 Dictionary를 DataFrame으로 다시 변환한 이후 Dictionary를 삭제하는 방법을 써봤지만 별 효과가 없었다.
2. Pandas.DataFrame.from_dict() 속도 문제
작업이 완료된 dictionary가 DataFrame으로 변환하는 데 꽤 시간이 많이 소요된다는 걸 알게 됐다. 어떤 데이터에서는 Loop를 다 도는데 약 5초 정도 소요된다면 DataFrame으로 변환하는 시간에만 5초가 소요되는 식이었다. 구글링을 해보니 나처럼 DataFrame 변환 함수의 퍼포먼스 문제로 고민하는 사람들이 꽤 있었고 Dictionary를 DataFrame으로 변환하는 속도를 보완하기 위해서 Scikit나 Numpy를 쓰는 등 몇 가지 대안들이 보였지만 내 경우에는 퍼포먼스가 개선되는 효과가 없었다.

1, 2번을 함께 해결할 수 있는 방법이 무엇일까 며칠을 고민하다가 결국 원초적인 방법으로 해결했다.
그 방법은 붉은 점선 부분에서 처리되는 데이터의 양을 줄이는 것이었다. Itertuples로 Loop를 돌리기 전에 불필요한 칼럼들을 빼고 마지막 DataFrame으로 변환하는 자료에서도 일부 자료를 제외했다. 단순히 시뮬레이션을 통해서 전략에 관한 성과 치만 산출하는 경우에는 당일 장 시작/종료시간, 시차, 보조지표 등 불필요한 정보들은 제거하고 필요하다면 최종적으로 확정된 버전으로 상세 데이터를 export 하는 경우에만 이를 다 포함해서 Loop를 돌린 다음 csv나 pickle로 저장하는 버전으로 변경했다.
11월 초부터 백테스트 속도 개선해보겠다고 매달렸으니 거의 한 달이 걸린 셈이다. 어제는 코드 수정을 다 마치고 머리가 너무 아파서 그대로 뻗어버렸다. 가끔은 내가 투자를 하고 있는 건지 프로그래밍을 하고 있는 것인지 헥갈린다.
'Python, API' 카테고리의 다른 글
Python 3.11의 속도개선 (feat. 5950X vs 7950X) (0) | 2023.01.07 |
---|---|
투자 관련 API를 사용할 때 조심해야 할 점 (0) | 2022.11.28 |
백테스트의 속도개선 (0) | 2022.11.16 |
DataFrame의 Loop속도 비교 (iloc, iat, iterrows, itertuples) (0) | 2022.11.13 |
[XINGAPI] 주식차트조회(일주월) - t8413 (0) | 2022.07.07 |