Feat. 업비트) — hELLO.

마지막 업데이트: 2022년 7월 6일 | 0개 댓글
  • 네이버 블로그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 트위터 공유하기
  • 카카오스토리 공유하기
Bot, Detector, Strategy 가 데이터를 주고받는 모습을 보여준다.

블록체인의 장단점

대부분의 블록체인은 분산화된 디지털 원장으로 기능하는 탈중앙화된 데이터베이스로 설계되어 있습니다. 이러한 블록체인 지갑은 블록 안에 데이터를 기록하고 저장하고, 이는 시간 순서대로 구성되며, 암호화된 증명을 통해 연결됩니다. 블록체인 기술의 탄생은 다양한 산업에 많은 이점을 가져다 주었고, 신뢰할 수 없는 상황에 보다 나은 보안을 제공했습니다. 그러나 탈중앙화적 특징에는 단점도 있습니다. 기존의 중앙화된 데이터베이스와 비교할 때, 블록체인은 효율성이 떨어지며, 보다 많은 저장 공간을 필요로 합니다.

블록체인 데이터는 대개 수천 개의 분산화된 네트워크 노드에 저장되기 때문에, 시스템과 데이터는 기술적 실패와 악의적 공격에 대한 강한 저항력을 갖습니다. 각 네트워크 노드는 데이터베이스 사본을 복제하고 저장할 수 있으며, 이 때문에 한 노드가 오프라인으로 전환하더라도 네트워크 이용과 보안에 영향을 미치지 않습니다.

반면, 다수의 전통적인 데이터베이스는 단일 혹은 소수의 서버에 의존하며, 기술적 실패와 사이버 공격에 더욱 취약합니다.

승인된 블록들은 되돌리기가 무척 어려우며, 이는 데이터가 블록체인에 기록된 다음에는 이를 삭제하거나 변경하기가 무척 어려움을 뜻합니다. 재무 기록을 저장하거나 감사 추적을 필요로 하는 데이터에 블록체인은 Feat. 업비트) — hELLO. 훌륭한 기술이며, 이는 모든 변경 기록을 추적할 수 있으며 분산화된 공개 원장에 영구적으로 기록되기 때문입니다.

예를 들어, 한 회사는 블록체인 기술을 직원의 부정 행위를 방지하는 데 사용할 수 있습니다. 이러한 상황에서 블록체인은 회사 내에서 발생하는 모든 재정 거래에 Feat. 업비트) — hELLO. 대한 보안 더불어 안정적인 기록을 제공할 수 있습니다. 이는 직원으로 하여금 의심스러운 거래들을 숨기기 더욱 어렵게 할 것입니다.

대부분의 전통적인 거래 시스템에서, 거래는 관련 두 당사자가 아닌 은행과 신용 카드 회사 또는 결제 제공자와 같은 중개자에 의존했습니다. 블록체인 기술을 사용하면 중개자가 더 이상 필요하지 않은데, 이는 분산화된 네트워크 노드가 마이닝이라 알려진 과정을 통해 거래를 검증하기 때문입니다. 이러한 이유로 Feat. 업비트) — hELLO. 블록체인은 종종 신뢰가 필요없는 시스템(trustless system)으로 지칭됩니다.

그러므로 블록체인 시스템은 단일 조직을 신뢰하는 데서 발생하는 리스크를 제거하고, 중개자와 제3자를 제외함으로써, 전체적인 비용과 거래 수수료를 절감할 수 있습니다.

블록체인 네트워크를 보호하는 작업 증명 합의 알고리즘(Proof of Work)은 수년에 걸쳐 매우 효율적이라는 것이 증명되었습니다. 그러나 블록체인 네트워크에 대해 수행할 수 있는 몇 가지 잠재적인 공격이 존재하며, 51%의 공격이 가장 많이 논의되고 있습니다. 이러한 공격은 단일 주체가 네트워크 해싱 파워의 50% 이상을 통제할 수 있게 됐을 때 발생할 수 있으며, 고의적으로 트랜잭션 순서를 변경하거나 제외하여 종국에는 네트워크를 방해할 수 있습니다.

