Skip to content
김치찌게2021.09.10 18:28
어쨋든
보유종목들의 현재가 기준으로 분할 매수/매도주문이 가능하게 되었다.




import sys
import os
import time
#import logging.conf
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
from beautifultable import BeautifulTable
from PyQt5.QtTest import *
from pandas import DataFrame

TR_REQ_TIME_INTERVAL = 0.2
class Kiwoom(QAxWidget):
def __init__(self):
self.app = QApplication(sys.argv)
print("Ui_class 입니다.")
super().__init__()
# 이벤트 루프 관련 변수
self.login_event_loop = QEventLoop()
self.account_event_loop = QEventLoop()
self.calculator_event_loop = QEventLoop()

# 계좌 관련 변수
self.account_number = None
self.total_buy_money = None
self.total_evaluation_money = None
self.total_evaluation_profit_and_loss_money = None
self.total_yield = None
self.account_stock_dict = {}
self.not_signed_account_dict = {}

# 예수금 관련 변수
self.deposit = None
self.withdraw_deposit = None
self.order_deposit = None

# 종목 분석 관련 변수
self.calculator_list = []

# 화면 번호
self.screen_my_account = "1000"
self.screen_calculation_stock = "2000"

# 초기 작업
print("로그인-초기작업시작")
self.create_kiwoom_instance()
self.event_collection() # 이벤트와 슬롯을 메모리에 먼저 생성.
self.login()
print("계좌정보시작")
# input()
#
self.get_account_info() # 계좌 번호만 얻어오기
self.get_deposit_info() # 예수금 관련된 정보 얻어오기
self.get_account_evaluation_balance() # 계좌평가잔고내역 얻어오기
self.not_signed_account() # 미체결내역 얻어오기
#self.calculator()
# self.menu()

print("스케쥴링시작")
###########[스케쥴링]############

self.test()


###########[스케쥴링]############

def test(self):
account_list = self.dynamicCall("GetLoginInfo(QString)", "ACCNO")
account_number = account_list.split(';')[0]
self.account_number = account_number ##계좌정보 획득!

user_name = self.dynamicCall("GetLoginInfo(QString)", "USER_NAME")
user_id = self.dynamicCall("GetLoginInfo(QString)", "USER_ID")
account_count = self.dynamicCall(
"GetLoginInfo(QString)", "ACCOUNT_CNT")

#############[보유종목과 매매가능수량확인 ]#############
self.item_nums = list(self.account_stock_dict.keys()) # dict key값을 self.item_nums 변수에 담기
self.item_values = list(self.account_stock_dict.values()) # dict value값을 self.item_nums 변수에 담기
print(self.item_nums) # 리스트 출력
print(self.item_values) # 리스트 출력
#for index, value in enumerate(self.item_nums):
# print("[%s] 종목번호[%s] 종목명[%s] 현재가[%s] 매매가능수량 : [%s]" % (
# index, self.item_nums[index], self.item_values[index]['종목명'], self.item_values[index]['현재가'],
# self.item_values[index]['매매가능수량']))

#############[호가 및 매수주문]#############
for index, value in enumerate(self.item_nums):
print("[%s]번째 종목을 매수주문 시도합니다." % index)
self.item_num = self.item_nums[index] # 종목코드 담기
self.item_value = self.item_values[index]['매매가능수량'] # 종목 값 담기
self.item_name = self.item_values[index]['종목명'] # 종목 값 담기
self.item_nowvalue = self.item_values[index]['현재가'] # 종목 값 담기

if '(폐)' in self.item_name:
print('[%s]는 상장폐지된 종목입니다.' % self.item_name)

else:
#print("[%s] 종목번호[%s] 종목명[%s] 현재가[%s] 매매가능수량 : [%s]" % (index, self.item_nums[index], self.item_values[index]['종목명'], self.item_values[index]['현재가'],self.item_values[index]['매매가능수량']))
print("[%s] 종목번호[%s] 종목명[%s] 현재가[%s] 매매가능수량 : [%s]" % (index, self.item_num, self.item_name, self.item_nowvalue,self.item_value))

############################################## 현재가 받아와서 그래미

order_money = self.item_nowvalue
max_order_money = 1000000
mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량

# 매도시 매매가능수량 파악을 위해 아래의 부분을 넣어야 함.
#if self.item_value < mom_ea:
# mom_ea = self.item_value # 매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.

rate = 0.01
sb_sum = 0
sellbuy_ea = []

print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
for i in range(0, 10):
sellbuy_ea.append(int(mom_ea * rate))
rate = rate + 0.02
sb_sum = int(int(mom_ea * rate) + sb_sum)

