Last active
November 22, 2017 00:14
-
-
Save esstory/997c4a69551b7faf8936e13baf64156e to your computer and use it in GitHub Desktop.
IOC/FOK 주문 테스트 - CYBOS PLUS/CREON PLUS 테스트 예제
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from PyQt5.QtWidgets import * | |
from enum import Enum | |
import win32com.client | |
g_objCpStatus = win32com.client.Dispatch('CpUtil.CpCybos') | |
g_objCpTrade = win32com.client.Dispatch('CpTrade.CpTdUtil') | |
g_objCodeMgr = win32com.client.Dispatch('CpUtil.CpCodeMgr') | |
# ioc 주문 테스트 | |
# CpEvent: 실시간 이벤트 수신 클래스 | |
class CpEvent: | |
def set_params(self, client, name, parent): | |
self.client = client # CP 실시간 통신 object | |
self.name = name # 서비스가 다른 이벤트를 구분하기 위한 이름 | |
self.parent = parent # callback 을 위해 보관 | |
# 구분값 : 텍스트로 변경하기 위해 딕셔너리 이용 | |
self.dicflag12 = {'1': '매도', '2': '매수'} | |
self.dicflag14 = {'1': '체결', '2': '확인', '3': '거부', '4':'접수'} | |
self.dicflag15 = {'00': '해당없음', '01': '유통융자', '02': '자기융자', '03': '유통대주', | |
'04':'자기대주', '05':'주식담보대출'} | |
self.dicflag16 = {'1': '정상주문', '2': '정정주문', '3': '취소주문'} | |
self.dicflag17 = {'1': '현금', '2': '신용', '3': '선물대용', '4': '공매도'} | |
self.dicflag18 = {'01': '보통', '02': '임의', '03':'시장가', '05': '조건부지정가'} | |
self.dicflag19 = {'0': '없음', '1': 'IOC', '2': 'FOK'} | |
# PLUS 로 부터 실제로 시세를 수신 받는 이벤트 핸들러 | |
def OnReceived(self): | |
print(self.name) | |
if self.name == 'conclution': | |
# 주문 체결 실시간 업데이트 | |
conc = {} | |
# 체결 플래그 | |
conc['체결플래그'] = self.dicflag14[self.client.GetHeaderValue(14)] | |
conc['주문번호'] = self.client.GetHeaderValue(5) # 주문번호 | |
conc['주문수량'] = self.client.GetHeaderValue(3) # 주문/체결 수량 | |
conc['주문가격'] = self.client.GetHeaderValue(4) # 주문/체결 가격 | |
conc['원주문'] = self.client.GetHeaderValue(6) | |
conc['종목코드'] = self.client.GetHeaderValue(9) # 종목코드 | |
conc['종목명'] = g_objCodeMgr.CodeToName(conc['종목코드']) | |
conc['매수매도'] = self.dicflag12[self.client.GetHeaderValue(12)] | |
flag15 = self.client.GetHeaderValue(15) # 신용대출구분코드 | |
if (flag15 in self.dicflag15): | |
conc['신용대출'] = self.dicflag15[flag15] | |
else: | |
conc['신용대출'] = '기타' | |
conc['정정취소'] = self.dicflag16[self.client.GetHeaderValue(16)] | |
conc['현금신용'] = self.dicflag17[self.client.GetHeaderValue(17)] | |
conc['주문조건'] = self.dicflag19[self.client.GetHeaderValue(19)] | |
conc['체결기준잔고수량'] = self.client.GetHeaderValue(23) | |
conc['대출일'] = self.client.GetHeaderValue(20) | |
flag18 = self.client.GetHeaderValue(18) | |
if (flag18 in self.dicflag18): | |
conc['주문호가구분'] = self.dicflag18[flag18] | |
else: | |
conc['주문호가구분'] = '기타' | |
conc['매도가능수량'] = self.client.GetHeaderValue(22) | |
print(conc) | |
return | |
# CpPBConclusion: 실시간 주문 체결 수신 클래그 | |
class CpPBConclusion: | |
def __init__(self): | |
self.name = 'conclution' | |
self.obj = win32com.client.Dispatch('DsCbo1.CpConclusion') | |
def Subscribe(self, parent): | |
self.parent = parent | |
handler = win32com.client.WithEvents(self.obj, CpEvent) | |
handler.set_params(self.obj, self.name, parent) | |
self.obj.Subscribe() | |
def Unsubscribe(self): | |
self.obj.Unsubscribe() | |
# CpRPCurrentPrice: 현재가 기본 정보 조회 클래스 | |
class CpRPCurrentPrice: | |
def __init__(self): | |
if (g_objCpStatus.IsConnect == 0): | |
print('PLUS가 정상적으로 연결되지 않음. ') | |
return | |
self.objStockMst = win32com.client.Dispatch('DsCbo1.StockMst') | |
return | |
def Request(self, code, caller): | |
self.objStockMst.SetInputValue(0, code) | |
ret = self.objStockMst.BlockRequest() | |
if self.objStockMst.GetDibStatus() != 0: | |
print('통신상태', self.objStockMst.GetDibStatus(), self.objStockMst.GetDibMsg1()) | |
return False | |
caller.curData = {} | |
caller.curData['code'] = code | |
caller.curData['종목명'] = g_objCodeMgr.CodeToName(code) | |
caller.curData['현재가'] = self.objStockMst.GetHeaderValue(11) # 종가 | |
caller.curData['대비'] = self.objStockMst.GetHeaderValue(12) # 전일대비 | |
caller.curData['기준가'] = self.objStockMst.GetHeaderValue(27) # 기준가 | |
caller.curData['거래량'] = self.objStockMst.GetHeaderValue(18) # 거래량 | |
caller.curData['예상플래그'] = self.objStockMst.GetHeaderValue(58) # 예상플래그 | |
caller.curData['예상체결가'] = self.objStockMst.GetHeaderValue(55) # 예상체결가 | |
caller.curData['예상대비'] = self.objStockMst.GetHeaderValue(56) # 예상체결대비 | |
# 10차호가 | |
for i in range(10): | |
key1 = '매도호가%d' %(i+1) | |
key2 = '매수호가%d' %(i+1) | |
caller.curData[key1] = (self.objStockMst.GetDataValue(0, i)) # 매도호가 | |
caller.curData[key2] = (self.objStockMst.GetDataValue(1, i) ) # 매수호가 | |
#print(caller.curData) | |
return True | |
class CpRPOrder: | |
def __init__(self): | |
# 연결 여부 체크 | |
if (g_objCpStatus.IsConnect == 0): | |
print('PLUS가 정상적으로 연결되지 않음. ') | |
return | |
# 주문 초기화 | |
if (g_objCpTrade.TradeInit(0) != 0): | |
print('주문 초기화 실패') | |
return | |
self.acc = g_objCpTrade.AccountNumber[0] # 계좌번호 | |
self.accFlag = g_objCpTrade.GoodsList(self.acc, 1) # 주식상품 구분 | |
print(self.acc, self.accFlag[0]) | |
# 주문 object 생성 | |
self.objBuySell = win32com.client.Dispatch('CpTrade.CpTd0311') # 매수 | |
# 주문 조건 구분 '0': 없음 1: IOC 2: FOK | |
self.dicFlag = {'IOC': '1', 'FOK': '2', '없음': '0'} | |
def sellOrder(self, code, price, amount, flag): | |
print('신규 매도', '주문조건구분:', flag, '종목코드:',code, '가격:',price, '수량:',amount) | |
self.objBuySell.SetInputValue(0, '1') # 1 매도 2 매수 | |
self.objBuySell.SetInputValue(1, self.acc) # 계좌번호 | |
self.objBuySell.SetInputValue(2, self.accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 | |
self.objBuySell.SetInputValue(3, code) # 종목코드 | |
self.objBuySell.SetInputValue(4, amount) # 수량 | |
self.objBuySell.SetInputValue(5, price) # 주문단가 | |
orderflag = self.dicFlag[flag] # 주문 조건 구분 '0': 없음 1: IOC 2: FOK | |
self.objBuySell.SetInputValue(7, orderflag) # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK | |
self.objBuySell.SetInputValue(8, '01') # 주문호가 구분코드 - 01: 보통 03 시장가 05 조건부지정가 | |
# 주문 요청 | |
self.objBuySell.BlockRequest() | |
rqStatus = self.objBuySell.GetDibStatus() | |
rqRet = self.objBuySell.GetDibMsg1() | |
print('통신상태', rqStatus, rqRet) | |
if rqStatus != 0: | |
return False | |
return True | |
def buyOrder(self, code, price, amount, flag): | |
print('신규 매수', '주문조건구분:', flag, '종목코드:', code, '가격:', price, '수량:', amount) | |
self.objBuySell.SetInputValue(0, '2') # 1 매도 2 매수 | |
self.objBuySell.SetInputValue(1, self.acc) # 계좌번호 | |
self.objBuySell.SetInputValue(2, self.accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 | |
self.objBuySell.SetInputValue(3, code) # 종목코드 | |
self.objBuySell.SetInputValue(4, amount) # 수량 | |
self.objBuySell.SetInputValue(5, price) # 주문단가 | |
orderflag = self.dicFlag[flag] # 주문 조건 구분 '0': 없음 1: IOC 2: FOK | |
self.objBuySell.SetInputValue(7, orderflag) # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK | |
self.objBuySell.SetInputValue(8, '01') # 주문호가 구분코드 - 01: 보통 03 시장가 05 조건부지정가 | |
# 주문 요청 | |
self.objBuySell.BlockRequest() | |
rqStatus = self.objBuySell.GetDibStatus() | |
rqRet = self.objBuySell.GetDibMsg1() | |
print('통신상태', rqStatus, rqRet) | |
if rqStatus != 0: | |
return False | |
return True | |
class MyWindow(QMainWindow): | |
def __init__(self): | |
super().__init__() | |
self.setWindowTitle('IOC/FOK 주문 테스트') | |
self.setGeometry(300, 300, 300, 230) | |
# 주문 통신 object | |
self.objRpOrder = CpRPOrder() | |
# 현재가 통신 object | |
self.curData = {} | |
self.objCur = CpRPCurrentPrice() | |
# 주문체결은 미리 실시간 요청 | |
self.conclution = CpPBConclusion() | |
self.conclution.Subscribe(self) | |
nH = 20 | |
# 코드 입력기 | |
self.codeEdit = QLineEdit('', self) | |
self.codeEdit.move(20, nH) | |
self.codeEdit.textChanged.connect(self.codeEditChanged) | |
self.codeEdit.setText('') | |
self.label = QLabel('종목코드', self) | |
self.label.move(140, nH) | |
self.code = '' | |
nH += 50 | |
btnIOCSell = QPushButton('매도IOC', self) | |
btnIOCSell.move(20, nH) | |
btnIOCSell.resize(200, 30) | |
btnIOCSell.clicked.connect(self.btnIOCSell_clicked) | |
nH += 50 | |
btnIOCBuy = QPushButton('매수IOC', self) | |
btnIOCBuy.move(20, nH) | |
btnIOCBuy.resize(200, 30) | |
btnIOCBuy.clicked.connect(self.btnIOCBuy_clicked) | |
nH += 50 | |
btnFOKSell = QPushButton('매도FOK', self) | |
btnFOKSell.move(20, nH) | |
btnFOKSell.resize(200, 30) | |
btnFOKSell.clicked.connect(self.btnFOKSell_clicked) | |
nH += 50 | |
btnFOKBuy = QPushButton('매수FOK', self) | |
btnFOKBuy.move(20, nH) | |
btnFOKBuy.resize(200, 30) | |
btnFOKBuy.clicked.connect(self.btnFOKBuy_clicked) | |
nH += 50 | |
btnExit = QPushButton('종료', self) | |
btnExit.move(20, nH) | |
btnExit.resize(200, 30) | |
btnExit.clicked.connect(self.btnExit_clicked) | |
nH += 50 | |
self.setGeometry(300, 300, 300, nH) | |
def btnIOCSell_clicked(self): | |
return self.sellOrder('IOC') | |
def btnIOCBuy_clicked(self): | |
return self.buyOrder('IOC') | |
def btnFOKSell_clicked(self): | |
return self.sellOrder('FOK') | |
def btnFOKBuy_clicked(self): | |
return self.buyOrder('FOK') | |
# 종료 | |
def btnExit_clicked(self): | |
exit() | |
def codeEditChanged(self): | |
code = self.codeEdit.text() | |
self.setCode(code) | |
def setCode(self, code): | |
if len(code) < 6: | |
return | |
print(code) | |
if not (code[0] == 'A'): | |
code = 'A' + code | |
name = g_objCodeMgr.CodeToName(code) | |
if len(name) == 0: | |
print('종목코드 확인') | |
return | |
self.label.setText(name) | |
self.code = code | |
# 매수는 매수3호가에 IOC/FOK 주문을 낸다. | |
def buyOrder(self, flag): | |
# 현재가 통신 | |
if (self.objCur.Request(self.code, self) == False): | |
w = QWidget() | |
QMessageBox.warning(w, '오류', '현재가 통신 오류 발생/주문 중단') | |
return | |
self.objRpOrder.buyOrder(self.code, self.curData['매수호가3'], 1, flag) | |
# 매도는 매도3호가에 IOC/FOK 주문을 낸다. | |
def sellOrder(self, flag): | |
# 현재가 통신 | |
if (self.objCur.Request(self.code, self) == False): | |
w = QWidget() | |
QMessageBox.warning(w, '오류', '현재가 통신 오류 발생/주문 중단') | |
return | |
self.objRpOrder.sellOrder(self.code, self.curData['매도호가3'], 1, flag) | |
if __name__ == '__main__': | |
app = QApplication(sys.argv) | |
myWindow = MyWindow() | |
myWindow.show() | |
app.exec_() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment