INVESTAR / StockAnalysisInPython

456 stars 412 forks source link

8장에 대해서 질문이 있습니다. #45

Open gustmddlek56 opened 3 years ago

gustmddlek56 commented 3 years ago

크레온 api를 이용해서 주식프로그램 매매를 진행중입니다. 투자하고 있는 여러 ETF들 중에서 유독 한 종목의 ETF에 대해서

"xx종목명" "주문가능한 수량"EA : "현재가격" meets the buy condition!

이라는 문구가 출력은 되고 있는데 실제로 구매로 이뤄지지는 않고 있습니다.

원인을 스스로 생각해봤을때 현재 구매가능한 수량이 98EA라고 나오는데, 구매방식이 FOK방식이기 때문에 한번에 물량을 구매하지 못하고 따라서 주문을 취소하고 있다고 생각을 합니다. 여기서 첫번째 궁금한 점이 과연 이 추측이 맞는지를 궁금합니다.

그리고 두번째로는 만일 추측이 맞다면 여러 종목들 중에서 코드 수정을 통해서 특정 종목들은 구매방식을 IOC방식으로 변경할수 있는지가 궁금합니다.

예를 들어서 #최유리 FOK 매수 주문의 마지막줄에

if str(code) = 특정 종목: cpOrder.SetInputValue(0, "2")
cpOrder.SetInputValue(1, acc)
cpOrder.SetInputValue(2, accFlag[0]) cpOrder.SetInputValue(3, code)
cpOrder.SetInputValue(4, buy_qty)
cpOrder.SetInputValue(7, "1") 이 부분을 바꾸는 방법으로 수정이 가능한지를 묻고 싶습니다. cpOrder.SetInputValue(8, "12")

INVESTAR commented 3 years ago

첫번째 질문에 대한 대답은 '그렇습니다'입니다.

1) 해당 종목의 호가 접수 시점에서 가장 낮은 매도호가로 나온 매도잔량이 98개가 안됐을 가능성이 커보입니다.

2) ETF 종목은 매수할 때 증권거래세는 없지만, 증권사수수료+유관기관제비용이 부과되므로 해당 금액을 제외하고 buy_percent를 설정해 주시는 게 좋습니다.

   target_buy_count = 5 # 매수할 종목 수
   buy_percent = 0.19 # 증권사수수료+유관기관제비용을 고려해서 설정

3) 해당 종목이 ETF 종목이 인버스나 레버리지 ETF가 아닌지 확인해 보시기 바랍니다. 작년 말부터 기본예탁금 내지 않거나 사전 교육을 듣지 않으면 인버스나 레버리지 ETF는 매수가 안되는 것으로 알고 있습니다. https://rassori.tistory.com/770

두번째 질문에 대한 대답도 '그렇습니다'입니다. 주문조건을 1로 변경하시면 IOC 방식으로 주문을 넣으실 수 있을 것입니다. 다만 전반적인 코드는 조금 변경하셔야 할 것 같습니다.

# 최유리 FOK 매수 주문
cpOrder.SetInputValue(0, "2") # 1:매도, 2:매수
cpOrder.SetInputValue(1, acc) # 계좌번호
cpOrder.SetInputValue(2, accFlag[0]) # 상품 구분 - 주식상품 중 첫 번째
cpOrder.SetInputValue(3, code) # 종목코드
cpOrder.SetInputValue(4, buy_qty) # 매수할 수량
cpOrder.SetInputValue(7, "2") # 주문조건 0:기본, 1:IOC, 2:FOK
cpOrder.SetInputValue(8, "12") # 주문호가 1:보통, 3:시장가, 5:조건부, 12:최유리, 13:최우선
gustmddlek56 commented 3 years ago

친절하게 답변주셔서 너무나 감사합니다.

두번째 질문했던 일부 종목만 IOC방식으로 주문하는 법에 대해서 고민을 해봤습니다. 코드를 변경하고 있는데 몇가지 추가적인 질문이 생겨서 이렇게 글을 남기게 되었습니다.

첫번째는 기존의 #최유리 FOK 매수 주문 설정 밑에 이런식의 코드를 추가했습니다.

if current_price > target_price and current_price > ma5_price and current_price > ma10_price and code(str('원하는 종목코드')):

            cpTradeUtil.TradeInit()
            acc = cpTradeUtil.AccountNumber[0]     
            accFlag = cpTradeUtil.GoodsList(acc, 1) 
            cpOrder.SetInputValue(0, "2")
            cpOrder.SetInputValue(1, acc) 
            cpOrder.SetInputValue(2, accFlag[0]) 
            cpOrder.SetInputValue(3, code)
            cpOrder.SetInputValue(4, buy_qty) 
            cpOrder.SetInputValue(7, "**1**") 
            cpOrder.SetInputValue(8, "12")

여기서 첫번째 질문이 이런식으로 코드를 수정하는 것이 맞는지에 대해서 궁금합니다. 여기서 추가적으로 수정해야한다면 어떤 방식으로 해야하는지 책을 살펴봐도 잘 모르겠습니다.

이어지는 두번째 질문은 만약에 이런 상황에서 내가 수정한 코드가 맞는지를 확인하는 방법이 궁금합니다. 예를 들어서 7장에 나온 백테스트같은 경우에는 내가 원하는 방향으로 수정을 하고 그것이 맞는지는 데이터가 나에게 있기 때문에 즉각적으로 확인이 가능하다고 생각합니다.

하지만 8장의 경우에는 실제 주식시장을 대상으로 하고 있기 때문에 내가 수정한 것이 맞는지를 확인하기 위해서는 실제 주식시장에서 해당상황이 발생해야만 알 수 있는것인지, 아니면 코드의 수정이나 다른 테스트 방법으로 미리 확인해볼 수 있는지가 궁금합니다.

INVESTAR commented 3 years ago

매수 시 IOC 조건으로 주문을 넣으려면 말씀하신대로 if 조건에서 IOC 조건으로 매수할 종목인지 판단하는 로직만 추가하시면 될 것 같습니다.

다만, 제가 처음 자동매매 코드를 작성했을 때에는 매수 시 FOK 조건으로, 매도 시 IOC 조건으로 주문하도록 설계했기 때문에 특정 종목에 대해서 IOC로 매수하려면, 전체적으로 코드를 수정하셔야 할 것 같습니다.

두번째 질문의 경우, 증권사 API 호출 전후로 디버깅용 데이터를 최대한 출력해 보는 수밖에 없을 것 같습니다. 제가 자동매매 코드를 작성했을 때에도 실제 코드 양만큼 디버깅용 출력 코드가 존재했던 것으로 기억합니다.

코드를 테스트 하실 때에도 주식 시장에서 무작정 특정 이벤트가 발생하기를 기다리는 것은 비효율적입니다. 거래량이나 가격 변동폭 등을 봐서 테스트에 맞는 적당한 종목을 찾은 후 종목수, K값, 매수/매도 조건 등을 변경해 가면서 테스트 해보시길 추천해 드립니다.