sellbuy_ea = sellbuy_ea

print("실제매수수량 %s, 매매가능수량 %s" % (order_money * sb_sum, sellbuy_ea))
# 0.5% ~ 10%까지의 매수호가/매도호가 생성
sell_m = []
buy_m = []
rate_v = 0.005
for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
sell_m.append(order_money + (order_money * rate_v))
buy_m.append(order_money - (order_money * rate_v))
rate_v = rate_v + 0.005
# print("매도호가",sell_m)
# 0.5% ~ 10%까지의 폭

## 호가를 자리수에 따라 반올림하면서 정수화 함.
buyQ = []
sellQ = []
for i in range(0, len(buy_m)):
if buy_m[i] < 1000:
buyQ.append(abs(int(round(buy_m[i], 0))))
elif buy_m[i] < 5000:
buyQ.append(abs(int(round(buy_m[i], -1))))
elif buy_m[i] < 10000:
buyQ.append(abs(int(round(buy_m[i], -1))))
elif buy_m[i] < 50000:
buyQ.append(abs(int(round(buy_m[i], -2))))
elif buy_m[i] < 100000:
buyQ.append(abs(int(round(buy_m[i], -2))))
elif buy_m[i] < 500000:
buyQ.append(abs(int(round(buy_m[i], -3))))
elif buy_m[i] < 1000000:
buyQ.append(abs(int(round(buy_m[i], -3))))
# print("매수호가 %s " % buyQ)

