파이썬과 인연

내가 파이썬을 알게된 건 꽤 오래전입니다. 컴퓨터공학과 학부시절 리눅스에 빠져 있을 때, 리눅스 매거진 이라는 잡지를 통해서 알게 되었습니다.

그때 내 눈길을 사로잡은 건 바로 이 코드

def swap(a, b):
    return b, a

엄청 흥미로웠습니다. 나는 이 직관성이 너무 마음에 들었습니다. Zen of Python 도 좋았습니다. 그리고 파이썬을 공부했습니다.

그런데 내가 파이썬을 쓸 일은 그리 많지 않았습니다. 우리 학교 학부과정은 C언어 위주로 되어 있었고, 사회로 나와선 Java로 개발을 했습니다. 파이썬은 오로지 가끔 새로운 것이 나오면 인터넷을 통해 정보를 얻고, 따라해 보고, 매년 파이콘을 참석하는 정도가 전부였습니다.

나에겐 지속적으로 붙잡고 있을 파이썬 프로젝트가 하나 필요했습니다. 때마침 서점에서 우연히 구입하게 된 책 파이썬과 리액트를 활용한 주식 자동 거래 시스템 구축1

시스템 트레이딩

사실 이 책이 아니더라도 파이썬 시스템 트레이딩은 이미 인터넷에 정보가 많이 있습니다. 책에서는 이것저것2 다루지만 정작 중요한건 증권사 연동과 이를 활용한 방법에 대한 부분 뿐입니다.

무작정 그대로 따라해서 만들어 봤습니다. 오! 잘 돌아가네요. 그치만 그게 전부였습니다.

정작 중요한 알고리즘이 빠져 있었습니다. 조회하고, 사고, 팔고 하는건 되는데 어떻게 하는지가 빠져 있었습니다.

변동성 돌파전략

퀀트 투자라는게 있습니다. 다양한 전략을 소개해 주죠. 그치만 좀 더 심플하고 명확한 하나의 조건으로 해보고 싶다는 생각을 했습니다. 그래서 찾다 보니 가상화폐 변동성 돌파전략3으로 구성한 샘플이 보였습니다.

이 전략은 아래와 같습니다.

  1. 가격 변동폭 계산: 투자 종목의 전일 고가(high)와 저가(low)의 차이(변동폭)를 계산
  2. 매수 기준: 당일 시간에서 (변동폭 * 0.5) 이상 상승하면 해당 가격에 바로 매수
  3. 매도 기준: 당일 종가에 매도

여기에 조금 보완하면 상승장 판단 여부를 붙이는 것입니다. 상승장이라는게 어차피 과거를 기반으로 하는 수치이고 이것이 미래를 100% 예측할 순 없습니다. 사실 주식이라는게 어차피 과거 기반 데이터의 미래 예측이 아닌가요.

상승장은 판단 기준은 이동평균선4 위에 있으면 상승장이라고 보는 것입니다.

프로젝트 시작

주식판

그래서 만들어 봤습니다. 모의투자를 대상으로 했습니다.

class DumbPlayer(Player):
  def __init__(self, agent):
    self.name = 'dumb'
    self.ebest = agent

  def scenario(self):
    deposit = self.get_balance()
    self._decide_sell()
    self._decide_buy(deposit)

if __name__ == '__main__':
    ebest = EBest(StageType.DEMO)
    try:
        ebest.login()
        player = DumbPlayer(ebest)
        player.scenario()
    finally:
        ebest.logout()

매수/매도가 일어나는걸 보니 신기하네요. 그치만 답답한게 몇 가지가 있습니다.

  1. 주식은 정해진 시간에만 오픈한다.
  2. 윈도우 개발환경만 지원한다.
  3. 증권사별 스펙이 너무 복잡하다.

재미는 있었지만 한정된 환경에 너무나도 오래된 레거시 API를 가지고 논다는게 답답했습니다. 무엇보다 정해진 장 시간에만 테스트 해볼 수 있다는 것도 불편한 부분.

코인판

그래서 환경을 코인판으로 바꿨습니다. REST API도 지원하고 24시간 계속 돌려볼 수 있었습니다. 이미 만들어둔 코드 베이스가 있어서 금방 구축했습니다.

# Initialize environment
context.stage = stage
context.mode = stage.mode

ScenarioStore.start()
log.info(f"STAGE: {stage.text}, MODE: {stage.mode.text}, VER: {__version__}")

# Start Nob threads
# Nob: crypto trader has own lifecycle
for crypto in NobType.DANTA.cryptos:
    nob = DantaNob(crypto, stage)
    nob.daemon = True
    nob.start()
    nob.join()
    time.sleep(1)
for crypto in NobType.SCORE.cryptos:
    nob = ScoreNob(crypto, stage)
    nob.daemon = True
    nob.start()
    nob.join()
    time.sleep(1)

# Start reporter thread
reporter = TelegramReporter()
reporter.daemon = True
reporter.start()
reporter.join()

# Start Telegram
# Should be last because of polling idle
context.bot = TelegramBot()
context.bot.start()

몇 가지 주요 개선점을 추가했다.

  1. 변동성 돌파전략의 고정 시점 매도를 개선하여 하락장을 인지하면 즉시 매도
  2. 스코어링을 기반으로 트레이딩을 하는 새로운 전략을 추가
  3. 텔레그램을 통한 현황/매수/매도/청산 등의 다양한 인터랙션 기능 추가
  4. 기간별 리포팅을 생성

시뮬레이션을 몇 주 거친 뒤 실전으로 들어갔습니다. 실전이 재미있지 않은가. 테스트용 푼돈이라고 생각. 내 돈을 가지고 이 녀석이 밤사이 사고팔고 하니까 재미있네요가슴은 후덜덜.

현재까지 계속 진행 중인 프로젝트입다. 코드도 무천 많이 개선되었습니다. 가상화폐는 훌륭한 테스트 베드입니다. 언젠간 다시 주식판으로도 들어갈 코드들입니다.

오픈소스?

오픈소스로 만들까 고민해 봤는데, 아직은 Github 사설 저장소를 사용하고 있습니다.

이유는… 아직 내놓기는 부끄럽기 때문입니다. 😢 수익률도 엉망이고… 뭔가 좀 재미를 보면 언젠가는 오픈하는걸 고민해 봐야겠습니다.

나중에 주식판으로 코드를 이관해서 오픈해 볼 생각입니다.

앞으로

파이썬은 재미있습니다. 밥벌이가 아닌 프로그래밍을 몇 년 만에 하는지 모르겠습니다. 수익률은 꽝입니다. 시스템 트레이딩으로선 실패에 가깝습니다. 현재까지는…

그치만 앞으로 계속 함께할 수 있는 친구가 생긴 느낌입니다. 수익률은… 존버 가즈아! 📈

각주


  1. http://www.yes24.com/Product/Goods/87579013
  2. 이런 종류의 책이 그렇듯이 REST, 크롤링, 웹페이지, DB 등 맛보기만 다양하게 다루면서 책의 분량만 채워놨다.
  3. https://wikidocs.net/21888
  4. 이동평균선, moving average, 특정 기간의 가격의 시계열 평균값