자동매매 봇 재작성 – 구조설계1 요구사항 분석 및 구조 설계
요구사항 도출
- 봇이 하는 일은 무엇인가? Functional Requirements
- 데이타 수신
- 신호 발생
- 주문처리
- 기록 관리
- 봇이 어떠해야 하는가? Non-functional Requirements
- 여러 거래소를 지원
- 여러 매매전략을 수용
- 유지보수 용이
- 안정성 및 신뢰성
- 확장성(cross platform, cloud, multiuser, multiple strategies, multiple exchanges)
- 처리속도
- 경량성(저성능 컴퓨터에서 운용)
- 작업 규칙
- KISS
- One thing at a time
- Avoid over-engineering(YAGNI You Ain’t Gonna Need It)
- DRY(Don’t Repeat Yourself)
- SOLID
아키텍쳐 선택
이것에 대해서는 저도 기초가 부실하므로 인공지능에게 물었습니다.
쓸만한 책을 골라서 요약해주라했는데 다음과 같습니다.
“Software Architecture Patterns”은 Mark Richards와 Neal Ford가 저술한 소프트웨어 개발 분야의 다양한 아키텍처 패턴을 다루는 책입니다
……
인공지능 덕분에 책 한권 읽기가 뚝딱이군요.
이 책에 다양한 패턴이 나오는데, 그중에서 자동매매봇이 적당한게 무엇인가에 대해서는 인공지능도 콕집어 답하진 못해서 좀더 조사해 보니 두세가지 패턴으로 압축됩니다.
- Microservices Architecture:
- Consider adopting a microservices architecture. Each microservice can handle a specific trading strategy or exchange integration. This allows for scalability and independent development and deployment of each component.
- Event-Driven Architecture:
- Implement an event-driven architecture where different components can communicate through events. Market data updates, order executions, and other events can trigger actions across different microservices.
마이크로서비스는 보다 스케일이 큰 프로젝트에 적합하고 이벤트 드리븐이 적합할 듯 합니다.
디자인 패턴
프로그램의 최상위 레벨에서 아키텍쳐를 이벤트드리븐 형태로 결정했다.
그 다음 단계로 코드 레벨에서 디렉토리 구성과 패키지, 모듈 등의 구조를 결정해야 한다.
코드레벨의 구조적 패턴은 여러가지가 있는데 리포지토리 패턴을 선택했다.
그 이유는 여러개의 거래소를 지원하도록 설계해야 하기 때문인데, 어찌하여 이 패턴이 적당한 지를 코드를 구현해 가면서 알아 보기로 한다.
Repository Pattern:
- Create a repository to abstract the data access layer, providing a clean separation between application logic and data storage.
먼저 ExchangeRepository를 인터페이스로 하고 각각의 거래소에 대해 구현하기로 한다.
BinanceRepository, BitgetRepository 순서로 구현하면 된다.
Components: 봇, 거래소, 매매전략
구조적인 틀은 대강 잡아놓았으니 이제는 구현작업을 위해 일감들을 구분지어야 합니다.
복잡한 물건은 여러가지 부품들로 구성되어있죠.
각각의 부품을 독립적으로 제작해서 나중에 합체하는 방식으로 작업능률을 높이는 겁니다.
그림을 그릴 때도 부분들을 대강 그려 놓고 나중에 디테일 작업을 해야지만 조화롭게 됩니다.
글을 쓸 때도 제목을 정하고 목차를 정해놓고 내용을 채워나가는 방식을 사용하죠.
코딩도 글쓰기의 일종이니 이런 방식으로 하면 능률적입니다.
그러기 위해서 일단 시나리오를 작성해 보고 이상이 없는지 검증해 보기로 합니다.
비봇이란 놈이 살았는데, 이놈에게 바이낸스의 지갑과 마켓데이타, 그리고 매매전략을 주면 자기가 알아서 코인을 사고파는 놈이렸다.
여기서 일단 3개의 부품을 발견할 수 있습니다.
비봇, 바이낸스, 매매전략이 그것이죠
이것들을 부품으로 해서 하나씩 조금씩 구현해 나가기로 합니다.
일단 고민은 그만하고, 요즘 말로 해서
좋빠가!
부품의 추상화
Python을 사용하다가 go를 사용하게 되면 Class가 없기 때문에 Type과 Interface를 이용해서 Python의 Class 와 Instance를 구현해야 합니다.
처음엔 조금 낯설고 어색합니다.
Object Oriented 방식으로 설계하면, 위의 예에서 클래스는 Bot, Exchange, Strategy가 됩니다.
이것들의 Instance가 beebot, binance, RSIStrategy 처럼 구현되겠죠.
go에서는 Exchange를 Interface type으로 정의하고, 각각의 거래소 struct를 구현함으로써 Object Oriented와 같은 결과를 얻을 수 있습니다.
즉, 한개의 Exchange type으로 여러개의 거래소를 처리할 수 있게 됩니다.
마찬가지로 Strategy 또한 Interface 타입으로 설계 구현합니다.
Exchange가 하는 일은 코인의 데이타 처리와 주문을 처리하는 것인데, 이것 또한 거래소 마다 상이 하므로 Interface타입으로 설계구현해야 합니다.
Exchange를 없애고 데이타처리와 주문처리를 하는 인터페이스를 최상위 레이어에 설계구현할 수도 있습니다.
그렇게 하는 것이 이해하기는 더 쉽지만 최상위 레이어를 보다 단순하게 설계하기 위해서 거래소 의존적인 것들을 하나로 묶어서 Exchange 타입으로 설계하고 그 하위 레이어에
마켓데이타제공자와 주문처리자, 지갑관리자 등의 타입을 배치하려 합니다.
거칠게 나마 개념도를 그려 보면 아래와 같습니다.