print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수호가:%s" % (
self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
# (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)
delay_time = 0.5
if sellbuy_ea[0] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[0], buyQ[0], "00","")
time.sleep(delay_time)
print("1번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[0], buyQ[0]))

if sellbuy_ea[1] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[1], buyQ[3], "00","")
time.sleep(delay_time)
print("2번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[1], buyQ[3]))

if sellbuy_ea[2] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[2], buyQ[6], "00","")
time.sleep(delay_time)
print("3번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[2], buyQ[6]))

if sellbuy_ea[3] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[3], buyQ[9], "00","")
time.sleep(delay_time)
print("4번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[3], buyQ[9]))

if sellbuy_ea[4] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[4], buyQ[12], "00","")
print("5번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[4], buyQ[12]))
time.sleep(delay_time)

if sellbuy_ea[5] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[5], buyQ[15], "00","")
print("6번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[5], buyQ[15]))
time.sleep(delay_time)

if sellbuy_ea[6] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[6], buyQ[18], "00","")
print("7번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[6], buyQ[18]))
time.sleep(delay_time)

if sellbuy_ea[7] != 0:
self.send_order("buy04", "0101", self.account_number, 1, self.item_num, sellbuy_ea[7], buyQ[21], "00","")
print("8번성공-%s, %s, %s, %s" % (self.account_number, self.item_num, sellbuy_ea[7], buyQ[21]))
time.sleep(delay_time)

print("buyQ 지정가 매수완료")
##################################################
# COM 오브젝트 생성.
def create_kiwoom_instance(self):
# 레지스트리에 저장된 키움 openAPI 모듈 불러오기
self.setControl("KHOPENAPI.KHOpenAPICtrl.1")



def event_collection(self):
self.OnEventConnect.connect(self.login_slot) # 로그인 관련 이벤트
self.OnReceiveTrData.connect(self.tr_slot) # 트랜잭션 요청 관련 이벤트

def login(self):
self.dynamicCall("CommConnect()") # 시그널 함수 호출.
self.login_event_loop.exec_()

def login_slot(self, err_code):
if err_code == 0:
print("로그인에 성공하였습니다.")
else:
os.system('cls')
print("에러 내용 :", errors(err_code)[1])
sys.exit(0)
self.login_event_loop.exit()

def get_account_info(self):
account_list = self.dynamicCall("GetLoginInfo(QString)", "ACCNO")
account_number = account_list.split(';')[0]
self.account_number = account_number

def menu(self):
sel = ""
while True:
os.system('cls')
print("1. 현재 로그인 상태 확인")
print("2. 사용자 정보 조회")
print("3. 예수금 조회")
print("4. 계좌 잔고 조회")
print("5. 미체결 내역 조회")
print("Q. 프로그램 종료")
sel = input("=> ")

if sel == "Q" or sel == "q":
sys.exit(0)

if sel == "1":
self.print_login_connect_state()
elif sel == "2":
self.print_my_info()
elif sel == "3":
self.print_get_deposit_info()
elif sel == "4":
self.print_get_account_evaulation_balance_info()
elif sel == "5":
self.print_not_signed_account()

def print_login_connect_state(self):
os.system('cls')
isLogin = self.dynamicCall("GetConnectState()")
if isLogin == 1:
print("\n현재 계정은 로그인 상태입니다.")
else:
print("\n현재 계정은 로그아웃 상태입니다.")
input()

def print_my_info(self):
os.system('cls')
user_name = self.dynamicCall("GetLoginInfo(QString)", "USER_NAME")
user_id = self.dynamicCall("GetLoginInfo(QString)", "USER_ID")
account_count = self.dynamicCall(
"GetLoginInfo(QString)", "ACCOUNT_CNT")

print(f"\n이름 : {user_name}")
print(f"ID : {user_id}")
print(f"보유 계좌 수 : {account_count}")
print(f"계좌번호 : {self.account_number}")
input()

def print_get_deposit_info(self):
os.system('cls')
print(f"\n예수금 : {self.deposit}원")
print(f"출금 가능 금액 : {self.withdraw_deposit}원")
print(f"주문 가능 금액 : {self.order_deposit}원")
input()

def print_get_account_evaulation_balance_info(self):
os.system('cls')
print("\n<싱글 데이터>")
print(f"총 매입 금액 : {self.total_buy_money}원")
print(f"총 평가 금액 : {self.total_evaluation_money}원")
print(f"총 평가 손익 금액 : {self.total_evaluation_profit_and_loss_money}원")
print(f"총 수익률 : {self.total_yield}%\n")

table = self.make_table("계좌평가잔고내역요청")
print("<멀티 데이터>")
if len(self.account_stock_dict) == 0:
print("보유한 종목이 없습니다!")
else:
print(f"보유 종목 수 : {len(self.account_stock_dict)}개")
print(table)
input()

def make_table(self, sRQName):
table = BeautifulTable()
table = BeautifulTable(maxwidth=150)

if sRQName == "계좌평가잔고내역요청":
for stock_code in self.account_stock_dict:
stock = self.account_stock_dict[stock_code]
stockList = []
for key in stock:
output = None

if key == "종목명":
output = stock[key]
elif key == "수익률(%)":
output = str(stock[key]) + "%"
elif key == "보유수량" or key == "매매가능수량":
output = str(stock[key]) + "개"
else:
output = str(stock[key]) + "원"
stockList.append(output)
table.rows.append(stockList)
table.columns.header = ["종목명", "평가손익",
"수익률", "매입가", "보유수량", "매매가능수량", "현재가"]
table.rows.sort('종목명')

elif sRQName == "실시간미체결요청":
for stock_order_number in self.not_signed_account_dict:
stock = self.not_signed_account_dict[stock_order_number]
stockList = [stock_order_number]
for key in stock:
output = None
if key == "주문가격" or key == "현재가":
output = str(stock[key]) + "원"
elif '량' in key:
output = str(stock[key]) + "개"
elif key == "종목코드":
continue
else:
output = stock[key]
stockList.append(output)
table.rows.append(stockList)
table.columns.header = ["주문번호", "종목명", "주문구분", "주문가격", "주문수량",
"미체결수량", "체결량", "현재가", "주문상태"]
table.rows.sort('주문번호')
return table

def print_not_signed_account(self):
os.system('cls')
print()
table = self.make_table("실시간미체결요청")
if len(self.not_signed_account_dict) == 0:
print("미체결 내역이 없습니다!")
else:
print(table)
input()

def get_deposit_info(self, nPrevNext=0):
self.dynamicCall("SetInputValue(QString, QString)",
"계좌번호", self.account_number)
self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "2")
self.dynamicCall("CommRqData(QString, QString, int, QString)",
"예수금상세현황요청", "opw00001", nPrevNext, self.screen_my_account)

self.account_event_loop.exec_()

def get_account_evaluation_balance(self, nPrevNext=0):
self.dynamicCall("SetInputValue(QString, QString)",
"계좌번호", self.account_number)
self.dynamicCall("SetInputValue(QString, QString)", "비밀번호", " ")
self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
self.dynamicCall("SetInputValue(QString, QString)", "조회구분", "1")
self.dynamicCall("CommRqData(QString, QString, int, QString)",
"계좌평가잔고내역요청", "opw00018", nPrevNext, self.screen_my_account)

if not self.account_event_loop.isRunning():
self.account_event_loop.exec_()