이론적으로 가능한 일임에도 불구하고, 51%의 공격이 비트코인 블록체인에 성공했던 적은 한 번도 없었습니다. 네트워크가 더 크게 성장함에 따라 보안이 증대되고, 정직하게 행동하는 것이 더 많은 보상을 얻을 수 있기에, 마이너가 비트코인을 공격하기 위해 많은 돈과 자원을 투자하지 않기 때문입니다. 이외에도, 성공적인 51% 공격은 단기간에 가장 최근의 트랜잭만을 수정할 수 있는데, 이는 블록들이 암호화된 증명을 통해 연결되어 있기 때문입니다(블록의 순서를 변경하는 것은 막대한 연산 능력을 필요로 합니다). 또한 비트코인 블록체인은 매우 탄력적이어서 공격에 빠르게 대처할 수 있습니다.

블록체인 시스템의 또 다른 단점은 블록체인에 데이터가 기록되면 이를 수정하기가 무척 어렵다는 것입니다. 안정성은 블록체인의 장점이긴 하지만, 이것이 언제나 좋은 것은 아닙니다. 블록체인 데이터나 코드를 변경하는 것은 매우 까다로우며, 한 체인이 버려지고 다른 체인이 이를 대신하는 하드 포크를 종종 필요로 합니다.

블록체인은 공개키(혹은 비대칭키) 암호학을 사용해 사용자가 자신의 암호 화폐 자산(혹은 다른 블록체인 데이터)에 소유권을 주장할 수 있게 합니다. 각 블록체인 계정(혹은 주소)은 상응하는 두 개의 키를 갖고 있는데, 퍼블릭 키(공유될 수 있는)와 프라이빗 키(안전하게 보관되어야 하는)입니다. 사용자는 자신들의 자금에 접근하기 위해 프라이빗 키가 필요하며, 이는 스스로가 자신의 은행 역할을 한다는 것을 의미합니다. 사용자가 만약 프라이빗 키를 잃어버리게 된다면, 사실상 자금을 잃게되며, 이를 어찌할 수 있는 방법이 없습니다.

작업 증명을 사용하는 Feat. 업비트) — hELLO. 블록체인은 상당히 비효율적입니다. 마이닝 경쟁이 치열하고, 매 10분마다 단 한 명의 승자만 존재하기 때문에, 다른 모든 마이너들의 작업은 무용지물이 됩니다. 유효한 블록 해시를 찾을 수 있는 확률을 높이기 위해 마이너들은 지속적으로 자신의 연산 능력을 증가시켜 왔기에, 비트코인 네트워크에서 사용되는 자원은 지난 몇 년간 상당히 증가해 왔으며, 현재 덴마크나, 아일랜드, 나이지리아와 같은 국가들보다 더 많은 에너지를 소비하고 있습니다.

블록체인 원장은 시간이 지나며 무척 거대해질 수 있습니다. 비트코인 블록체인은 현재 200GB의 저장 공간을 필요로 합니다. 블록체인 규모의 성장 속도는 하드 드라이브의 성장 속도를 앞지를 것으로 보이며, 원장이 너무 커져 개인이 이를 다운로드하거나 저장할 수 없게 되면, 노드를 잃게 될 위험이 있습니다.

이러한 단점들에도 불구하고, 블록체인 기술은 고유한 장점들을 제공하며, 이는 분명 대중화되고 있습니다. 주류에 채택되기까지는 아직 가야 할 길이 멀지만, 많은 기업들이 블록체인 시스템의 장점과 단점을 이해하기 시작했습니다. 향후 몇 년 간, 블록체인 기술이 어디에서 가장 많은 가치를 더할 수 있는지 알아내기 위해, 기업과 정부가 새로운 애플리케이션들을 실험하는 것을 보게 될 것입니다.

암호화폐 트레이딩 봇을 만들었다 (feat. 업비트)

최근 블로그 포스팅이 한 동안 뜸했던 이유는, 어느 날 트레이딩 봇을 만들고 싶은 욕구가 생겨서 여기에 지속적으로 힘을 쓰고 있었기 때문이다. 개발자라면 누구나 한 번쯤은 만들어본다는 이것을, 아직 나는 만들어본 적이 없으니 괜찮은 기회라 여겨 해보기로 했다. 설계를 여러번 수정하다가 이제서야 어느정도 완성도를 보이고 있어 블로그에 적기로 했다. 참고로 개발 언어는 파이썬이 아닌 Go 다. 그 이유는 아래에서하자.

