삼성증권 POP HTS 실행과 로그인 자동화 코드 정리
이번 글에서는 삼성증권 POP HTS를 자동 실행하고, 인증서 비밀번호를 입력한 뒤, 창 크기와 위치를 고정하는 코드 흐름을 정리해본다.
이 코드는 단순히 프로그램을 실행하는 수준이 아니라, 실제 자동매매를 안정적으로 돌리기 위해 필요한 다음 과정을 포함한다.
- POP HTS가 이미 실행 중인지 확인
- 실행 중이면 기존 창 활성화
- 실행되어 있지 않으면 프로그램 시작
- 인증서 비밀번호 자동 입력
- 로그인 이후 확인 팝업 처리
- 창 크기와 위치를 일정하게 맞춤
자동화 관점에서 보면 이 단계는 주문 로직보다도 더 중요할 수 있다. 로그인 단계가 흔들리면 이후의 UI 탐색, 버튼 클릭, 이미지 인식이 전부 불안정해지기 때문이다.
전체 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import pygetwindow
def is_pop_running():
for w in pygetwindow.getAllWindows():
if w.title and ("POP" in w.title or "삼성" in w.title):
w.activate()
return True
return False
def enter_cert_password(run_dir: Path):
# 인증서 비번 입력칸 클릭(라벨+오프셋 추천)
screen.wait_exists("cert_pw_label.png", timeout=10, confidence=0.8)
screen.click_field_by_label(run_dir, "cert_pw_label.png", x_offset=160, conf=0.80)
screen.ctrl_a()
time.sleep(0.05)
CERT_PW = os.getenv("CERT_PW")
screen.safe_type_symbol(CERT_PW) # 클립보드 붙여넣기
time.sleep(0.1)
screen.wait_and_click("cert_btn_confirm.png", run_dir, timeout=10, confidence=0.80)
time.sleep(5)
if screen.exists_on_screen("btn_confirm_after_login.png", confidence=0.80):
screen.wait_and_click("btn_confirm_after_login.png", run_dir,
timeout=10, confidence=0.80)
time.sleep(5)
def start_pop_hts(run_dir: Path):
if is_pop_running():
t_util.log("POP HTS 이미 실행 중")
normalize_pop_window()
return
for i in range(2):
try:
t_util.log("POP HTS 실행 시작")
subprocess.Popen(POP_EXE_PATH)
time.sleep(15) # 실행 대기
enter_cert_password(run_dir)
normalize_pop_window()
time.sleep(10) # 실행 대기
screen.close_login_notice(run_dir)
time.sleep(10) # 실행 대기
break
except Exception as ex:
t_util.log(ex)
def normalize_pop_window(target_width=1900, target_height=1100):
# POP HTS 창을 지정한 크기로 변경 + 화면 중앙 배치
windows = pygetwindow.getAllWindows()
pop_win = None
for w in windows:
if w.title and ("POP" in w.title or "삼성" in w.title):
pop_win = w
break
if not pop_win:
raise RuntimeError("POP HTS 창을 찾지 못했습니다.")
if pop_win.isMinimized:
pop_win.restore()
pop_win.activate()
time.sleep(0.2)
# 현재 화면 해상도
screen_width, screen_height = pyautogui.size()
# 중앙 좌표 계산
left = (screen_width - target_width) // 2
top = (screen_height - target_height) // 2
# 크기 및 위치 설정
pop_win.resizeTo(target_width, target_height)
time.sleep(0.1)
pop_win.moveTo(left, top)
time.sleep(0.3)
t_util.log(f"POP HTS 창 크기 고정: {target_width}x{target_height}")
1. is_pop_running(): POP HTS가 이미 떠 있는지 확인
가장 먼저 하는 일은 삼성증권 POP HTS가 이미 실행 중인지 확인하는 것이다.
1
2
3
4
5
6
def is_pop_running():
for w in pygetwindow.getAllWindows():
if w.title and ("POP" in w.title or "삼성" in w.title):
w.activate()
return True
return False
이 함수는 pygetwindow의 getAllWindows()로 현재 열려 있는 모든 창을 순회하면서, 제목에 "POP" 또는 "삼성"이 포함된 창을 찾는다.
찾으면 바로:
- 해당 창을 활성화하고
True를 반환한다.
찾지 못하면 False를 반환한다.
이 방식의 장점
- 구현이 단순하다.
- 삼성증권 창이 이미 떠 있는지 빠르게 확인할 수 있다.
- 실행 중인 창을 바로 앞으로 가져올 수 있다.
주의할 점
창 제목 문자열에 의존하므로, 실제 환경에서 창 제목이 바뀌거나 예기치 않은 다른 삼성 관련 창이 떠 있을 경우 오탐 가능성은 있다. 그래도 HTS 실행 여부를 거칠게 확인하는 용도로는 꽤 실용적이다.
2. enter_cert_password(): 인증서 비밀번호 입력 자동화
로그인 단계에서 가장 중요한 부분은 인증서 비밀번호 입력이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def enter_cert_password(run_dir: Path):
# 인증서 비번 입력칸 클릭(라벨+오프셋 추천)
screen.wait_exists("cert_pw_label.png", timeout=10, confidence=0.8)
screen.click_field_by_label(run_dir, "cert_pw_label.png", x_offset=160, conf=0.80)
screen.ctrl_a()
time.sleep(0.05)
CERT_PW = os.getenv("CERT_PW")
screen.safe_type_symbol(CERT_PW) # 클립보드 붙여넣기
time.sleep(0.1)
screen.wait_and_click("cert_btn_confirm.png", run_dir, timeout=10, confidence=0.80)
time.sleep(5)
if screen.exists_on_screen("btn_confirm_after_login.png", confidence=0.80):
screen.wait_and_click("btn_confirm_after_login.png", run_dir,
timeout=10, confidence=0.80)
time.sleep(5)
이 함수의 핵심은 입력칸을 직접 찾는 대신, 라벨 이미지를 찾고 그 기준으로 오프셋을 적용해 입력칸을 클릭하는 방식이다.
왜 라벨 + 오프셋 방식을 쓰는가
HTS는 입력창 자체를 정확히 이미지 매칭하기 어려운 경우가 있다. 반면 "인증서 비밀번호" 같은 라벨은 비교적 안정적으로 잡히는 경우가 많다.
그래서 다음처럼 처리한다.
cert_pw_label.png이미지가 화면에 나타날 때까지 대기- 해당 라벨 기준으로 오른쪽
x_offset=160위치 클릭 Ctrl+A로 기존 텍스트 전체 선택- 환경변수에서 인증서 비밀번호 읽기
- 안전한 입력 방식으로 비밀번호 입력
- 확인 버튼 클릭
- 로그인 이후 추가 확인 팝업이 있으면 한 번 더 처리
screen.safe_type_symbol()를 쓴 이유
보통 pyautogui.write() 같은 직접 타이핑 방식은 한글, 특수문자, 보안 입력 환경에서 불안정할 수 있다. 그래서 클립보드 기반 붙여넣기 방식을 감싼 safe_type_symbol() 같은 함수를 쓰면 안정성이 올라간다.
환경변수 사용의 의미
1
CERT_PW = os.getenv("CERT_PW")
비밀번호를 코드에 하드코딩하지 않고 환경변수에서 읽어오면:
- 코드 저장소 유출 위험 감소
- 설정 분리 가능
- 운영 환경별 비밀번호 관리 용이
라는 장점이 있다.
3. start_pop_hts(): 전체 실행 흐름 제어
실제로 프로그램을 시작하는 메인 함수는 아래 코드다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def start_pop_hts(run_dir: Path):
if is_pop_running():
t_util.log("POP HTS 이미 실행 중")
normalize_pop_window()
return
for i in range(2):
try:
t_util.log("POP HTS 실행 시작")
subprocess.Popen(POP_EXE_PATH)
time.sleep(15) # 실행 대기
enter_cert_password(run_dir)
normalize_pop_window()
time.sleep(10) # 실행 대기
screen.close_login_notice(run_dir)
time.sleep(10) # 실행 대기
break
except Exception as ex:
t_util.log(ex)
이 함수는 크게 두 갈래로 나뉜다.
이미 실행 중인 경우
1
2
3
4
if is_pop_running():
t_util.log("POP HTS 이미 실행 중")
normalize_pop_window()
return
이미 POP HTS가 켜져 있으면 굳이 다시 실행하지 않고:
- 로그 남기고
- 창 크기와 위치만 정리한 뒤
- 종료한다.
이렇게 하면 중복 실행을 피할 수 있다.
실행되어 있지 않은 경우
실행 중이 아니라면 최대 2번까지 시도한다.
1
for i in range(2):
한 번 실패하더라도 바로 포기하지 않고 재시도할 수 있게 한 것이다.
실행 순서는 다음과 같다.
- HTS 실행 시작 로그 남김
subprocess.Popen(POP_EXE_PATH)로 프로그램 실행- 15초 대기
- 인증서 비밀번호 입력
- 창 크기/위치 정리
- 로그인 후 공지 팝업 닫기
- 마무리 대기 후 종료
왜 sleep()이 많은가
이런 UI 자동화 코드는 화면이 바뀌기 전에 다음 동작을 실행하면 실패하기 쉽다. 특히 HTS 같은 무거운 데스크톱 앱은:
- 실행 직후 로딩 시간
- 로그인 후 초기화 시간
- 팝업 생성 시간
이 일정하지 않을 수 있다.
그래서 sleep()은 다소 투박하지만, 실제 현장에서는 매우 자주 쓰는 안정화 수단이다.
다만 장기적으로는 단순 대기보다:
- 특정 화면 요소가 나타날 때까지 기다리기
- 창 제목 변경 확인
- 버튼 활성화 여부 확인
같은 조건 기반 대기로 바꾸는 것이 더 안정적이다.
4. normalize_pop_window(): 창 크기와 위치를 고정
자동화에서는 창 크기와 위치를 일정하게 맞추는 것이 매우 중요하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def normalize_pop_window(target_width=1900, target_height=1100):
# POP HTS 창을 지정한 크기로 변경 + 화면 중앙 배치
windows = pygetwindow.getAllWindows()
pop_win = None
for w in windows:
if w.title and ("POP" in w.title or "삼성" in w.title):
pop_win = w
break
if not pop_win:
raise RuntimeError("POP HTS 창을 찾지 못했습니다.")
if pop_win.isMinimized:
pop_win.restore()
pop_win.activate()
time.sleep(0.2)
# 현재 화면 해상도
screen_width, screen_height = pyautogui.size()
# 중앙 좌표 계산
left = (screen_width - target_width) // 2
top = (screen_height - target_height) // 2
# 크기 및 위치 설정
pop_win.resizeTo(target_width, target_height)
time.sleep(0.1)
pop_win.moveTo(left, top)
time.sleep(0.3)
t_util.log(f"POP HTS 창 크기 고정: {target_width}x{target_height}")
이 함수는 POP HTS 창을 찾아서:
- 최소화되어 있으면 복원
- 활성화
- 지정된 크기로 리사이즈
- 화면 중앙으로 이동
왜 이게 중요한가
이미지 매칭이나 좌표 클릭은 창 위치와 크기에 영향을 많이 받는다. 창이 조금만 달라져도:
- 버튼 좌표가 어긋나고
- 이미지 인식 결과가 흔들리고
- 다음 단계 자동화가 실패
그래서 자동화 시작 단계에서 창을 일관된 상태로 맞추는 것은 거의 필수에 가깝다.
중앙 배치 계산
1
2
left = (screen_width - target_width) // 2
top = (screen_height - target_height) // 2
현재 모니터 해상도 기준으로 창을 가운데에 놓기 위한 좌표 계산이다.
이렇게 하면 매번 같은 위치에 HTS 창을 배치할 수 있다.
5. 이 코드의 전체 흐름 요약
이 코드는 아래 순서로 동작한다.
1
2
3
4
5
6
POP HTS 실행 여부 확인
→ 이미 실행 중이면 활성화 및 창 정렬
→ 실행 중이 아니면 HTS 시작
→ 인증서 비밀번호 입력
→ 로그인 후 팝업 처리
→ 창 크기와 위치 고정
자동매매 관점에서 보면 이 단계는 주문보다 먼저 보장되어야 하는 사전 준비 루틴이다.
6. 이 코드의 장점
1) 중복 실행 방지
이미 POP HTS가 떠 있으면 다시 실행하지 않는다.
2) 로그인 자동화 포함
인증서 비밀번호 입력과 확인 버튼 클릭까지 처리한다.
3) 팝업 대응 포함
로그인 후 추가 확인 버튼이나 공지창도 이어서 처리할 수 있다.
4) 창 상태 정규화
이미지 매칭과 좌표 클릭이 흔들리지 않도록 창 크기와 위치를 일정하게 맞춘다.
7. 개선 포인트
실전에서 더 안정적으로 만들려면 아래와 같은 보완도 고려할 수 있다.
1) 제목 문자열만으로 창 식별하지 않기
현재는 "POP" 또는 "삼성" 문자열에 의존한다. 가능하면 더 구체적인 창 제목이나 프로세스 기준 식별이 있으면 더 좋다.
2) sleep() 대신 조건 기반 대기 사용
예를 들면:
- 인증서 입력창 등장까지 대기
- 로그인 완료 후 메인 화면 특정 요소 확인
- 공지창 존재 여부 체크
처럼 바꾸면 속도와 안정성이 둘 다 좋아진다.
3) 예외 로그를 더 자세히 남기기
현재는 예외 객체만 기록한다.
1
2
except Exception as ex:
t_util.log(ex)
여기에:
- 현재 단계
- 스크린샷
- 마지막 탐색 대상 이미지
- 재시도 횟수
까지 남기면 디버깅이 쉬워진다.
4) 재시도 실패 시 명시적으로 실패 처리
지금은 2회 시도 후에도 실패하면 조용히 함수가 끝날 수 있다. 실전 자동매매라면 마지막에는 raise 하거나 상위 로직으로 실패를 명확히 전달하는 편이 더 안전하다.
8. 마무리
삼성증권 POP HTS 자동화에서 실행과 로그인 단계는 단순 준비 작업이 아니다. 이 단계가 안정적으로 동작해야 이후의 주문 화면 탐색, 버튼 클릭, 체결 처리까지 이어질 수 있다.
특히 이 코드에서 핵심은 다음 세 가지다.
- 실행 여부를 먼저 확인해 중복 실행을 막는다.
- 인증서 비밀번호 입력을 이미지 기반으로 처리한다.
- 창 크기와 위치를 고정해 이후 자동화를 안정화한다.
자동매매는 주문 로직만 잘 짜는 것으로 끝나지 않는다. 실제로는 프로그램 실행 → 로그인 → 팝업 정리 → 창 상태 고정 같은 사전 루틴이 전체 안정성을 좌우한다.