def not_signed_account(self, nPrevNext=0):
self.dynamicCall("SetInputValue(QString, QString)",
"계좌번호", self.account_number)
self.dynamicCall("SetInputValue(QString, QString)", "전체종목구분", "0")
self.dynamicCall("SetInputValue(QString, QString)", "매매구분", "0")
self.dynamicCall("SetInputValue(QString, QString)", "체결구분", "1")
self.dynamicCall("CommRqData(QString, QString, int, QString)",
"실시간미체결요청", "opt10075", nPrevNext, self.screen_my_account)

if not self.account_event_loop.isRunning():
self.account_event_loop.exec_()





def send_order(self, rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no):
self.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
[rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no])

def send_order1(self, rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no):
self.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
[rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no])

def trcode_buy04(self,sPrevNext="0"): ##현재가로 피라미드 0~4까지 매수
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
self.dynamicCall("CommRqData(QString, QString, int, QString)", "buy04", "opt10001", sPrevNext, "2000")
print("현재가요청 서버 전송 완료")

def trcode_buy59(self,sPrevNext="0"): ##현재가로 피라미드 5~9까지 매수
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
self.dynamicCall("CommRqData(QString, QString, int, QString)", "buy59", "opt10001", sPrevNext, "2000")
print("현재가요청 서버 전송 완료")

def trcode_sell04(self,sPrevNext="0"): ##현재가로 피라미드 0~4까지 매도
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
self.dynamicCall("CommRqData(QString, QString, int, QString)", "sell04", "opt10001", sPrevNext, "2000")
print("현재가요청 서버 전송 완료")

def trcode_sell59(self,sPrevNext="0"): ##현재가로 피라미드 5~9까지 매도
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
self.dynamicCall("CommRqData(QString, QString, int, QString)", "sell59", "opt10001", sPrevNext, "2000")
print("현재가요청 서버 전송 완료")

def trcode_closem(self,sPrevNext="0"): ##
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
self.dynamicCall("CommRqData(QString, QString, int, QString)", "종목현재가", "opt10001", sPrevNext, "2000")
print("현재가요청 서버 전송 완료")




def tr_slot(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext):

print("tr_slot 수신코드로 진입했습니다.")
if sRQName == "buy04":
print("잘 전달했겠죠?")

####################[현재가 확인후 피라미드 매수 0~4번]
if sRQName == "buy59":
print("현재가피라미드매수-buy59 %s", self.item_num)
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
print("종목코드입력")
self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
print("종목코드전달")
trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
print("현재가 : %s" % abs(int(trvalue.strip())))
order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

max_order_money = 500000
mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
if self.item_value < mom_ea :
mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
rate = 0.01
sb_sum = 0
sellbuy_ea = []

print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
for i in range(0, 5):
sellbuy_ea.append(int(mom_ea * rate))
rate = rate + 0.02
sb_sum = int(int(mom_ea * rate) + sb_sum)

sellbuy_ea = sellbuy_ea
print("총매매 주식수 : ", mom_ea)
print("총매매금액 : ", max_order_money)

print(order_money * sb_sum, sellbuy_ea)

# 0.5% ~ 10%까지의 매수호가/매도호가 생성
sell_m = []
buy_m = []
rate_v = 0.005
for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
sell_m.append(order_money + (order_money * rate_v))
buy_m.append(order_money - (order_money * rate_v))
rate_v = rate_v + 0.005
# print("매도호가",sell_m)
# 0.5% ~ 10%까지의 폭

## 호가를 자리수에따라 반올림하면서 정수화 함.
buyQ = []
sellQ = []
for i in range(0, len(buy_m)):
if buy_m[i] < 1000:
buyQ.append(abs(int(round(buy_m[i], 0))))
elif buy_m[i] < 5000:
buyQ.append(abs(int(round(buy_m[i], -1))))
elif buy_m[i] < 10000:
buyQ.append(abs(int(round(buy_m[i], -1))))
elif buy_m[i] < 50000:
buyQ.append(abs(int(round(buy_m[i], -2))))
elif buy_m[i] < 100000:
buyQ.append(abs(int(round(buy_m[i], -2))))
elif buy_m[i] < 500000:
buyQ.append(abs(int(round(buy_m[i], -3))))
elif buy_m[i] < 1000000:
buyQ.append(abs(int(round(buy_m[i], -3))))
# print("매수호가 %s " % buyQ)

print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수호가:%s" % (
self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
# (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)

if sellbuy_ea[5] != 0:
self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[5], buyQ[5], "00", "")
time.sleep(0.3)
print("1번성공")

if sellbuy_ea[6] != 0:
self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[6], buyQ[8], "00", "")
time.sleep(0.3)
print("2번성공")

if sellbuy_ea[7] != 0:
self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[7], buyQ[12], "00", "")
time.sleep(0.3)
print("3번성공")

