배포된 전략 관리하기#

PyQQQ CLI 사용하기에서 간단한 애플리케이션을 작성하고 배포 했습니다. 이제 조금 더 자세하게 배포에 대해서 알아보도록 하겠습니다.

배포란?#

배포란 PyQQQ 플랫폼에서 애플리케이션을 서버에 전송하여 원격으로 실행시키는 과정을 의미합니다. PC에서 프로그램을 실행하는 것과 달리, 클라우드에서 실행하면 주식 거래와 같은 실시간 데이터 처리에서 더 높은 신뢰성을 제공합니다. 클라우드는 서버 중단, 네트워크 지연 등의 위험을 최소화하며, 항상 안정적으로 작동하는 환경을 통해 중요한 거래와 분석이 중단 없이 이루어질 수 있도록 지원합니다.

애플리케이션 구조#

간단한 애플리케이션(이하 전략)의 폴더 구조를 보면 다음과 같습니다.

.
├── .env
├── sample.py
└── requirements.txt

크게 3가지로 나누어 볼 수 있습니다. 전략을 구동시키는 파이썬 파일과 환경변수 그리고 실행에 필요한 패키지 목록입니다.

  • 파이썬 파일 (sample.py): 엔트리 함수가 구현되어 있는 파일

  • 패키지 목록 (requirements.txt): 라이브러리 패키지 목록이 기록되어 있는 파일

  • 환경변수 파일 (.env): 전략 실행에 필요한 변수가 저장되어 있는 파일

각각에 대해서 알아보도록 하겠습니다.

엔트리 함수#

PyQQQ 플랫폼에 전략을 배포하기 위해서는 필수 엔트리 함수가 반드시 구현되어 있어야 합니다. 배포하는 전략의 성격에 맞춰 엔트리 함수를 추가해야 합니다.

구분

함수

구현방식

일반

async def run()

무한 루프

백테스트

async def run_batch()

1회 실행 후 종료

클라우드 서버는 배포된 전략의 엔트리 함수를 자동으로 찾아 실행합니다. 만약, 엔트리 함수가 없다면 실행이 중단됩니다.

실행 시간#

일반 전략을 배포할 때, 엔트리 함수는 무한 루프 형태로 구현하는 것이 일반적이며, 이를 통해 배포된 전략은 24시간 지속적으로 동작합니다. 이 방식은 시간에 따라 유연하게 대응할 수 있는 장점을 제공합니다.

예를 들어, 거래소 마감 30분/20분/10분 전에 각각 매수를 수행하도록 할 수 있습니다. 또한, 미국의 데이장 마감 후 차트를 분석하여 애프터마켓에서 매수를 진행하는 전략도 구현 가능합니다.

    ...
    async def run(self):
        while True:
            try:
                if is_trading_time(): # 거래시간 확인
                    await self.on_trade()
                else:
                    self.logger.info(f"market closed")

            except Exception as e:
                self.logger.exception(e)

            await asyncio.sleep(60) # 1분마다 실행
    ...

위 코드는 거래 시간을 체크하며 지속적으로 on_trade함수를 호출해 거래 작업을 수행하고, 거래 시간이 아니면 market closed 메시지를 출력합니다.

라이브러리#

전략을 작성하다보면 단순 이동평균, 지수 이동평균 등 수학 계산을 많이 필요로 합니다. 이런 경우, 일일이 코드를 작성하는 것보다 데이터 분석 라이브러리를 사용하는 것이 바람직합니다.

import pandas as pd

# 예제 데이터
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
period = 3

# pandas를 사용한 SMA 계산
df = pd.DataFrame(data, columns=["Value"])
df["SMA"] = df["Value"].rolling(window=period).mean()

print("SMA (pandas):")
print(df)

다음 명령어를 통해 사용하고 있는 라이브러리 패키지 목록을 기록할 수 있습니다. 전략이 배포되면 클라우드 서버에서 requirements.txt 파일을 찾아 라이브러리를 자동으로 설치합니다.

$ pip freeze > requirements.txt

환경변수#

전략에는 Broker API 정보와 같은 중요한 데이터가 필요하며, 이를 환경변수 파일(.env)에 저장하여 사용합니다. 전략을 배포하면 코드와 .env 파일이 같이 전송됩니다. 전송 된 환경변수는 암호화되어 저장되며, 해당 전략에서만 접근 가능하도록 보호됩니다. 전략을 삭제하면 암호화된 환경변수 데이터도 모두 삭제되어 사용할 수 없게 됩니다.

## 한투 미국거래 계좌
KIS_APP_KEY=...
KIS_APP_SECRET=...
KIS_CANO=...
KIS_ACNT_PRDT_CD=...

## LS(구 이베스트투자)증권 계좌
EBEST_APP_KEY=...
EBEST_APP_SECRET=...

환경변수에서 Broker API정보를 읽어서 다음처럼 사용할 수 있습니다.

import os
import dotenv
from pyqqq.brokerage.ebest.oauth import EBestAuth
from pyqqq.brokerage.ebest.simple import EBestSimpleDomesticStock

dotenv.load_dotenv()

auth = EBestAuth(
    os.getenv("EBEST_APP_KEY"),
    os.getenv("EBEST_APP_SECRET"),
    paper_trading=os.getenv("PAPER_TRADING") == "1",
)
simple_api = EBestSimpleDomesticStock(auth=auth)

또한, KV 저장소에 환경변수를 저장해 사용할 수 있습니다.