트레이딩 봇을 구동한다. CLI 기반이기 때문에 GUI 같은건 없다.

봇 같은 경우 주식 트레이딩은 봇은 아니고, 암호화폐 거래소 중 하나인 업비트에 암호화폐를 주문하고, 조건에 맞는 코인을 감지, 이후 감지된 마켓을 대상으로 전략을 실행할 수 있는 봇을 개발했다. 이미 서문만으로도 봇의 구조가 이미 노출되었지만, 이는 그저 프레임워크를 만들어낸 것 뿐이며 가장 중요한 것은 전략인데, 이는 Feat. 업비트) — hELLO. 기업 비밀이라 비공개다. 애초에 수익을 제대로 내고 있지도 않지만.

업비트 Open API 사용을 위한 개발 문서를 제공 합니다.업비트 Open API 사용하여 다양한 앱과 프로그램을 제작해보세요.

파이썬이 아닌 Go 언어로 개발한 이유

이 프로젝트는 내가 Go 로 작성한 첫 번째 사이드 프로젝트다. 일반적으로 트레이딩 봇은 파이썬으로 개발된 경우가 많은데, 나같은 경우에는 Go 를 선택했다. Go 를 사용한 이유는 물론 Feat. 업비트) — hELLO. 현재 내 주력 언어가 Go 인 것이 가장 큰 이유이기도 하지만, Go 를 봇 개발에 사용했을때 가지는 간편하고 채널을 통한 동시성 제어에서의 이점이 크다고 여겼기 때문이다. 트레이딩 봇에서 여러 마켓의 감시를 위해 고루틴을 사용하여 동시성을 사용할 일은 많은데, 그 예는 설계에서 살펴보도록 하자.

내가 개발한 트레이딩 봇은 오픈소스다. 따라서 봇의 사용법이나 코어 소스코드가 궁금하다면 아래의 깃허브 레포지토리를 확인하자. 이 포스트에서는 봇에 대한 전반적인 설계를 살펴본다.

GitHub - pronist/PachinCo: 암호화폐 트레이딩 봇 (feat. 업비트)

암호화폐 트레이딩 봇 (feat. 업비트). Contribute to pronist/PachinCo development by creating an account on GitHub.

프로젝트 이름이 upbit-trading-bot 에서 PachinCo 로 바뀌었다! 요즘 잘 나가는 파친코 코인을 타보자. 참고로 파친코의 철자는 본래 PachinKo 인데, 코인(Coin, Crypto) 트레이딩 봇이어서 C 로 바꾸었다.

봇은 가장 큰 관점에서 보자면, 봇은 업비트 서버의 관점에서 클라이언트라는 점이다. 어떤 서버에 요청을 보내는 클라이언트냐 하면 업비트 API 서버에 보내는 클라이언트라고 볼 수 있다. 어떠한 형태로든 트레이딩 봇은 업비트 서버에 요청을 보내게 된다. 그게 조회가 될 수도 있고 주문을 요청을 하는 것일 수도 있다.

트레이딩 봇은 업비트 Open API 서버로 요청을 보낸다.

또한 시세를 주기적으로 감시하여 조건에 도달했는지를 판단하는 Detector , 각 마켓을 대상으로 개별적인 매수/매도 전략을 실행할 수 있는 Strategy 가 고루틴의 주요 사용처다. 이는 서로 독립적으로 돌아간다. Strategy 에서는 조건에 도달하면 업비트 API 서버에 주문을 보내기 때문에 다른 문맥에서 독립적으로 동작해도 아무런 영향이 없다. 봇의 전반적인 구조는 다음과 같다.

Detector 에서 시작하여 전략을 실행하는 트레이딩 봇의 전반적인 구조를 보여준다.