if sellbuy_ea[8] != 0:
self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[8], buyQ[17], "00", "")
time.sleep(0.3)
print("4번성공")

if sellbuy_ea[9] != 0:
self.send_order("buy59", "0101", self.account_number, 1, self.item_num, sellbuy_ea[9], buyQ[20], "00", "")
time.sleep(0.3)
print("5번성공")

print("지정가 매수완료")

####################[현재가 확인후 피라미드 매도 0~4번]
if sRQName == "sell04":
print("현재가피라미드매도-sell04 %s",self.item_num)
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
print("종목코드입력")
self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
print("종목코드전달")
trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
print("현재가 : %s" % abs(int(trvalue.strip())))
order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

max_order_money = 500000
mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
if self.item_value < mom_ea :
mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
rate = 0.01
sb_sum = 0
sellbuy_ea = []

print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
for i in range(0, 5):
sellbuy_ea.append(int(mom_ea * rate))
rate = rate + 0.02
sb_sum = int(int(mom_ea * rate) + sb_sum)

sellbuy_ea = sellbuy_ea
print("총매매 주식수 : ", mom_ea)
print("총매매금액 : ", max_order_money)

print(order_money * sb_sum, sellbuy_ea)

# 0.5% ~ 10%까지의 매수호가/매도호가 생성
sell_m = []
buy_m = []
rate_v = 0.005
for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
sell_m.append(order_money + (order_money * rate_v))
buy_m.append(order_money - (order_money * rate_v))
rate_v = rate_v + 0.005
# print("매도호가",sell_m)
# 0.5% ~ 10%까지의 폭

## 호가를 자리수에따라 반올림하면서 정수화 함.
buyQ = []
sellQ = []

for i in range(0, len(sell_m)):
if sell_m[i] < 1000:
sellQ.append(abs(int(round(sell_m[i], 0))))
elif sell_m[i] < 5000:
sellQ.append(abs(int(round(sell_m[i], -1))))
elif sell_m[i] < 10000:
sellQ.append(abs(int(round(sell_m[i], -1))))
elif sell_m[i] < 50000:
sellQ.append(abs(int(round(sell_m[i], -2))))
elif sell_m[i] < 100000:
sellQ.append(abs(int(round(sell_m[i], -2))))
elif sell_m[i] < 500000:
sellQ.append(abs(int(round(sell_m[i], -3))))
elif sell_m[i] < 1000000:
sellQ.append(abs(int(round(sell_m[i], -3))))

# print("매도호가:%s \n매수호가:%s", (sellQ,buyQ))

print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수금액:%s" % (
self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
# (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)
if sellbuy_ea[0] != 0:
self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[0], sellQ[5], "00", "")
time.sleep(0.3)
print("1번성공")

if sellbuy_ea[1] != 0:
self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[1], sellQ[10], "00", "")
time.sleep(0.3)
print("2번성공")

if sellbuy_ea[2] != 0:
self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[2], sellQ[15], "00", "")
time.sleep(0.3)
print("3번성공")

if sellbuy_ea[3] != 0:
self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[3], sellQ[20], "00", "")
time.sleep(0.3)
print("4번성공")

if sellbuy_ea[4] != 0:
self.send_order("sell04", "0101", self.account_number, 2, self.item_num, sellbuy_ea[4], sellQ[25], "00", "")
time.sleep(0.3)
print("5번성공")
print("5,10,15,20,25호가 지정가 매도완료")

####################[현재가 확인후 피라미드 매도 5~9번]
if sRQName == "sell59":
print("현재가피라미드매도-sell59 시작! %s" % self.item_num)
self.dynamicCall("SetInputValue(QString, QString)", "종목코드", self.item_num)
print("종목코드입력")
self.dynamicCall("CommRqData(QString, QString, int, QS tring)", "OPT10001", "opt10001", 0, "0101")
print("종목코드전달")
trvalue = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, "OPT10001", 0, "현재가")
print("현재가 : %s" % abs(int(trvalue.strip())))
order_money = abs(int(trvalue.strip().replace(",", ""))) # 현재가를 변수에 담기

max_order_money = 1000000
mom_ea = abs(int(max_order_money / order_money)) # 총매매금액 나누기 현재가 = 총매매 수량
if self.item_value < mom_ea :
mom_ea = self.item_value #매매가능수량이 총매매수량보다 작으면 매매가능수량을 총매매수량에 넣는다.
rate = 0.01
sb_sum = 0
sellbuy_ea = []

