Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 판매자계산기
- rci보조지표
- 주가예측
- JP모건CEO
- 급등주패턴
- 매수위치
- 주식지표매수
- 계엄령관련주
- 역마진계산기
- 할인가계산
- 트레이딩뷰차트
- 주식분석
- 로또1등번호예측
- 트레이딩뷰지표
- 보조지표매매법
- 온라인쇼핑마진
- 주식지표
- 판매가계산
- JP모건
- rci지표매매법
- 성공방정식
- 마진계산기
- rci매수매도
- 아마존CEO
- 주린이매수타이밍
- 트레이딩뷰매매
- 생성형이미지
- rci지표매매
- 주식보조지표
- 할인율계산기
Archives
- Today
- Total
핫트레이딩
키움API ID와 비밀번호를 입력 후 "Running on http://0.0.0.0:5000" 메시지가 출력되지 않는 문제 본문
IT 정보/트레이딩뷰 자동매매
키움API ID와 비밀번호를 입력 후 "Running on http://0.0.0.0:5000" 메시지가 출력되지 않는 문제
HOTT 2025. 3. 13. 00:54
AWS EC2에서 TradingView와 키움증권 Open API를 연동한 자동매매 프로그램을 제작하는 과정에서, "서버 실행" 단계에서 키움증권 로그인 창이 나타난 후 ID와 비밀번호를 입력했음에도 "Running on http://0.0.0.0:5000" 메시지가 출력되지 않는 문제에 대해 상세히 분석하고 해결 방법을 설명하겠습니다. 이 문제는 주로 Flask와 PyQt5의 이벤트 루프 충돌, 코드 실행 흐름, 또는 키움 Open API의 로그인 처리 지연과 관련이 있습니다. 단계별로 원인을 파악하고 해결책을 제시하겠습니다.
문제 상황 재현
- 상황: python webhook_server.py를 실행하면:
- 키움증권 로그인 창이 나타남.
- ID와 비밀번호를 입력해 로그인 성공.
- 하지만 CMD에 "Running on http://0.0.0.0:5000" 메시지가 출력되지 않고, 프로그램이 멈춘 듯 보임.
- 코드: 이전에 제공한 Flask 웹훅 서버 코드 사용 가정:
기존 파이션코드 "webhook_server.py"
from flask import Flask, request, jsonify
from PyQt5.QAxContainer import QAxWidget
from PyQt5.QtWidgets import QApplication
import sys
import logging
logging.basicConfig(filename='trade.log', level=logging.INFO,
format='%(asctime)s - %(message)s')
app = Flask(__name__)
sys.argv.append("--remote-debugging-port=9222")
kiwoom_app = QApplication(sys.argv)
kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
kiwoom.dynamicCall("CommConnect()") # 로그인 대기
def send_order(symbol, action, quantity, price):
account = "YOUR_ACCOUNT_NUMBER"
order_type = 1 if action == "buy" else 2
kiwoom.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
["주문", "0101", account, order_type, symbol, quantity, price, "03", ""])
logging.info(f"Order sent: {symbol}, {action}, {quantity}, {price}")
@app.route('/webhook', methods=['POST'])
def webhook():
try:
data = request.json
if not data:
return jsonify({"error": "No data received"}), 400
symbol = data.get('symbol')
action = data.get('action')
price = int(float(data.get('price')))
quantity = 1
send_order(symbol, action, quantity, price)
return jsonify({"message": f"Order sent: {symbol}, {action}, {price}"}), 200
except Exception as e:
logging.error(f"Error: {str(e)}")
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, threaded=True)
가능한 원인
- PyQt5 이벤트 루프 차단:
- kiwoom.dynamicCall("CommConnect()")는 키움 Open API의 로그인 창을 띄우고, 로그인 완료까지 메인 스레드를 차단합니다.
- Flask의 app.run()은 그 이후에 실행되지만, PyQt5의 이벤트 루프(QApplication)와 Flask의 서버 루프가 충돌하거나 순서가 꼬여 진행이 멈춤.
- 로그인 상태 확인 누락:
- 키움 API는 로그인 완료 여부를 확인하는 이벤트(OnEventConnect)를 제공하는데, 이를 처리하지 않아 코드가 대기 상태로 남음.
- Flask 서버 실행 지연:
- threaded=True를 사용했지만, PyQt5와의 상호작용으로 인해 Flask 서버가 제대로 시작되지 않음.
- 예외 발생:
- 코드 내 예외(예: 네트워크 문제, 키움 API 오류)가 발생했으나, CMD에 출력되지 않고 로그 파일에만 기록됨.
해결 방법 (단계별)
1. 로그인 완료 확인 추가
키움 API의 로그인 상태를 비동기적으로 확인하도록 수정합니다. OnEventConnect 이벤트를 처리해 로그인 완료 후 Flask 서버를 시작하도록 합니다.
- 수정된 코드
아래 python 코드를 EC2에서 메모장에 붙여넣기 후 기존 파일과 구분하여 저장가능 예) C:\webhook_server_1.py
from flask import Flask, request, jsonify
from PyQt5.QAxContainer import QAxWidget
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QEventLoop
import sys
import logging
logging.basicConfig(filename='trade.log', level=logging.INFO,
format='%(asctime)s - %(message)s')
app = Flask(__name__)
class Kiwoom:
def __init__(self):
self.app = QApplication(sys.argv)
self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
self.logged_in = False
self.kiwoom.OnEventConnect.connect(self.on_login)
def login(self):
self.kiwoom.dynamicCall("CommConnect()")
loop = QEventLoop()
while not self.logged_in:
loop.exec_() # 로그인 완료까지 대기
def on_login(self, err_code):
if err_code == 0:
logging.info("Login successful")
self.logged_in = True
else:
logging.error(f"Login failed with error code: {err_code}")
sys.exit(1)
def send_order(self, symbol, action, quantity, price):
account = "YOUR_ACCOUNT_NUMBER" # 본인 계좌번호 변경입력
order_type = 1 if action == "buy" else 2
self.kiwoom.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
["주문", "0101", account, order_type, symbol, quantity, price, "03", ""])
logging.info(f"Order sent: {symbol}, {action}, {quantity}, {price}")
kiwoom = Kiwoom()
@app.route('/webhook', methods=['POST'])
def webhook():
try:
data = request.json
if not data:
return jsonify({"error": "No data received"}), 400
symbol = data.get('symbol')
action = data.get('action')
price = int(float(data.get('price')))
quantity = 1
kiwoom.send_order(symbol, action, quantity, price)
return jsonify({"message": f"Order sent: {symbol}, {action}, {price}"}), 200
except Exception as e:
logging.error(f"Error: {str(e)}")
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
kiwoom.login() # 로그인 완료까지 대기
logging.info("Starting Flask server")
app.run(host="0.0.0.0", port=5000, threaded=True)
- 변경 내용:
- Kiwoom 클래스로 로그인 로직 분리.
- OnEventConnect 이벤트 핸들러 추가.
- QEventLoop로 로그인 완료 대기.
- 로그인 성공 후 Flask 서버 시작.
- 실행:
- CMD에서 python webhook_server.py 실행.
- 로그인 창에서 ID/비밀번호 입력 후, "Starting Flask server" 로그와 "Running on http://0.0.0.0:5000" 메시지 확인.
2. Flask와 PyQt5 분리 (스레드 사용)
PyQt5와 Flask의 이벤트 루프 충돌을 피하기 위해, Flask 서버를 별도 스레드에서 실행합니다.
- 수정된 코드:
아래 python 코드를 EC2에서 메모장에 붙여넣기 후 기존 파일과 구분하여 저장가능 예) C:\webhook_server_2.pyfrom flask import Flask, request, jsonify
from PyQt5.QAxContainer import QAxWidget
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QEventLoop
import sys
import logging
import threading
logging.basicConfig(filename='trade.log', level=logging.INFO,
format='%(asctime)s - %(message)s')
app = Flask(__name__)
class Kiwoom:
def __init__(self):
self.app = QApplication(sys.argv)
self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
self.logged_in = False
self.kiwoom.OnEventConnect.connect(self.on_login)
def login(self):
self.kiwoom.dynamicCall("CommConnect()")
loop = QEventLoop()
while not self.logged_in:
loop.exec_()
def on_login(self, err_code):
if err_code == 0:
logging.info("Login successful")
self.logged_in = True
else:
logging.error(f"Login failed with error code: {err_code}")
sys.exit(1)
def send_order(self, symbol, action, quantity, price):
account = "YOUR_ACCOUNT_NUMBER" # 본인 계좌번호 입력
order_type = 1 if action == "buy" else 2
self.kiwoom.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
["주문", "0101", account, order_type, symbol, quantity, price, "03", ""])
logging.info(f"Order sent: {symbol}, {action}, {quantity}, {price}")
kiwoom = Kiwoom()
@app.route('/webhook', methods=['POST'])
def webhook():
try:
data = request.json
if not data:
return jsonify({"error": "No data received"}), 400
symbol = data.get('symbol')
action = data.get('action')
price = int(float(data.get('price')))
quantity = 1
kiwoom.send_order(symbol, action, quantity, price)
return jsonify({"message": f"Order sent: {symbol}, {action}, {price}"}), 200
except Exception as e:
logging.error(f"Error: {str(e)}")
return jsonify({"error": str(e)}), 500
def run_flask():
app.run(host="0.0.0.0", port=5000, threaded=True)
if __name__ == "__main__":
kiwoom.login() # 로그인 완료 대기
flask_thread = threading.Thread(target=run_flask)
flask_thread.start()
logging.info("Flask server started in separate thread")
kiwoom.app.exec_() # PyQt5 이벤트 루프 실행 - 변경 내용:
- Flask 서버를 threading.Thread로 별도 스레드에서 실행.
- PyQt5 이벤트 루프(app.exec_())를 메인 스레드에서 유지.
- 실행:
- 로그인 후 "Flask server started in separate thread" 로그와 "Running on http://0.0.0.0:5000" 메시지 확인.
3. 디버깅 및 로그 확인
- 로그 확인:
- C:\trade.log 파일 열기:
- 로그인 성공: "Login successful".
- 오류: "Login failed with error code: X".
- 오류 코드 예:
- -100: ID/비밀번호 오류.
- -101: 서버 연결 실패.
- C:\trade.log 파일 열기:
- CMD 출력 활성화:
- 콘솔에도 로그 출력 추가:
python 코드logging.getLogger().addHandler(logging.StreamHandler())
- 콘솔에도 로그 출력 추가:
4. 추가 문제 해결
- 네트워크 문제:
- EC2 보안 그룹에서 포트 5000이 열려 있는지 확인.
- CMD에서 netstat -an | find "5000"으로 포트 사용 여부 점검.
- 키움 API 설치 문제:
- 키움 Open API가 제대로 설치되지 않았으면 재설치:
- 키움증권 홈페이지 > OpenAPISetup.exe 다운로드 및 실행.
- 키움 Open API가 제대로 설치되지 않았으면 재설치:
- Python 버전:
- 32비트 Python 사용 확인:
text 명령어python -c "import platform; print(platform.architecture())"
- 32비트 Python 사용 확인:
최종 확인
- 수정된 코드로 python webhook_server.py 실행.
- 로그인 성공 후 CMD에 "Running on http://0.0.0.0:5000" 출력 확인.
- 브라우저에서 http://<EC2-퍼블릭-IP>:5000/webhook 접속 시 405 에러(Method Not Allowed) 뜨면 정상 (POST만 허용).
요약
문제의 핵심은 PyQt5와 Flask의 이벤트 루프 충돌입니다. 해결책은:
- 로그인 완료를 이벤트로 확인 (OnEventConnect).
- Flask를 별도 스레드로 분리. 로그를 통해 디버깅하며 진행하세요.
반응형
'IT 정보 > 트레이딩뷰 자동매매' 카테고리의 다른 글
키움증권 Open API 작동시 AWS EC2에서 한글 깨짐 현상 해결 (0) | 2025.03.12 |
---|---|
파이션 설치 후 CMD 명령 python --version 에러메시지 해결방법 (0) | 2025.03.12 |
트레이딩뷰 자동매매 웹훅 클라우드 서버 비교 및 추천 (0) | 2025.03.12 |
트레이딩뷰와 키움증권을 연동한 웹훅서버 AWS EC2 를 사용 자동 매매 프로그램 제작 (0) | 2025.03.12 |
트레이딩뷰 자동매매 기능 사용 방법 상세 (0) | 2025.02.21 |