프로젝트 진행 기간(6.4 ~ 7.5)
자동매매 프로그램을 강화학습을 사용하기로 선택한 이유는 아래와 같다.
코인 강화학습 자동매매 프로그램[제작계기]
계기 살면서 누구나 한번쯤은 주식이나 코인매매로 자산을 불리고 싶은 생각이 들것이다. 나도 그랬으며 실제 매매를 시도해본적이 있다. 그치만 실제 돈이 들어가다보니 온 신경이 그쪽으로
jinho082008.tistory.com
해당 프로젝트는 실제 해보고 싶었지만, 강화학습을 따로 집중해서 공부하기엔 다른 공부할 것이 많아서 미뤄오다가 이번에 agent의 성능이 좋아져서 agent에 대해서 공부하면서 진행한 프로젝트이다. 프로젝트는 claude code를 사용해서 진행하였으며, 사용한 기술로는 강화학습의 ppo를 사용해서 학습시켰고, 기본적인 agent 사용부터 Muti-Agent Debate, Loop Protocol 등을 사용해서 프로젝트를 진행하였다.
프로젝트 진행 방향
처음에는 BTC의 5분봉 데이터를 학습시키는 것으로 진행되었다. 비트코인의 5분봉 데이터를 5년치 추출하였으며, 거래량, 시작가, 최고가, 최저가, 종가 등 데이터들을 csv로 추출하였다. 이후 해당 데이터들을 ppo로 학습을 진행시켰다.
학습 중 깨달을 것은 비트코인은 변동성이 다른 코인에 비해 크지 않기 때문에 비트코인의 변동성으로는 거래소의 거래 수수료를 이기기 힘들었다. 업비트의 경우 매수, 매도시 수수료가 발생하는데 0.05%가 발생한다. 즉 매수하고 매도한다면 거의 0.1%가 발생한다는 것이고, 이는 매매차익이 0.1% 이상이 되어야 자산이 증가한다는 것이었다. 하지만 비트코인은 평상시 변동률이 크지 않기 때문에 자동매매 프로그램에는 적합하지 않다고 생각했다.
위와 같은 이유로 BTC에서 ETH로 변경하였다. 또한 5분봉의 데이터만 학습한 것으로는 적당히 큰 흐름은 알 수 있지만 큰 흐름과 작은 흐름을 알기는 힘들었다. 때문에 9년치 1분봉 데이터를 더 추출하였고, 5분봉 데이터를 학습한 A모델과 1분봉 데이터를 학습한 B모델을 가지고 A모델의 결과와 B모델의 결과, 거래량 등을 가지고 한습한 meta 모델을 만들었다. 의도는 5분봉에서 상승한다고 예측하고 1분봉에서 상승한다고 예측했을 때, 즉 두 모델의 의견이 통합될 때 meta 모델이 다른 조건들을 이용해 판단해서 매수하는 것이었다.
말도 안되는 수익률
이렇게 생성된 meta 모델을 가지고 test를 돌려보았다. 5분봉 데이터 중 70%는 학습에 사용하고 15%는 검증과정에, 나머지 15%는 test 과정에 사용하였다. 즉 학습 데이터와 test 데이터는 독립되어있었으며, test에서 높은 수익률이 보장된다면 실제 거래에 사용해도 된다고 판단한 것이다. 실제 test 과정에서 17만%라는 말도 안되는 수익률이 나왔었으며, 이는 원금의 1700배라는 말도 안되는 결과였다. 분명 오류가 있는 것이라고 판단했지만, 실제 test에서의 거래 내역을 보니 승률 97%로 1%내외로 수익을 내니까 말이 안되는 것이 아니였다. 때문에 3일정도 해당 모델로 실거래를 돌렸었고, 6번의 거래 중 5번을 1%로 수익을 냈지만 나머지 한번의 거래에서 3%의 손실이 발생하며, 이상함을 느꼈었다.
데이터 오염 문제
말도 안되는 수익률이 나온 이유는 간단했다. 데이터를 추출하는 과정에서 한번만 추출했어야 하는데 2번을 추출한 것이었고, 이로인해 앞에 50%와 뒤에 50%가 동일한 데이터였다. 즉, test 데이터는 뒤의 15%인데 이는 앞에 데이터에 이미 포함되어 있었던 것이어서 모델이 완벽하게 같은 데이터를 알아차린 것 뿐이었다. 강화학습에서 학습 데이터의 중요성을 제대로 깨달았다.
데이터 정상화 이후
추출 데이터에 이상이 있다는 것을 알게되고 중복 데이터와 누락 데이터 문제를 전부 해결하였다. 이렇게 정상화 된 데이터를 가지고 다시 학습을 진행했을 때는 수익률이 이전처럼 드라마틱하게 나오지 않았다. 오히려 하락장에서 홀드보다 더욱 큰 손실이 생기는 등 결과는 실망스러웠다. 하지만 처음부터 잘 될것이라고 생각하지 않았기에 ppo의 파라미터 값을 수정하면서 학습을 진행하였다.
학습 시간은 5분봉의 경우 4~6시간정도, 1분봉의 경우 8~12시간정도, meta 모델의 경우 6~8시간 정도 걸렸던 것 같다. 초반에는 값을 한번 바꿀때마다 meta 모델을 만드려면 하루 정도 학습을 시켰던 것으로 기억난다. cpu가 거의 100%로 계속 돌아가기 때문에 방이 항상 뜨거웠다.
또한 항상 오를것을 예측하는 것은 사실상 청산하는 것이 떨어질 것을 예상하는 것이라고 생각해서 거래소를 업비트에서 bybit로 옮겼다. 이유는 업비트에는 숏 포지션이 존재하지 않으며, bybit에는 숏 포지션이 존재하기 때문이다. 이후의 학습은 오르는 것만 예측하는 것에서 떨어지는 것도 예측하는 방향으로 진행되었다.
매 학습 이후 개선 방법
학습을 진행할 때 관련 로그가 생성되는데, 해당 로그들은 학습의 결과가 되기 때문에 이후 개선을 위해서 로그들을 전부 저장해두었다.
------------------------------------------
| time/ | |
| fps | 6154 |
| iterations | 2 |
| time_elapsed | 21 |
| total_timesteps | 131072 |
| train/ | |
| approx_kl | 0.0037135915 |
| clip_fraction | 0.00719 |
| clip_range | 0.2 |
| clip_range_vf | 0.2 |
| entropy_loss | -1.1 |
| explained_variance | -0.142 |
| learning_rate | 0.0001 |
| loss | 0.0143 |
| n_updates | 6 |
| policy_gradient_loss | -0.00159 |
| value_loss | 0.152 |
------------------------------------------
위 데이터는 학습 초기 로그이며
-----------------------------------------
| time/ | |
| fps | 3613 |
| iterations | 328 |
| time_elapsed | 5949 |
| total_timesteps | 21495808 |
| train/ | |
| approx_kl | 0.013283077 |
| clip_fraction | 0.127 |
| clip_range | 0.2 |
| clip_range_vf | 0.2 |
| entropy_loss | -0.722 |
| explained_variance | 0.0453 |
| learning_rate | 6.31e-05 |
| loss | -0.049 |
| n_updates | 1950 |
| policy_gradient_loss | -0.0248 |
| value_loss | 0.0319 |
-----------------------------------------
위 데이터는 학습 말기 로그이다.
total_timesteps가 현재까지의 총 학습 단계이며, explained_variance는 현재 모델이 방향을 예측했을 때 정확도라고 볼 수 있다. explained_variance가 낮은 이유는 실패한 모델의 로그를 가져왔기 때문이다.
이렇게 모든 로그들을 저장해놓는다면 agent에게 해당 로그를 분석해서 파라미터를 수정해달라고 지시할 수 있다. 그러면 agent가 학습 코드와 해당 로그들을 분석해서 파라미터의 값들을 수정해준다.
이때의 분석 결과와 수정한 이유, 이후 목표는 중요한 정보라고 생각한다. 때문에 각 학습이 끝난 이후 파라미터나 코드를 수정했다면 problem.md에 저장하도록 만들어놨다. 저장 방식은 n차 수정 이전 증상, n차 수정 내용 으로 매번 증상과 수정 내용들을 저장하였다.
agent 사용 방법
위와 같은 방법으로 수정을 진행하였는데, 처음에는 한개의 agent가 로그와 problem.md, 코드를 분석해서 문제점을 파악하고 이를 개선해서 재학습 시키는 방향으로 진행하였다. 그러던 도중 학습하는 시간이 많고 실제 코드 수정 과정은 적기 때문에 claude code의 토큰 사용량이 생각보다 적었고, 더욱 효율적인 사용을 위해 agent를 여러개 생성해서 서로 토론하고 방법을 개선하는 방향으로 방법을 수정하였다.
Muti-Agent Debate
claude code는 기본적으로 한개의 agent를 통해서 작업이 이루어진다. 하지만 agent라고 해도 매번 방향과 관점이 다를 수 있다고 생각했기 때문에 여러개의 agent들의 의견을 모아서 서로 토론해 문제점을 지적한다면 더욱 효육적으로 개선할 수 있다고 생각했다. 때문에 프로젝트와 로그들을 분석하고 agent들을 2~3개 더 생성해서 각자 프로젝트들의 문제점을 분석하고, 서로가 의견을 공유하면서 토론을 진행하도록 지시하였다.
위와 같은 방법으로 진행하는데 agent는 완벽하지 않아서 이전의 프로젝트가 최신보다 학습이 잘 될수도 있을 것이라고 생각했다. 때문에 학습에 사용된 코드와 학습 모델들을 전부 저장해두었다. problem.md에 n차 수정 이라는 이름으로 각 학습 모델들의 정보를 저장해놨기 때문에 학습 n차 백업 이라는 폴더명으로 각 모델들을 저장해놓았다.
Loop Protocol
위 작업을 하던 도중 깨달은 것은 어짜피 위 과정을 반복하고 있고, 파라미터 값을 수정한다고 해서 내가 검토하고 반박하기가 힘들기 때문에 대부분을 그대로 반영하는데, 굳이 내가 확인할 필요가 있을까? 라는 생각이 들었다. 또한 학습 시간이 긴 것이지 agent의 수정 시간이 길어서 토큰이 많이 사용되는 것이 아니기 때문에 이 과정을 자동화로 만들어버리는 것이 더 합리적이라는 생각이 들었다. 이때쯤이 이미 problem.md에는 11차 수정이 진행중이었기 때문에 반복되는 작업을 Loop로 반복해서 의미있는 결과가 나올때까지 반복시키는 것이 좋다고 생각했다.
방법은 간단하다. problem.md, 로그 파일, 프로젝트 코드 들을 agent 3개를 생성해서 분석하고 토론하면서 개선점을 찾아서 코드를 수정하도록 한다. 이후 백그라운드에서 수정한 코드로 학습을 진행한다. 학습이 완료되면 claude code가 problem.md, 로그 파일, 프로젝트 코드 들을 다시 agent 3개를 생성해 분석하고 코드를 수정한다. 이러한 과정을 학습이 완료되었을 때 수익률과 예측 값이 유의미한 값이 나올때까지 반복한다. 물론 모든 학습 모델들은 backup 데이터로 저장한다.
자동매매 프로그램 결과
이렇게 한달간 강화학습으로 자동매매 프로그램을 만들기 프로젝트를 진행하였다. 결과는 16차 수정까지 Loop가 진행되었고, 1~16차까지 결과를 예측하는 것이 아닌 동전 던지기(50%확률로 찍기)에 가까운 확률로 예측을 하고 있다고 결론이 나왔으며, 파라미터를 수정하는 것은 더 이상 의미가 없으며, 데이터를 바꾸는 것이 효율적인데 유의미한 데이터는 유료이기 때문에 진행을 멈춘다는 결과가 나왔다. 프로젝트가 실패한 결정적인 이유는 강화학습은 이전의 학습한 데이터가 있으면 유리한 다음 행동을 결정하는 것인데, 실제 5분봉, 1분봉, 1시간봉 데이터들은 매번 일치하기 쉽지 않으며, 매번 패턴대로 움직이는 것이 아니라 의미 없는 움직임(방향이 패턴이 없이 움직이는)이 많기 때문에 학습하기에 적합하지 않았다.
결론
자동매매 프로그램을 만들어서 적은 수익률로 높은 승률과 많은 거래량으로 큰 수익을 내는 목표는 사실상 실패로 돌아갔다. 이후의 방법으로는 bybit에서 펀딩 캐리라는 방법으로 수익률을 올리는 방법도 제시가 되었으나, 연간 수익률이 2~7%라고 해서 자동매매 프로그램으로는 효율적이지 않다고 생각해서 프로젝트를 종료하기로 결정했다.
'프로젝트 > 강화학습 자동매매 프로그램' 카테고리의 다른 글
| 코인 강화학습 자동매매 프로그램[제작계기] (0) | 2025.11.02 |
|---|