print("총매매금액 : %s, 현재가 : %s, 총수량 %s" % (max_order_money, order_money, mom_ea))
for i in range(0, 5):
sellbuy_ea.append(int(mom_ea * rate))
rate = rate + 0.02
sb_sum = int(int(mom_ea * rate) + sb_sum)

sellbuy_ea = sellbuy_ea
print("총매매 주식수 : ", mom_ea)
print("총매매금액 : ", max_order_money)

print(order_money * sb_sum, sellbuy_ea)

# 0.5% ~ 10%까지의 매수호가/매도호가 생성
sell_m = []
buy_m = []
rate_v = 0.005
for i in range(0, 40): ## 20 = 10%에 대한 매도호가 생성 / 40 = 20%에 대한 매도호가 생성
sell_m.append(order_money + (order_money * rate_v))
buy_m.append(order_money - (order_money * rate_v))
rate_v = rate_v + 0.005
# print("매도호가",sell_m)
# 0.5% ~ 10%까지의 폭

## 호가를 자리수에따라 반올림하면서 정수화 함.
buyQ = []
sellQ = []
for i in range(0, len(sell_m)):
if sell_m[i] < 1000:
sellQ.append(abs(int(round(sell_m[i], 0))))
elif sell_m[i] < 5000:
sellQ.append(abs(int(round(sell_m[i], -1))))
elif sell_m[i] < 10000:
sellQ.append(abs(int(round(sell_m[i], -1))))
elif sell_m[i] < 50000:
sellQ.append(abs(int(round(sell_m[i], -2))))
elif sell_m[i] < 100000:
sellQ.append(abs(int(round(sell_m[i], -2))))
elif sell_m[i] < 500000:
sellQ.append(abs(int(round(sell_m[i], -3))))
elif sell_m[i] < 1000000:
sellQ.append(abs(int(round(sell_m[i], -3))))

# print("매도호가:%s \n매수호가:%s", (sellQ,buyQ))

print("계좌번호:%s, 종목번호:%s\n총매수수량:%s\n매수금액:%s" % (
self.account_number, self.item_num, sellbuy_ea, buyQ)) # buyQ는 40호가 까지 / sellbuy_ea는 10개까지)
# (1:신규매수, 2:신규매도, 3:매수취소, 4:매도취소, 5:매수정정, 6:매도정정)

if sellbuy_ea[5] != 0:
self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[5], sellQ[28], "00", "")
time.sleep(0.3)
print("1번성공")

if sellbuy_ea[6] != 0:
self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[6], sellQ[33], "00", "")
time.sleep(0.3)
print("2번성공")

if sellbuy_ea[7] != 0:
self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[7], sellQ[35], "00", "")
time.sleep(0.3)
print("3번성공")

if sellbuy_ea[8] != 0:
self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[8], sellQ[38], "00", "")
time.sleep(0.3)
print("4번성공")

if sellbuy_ea[9] != 0:
self.send_order("sell59", "0101", self.account_number, 2, self.item_num, sellbuy_ea[9], sellQ[40], "00", "")
time.sleep(0.3)
print("5번성공")
print("28,33,35,38,40호가 지정가 매도완료")


if sRQName == "예수금상세현황요청":
deposit = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "예수금")
self.deposit = int(deposit)

withdraw_deposit = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "출금가능금액")
self.withdraw_deposit = int(withdraw_deposit)

order_deposit = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "주문가능금액")
self.order_deposit = int(order_deposit)
self.cancel_screen_number(self.screen_my_account)
self.account_event_loop.exit()

elif sRQName == "계좌평가잔고내역요청":
if (self.total_buy_money == None or self.total_evaluation_money == None
or self.total_evaluation_profit_and_loss_money == None or self.total_yield == None):
total_buy_money = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총매입금액")
self.total_buy_money = int(total_buy_money)

total_evaluation_money = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가금액")
self.total_evaluation_money = int(total_evaluation_money)

total_evaluation_profit_and_loss_money = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총평가손익금액")
self.total_evaluation_profit_and_loss_money = int(
total_evaluation_profit_and_loss_money)

total_yield = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "총수익률(%)")
self.total_yield = float(total_yield)

cnt = self.dynamicCall(
"GetRepeatCnt(QString, QString)", sTrCode, sRQName)

for i in range(cnt):
stock_code = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목번호")
stock_code = stock_code.strip()[1:]

stock_name = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
stock_name = stock_name.strip() # 필요 없는 공백 제거.

stock_evaluation_profit_and_loss = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "평가손익")
stock_evaluation_profit_and_loss = int(
stock_evaluation_profit_and_loss)

stock_yield = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "수익률(%)")
stock_yield = float(stock_yield)

