본문 바로가기

영웅문Global 핸들링

매매 결과 확인 (실시간 잔고 스크린샷과 값 확인 방법)

728x90

앞서서 매수 / 매도를 잘 수행했다면 주식 계좌에 관련 내용이 반영되어 있을 겁니다. 그래서 어느 순간에는 실시간 잔고를 확인하고 싶게 됩니다. 앞서서 스크린샷을 찍는 방법이 있었던 것 기억하시나요? 매수 / 매도 확인창이 뜨면 내가 잘 설정했는지 확인하기 위한 용도로 스크린샷을 찍어봤습니다. 오늘은 실시간 잔고 창을 띄워서 내가 보유한 종목들의 현재 상태를 스크린샷으로 찍고 안의 값들을 인식해보는 것을 해보겠습니다. 마찬가지로 전체적인 수행 결과를 먼저 보시죠.

실시간잔고 창을 띄우고 스크린샷 찍고 인식을 시도합니다.

 

영웅문Global 인식

영웅문Global 인식은 앞서서 진행했던 내용들과 같습니다. 해당 소스를 구현했었다면 그대로 사용하시면 됩니다.

더보기
# result 폴더 만들기
if not os.path.exists("result"):
    os.mkdir("result")

# 영웅문 process id 찾기
process_id = 0
for process in psutil.process_iter(['pid', 'name']):
    if process.info['name'] == 'nfrunlite.exe':
        process_id = process.info['pid']
        break

# 실행 중인 어플리케이션에 연결
app = Application(backend="uia").connect(process=process_id)

# 메인 윈도우 핸들링
main_window = app.window(title='영웅문Global')
main_window.maximize()
time.sleep(1)

# 각 자식 컨트롤의 정보 출력
screen_area = None
menutoolbar = None
for child in main_window.children():
    if child.window_text() == "메뉴툴바":
        menutoolbar = child

    if child.class_name() == "MDIClient": # 작업 영역
        screen_area = child

# 메뉴툴바로 부터 메뉴를 호출 할 예정
menus = None
if menutoolbar:
    menutoolbar_children = menutoolbar.children()
    for child in menutoolbar_children:
        if len(child.children()) == 4:
            menus = child

if menus:
    input_field = menus.children()[0].children()[0]

 

실시간잔고 창

미니주문 창을 띄웠던 것 처럼 번호만 입력하면 실시간잔고 창을 띄워서 확인 할 수 있습니다.

# 2150 계좌정보
input_field.set_focus()
input_field.type_keys('2150')
time.sleep(2)

 

실시간잔고 창 - 스크린샷

실시간잔고 창이 잘 떴는지 확인하고 창을 핸들링 하기 위해서 정보를 가져옵니다.

account_info_window = None
for child in screen_area.children():
    if child.window_text().startswith("[2150]"):
        account_info_window = child
        break

 

실시간잔고 창 - 인식 (OCR & PARSING)

기본적으로 실시간잔고 창을 스크린샷을 찍습니다. 그리고 이를 tesseract를 통해 인식을 시도합니다.

pane_control = find_controls_recursively_friendly(account_info_window, "Pane")[0]

screenshot = pane_control.capture_as_image()
screenshot_file = f"pane_screenshot_{int(time.time())}.png"
screenshot.save(f"result/{screenshot_file}")

image = cv2.imread(f"result/{screenshot_file}")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imwrite(f"result/gray_{screenshot_file}", gray)

config = ('-l kor+eng --oem 3 --psm 6') # 6
text = pytesseract.image_to_string(image=gray, config=config)
print(text)

좀 더 잘 인식해보기 위해서 노력하고 있는데 그 과정 중에서 스크린샷을 찍은 후 gray 처리를 합니다. 흰색과 검은색으로만 표현되도록 변경하는 작업인데 그러면 좀 더 인식을 잘 할 수 있을 거라는 생각 때문입니다. (그러나 생각보다 인식 결과가 좋진 않네요. ^^;;)

계좌가 참담하네요. ㅠ_ㅠ
조금 이상하지만 90% 정도 인식 되는 것 같습니다?!!

 

인식률을 높이기 위한 고민

tesseract를 사용하는데 생각보다 결과가 잘 안나옵니다. 이를 높이기 위해서 몇 가지 방법들을 시도해보고 있는데 아직 완전히 일치하는 결과를 얻진 못했습니다. 그래도 힌트를 위해 내용을 남깁니다.

  • 이미지 전처리 : 스케일링을 고려해볼 수 있습니다. (이진화 작업은 앞서서 gray 작업을 적용한 상태입니다.)
  • 학습 데이터 개선 : 표현하는 종목이나 수량, % 정보 등 실시간잔고 창에서 사용되는 용어는 정해져 있으므로 이를 사전 학습을 통해 개선할 수 있을 것으로 생각합니다.

 

인식률 100% 달성

결과적으로 tesseract를 통한 이미지 인식 방법이 아닌, 영웅문Global에서 제공해주는 내용 복사 기능을 통해 값을 가져오면 인식률 100%를 달성할 수 있습니다. ㅠ_ㅠ

pane_control = find_controls_recursively_friendly(account_info_window, "Pane")[0]
pywinauto.mouse.right_click(coords=(pane_control.rectangle().left + 50, pane_control.rectangle().bottom - 50))
pywinauto.keyboard.send_keys('Z')
print(pyperclip.paste())

물론 해당 작업은 영웅문Global을 직접 핸들링 하므로 순간적인 사용자의 개입에 의해 작업이 실패 할 수 있습니다. 그러나 인식률 100%가 로직 구현에 중요하다면 이 방법을 사용해야만 합니다.

 

여기까지 내용을 직접 실행해보셨나요? 부족한 점이 있거나 어려운 점이 있다면 언제든지 댓글, 이메일로 문의 주세요. 문의를 주시는데 시간을 쏟으신 만큼 최선을 다해 답변 드리겠습니다.

계획했던 1차 작업은 여기까지 입니다. 앞서서 작성했던 내용은 아래를 참고 해주세요.

관심의 표현은 저에게 큰 힘이 됩니다. 😍 도움을 주셔서 정말 감사합니다.

2023.11.23 - [영웅문Global 핸들링] - 프로그램 실행 전 준비 (실행 중인 영웅문Global 연결하고 "모든창 닫기")

 

프로그램 실행 전 준비 (실행 중인 영웅문Global 연결하고 "모든창 닫기")

앞으로 영웅문Global을 내 맘처럼 핸들링 하기 위해서 사전에 준비해야 할 내용이 있습니다. 그 것은 바로 실행 중인 영웅문Global을 찾고 핸들링 할 수 있도록 연결하는 작업을 하는 것입니다. 더

kyeyangdak.tistory.com

2023.11.28 - [영웅문Global 핸들링] - 매수 / 매도 수행하기 - 1 (미니주문 창 호출하기)

 

매수 / 매도 수행하기 - 1 (미니주문 창 호출하기)

매수 / 매도를 수행하는 방법도 여러 가지가 있을 것 같습니다. 그중에서 저는 미니 주문창을 통해 수행해보려 합니다. 전체적인 수행 결과를 먼저 보시죠. 미니주문 창 우리가 사용할 미니주문

kyeyangdak.tistory.com

2023.11.28 - [영웅문Global 핸들링] - 매수 / 매도 수행하기 - 2 (미니주문 창 핸들링하기)

 

반응형