다이어그램을 보면 알겠지만, 봇은 중간에서 중개인의 역할을 수행하게 되며 Detector 가 특정 조건에 해당하는 종목을 찾아서 봇에게 보고를 하면, 봇은 코인을 추상화한 Coin 객체를 생성하고 매수/매도를 위한 Strategy 에 생성한 Coin 객체를 전달하여 실행하게 될 것이다. 여기서 Detector 는 별개의 고루틴에서 동작, 봇이 실행하는 전략들도 모두 별개의 고루틴에서 실행되며 독립적으로 조건을 검증하여 매수/매도를 진행한다. 거의 동시에 여러 개의 마켓에 대해 전략을 실행할 수 있다.

예를 들어 Detector 가 특정 조건을 만족한 종목인 KRW-BTC 를 발견하여 봇에 보고하면, 봇은 BTC 코인에 해당하는 Coin 객체를 생성하고 KRW-BTC 마켓이 Strategy 에 따라 매수/매도 될 수 있도록 하게하는 것이다. 그래서 주목해볼만한 부분은 결론적으로 트레이딩 봇이라는 것이 의도대로 동작하기 위해서는 종목 선정(Detecting)매수/매도 전략(Strategy)이라는 두 가지의 주요 핵심 알고리즘이 있다는 것이며 이에따라 적절한 종목선정과 전략에 따라 봇의 성과가 결정된다는 것이다.

업비트 API 클라이언트

봇은 위에서 언급했듯 업비트의 API 서버에 요청을 보내는 클라이언트다. 따라서 업비트 API 에 요청을 보낼 수 있는 클라이언트 래핑 객체가 필요하게 된다. 물론 이 부분은 업비트 API 문서에 따라 작성된 것이기 때문에 그렇게 중요하지는 않지만, 실제로 업비트 API 서버에 요청을 보내는 역할을 하므로 짤막하게나마 이야기해본다.

자산 조회나 주문 요청의 경우 Jwt 가 필요하고, 그렇지 않은 일반적인 정보는 그냥 보내도 상관없다.

업비트 API 서버는 두 종류로 나눌 수 있는데, Jwt 를 포함하여 요청을 보내야 하는 일반적인 Client 와 그저 Get 요청만 보내도 정보를 얻을 수 있는 QuotationClient 로 분리된다.

type Client

자산, 주문 요청을 업비트 서버에 보내기 위해 사용하는 클라이언트다. 당연하겠지만 여기에는 AccessKey, SecretKey 가 포함되어야 한다.

type QuotationClient

QuotationClient 는 단순한 Get 요청을 위해 사용한다. 이를 통해 종목에 대한 Tick, Trades 를 얻어오는 등 인증이 필요하지 않은 단순한 정보들을 얻어올 수 있다. 따라서 http.Client 만을 가진다.

이렇게 선언된 두 개의 클라이언트는 Bot 을 통해 접근할 수 있도록 하였다. 따라서 Client, QuotationClient 를 통해 업비트 서버에 요청을 보낼 수 있게된다.

트레이딩 봇

type Bot

Bot 은 main 고루틴에서 사용되며 Bot.Run() 이라는 메서드를 main() 함수에서 호출할 것이다. 먼저 Bot 구조체는 다음과 같이 생겼다. 위에서 언급한 것처럼 클라이언트의 역할도 한다는 것을 잊어서는 안 된다.

Accounts, Strategy 타입은 모두 인터페이스다. 특히 Accounts 의 경우, 업비트는 기본적으로 모의투자를 지원하지 않는다. 따라서 안전하게 전략이 동작하는지 실험을 할 수 있어야 하는데, 그럴때 필요한 것이 프로그램에서 임의로 만든 테스트용 계정이다. 이는 실제 업비트 계정이 아니며 비슷한 동작을 하도록 구현이 된 것 뿐이다. 따라서 미묘한 차이가 발생한다.

또한 Bot 에서는 미리 마켓에 사용할 전략을 가지고 있다. Detector 가 조건에 도달한 마켓을 발견하게 되면 해당 마켓에 Strategies 에 있는 전략들을 실행하게 된다.

Bot 을 호출하는 main() 함수는 아래와 같이 작성된다. 계정을 임의로 생성하여 전략을 테스트할 수 있다.

.Run() 메서드는 main 고루틴이 실행하는 메서드이며, Detector 의 보고를 받고, 전략을 실행하는 핵심 메서드다. Detector 에게 보고를 받을 때는 자연스럽게 채널을 사용한다. 참고로 아래의 코드가 실제 돌아가고 있는 봇의 코드랑 동일한 것이 아니다. 핵심적인 코드만을 가져와 포스트하기 편하도록 짜집기했다.