stock_buy_money = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매입가")
stock_buy_money = int(stock_buy_money)

stock_quantity = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "보유수량")
stock_quantity = int(stock_quantity)

stock_trade_quantity = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "매매가능수량")
stock_trade_quantity = int(stock_trade_quantity)

stock_present_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
stock_present_price = int(stock_present_price)

if not stock_code in self.account_stock_dict:
self.account_stock_dict[stock_code] = {}

self.account_stock_dict[stock_code].update({'종목명': stock_name})
self.account_stock_dict[stock_code].update(
{'평가손익': stock_evaluation_profit_and_loss})
self.account_stock_dict[stock_code].update(
{'수익률(%)': stock_yield})
self.account_stock_dict[stock_code].update(
{'매입가': stock_buy_money})
self.account_stock_dict[stock_code].update(
{'보유수량': stock_quantity})
self.account_stock_dict[stock_code].update(
{'매매가능수량': stock_trade_quantity})
self.account_stock_dict[stock_code].update(
{'현재가': stock_present_price})

if sPrevNext == "2":
self.get_account_evaluation_balance(2)
else:
self.cancel_screen_number(self.screen_my_account)
self.account_event_loop.exit()

elif sRQName == "실시간미체결요청":
cnt = self.dynamicCall(
"GetRepeatCnt(QString, QString)", sTrCode, sRQName)

for i in range(cnt):
stock_code = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목코드")
stock_code = stock_code.strip()

stock_order_number = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문번호")
stock_order_number = int(stock_order_number)

stock_name = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "종목명")
stock_name = stock_name.strip()

stock_order_type = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문구분")
stock_order_type = stock_order_type.strip().lstrip('+').lstrip('-')

stock_order_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문가격")
stock_order_price = int(stock_order_price)

stock_order_quantity = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문수량")
stock_order_quantity = int(stock_order_quantity)

stock_not_signed_quantity = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "미체결수량")
stock_not_signed_quantity = int(stock_not_signed_quantity)

stock_signed_quantity = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "체결량")
stock_signed_quantity = int(stock_signed_quantity)

stock_present_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
stock_present_price = int(
stock_present_price.strip().lstrip('+').lstrip('-'))

stock_order_status = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "주문상태")
stock_order_status = stock_order_status.strip()

if not stock_order_number in self.not_signed_account_dict:
self.not_signed_account_dict[stock_order_number] = {}

self.not_signed_account_dict[stock_order_number].update(
{'종목코드': stock_code})
self.not_signed_account_dict[stock_order_number].update(
{'종목명': stock_name})
self.not_signed_account_dict[stock_order_number].update(
{'주문구분': stock_order_type})
self.not_signed_account_dict[stock_order_number].update(
{'주문가격': stock_order_price})
self.not_signed_account_dict[stock_order_number].update(
{'주문수량': stock_order_quantity})
self.not_signed_account_dict[stock_order_number].update(
{'미체결수량': stock_not_signed_quantity})
self.not_signed_account_dict[stock_order_number].update(
{'체결량': stock_signed_quantity})
self.not_signed_account_dict[stock_order_number].update(
{'현재가': stock_present_price})
self.not_signed_account_dict[stock_order_number].update(
{'주문상태': stock_order_status})

if sPrevNext == "2":
self.not_signed_account(2)
else:
self.cancel_screen_number(sScrNo)
self.account_event_loop.exit()

elif sRQName == "주식일봉차트조회요청":
stock_code = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "종목코드")
#six_hundred_data = self.dynamicCall("GetCommDataEx(QString, QString)", sTrCode, sRQName)

stock_code = stock_code.strip()
cnt = self.dynamicCall(
"GetRepeatCnt(QString, QString)", sTrCode, sRQName) # 최대 600일

for i in range(cnt):
calculator_list = []

