Open API로 시장가 주문이 되질 않았다
현재 저는 “한국투자증권 Open API + 파이썬” 으로 주식 자동매매 시스템을 구축하고 운영중입니다.
국내에서 자동 매매(시스템 트레이딩)쪽으로 여러 책을 저술하신 “조대표” 님의 모히또 모듈을 사용하여 테스트를 진행하고 있었습니다. 위의 링크 글의 예제를 기반으로 저만의 시스템을 구현하였으며 실제 계좌로 테스트를 진행하기에는 위험 부담이 크기 때문에 “모의투자” 계좌로 테스트를 진행하였고 최근들어 매수/매도가 잘 되는 것을 확인하였습니다.
어느 정도 충분하다 판단이 되어서 바로 “실전 계좌” 로 전환을 하였고 정해놓은 룰에 따라 매수 상태가 되어서 매수를 해야 했는데요 여기서 2가지 문제가 발생하였습니다.
- 기본예탁금 부족으로 매수 안됨.
- 기본예탁금을 채워 넣었지만 매수 수량이 전체 예수금의 60% 밖에 되지 않았음.
일단 기본예탁금 부족은 제가 ETF 거래에 대한 개념이 부족해서 발생했던 문제였습니다. 저는 일반 주식 종목이 아닌 ETF 를 자동매매로 거래를 하고 있던 상황입니다.
기본 예탁금의 대한 내용은 위의 글을 참고하시기 바랍니다.
일단 기본예탁금에 대한 문제는 해결했으나 실제 매수 금액의 60% 밖에 되지 않았던 문제는 처음에는 도대체 알 수가 없었습니다. 저는 매수를 할 때 “시장가” 로 매수 주문을 넣었거든요.
#위 생략
def buyOrderMarket(self, code, q):
# 시장가 종목 매수
try:
r = broker.create_market_buy_order(
symbol = code,
quantity = q
)
pprint.pprint(r)
print("[매수주문] 종목:%s, 수량:%d, 주문정보:%s " % (code, q, r))
return True
except:
log.debug("매수 주문에 실패했습니다.")
return False
# 하단 생략
위의 함수는 제가 한국투자증권 Open API + 파이썬 예제로 공유드린 소스에서 시장가 매수를 하는 함수입니다. 일단 구문상으로는 전혀 문제가 없었으나 위 함수로 매수 주문을 넣으면 이상하게도 전체 예수금의 60% 만 주식을 매수하였습니다.
예수금 대비 매수 수량 계산도 문제가 없었고 코드상에서 별다른 문제도 발생하지 않았습니다. 이유를 알 수 없던 도중에… “시장가” 주문 자체가 문제가 있다는 것을 알게 되었습니다.
“시장가” 로 주문하게 되면 “상한가” 기준으로 계산한다
이게 무슨 말일까요? 시장가의 개념은 간단하게 말해서 “현재 시장에 형성된 가격”을 의미합니다. 따라서 시장가로 주식을 매수하게 되면 현재 형성된 최 하단의 매도가로 빠르게 매수 하게 됩니다.
위의 그림을 보면서 설명드리겠습니다. 장중에 앱에서 “시장가”로 선택한 모습입니다. 현재 계좌에는 1천만원이 있으며 시장가로 선택했을 때 최대 750주를 매수 할 수가 있습니다. 시장가는 현재 형성된 가격에 사게 되므로 별도의 가격을 설정하지 않습니다. 사려는 주식 수량만 입력하게 되어 있습니다.
그런데 최대 가능 수량이 좀 이상합니다. 위 주식의 현재 가격은 8,695원인데 최대 가능 수량은 750 주로 되어 있습니다. 실제 계산해 보면 6,521,250 원이 됩니다. 왜 이러는 걸까요?
시장가는 현재 가격의 “상한가”를 기준으로 계산하여 매수합니다.
시장가는 가격이 정해진게 아니라 현재 형성된 가격에 매수하기 때문에 최대 가능 수량은 “상한가 X 주문수량” 이 되는 것입니다. 저는 이런 원리를 모르고 한국투자증권 Open API로 주문을 했는데도 전체 예수금의 60% 정도만 매수가 된 것이었죠.
따라서 여러분이 Open API를 통해 “시장가”로 매수를 한다면 이 원리에 대해 잘 알고 있어야 합니다. 시장가로 주문하면 빠르게 매수가 가능하지만 수량 계산에 있어서 착오가 있을 수 있습니다.
그렇다면 어떻게 처리를 해야 할까요? 답은 의외로 간단합니다. “지정가” 로 매수하면 됩니다.
위 그림에도 보이듯이 “지정가” 를 선택하여 주문하면 가지고 있는 예수금에 딱 맞게 매수가 가능합니다. 대신에 지정가는 매도호가 최 하단에 있는 수량이 부족하면 매수가 바로 되지 않는 다는 점입니다. 이점을 염두해 두고 지정가와 시장가를 적절히 활용하는게 중요할거 같습니다.
import mojito
import pprint
with open("../../koreainvestment.key") as f:
lines = f.readlines()
key = lines[0].strip()
secret = lines[1].strip()
acc_no = "12345678-01"
broker = mojito.KoreaInvestment(api_key=key, api_secret=secret, acc_no=acc_no)
resp = broker.create_limit_buy_order(
symbol="005930",
price=65000,
quantity=1
)
pprint.pprint(resp)
위 코드는 조대표 님의 위키독스에 있는 예제입니다. 지정가는 create_limit_buy_order( )라는 함수를 사용하면 되겠네요. 좀더 자세한 내용은 아래 위키 독스 글을 참고해 보세요.
Open API로 자동 매매 구현시 매수 수량 계산을 꽤 중요한 기능입니다. 이 글을 읽으시는 분들도 이 점에 있어서 착오 없으셨으면 좋겠습니다.
안녕하세요. 좋은 Lesson learned 글 잘 보고 갑니다.
저도 조대표님의 책을 보면서 mojito module을 사용해서 한국투자증권 open api를 공부하고 있는데요, 한가지 궁금한 부분이 있어서 이렇게 문의 드립니다.
저의 경우에는 분봉조회 시 간혹 오류가 발생되는 경우가 있는데, 혹시 이런 경우가 있으셨는지와 어떻게 해결하셨는지 궁금합니다.
바쁘시겠지만 도움 부탁 드립니다. 감사합니다.
오류가 발생하는 구문입니다
Exception has occurred: KeyError
‘output2’
마지막 부분에 약간의 typo가 있어 정정 드립니다.
오류구문과 오류 메세지는 다음과 같습니다.
오류구문:
resp = broker.fetch_today_1m_ohlcv(“종목코드”)
오류메시지:
Exception has occurred: KeyError
‘output2’