추가적으로 Detector.run() 의 파라매터에 predicate 가 사용된 것이 있는데, 저것은 함수이며 디텍터가 찾을 종목에 대한 조건을 명시한다. 해당 함수가 true 를 반환하면 조건에 맞는 종목으로 판단하며 Detector.d 채널에 신호를 보낸다. Detector.run() 에서는 내부적으로 업비트 웹소켓 서버에 요청을 보내 가격을 얻어오고 조건을 처리한다.

Bot, Detector, Strategy 가 데이터를 주고받는 모습을 보여준다.

Bot.tick() 메서드는 coin 구조체에 정의되어 있는 t 채널에 가격 정보를 보내고 이를 Strategy 에서 소모한다. Strategy 에서 직접 가격정보를 얻어와도 되지만, 요청의 수가 너무 많아지면 업비트 서버의 제약에 따라 요청이 거절된다. 업비트 서버의 제한은 초당 10번의 요청으로 파악되었다.

위의 다이어그램은 Bot 이 Detector.run() 를 실행하면 해당 메서드가 Detector.d 채널로 틱을 보내고 그것을 Bot 이 소비하는 모습을 보인다. 또한 Bot.tick() 이 실행되면 Coin.t 채널에 틱을 보내고 Strategy 가 이를 소비하게 된다. Strategy 가 소비를 하는 모습은 다음과 같다.

.strategy(*coin, Strategy)

type Accounts

Accounts 는 인터페이스다. Accounts 는 업비트 계정을 포함한 테스트용 계정이 구현해야 할 메서드를 가진다. Accounts 가 가져야 하는 메서드 중 중요한 것이 바로 .order() 다. 주문은 봇, 또는 사람이 하지만 논리적으로 계정을 사람, 또는 봇과 동일시하여 Accounts 가 특정 코인에 대해 매수/매도 주문을 낼 수 있다.

.order(*Bot, *Coin, string, float64, float64) (bool, error)

오더에서는 실제로 업비트 계정에서는 주문을 요청하고, 테스트 계정에서는 내부의 자산 현황을 갱신하게 된다. 여기서 살펴볼 것은 실사용 계정에서 주문을 넣었으나 체결되지 않고 계속 기다리기만 하면 트래킹 중인 해당 마켓의 전략 고루틴이 락이 되어버릴 수도 있다는 점이다. 따라서 타이머를 두고 체결을 기다렸다가 체결이 되지 않으면 주문을 캔슬한다.

여기서 log.Logger 는 로그를 보내기 위한 채널이다. 이전에 적지는 않았지만, 로그 채널은 봇을 실행하기 이전에 초기화를 별도로 진행한다. 별도로 아래에서 언급하지는 않겠지만 나온김에 이야기했다. 또한 static.Config 객체는 글로벌 객체이며 config.yml 로 부터 Timeout 설정을 얻어와서 매핑한다.

type Strategy

Strategy 또한 인터페이스다. 해당 인터페이스를 만족하는 모든 전략은 봇에서 사용할 수 있도록 구성되었다. 여기서 .register() 는 전략을 실행하기 전에 준비해야 할 것을, .run() 메서드는 전략을 진행한다.

트레이딩 봇을 만드는 과정은 흥미롭다. 프레임워크에 해당하는 틀은 어느정도 구성되었기에 이제 전략을 재미나게 생각하는 일만 남았다. 봇은 사실 전략이 제일 중요하다. 전략에 따라 수익이 날 수도 있고 안 날수도 있기 때문이다.

그러나 내가 이렇게 까지 구조적으로 봇을 작성한 이유는 이것을 단순 경험만으로 끝낼게 아니라 무언가 결과를 도출해볼 것이기 때문이다. 또한 이 프로젝트는 나의 첫번째 Go 언어 사이드 프로젝트라는 점에서 의미가 있으며 부가적인 써드파티 라이브러리들을 사용해볼 기회또한 있어서 나름 괜찮은 프로젝트라고 생각한다.


0 개 댓글

답장을 남겨주세요