current_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가")
volume = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래량")
trade_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래대금")
date = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "일자")
start_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "시가")
high_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "고가")
low_price = self.dynamicCall(
"GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "저가")

calculator_list.append("")
calculator_list.append(int(current_price))
calculator_list.append(int(volume))
calculator_list.append(int(trade_price))
calculator_list.append(int(date))
calculator_list.append(int(start_price))
calculator_list.append(int(high_price))
calculator_list.append(int(low_price))
calculator_list.append("")

self.calculator_list.append(calculator_list.copy())

if sPrevNext == "2":
self.day_kiwoom_db(stock_code, None, 2)
else:
self.calculator_event_loop.exit()

def cancel_screen_number(self, sScrNo):
self.dynamicCall("DisconnectRealData(QString)", sScrNo)

def get_code_list_by_market(self, market_code):
code_list = self.dynamicCall(
"GetCodeListByMarket(QString)", market_code)
code_list = code_list.split(";")[:-1]
return code_list

def calculator(self):
kosdaq_list = self.get_code_list_by_market("10")

for idx, stock_code in enumerate(kosdaq_list):
self.dynamicCall("DisconnectRealData(QString)",
self.screen_calculation_stock)

print(
f"{idx + 1} / {len(kosdaq_list)} : KOSDAQ Stock Code : {stock_code} is updating...")
self.day_kiwoom_db(stock_code)

def day_kiwoom_db(self, stock_code=None, date=None, nPrevNext=0):
QTest.qWait(3600) # 3.6초마다 딜레이

self.dynamicCall("SetInputValue(QString, QString)", "종목코드", stock_code)
self.dynamicCall("SetInputValue(QString, QString)", "수정주가구분", 1)

if date != None: # date가 None일 경우 date는 오늘 날짜 기준
self.dynamicCall("SetInputValue(QString, QString)", "기준일자", date)

self.dynamicCall("CommRqData(QString, QString, int, QString)",
"주식일봉차트조회요청", "opt10081", nPrevNext, self.screen_calculation_stock)

if not self.calculator_event_loop.isRunning():
self.calculator_event_loop.exec_()

def errors(err_code):

err_dic = {0: ('OP_ERR_NONE', '정상처리'),
-10: ('OP_ERR_FAIL', '실패'),
-100: ('OP_ERR_LOGIN', '사용자정보교환실패'),
-101: ('OP_ERR_CONNECT', '서버접속실패'),
-102: ('OP_ERR_VERSION', '버전처리실패'),
-103: ('OP_ERR_FIREWALL', '개인방화벽실패'),
-104: ('OP_ERR_MEMORY', '메모리보호실패'),
-105: ('OP_ERR_INPUT', '함수입력값오류'),
-106: ('OP_ERR_SOCKET_CLOSED', '통신연결종료'),
-200: ('OP_ERR_SISE_OVERFLOW', '시세조회과부하'),
-201: ('OP_ERR_RQ_STRUCT_FAIL', '전문작성초기화실패'),
-202: ('OP_ERR_RQ_STRING_FAIL', '전문작성입력값오류'),
-203: ('OP_ERR_NO_DATA', '데이터없음'),
-204: ('OP_ERR_OVER_MAX_DATA', '조회가능한종목수초과'),
-205: ('OP_ERR_DATA_RCV_FAIL', '데이터수신실패'),
-206: ('OP_ERR_OVER_MAX_FID', '조회가능한FID수초과'),
-207: ('OP_ERR_REAL_CANCEL', '실시간해제오류'),
-300: ('OP_ERR_ORD_WRONG_INPUT', '입력값오류'),
-301: ('OP_ERR_ORD_WRONG_ACCTNO', '계좌비밀번호없음'),
-302: ('OP_ERR_OTHER_ACC_USE', '타인계좌사용오류'),
-303: ('OP_ERR_MIS_2BILL_EXC', '주문가격이20억원을초과'),
-304: ('OP_ERR_MIS_5BILL_EXC', '주문가격이50억원을초과'),
-305: ('OP_ERR_MIS_1PER_EXC', '주문수량이총발행주수의1 % 초과오류'),
-306: ('OP_ERR_MIS_3PER_EXC', '주문수량은총발행주수의3 % 초과오류'),
-307: ('OP_ERR_SEND_FAIL', '주문전송실패'),
-308: ('OP_ERR_ORD_OVERFLOW', '주문전송과부하'),
-309: ('OP_ERR_MIS_300CNT_EXC', '주문수량300계약초과'),
-310: ('OP_ERR_MIS_500CNT_EXC', '주문수량500계약초과'),
-340: ('OP_ERR_ORD_WRONG_ACCTINFO', '계좌정보없음'),
-500: ('OP_ERR_ORD_SYMCODE_EMPTY', '종목코드없음')
}

result = err_dic[err_code]

return result


class KiwoomProcessingError(Exception):
""" 키움에서 처리실패에 관련된 리턴코드를 받았을 경우 발생하는 예외 """

def __init__(self, msg="처리 실패"):
# self.msg = msg
print(msg)

def __str__(self):
return self.msg

def __repr__(self):
return self.msg


######################## 시작
if __name__=="__main__":

kiwoom = Kiwoom()

http://urin79.com

우린친구블로그

sketchbook5, 스케치북5

sketchbook5, 스케치북5

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소