Created
June 5, 2020 02:59
-
-
Save Lay4U/2e0702b024c232c911356e06f0760abe to your computer and use it in GitHub Desktop.
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
# -*-coding: utf-8 - | |
import sys, os, re, datetime, copy, json | |
import logging | |
import xlwings as xw | |
import resource_rc | |
import util, kw_util | |
from PyQt5 import QtCore, QtWidgets | |
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, QUrl, QEvent | |
from PyQt5.QtCore import QStateMachine, QState, QTimer, QFinalState | |
from PyQt5.QtWidgets import QApplication | |
from PyQt5.QAxContainer import QAxWidget | |
from mainwindow_ui import Ui_MainWindow | |
################################################################################################### | |
# μ¬μ©μ μ μ νλΌλ―Έν° | |
################################################################################################### | |
AUTO_TRADING_OPERATION_TIME = [ [ [8, 50], [15, 19] ] ] # 8μ 50λΆμ λμν΄μ 15μ 19λΆμ μλ 맀μ/맀λ μ μ§/ 맀λνΈκ° μ 보μ κ²½μ° λμνΈκ° μκ°μλ μ¬λΌμ€λ―λ‘ μ£Όμ | |
JANG_CHOBAN_TIME = [ AUTO_TRADING_OPERATION_TIME[0][0][0] + 1, 59 ] # 9μ 1λΆλΆν° | |
TOTAL_BUY_AMOUNT = 100000 # 맀λ νΈκ° 1,2,3 μ΄ μλμ΄ TOTAL_BUY_AMOUNT μ΄μ μλλ©΄ 맀μκΈμ§ (μ¬λ¦¬νΌμ§ μ΅μν) | |
MAESU_UNIT = 1000000 # μΆκ° 맀μ κΈ°λ³Έ λ¨μ μ΄ μλ³Έμ 1/10 μμ€ μ μ§ μ¦κ±°κΈ 40% μ μ©(1/20) | |
BUNHAL_MAESU_LIMIT = 4 # λΆν 맀μ νμ μ ν | |
MAX_STOCK_POSSESION_COUNT = 8 # μ μΈ μ’ λͺ© 리μ€νΈ λΆν¬ν¨ν μ΅λ μ’ λͺ© 보μ μ맀μ | |
BUNHAL_MAESU_PROHIBIT_DAYS = 1 # μ΅κ·Ό ? λ΄μμλ λΆν 맀μ κΈμ§ | |
STOP_LOSS_CALCULATE_DAY = 1 # μ΅κ·Ό ? μΌκ° νΉμ κ°κ²© κΈ°μ€μΌλ‘ μμ κ³μ° | |
REQUEST_MINUTE_CANDLE_TYPE = 3 # μ΄μμ€ μμ²ν λΆλ΄ μ’ λ₯ -1 μ κ²½μ° λΆλ΄ μμ² μν¨ | |
MAX_SAVE_CANDLE_COUNT = (STOP_LOSS_CALCULATE_DAY +1) * 140 # 3λΆλ΄ κΈ°μ€ μ μ₯ λΆλ΄ κ°―μ | |
MAESU_TOTAL_PRICE = [ MAESU_UNIT * 1, MAESU_UNIT * 1, MAESU_UNIT * 1, MAESU_UNIT * 1, MAESU_UNIT * 1] | |
# μΆκ° 맀μ μ§νμ stoploss λ° stopplus νΌμΌν°μ§ λ³κ²½ | |
# μΆκ° 맀μ μ΄λ λ¨κ³μμλ μ§ μμ κΈμ‘μ νμ μ μ΄μ¬μΌ ν¨ | |
BASIC_STOP_LOSS_PERCENT = -80 | |
STOP_PLUS_PER_MAESU_COUNT = [ 150, 150, 150, 150, 150 ] | |
STOP_LOSS_PER_MAESU_COUNT = [ int(BASIC_STOP_LOSS_PERCENT), int(BASIC_STOP_LOSS_PERCENT/2), int(BASIC_STOP_LOSS_PERCENT/3), int(BASIC_STOP_LOSS_PERCENT/4), int(BASIC_STOP_LOSS_PERCENT/3) ] | |
EXCEPTION_LIST = ['035480'] # μ₯κΈ° 보μ μ’ λͺ© λ²νΈ 리μ€νΈ ex) EXCEPTION_LIST = ['034220'] | |
################################################################################################### | |
################################################################################################### | |
TEST_MODE = False # μ£Όμ TEST_MODE λ₯Ό True λ‘ νλ©΄ 1μ£Ό λ¨μλ‘ μΌ | |
TRADING_INFO_GETTING_TIME = [15, 55] # νΈλ μ΄λ© μ 보λ₯Ό μ μ₯νκΈ° μμνλ μκ° | |
SLIPPAGE = 1.0 # μμ΅μ 보ν΅κ° μμ μ μμ₯κ° μμλ£ ν¬ν¨ 3νΈκ°κΉμ§ κ³μ°ν΄μ 맀μ νλ―λ‘ 1% μ μ© | |
TR_TIME_LIMIT_MS = 7600 # ν€μ μ¦κΆμμ μ μν μ°μ TR μ νμ λλ μ΄ | |
INTERESTED_STOCKS_FILE_PATH = "log" + os.path.sep + "interested_stocks.json" | |
CHEGYEOL_INFO_FILE_PATH = "log" + os.path.sep + "chegyeol.json" | |
JANGO_INFO_FILE_PATH = "log" + os.path.sep + "jango.json" | |
CHEGYEOL_INFO_EXCEL_FILE_PATH = "log" + os.path.sep + "chegyeol.xlsx" | |
################################################################################################### | |
################################################################################################### | |
class CloseEventEater(QObject): | |
def eventFilter(self, obj, event): | |
if( event.type() == QEvent.Close): | |
test_make_jangoInfo() | |
return True | |
else: | |
return super(CloseEventEater, self).eventFilter(obj, event) | |
class KiwoomConditon(QObject): | |
sigInitOk = pyqtSignal() | |
sigConnected = pyqtSignal() | |
sigDisconnected = pyqtSignal() | |
sigTryConnect = pyqtSignal() | |
sigGetConditionCplt = pyqtSignal() | |
sigSelectCondition = pyqtSignal() | |
sigReselectCondition = pyqtSignal() | |
sigStateStop = pyqtSignal() | |
sigStockComplete = pyqtSignal() | |
sigConditionOccur = pyqtSignal() | |
sigRequestMinuteCandleInfo = pyqtSignal() | |
sigRequestEtcInfo = pyqtSignal() | |
sigGetBasicInfo = pyqtSignal() | |
sigDetermineBuy = pyqtSignal() | |
sigGetHogaInfo = pyqtSignal() | |
sigTrWaitComplete = pyqtSignal() | |
sigWaitTr = pyqtSignal() | |
sigNoWaitTr = pyqtSignal() | |
sigRequestRealHogaComplete = pyqtSignal() | |
sigError = pyqtSignal() | |
sigRequestJangoComplete = pyqtSignal() | |
sigCalculateStoplossComplete = pyqtSignal() | |
sigStartProcessBuy = pyqtSignal() | |
sigStopProcessBuy = pyqtSignal() | |
sigTerminating = pyqtSignal() | |
def __init__(self): | |
super().__init__() | |
self.ocx = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1") | |
self.fsm = QStateMachine() | |
self.account_list = [] | |
self.timerSystem = QTimer() | |
self.lineCmdText = '' | |
self.prohibitCodeList = [] # μ΅κ·Ό ? μΌλμ κ±°λ λμλ μ’ λͺ© κ±°λ κΈμ§ list | |
self.yupjongInfo = {'μ½μ€νΌ': {}, 'μ½μ€λ₯': {} } # { 'yupjong_code': { 'νμ¬κ°': 222, ...} } | |
self.michegyeolInfo = {} | |
self.jangoInfo = {} # { 'jongmok_code': { 'μ΄μ΅μ€νκ°': 222, ...}} | |
self.jangoInfoFromFile = {} # TR μκ³ μ 보 μμ² μ‘°νλ‘λ μ»μ μ μλ λ°μ΄ν°λ₯Ό νμΌλ‘ μ μ₯νκ³ μ²« μ€νμ λ‘λν¨ | |
self.chegyeolInfo = {} # { 'λ μ§' : [ [ '주문ꡬλΆ', '맀λ', 'λΆν 맀μμ΄λ ₯', '체결κ°' , '체결μλ', '미체결μλ'] ] } | |
self.conditionOccurList = [] # 쑰건 μ§μ μ΄ λ°μν λͺ¨λ 리μ€νΈ μ μ₯νκ³ λ§€μ κ²°μ μ μ¬μ©λλ λͺ¨λ μ 보λ₯Ό μ μ₯ν¨ [ {'μ’ λͺ©μ½λ': code, ...}] | |
self.conditionRevemoList = [] # 쑰건 μ΄νμ΄ λ°μν λͺ¨λ 리μ€νΈ μ μ₯ | |
self.kospiCodeList = () | |
self.kosdaqCodeList = () | |
self.createState() | |
self.createConnection() | |
self.currentTime = datetime.datetime.now() | |
self.current_condition_name = '30a' | |
# μκ³ μ 보 μ μ₯μ μ μ₯ μ μΈλ ν€ κ°λ€ | |
self.jango_remove_keys = [ | |
'맀λνΈκ°1', '맀λνΈκ°2', '맀λνΈκ°3', '맀λνΈκ°μλ1', '맀λνΈκ°μλ2', '맀λνΈκ°μλ3','맀λνΈκ°μ΄μλ', | |
'맀μνΈκ°1', '맀μνΈκ°2', '맀μνΈκ°3', '맀μνΈκ°μλ1', '맀μνΈκ°μλ2', '맀μνΈκ°μλ3', '맀μνΈκ°μ΄μλ', | |
'νμ¬κ°', 'νΈκ°μκ°', 'μΈκΈ', 'μ μΌμ’ κ°', 'νμ¬κ°', 'μ’ λͺ©λ²νΈ', 'μμ΅μ¨', 'μμ΅', 'μκ³ ' , '맀λμ€', 'μκ°', 'κ³ κ°', 'μ κ°', 'μ₯ꡬλΆ', | |
'κ±°λλ', 'λ±λ½μ¨', 'μ μΌλλΉ', 'κΈ°μ€κ°', 'μνκ°', 'ννκ°', | |
'μΌ{}λ΄'.format(MAX_SAVE_CANDLE_COUNT), '{}λΆ{}λ΄'.format(REQUEST_MINUTE_CANDLE_TYPE, MAX_SAVE_CANDLE_COUNT) ] | |
def createState(self): | |
# state defintion | |
mainState = QState(self.fsm) | |
stockCompleteState = QState(self.fsm) | |
finalState = QFinalState(self.fsm) | |
self.fsm.setInitialState(mainState) | |
initState = QState(mainState) | |
disconnectedState = QState(mainState) | |
connectedState = QState(QtCore.QState.ParallelStates, mainState) | |
systemState = QState(connectedState) | |
initSystemState = QState(systemState) | |
waitingTradeSystemState = QState(systemState) | |
standbySystemState = QState(systemState) | |
requestingJangoSystemState = QState(systemState) | |
terminatingSystemState = QState(systemState) | |
#transition defition | |
mainState.setInitialState(initState) | |
mainState.addTransition(self.sigStateStop, finalState) | |
mainState.addTransition(self.sigStockComplete, stockCompleteState) | |
stockCompleteState.addTransition(self.sigStateStop, finalState) | |
initState.addTransition(self.sigInitOk, disconnectedState) | |
disconnectedState.addTransition(self.sigConnected, connectedState) | |
disconnectedState.addTransition(self.sigTryConnect, disconnectedState) | |
connectedState.addTransition(self.sigDisconnected, disconnectedState) | |
systemState.setInitialState(initSystemState) | |
initSystemState.addTransition(self.sigGetConditionCplt, requestingJangoSystemState) | |
requestingJangoSystemState.addTransition(self.sigRequestJangoComplete, waitingTradeSystemState) | |
waitingTradeSystemState.addTransition(self.sigSelectCondition, standbySystemState) | |
standbySystemState.addTransition(self.sigTerminating, terminatingSystemState ) | |
standbySystemState.addTransition(self.sigReselectCondition, waitingTradeSystemState ) | |
#state entered slot connect | |
mainState.entered.connect(self.mainStateEntered) | |
stockCompleteState.entered.connect(self.stockCompleteStateEntered) | |
initState.entered.connect(self.initStateEntered) | |
disconnectedState.entered.connect(self.disconnectedStateEntered) | |
connectedState.entered.connect(self.connectedStateEntered) | |
systemState.entered.connect(self.systemStateEntered) | |
initSystemState.entered.connect(self.initSystemStateEntered) | |
waitingTradeSystemState.entered.connect(self.waitingTradeSystemStateEntered) | |
requestingJangoSystemState.entered.connect(self.requestingJangoSystemStateEntered) | |
standbySystemState.entered.connect(self.standbySystemStateEntered) | |
terminatingSystemState.entered.connect(self.terminatingSystemStateEntered) | |
# processBuy definition | |
processBuyState = QState(connectedState) | |
initProcessBuyState = QState(processBuyState) | |
standbyProcessBuyState = QState(processBuyState) | |
requestEtcInfoProcessBuyState = QState(processBuyState) | |
# requestMinuteCandleInfoProcessBuyState = QState(processBuyState) | |
determineBuyProcessBuyState = QState(processBuyState) | |
waitingTRlimitProcessBuyState = QState(processBuyState) | |
processBuyState.setInitialState(initProcessBuyState) | |
initProcessBuyState.addTransition(self.sigStartProcessBuy, standbyProcessBuyState) | |
standbyProcessBuyState.addTransition(self.sigConditionOccur, standbyProcessBuyState) | |
standbyProcessBuyState.addTransition(self.sigRequestEtcInfo, requestEtcInfoProcessBuyState) | |
standbyProcessBuyState.addTransition(self.sigStopProcessBuy, initProcessBuyState) | |
requestEtcInfoProcessBuyState.addTransition(self.sigRequestEtcInfo, requestEtcInfoProcessBuyState) | |
requestEtcInfoProcessBuyState.addTransition(self.sigDetermineBuy, determineBuyProcessBuyState) | |
requestEtcInfoProcessBuyState.addTransition(self.sigError, standbyProcessBuyState ) | |
# requestMinuteCandleInfoProcessBuyState.addTransition(self.sigDetermineBuy, determineBuyProcessBuyState) | |
# requestMinuteCandleInfoProcessBuyState.addTransition(self.sigError, standbyProcessBuyState ) | |
determineBuyProcessBuyState.addTransition(self.sigNoWaitTr, standbyProcessBuyState) | |
determineBuyProcessBuyState.addTransition(self.sigWaitTr, waitingTRlimitProcessBuyState) | |
waitingTRlimitProcessBuyState.addTransition(self.sigTrWaitComplete, standbyProcessBuyState) | |
processBuyState.entered.connect(self.processBuyStateEntered) | |
initProcessBuyState.entered.connect(self.initProcessBuyStateEntered) | |
standbyProcessBuyState.entered.connect(self.standbyProcessBuyStateEntered) | |
requestEtcInfoProcessBuyState.entered.connect(self.requestEtcInfoProcessBuyStateEntered) | |
# requestMinuteCandleInfoProcessBuyState.entered.connect(self.requestMinuteCandleInfoProcessBuyStateEntered) | |
determineBuyProcessBuyState.entered.connect(self.determineBuyProcessBuyStateEntered) | |
waitingTRlimitProcessBuyState.entered.connect(self.waitingTRlimitProcessBuyStateEntered) | |
#fsm start | |
finalState.entered.connect(self.finalStateEntered) | |
self.fsm.start() | |
pass | |
def initQmlEngine(self): | |
self.qmlEngine.load(QUrl('qrc:///qml/main.qml')) | |
self.rootObject = self.qmlEngine.rootObjects()[0] | |
self.rootObject.startClicked.connect(self.onStartClicked) | |
self.rootObject.restartClicked.connect(self.onRestartClicked) | |
self.rootObject.requestJangoClicked.connect(self.onRequestJangoClicked) | |
self.rootObject.chegyeolClicked.connect(self.onChegyeolClicked) | |
self.rootObject.testClicked.connect(self.onTestClicked) | |
rootContext = self.qmlEngine.rootContext() | |
rootContext.setContextProperty("model", self) | |
pass | |
@pyqtSlot() | |
def onBtnMakeExcelClicked(self): | |
print(util.whoami()) | |
self.make_excel(CHEGYEOL_INFO_EXCEL_FILE_PATH, self.chegyeolInfo) | |
pass | |
@pyqtSlot() | |
def onBtnStartClicked(self): | |
print(util.whoami()) | |
self.sigInitOk.emit() | |
@pyqtSlot() | |
def onBtnJangoClicked(self): | |
self.printStockInfo() | |
@pyqtSlot() | |
def onBtnYupjongClicked(self): | |
self.printYupjongInfo() | |
pass | |
@pyqtSlot() | |
def onBtnChegyeolClicked(self): | |
self.printChegyeolInfo('all') | |
@pyqtSlot() | |
def onBtnRunClicked(self): | |
arg = self.lineCmdText | |
if( arg ): | |
eval(arg) | |
pass | |
@pyqtSlot() | |
def onBtnConditionClicked(self): | |
items = self.getCodeListConditionOccurList() | |
buffer = [] | |
for item in items: | |
boyou = "보μ " if item in self.jangoInfo else "" | |
log_string = "{} {} ({}-{})".format( | |
item, | |
self.getMasterCodeName(item), | |
self.getMasterStockInfo(item), | |
boyou) | |
if( boyou == "보μ " ): | |
buffer.append(log_string) | |
else: | |
buffer.insert(0, log_string) | |
print( '\n'.join(buffer) ) | |
pass | |
@pyqtSlot(str) | |
def onLineCmdTextChanged(self, str): | |
self.lineCmdText = str | |
pass | |
@pyqtSlot(str) | |
def onTestClicked(self, arg): | |
print(util.whoami() + ' ' + arg) | |
eval(arg) | |
pass | |
def createConnection(self): | |
self.ocx.OnEventConnect[int].connect(self._OnEventConnect) | |
self.ocx.OnReceiveMsg[str, str, str, str].connect(self._OnReceiveMsg) | |
self.ocx.OnReceiveTrData[str, str, str, str, str, | |
int, str, str, str].connect(self._OnReceiveTrData) | |
self.ocx.OnReceiveRealData[str, str, str].connect( | |
self._OnReceiveRealData) | |
self.ocx.OnReceiveChejanData[str, int, str].connect( | |
self._OnReceiveChejanData) | |
self.ocx.OnReceiveConditionVer[int, str].connect( | |
self._OnReceiveConditionVer) | |
self.ocx.OnReceiveTrCondition[str, str, str, int, int].connect( | |
self._OnReceiveTrCondition) | |
self.ocx.OnReceiveRealCondition[str, str, str, str].connect( | |
self._OnReceiveRealCondition) | |
self.timerSystem.setInterval(1000) | |
self.timerSystem.timeout.connect(self.onTimerSystemTimeout) | |
def isTradeAvailable(self): | |
# 맀μ κ°λ₯ μκ° μ²΄ν¬ | |
# κΈ°λ³Έ μ 보λ₯Ό μ»κΈ° μν΄μλ μ₯ μμμ 미리 λμμ μμΌμΌ νκ³ λ§€μλ₯Ό μν μκ°μ μ νν 9μλ₯Ό λ§μΆ€ (λμνΈκ° μκ°μ 맀λ νΈκ°λ‘ μΈν΄ 맀μ λ¨μ λ§κΈ° μν¨) | |
ret_vals= [] | |
current_time = self.currentTime.time() | |
for start, stop in AUTO_TRADING_OPERATION_TIME: | |
start_time = datetime.time( | |
hour = 9, | |
minute = 0 ) | |
stop_time = datetime.time( | |
hour = stop[0], | |
minute = stop[1]) | |
if( current_time >= start_time and current_time <= stop_time ): | |
ret_vals.append(True) | |
else: | |
ret_vals.append(False) | |
pass | |
# νλλΌλ True μμΌλ©΄ κ±°λ κ°λ₯μκ°μ | |
if( ret_vals.count(True) ): | |
return True | |
else: | |
return False | |
pass | |
@pyqtSlot() | |
def mainStateEntered(self): | |
pass | |
@pyqtSlot() | |
def stockCompleteStateEntered(self): | |
print(util.whoami()) | |
self.sigStateStop.emit() | |
pass | |
@pyqtSlot() | |
def initStateEntered(self): | |
print(util.whoami()) | |
self.sigInitOk.emit() | |
pass | |
@pyqtSlot() | |
def disconnectedStateEntered(self): | |
# print(util.whoami()) | |
if( self.getConnectState() == 0 ): | |
self.commConnect() | |
QTimer.singleShot(90000, self.sigTryConnect) | |
pass | |
else: | |
self.sigConnected.emit() | |
@pyqtSlot() | |
def connectedStateEntered(self): | |
# get κ³μ’ μ 보 | |
account_cnt = self.getLoginInfo("ACCOUNT_CNT") | |
acc_num = self.getLoginInfo("ACCNO") | |
user_id = self.getLoginInfo("USER_ID") | |
user_name = self.getLoginInfo("USER_NAME") | |
keyboard_boan = self.getLoginInfo("KEY_BSECGB") | |
firewall = self.getLoginInfo("FIREW_SECGB") | |
print("account count: {}, acc_num: {}, user id: {}, " | |
"user_name: {}, keyboard_boan: {}, firewall: {}" | |
.format(account_cnt, acc_num, user_id, user_name, | |
keyboard_boan, firewall)) | |
self.account_list = (acc_num.split(';')[:-1]) | |
print(util.whoami() + 'account list ' + str(self.account_list)) | |
# μ½μ€νΌ , μ½μ€λ₯ μ’ λͺ© μ½λ 리μ€νΈ μ»κΈ° | |
result = self.getCodeListByMarket('0') | |
self.kospiCodeList = tuple(result.split(';')) | |
result = self.getCodeListByMarket('10') | |
self.kosdaqCodeList = tuple(result.split(';')) | |
pass | |
@pyqtSlot() | |
def systemStateEntered(self): | |
pass | |
@pyqtSlot() | |
def initSystemStateEntered(self): | |
# 체결μ 보 λ‘λ | |
if( os.path.isfile(CHEGYEOL_INFO_FILE_PATH) == True ): | |
with open(CHEGYEOL_INFO_FILE_PATH, 'r', encoding='utf8') as f: | |
file_contents = f.read() | |
self.chegyeolInfo = json.loads(file_contents) | |
if( os.path.isfile(JANGO_INFO_FILE_PATH) == True ): | |
with open(JANGO_INFO_FILE_PATH, 'r', encoding='utf8') as f: | |
file_contents = f.read() | |
self.jangoInfoFromFile = json.loads(file_contents) | |
# get 쑰건 κ²μ 리μ€νΈ | |
self.getConditionLoad() | |
self.setRealReg(kw_util.sendRealRegUpjongScrNo, '1;101', kw_util.type_fidset['μ μ’ μ§μ'], "0") | |
self.setRealReg(kw_util.sendRealRegTradeStartScrNo, '', kw_util.type_fidset['μ₯μμμκ°'], "0") | |
self.timerSystem.start() | |
pass | |
@pyqtSlot() | |
def requestingJangoSystemStateEntered(self): | |
# print(util.whoami() ) | |
# κ³μ’ μ 보 μ‘°ν | |
self.requestOpw00018(self.account_list[0], "0") | |
pass | |
@pyqtSlot() | |
def waitingTradeSystemStateEntered(self): | |
# μ₯μμ μ μ μ‘°κ±΄μ΄ μμνλλ‘ ν¨ | |
self.sigSelectCondition.emit() | |
# λ°νκ° : 쑰건μΈλ±μ€1^쑰건λͺ 1;쑰건μΈλ±μ€2^쑰건λͺ 2;β¦; | |
# result = '쑰건μΈλ±μ€1^쑰건λͺ 1;쑰건μΈλ±μ€2^쑰건λͺ 2;' | |
result = self.getConditionNameList() | |
searchPattern = r'(?P<index>[^\/:*?"<>|;]+)\^(?P<name>[^\/:*?"<>|;]+);' | |
fileSearchObj = re.compile(searchPattern, re.IGNORECASE) | |
findList = fileSearchObj.findall(result) | |
tempDict = dict(findList) | |
# print(tempDict) | |
condition_name_screenNo_dict = {} | |
for number, condition in tempDict.items(): | |
condition_name_screenNo_dict[condition] = [kw_util.sendConditionScreenNo + '{}'.format(int (number)), number] | |
start_info = [] | |
start_name = None | |
for name, info in condition_name_screenNo_dict.items(): | |
if name == self.current_condition_name: | |
start_info = info | |
start_name = name | |
else: | |
# print("stop condition " + name + ", screen_no: " + info[0] + ", number " + info[1] ) | |
self.sendConditionStop( info[0], name, info[1]) | |
print("start condition " + start_name + ", screen_no: " + start_info[0] + ", number " + start_info[1] ) | |
self.sendCondition( start_info[0], start_name, start_info[1], 1) | |
pass | |
@pyqtSlot() | |
def standbySystemStateEntered(self): | |
print(util.whoami() ) | |
self.makeJangoInfoFile() | |
# μ°μμΌλ‘ μ΅λ 5κ° κ°λ₯νλ―λ‘ 5κ°κΉμ§ κΈ°λ€λ¦Ό | |
QTimer.singleShot( TR_TIME_LIMIT_MS * 5, self.sigStartProcessBuy) | |
pass | |
@pyqtSlot() | |
def terminatingSystemStateEntered(self): | |
print(util.whoami() ) | |
pass | |
@pyqtSlot() | |
def processBuyStateEntered(self): | |
pass | |
@pyqtSlot() | |
def initProcessBuyStateEntered(self): | |
print(util.whoami()) | |
pass | |
@pyqtSlot() | |
def standbyProcessBuyStateEntered(self): | |
# print(util.whoami() ) | |
QTimer.singleShot(100, self.sigRequestEtcInfo) | |
@pyqtSlot() | |
def requestEtcInfoProcessBuyStateEntered(self): | |
#μ₯μ€μ νλ²λ§ μ»μ΄λ λλ μ 보λ₯Ό μμ²ν λ | |
# print(util.whoami() ) | |
# 쑰건 λ°μ 리μ€νΈ κ²μ | |
for jongmok_code in self.conditionRevemoList: | |
self.removeConditionOccurList(jongmok_code) | |
self.conditionRevemoList.clear() | |
self.refreshRealRequest() | |
jongmok_info_dict = self.getConditionOccurList() | |
if( jongmok_info_dict == None ): | |
self.sigError.emit() | |
return | |
jongmok_code = jongmok_info_dict['μ’ λͺ©μ½λ'] | |
jongmok_name = jongmok_info_dict['μ’ λͺ©λͺ '] | |
key_day_candle = 'μΌ{}λ΄'.format(MAX_SAVE_CANDLE_COUNT) | |
key_minute_candle = '{}λΆ{}λ΄'.format(REQUEST_MINUTE_CANDLE_TYPE, MAX_SAVE_CANDLE_COUNT) | |
key_day_low_candle = '{}μΌλ΄μ€μ κ°'.format(STOP_LOSS_CALCULATE_DAY) | |
# μΌλ΄μ μμ²νμκ³ μκ³ μ 보μ μΌλ΄ μ 보 μλ κ²½μ° update | |
if( key_day_candle in jongmok_info_dict and jongmok_code in self.jangoInfo ): | |
if( key_day_candle not in self.jangoInfo[jongmok_code] ): | |
self.jangoInfo[jongmok_code][key_day_candle] = jongmok_info_dict[key_day_candle] | |
if( key_day_low_candle not in self.jangoInfo[jongmok_code] ): | |
self.jangoInfo[jongmok_code][key_day_low_candle] = jongmok_info_dict[key_day_low_candle] | |
########################################################################################################## | |
# κΈ°λ³Έμ 보 μμ² | |
# κΈ°μ€κ°μ κ²½μ° λΉμΌ μμ₯ μ’ λͺ©μ κ²½μ° κ³΅λ°±μΌ μ μμ | |
# if ( 'κΈ°μ€κ°' not in jongmok_info_dict ): | |
# #κΈ°λ³Έ μ 보 μ¬λΆ νμΈ | |
# self.requestOpt10001(jongmok_code) | |
# print("request {}".format(jongmok_name) ) | |
########################################################################################################## | |
# μΌλ΄ μ 보 μμ² | |
# if(key_day_candle not in jongmok_info_dict): | |
# #μΌλ΄ μ 보 μ¬λΆ νμΈ | |
# self.requestOpt10081(jongmok_code) | |
# print("request {}".format(jongmok_name) ) | |
########################################################################################################## | |
# λΆλ΄ μ 보 μμ² | |
if( True ): | |
#λΆλ΄ μ 보 νμΈ | |
key_last_minute_candle_time = 'μ΅κ·Ό{}λΆλ΄μ²΄κ²°μκ°'.format(REQUEST_MINUTE_CANDLE_TYPE) | |
last_request_time_str = jongmok_info_dict.get(key_last_minute_candle_time, '') | |
isRequestNeeded = False | |
if( last_request_time_str != ''): | |
last_request_time = datetime.datetime.strptime(last_request_time_str, "%Y%m%d%H%M%S") | |
# μ΄ μ 보 μ΄κΈ°ν | |
last_request_time = last_request_time.replace(second = 0) | |
time_span = datetime.timedelta(minutes = REQUEST_MINUTE_CANDLE_TYPE) | |
expected_time = (last_request_time + time_span) | |
request_start_time = datetime.time( | |
hour = 9, | |
minute = REQUEST_MINUTE_CANDLE_TYPE | |
) | |
# μ§μ λ΄μκ°μ΄ μ΄κ³Όν κ²½μ°μ μ₯ μμ νκ³ λ°λ‘ λΆλ΄ κ³μ μμ²νλ νμ λ§μ | |
if( expected_time <= self.currentTime and request_start_time <= self.currentTime.time() ): | |
isRequestNeeded = True | |
else: | |
#첫 μμ² | |
isRequestNeeded = True | |
if( isRequestNeeded == True ): | |
if( self.requestOpt10080(jongmok_code) == False ): | |
self.sigError.emit() | |
else: | |
self.sigDetermineBuy.emit() | |
pass | |
pass | |
@pyqtSlot() | |
def determineBuyProcessBuyStateEntered(self): | |
jongmok_info_dict = self.getConditionOccurList() | |
key_day_candle = 'μΌ{}λ΄'.format(MAX_SAVE_CANDLE_COUNT) | |
key_minute_candle = '{}λΆ{}λ΄'.format(REQUEST_MINUTE_CANDLE_TYPE, MAX_SAVE_CANDLE_COUNT) | |
# 쑰건 κ²μμ κ±Έλ¦° μ’ λͺ©λ κ°μ΄ 리μ€νΈμ λλ―λ‘ | |
# μ’ λͺ© κΈ°λ³Έμ 보, μ€μκ° μ²΄κ²°μ 보, μ€μκ° νΈκ° μλ μ 보, μΌλ΄ λΆλ΄ μμ΄μΌ ν¨ | |
if( jongmok_info_dict != None ): | |
# κΈ°λ³Έ, μΌλ΄, λΆλ΄, μ€μκ° μ λ³΄κ° μλ κ²½μ° λ§€μ κΈμ§ | |
if( | |
jongmok_info_dict.get('λ±λ½μ¨', '') == '' or | |
jongmok_info_dict.get('맀λνΈκ°1', '') == '' | |
): | |
self.shuffleConditionOccurList() | |
self.sigNoWaitTr.emit() | |
print("1", end= '') | |
return | |
# μμ₯νμ§ μΌλ§ μλμ μΌλ΄ / λΆλ΄ μ λ³΄κ° λΆμ‘±ν κ²½μ° μ μΈ | |
if( | |
# len(jongmok_info_dict.get(key_day_candle, [])) != MAX_SAVE_CANDLE_COUNT or | |
len(jongmok_info_dict.get(key_minute_candle, [])) != MAX_SAVE_CANDLE_COUNT | |
): | |
self.shuffleConditionOccurList() | |
self.sigNoWaitTr.emit() | |
print("2", end= '') | |
return | |
else: | |
self.sigNoWaitTr.emit() | |
print("3", end= '') | |
return | |
if( self.isTradeAvailable() == False ): | |
print("4", end= '') | |
self.sigNoWaitTr.emit() | |
return | |
is_log_print_enable = False | |
return_vals = [] | |
printLog = '' | |
jongmok_code = jongmok_info_dict['μ’ λͺ©μ½λ'] | |
jongmok_name = jongmok_info_dict['μ’ λͺ©λͺ '] | |
# νΈκ° μ 보λ λ¬Έμμ΄λ‘ κΈ°μ€κ° λλΉ + , - κ°μ΄ λΆμ΄ λμ΄ | |
maedoHoga1 = abs(int(jongmok_info_dict['맀λνΈκ°1'])) | |
maedoHogaAmount1 = int(jongmok_info_dict['맀λνΈκ°μλ1']) | |
maedoHoga2 = abs(int(jongmok_info_dict['맀λνΈκ°2']) ) | |
maedoHogaAmount2 = int(jongmok_info_dict['맀λνΈκ°μλ2']) | |
# print( util.whoami() + maedoHoga1 + " " + maedoHogaAmount1 + " " + maedoHoga2 + " " + maedoHogaAmount2 ) | |
# print( util.whoami() + jongmok_name + " " + str(sum) + (" won") ) | |
# util.save_log( '{0:^20} νΈκ°1:{1:>8}, μλ1:{2:>8} / νΈκ°2:{3:>8}, μλ2:{4:>8}' | |
# .format(jongmok_name, maedoHoga1, maedoHogaAmount1, maedoHoga2, maedoHogaAmount2), 'νΈκ°μλ' , folder= "log") | |
printLog += ' ' + jongmok_name + ' ' + jongmok_code + ' ' + str(maedoHoga1) + ' ' | |
########################################################################################################## | |
# μ μΈ μ’ λͺ©μΈμ§ νμΈ | |
if( jongmok_code in EXCEPTION_LIST ): | |
printLog += "(μ μΈμ’ λͺ©)" | |
return_vals.append(False) | |
########################################################################################################## | |
# μ΅λ 보μ ν μ μλ μ’ λͺ© 보μ μλ₯Ό λμλμ§ νμΈ | |
if( len(self.jangoInfo.keys()) < MAX_STOCK_POSSESION_COUNT + len(EXCEPTION_LIST) ): | |
pass | |
else: | |
if( jongmok_code not in self.jangoInfo): | |
printLog += "(μ’ λͺ©μ΅λ보μ μ€)" | |
return_vals.append(False) | |
########################################################################################################## | |
# μ΅κ·Ό 맀μκ°/λΆν 맀μ νμ μ 보 μμ± | |
bunhal_maesu_list = [] | |
last_maeip_price = 99999999 | |
maesu_count = 0 | |
if( jongmok_code in self.jangoInfo): | |
bunhal_maesu_list = self.jangoInfo[jongmok_code].get('λΆν 맀μμ΄λ ₯', []) | |
chegyeol_info = bunhal_maesu_list[-1] | |
last_maeip_price = int(chegyeol_info.split(':')[1]) #λ μ§:κ°κ²©:μλ | |
maesu_count = len(bunhal_maesu_list) | |
########################################################################################################## | |
# μ μΌ μ’ κ°λ₯Ό μ»κΈ° μν κΈ°μ€κ° μ 보 μμ± | |
# κΈ°μ€κ° μ λ³΄κ° κ³΅λ°± μΈ κ²½μ° μμ | |
gijunga = int(float(jongmok_info_dict['νμ¬κ°']) / ( 1 + float(jongmok_info_dict['λ±λ½μ¨']) / 100 ) ) | |
# print( '{} κΈ°μ€κ°: {}'.format( jongmok_name, gijunga )) | |
# 0λ²μ κ²½μ° νμ¬λ΄μ λ»νλ©°, TR μμ²μ κ³μ νκ² λλ κ²½μ° μ νν΄μ§ --> μ€μκ° μ²΄κ²°κ°λ‘ νμΈ | |
# νμ¬λ΄μ κ²½μ° λ§€λ² μμ²νμ§ μμΌλ©΄ λ°μ΄ν°κ° μ ννμ§ μμ | |
########################################################################################################## | |
# μΆκ° 맀μ νμ μ ν | |
if( maesu_count < BUNHAL_MAESU_LIMIT ): | |
pass | |
else: | |
printLog += '(λΆν 맀μνκ³)' | |
return_vals.append(False) | |
########################################################################################################## | |
# λΉμΌ λΆλ΄ νμΈ | |
# _today_min_list = [] | |
# for item in jongmok_info_dict[key_minute_candle][1:]: | |
# # νμ¬λ΄ μ μΈ | |
# # 20191104145500 νμ | |
# item_date = datetime.datetime.strptime(item[time_index], '%Y%m%d%H%M%S').date() | |
# # print(item_date) | |
# # λΉμΌ λ΄λ§ ν¬ν¨ | |
# if( item_date >= self.currentTime.date()) : | |
# # print(item) | |
# _today_min_list.append(item) | |
########################################################################################################## | |
# 맀λ νΈκ° μλ νμΈν΄ μ΄λ§νΌ μλ κ²½μ° λ§€μ | |
# 맀λ 2νΈκ°κΉμ§ λ΄ | |
totalMaedoHogaAmount = maedoHoga1 * maedoHogaAmount1 + maedoHoga2 * maedoHogaAmount2 | |
if( totalMaedoHogaAmount >= TOTAL_BUY_AMOUNT): | |
pass | |
else: | |
# print('{} (νΈκ°μλλΆμ‘±: 맀λνΈκ°1 {} 맀λνΈκ°μλ1 {} 맀λνΈκ°2 {} 맀λνΈκ°μλ2 {})'.format(jongmok_name, maedoHoga1, maedoHogaAmount1, maedoHoga2, maedoHogaAmount2)) | |
printLog += '(νΈκ°μλλΆμ‘±: 맀λνΈκ°1 {0} 맀λνΈκ°μλ1 {1})'.format(maedoHoga1, maedoHogaAmount1) | |
# return_vals.append(False) | |
########################################################################################################## | |
# κΈ°μ‘΄μ μ΄λ―Έ 맀λ λ°μνκ±°λ, | |
# μ΅κ·Ό ? μΌλ΄ 맀μ μ’ λͺ©μ΄μ΄μ μΆκ° 맀μλ₯Ό λ§κΈ° μν¨μΈ κ²½μ° | |
if( self.prohibitCodeList.count(jongmok_code) == 0 ): | |
pass | |
else: | |
printLog += '(κ±°λκΈμ§μ’ λͺ©)' | |
return_vals.append(False) | |
########################################################################################################## | |
# μ’ λͺ© λ±λ½μ¨μ 쑰건 μ μ© | |
# +, - λΆλ μμμ΄λ―λ‘ float μΌλ‘ λ¨Όμ μ²λ¦¬ | |
updown_percentage = float(jongmok_info_dict['λ±λ½μ¨'] ) | |
if( updown_percentage < 23 and updown_percentage > 0): | |
pass | |
else: | |
printLog += '(μ’ λͺ©λ±λ½μ¨λ―ΈμΆ©μ‘±: λ±λ½μ¨ {0})'.format(updown_percentage) | |
return_vals.append(False) | |
pass | |
########################################################################################################## | |
# 첫 맀μμλ§ μ μ©λλ 쑰건 | |
if( jongmok_code not in self.jangoInfo ): | |
if( self.current_condition_name == 'μ₯μ΄λ°'): | |
pass | |
else: | |
pass | |
########################################################################################################## | |
# μΆκ° 맀μμλ§ μ μ©λλ 쑰건 | |
else: | |
########################################################################################################## | |
# μ΅κ·Ό 맀μ κ° λλΉ λΉκ΅νμ¬ μΆλ§€ | |
if( maedoHoga1 > last_maeip_price | |
): | |
# print("{:<30}".format(jongmok_name) + "μΆλ§€μ‘°κ±΄μΆ©μ‘±" +" μ΅κ·Όλ§€μκ°:" + str(last_maeip_price) + ' 맀λνΈκ°1:' + str(maedoHoga1) ) | |
pass | |
else: | |
printLog += '(μΆλ§€μ‘°κ±΄λ―ΈμΆ©μ‘±)' | |
return_vals.append(False) | |
temp = '({} {})'\ | |
.format( jongmok_name, maedoHoga1 ) | |
# print( util.cur_time_msec() , temp) | |
printLog += temp | |
pass | |
########################################################################################################## | |
# 맀μ | |
########################################################################################################## | |
# 맀λ νΈκ°κ° 0μΈκ²½μ° μνκ°μ | |
if( return_vals.count(False) == 0 and maedoHoga1 != 0 ): | |
util.save_log(jongmok_name, '맀μμ£Όλ¬Έ', folder= "log") | |
qty = 0 | |
if( TEST_MODE == True ): | |
qty = 1 | |
else: | |
# 맀μ μλμ μ‘°μ νκΈ° μν¨ | |
if( jongmok_code in self.jangoInfo): | |
first_chegyeol_time_str = "" | |
if( len(bunhal_maesu_list) ): | |
first_chegyeol_time_str = bunhal_maesu_list[0].split(':')[0] # λ μ§:κ°κ²©:μλ | |
if( first_chegyeol_time_str != ''): | |
base_time = datetime.datetime.strptime("20180127010101", "%Y%m%d%H%M%S") | |
base2_time = datetime.datetime.strptime("20180319010101", "%Y%m%d%H%M%S") | |
first_maesu_time = datetime.datetime.strptime(first_chegyeol_time_str, "%Y%m%d%H%M%S") | |
total_price = MAESU_TOTAL_PRICE[maesu_count] | |
if( base2_time > first_maesu_time and base_time < first_maesu_time ): | |
# 500000 | |
qty = int(total_price / maedoHoga1 ) / 3 + 1 # μ½κ° μ€λ²νκ² μΌ | |
pass | |
elif( base2_time < first_maesu_time ): | |
# 1500000 | |
qty = int(total_price / maedoHoga1 ) + 1 # μ½κ° μ€λ²νκ² μΌ | |
pass | |
else: | |
qty = int(total_price / maedoHoga1 / 30 ) + 1 | |
else: | |
pass | |
else: | |
# μ κ· λ§€μ | |
total_price = MAESU_TOTAL_PRICE[maesu_count] | |
qty = int(total_price / maedoHoga1 ) + 1 | |
result = "" | |
result = self.sendOrder("buy_" + jongmok_code, kw_util.sendOrderScreenNo, | |
objKiwoom.account_list[0], kw_util.dict_order["μ κ·λ§€μ"], jongmok_code, | |
qty, maedoHoga2 , kw_util.dict_order["μ§μ κ°"], "") | |
print("B " + str(result) , sep="") | |
printLog = '**** [맀μμλ: {0}, 맀μκ°: {1}, 맀μνμ: {2}] ****'.format( | |
qty, | |
maedoHoga1, | |
maesu_count | |
) + printLog | |
is_log_print_enable = True | |
pass | |
else: | |
self.sigNoWaitTr.emit() | |
pass | |
self.shuffleConditionOccurList() | |
if( is_log_print_enable ): | |
util.save_log(printLog, '쑰건μ§μ ', folder = "log") | |
pass | |
@pyqtSlot() | |
def waitingTRlimitProcessBuyStateEntered(self): | |
# print(util.whoami()) | |
# TR μ κ°λΉ 3.7 μ΄ μ ν | |
# 5μ°μ μ‘°νμ 17μ΄ λκΈ° ν΄μΌν¨ | |
# print(util.whoami() ) | |
QTimer.singleShot(TR_TIME_LIMIT_MS, self.sigTrWaitComplete) | |
pass | |
@pyqtSlot() | |
def finalStateEntered(self): | |
print(util.whoami()) | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
util.save_log('', subject= '', folder='log') | |
# import subprocess | |
# subprocess.call(["shutdown", "-s", "-t", "500"]) | |
pass | |
def sendorder_multi(self, rQName, screenNo, accNo, orderType, code, qty, price, hogaGb, orgOrderNo): | |
def inner(): | |
self.sendOrder(rQName, screenNo, accNo, orderType, code, qty, price, hogaGb, orgOrderNo) | |
return inner | |
def printStockInfo(self, jongmok_code = 'all'): | |
if( jongmok_code == 'all'): | |
print(json.dumps(self.jangoInfo, ensure_ascii= False, indent =2, sort_keys = True)) | |
else: | |
print(json.dumps(self.jangoInfo[jongmok_code], ensure_ascii= False, indent =2, sort_keys = True)) | |
pass | |
def printChegyeolInfo(self, current_date = 'all'): | |
if( current_date == 'all' ): | |
print(json.dumps(self.chegyeolInfo, ensure_ascii= False, indent = 2, sort_keys = True)) | |
elif( current_date == ''): | |
current_date = self.currentTime.date().strftime("%y%m%d") | |
if( current_date in self.chegyeolInfo): | |
print(json.dumps(self.chegyeolInfo[current_date], ensure_ascii= False, indent = 2, sort_keys = True)) | |
def printYupjongInfo(self): | |
print(json.dumps(self.yupjongInfo, ensure_ascii= False, indent =2, sort_keys = True)) | |
# μ£Όμ μκ³ μ 보 μμ² | |
def requestOpw00018(self, account_num, sPrevNext): | |
self.setInputValue('κ³μ’λ²νΈ', account_num) | |
self.setInputValue('λΉλ°λ²νΈ', '') # μ¬μ©μν¨(곡백) | |
self.setInputValue('λΉλΉλ²νΈμ λ ₯맀체ꡬλΆ', '00') | |
self.setInputValue('μ‘°νꡬλΆ', '1') | |
# μ°μ λ°μ΄ν° μ‘°νν΄μΌ νλ κ²½μ° | |
if( sPrevNext == "2" ): | |
ret = self.commRqData(account_num, "opw00018", 2, kw_util.sendAccountInfoScreenNo) | |
else: | |
ret = self.commRqData(account_num, "opw00018", 0, kw_util.sendAccountInfoScreenNo) | |
errorString = None | |
if( ret != 0 ): | |
errorString = account_num + " commRqData() " + kw_util.parseErrorCode(str(ret)) | |
print(util.whoami() + errorString ) | |
util.save_log(errorString, util.whoami(), folder = "log" ) | |
return False | |
return True | |
# μ£Όμ μκ³ μ 보 #rQName μ κ²½μ° κ³μ’ λ²νΈλ‘ λκ²¨μ€ | |
def makeOpw00018Info(self, rQName): | |
data_cnt = self.getRepeatCnt('opw00018', rQName) | |
for cnt in range(data_cnt): | |
info_dict = {} | |
for item_name in kw_util.dict_jusik['TR:κ³μ’νκ°μκ³ λ΄μμμ²']: | |
result = self.getCommData("opw00018", rQName, cnt, item_name) | |
# μλ 컬λΌμ pass | |
if( len(result) == 0 ): | |
continue | |
if( item_name == 'μ’ λͺ©λͺ '): | |
info_dict[item_name] = result.strip() | |
elif( item_name == 'μ’ λͺ©λ²νΈ'): | |
info_dict[item_name] = result[1:-1].strip() | |
elif( item_name == 'μμ΅λ₯ (%)'): | |
info_dict[item_name] = int(result) / 100 | |
else: | |
info_dict[item_name] = int(result) | |
jongmok_code = info_dict['μ’ λͺ©λ²νΈ'] | |
info_dict['μ μ’ '] = self.getMasterStockInfo(jongmok_code) | |
if( jongmok_code not in self.jangoInfo.keys() ): | |
self.jangoInfo[jongmok_code] = info_dict | |
else: | |
# κΈ°μ‘΄μ κ°μ§κ³ μλ μ’ λͺ©μ΄λ©΄ update | |
self.jangoInfo[jongmok_code].update(info_dict) | |
# print(self.jangoInfo) | |
return True | |
# μ£Όμ 1μΌλ΄ μμ² | |
def requestOpt10081(self, jongmok_code): | |
# print(util.cur_time_msec() ) | |
datetime_str = datetime.datetime.now().strftime('%Y%m%d') | |
self.setInputValue("μ’ λͺ©μ½λ", jongmok_code) | |
self.setInputValue("κΈ°μ€μΌμ", datetime_str) | |
self.setInputValue('μμ μ£Όκ°κ΅¬λΆ', '1') | |
ret = self.commRqData(jongmok_code, "opt10081", 0, kw_util.sendGibonScreenNo) | |
errorString = None | |
if( ret != 0 ): | |
errorString = jongmok_code + " commRqData() " + kw_util.parseErrorCode(str(ret)) | |
print(util.whoami() + errorString ) | |
util.save_log(errorString, util.whoami(), folder = "log" ) | |
return False | |
return True | |
# μ£Όμ μΌλ΄ λ°μ΄ν° μμ± | |
def makeOpt10081Info(self, rQName): | |
# 쑰건 λ°μν μ’ λͺ© μμ 리μ€νΈμ μ 보λ₯Ό μ»κΈ° μν¨ | |
jongmok_info_dict = self.getConditionOccurList() | |
if( jongmok_info_dict == None ): | |
return False | |
# νλ² μ½μΌλ©΄ 900κ° μ½ν | |
repeatCnt = self.getRepeatCnt("opt10081", rQName) | |
jongmok_code = rQName | |
# κ±°λλμ§ μλ μ’ λͺ©μ κ²½μ° μ κ°κ° '' κ°μ΄ μ€κΈ° λλ¬Έμ 1κ°λ μ±μλ | |
low_price_list = [999999999] | |
total_current_price_list = [] | |
# μΌλ΄μ νμ¬ λ΄λ ν¬ν¨ | |
for i in range(min(repeatCnt, 200)): | |
for item_name in kw_util.dict_jusik['TR:μΌλ΄']: | |
if( item_name == "μ κ°"): | |
result = self.getCommData("opt10081", rQName, i, item_name) | |
if( i != 0 and result != '' and i <= STOP_LOSS_CALCULATE_DAY): | |
# 첫λ²μ§Έλ λΉμΌμ΄λ―λ‘ μ μΈ | |
low_price_list.append( abs(int(result) ) ) | |
if( item_name == "νμ¬κ°"): | |
result = self.getCommData("opt10081", rQName, i, item_name) | |
if( i != 0 and result != '' ): | |
# 첫λ²μ§Έλ λΉμΌμ΄λ―λ‘ μ μΈ | |
total_current_price_list.append( abs(int(result) ) ) | |
jongmok_info_dict['{}μΌλ΄μ€μ κ°'.format(STOP_LOSS_CALCULATE_DAY)] = min(low_price_list) | |
jongmok_info_dict['μΌ{}λ΄'.format(MAX_SAVE_CANDLE_COUNT)] = total_current_price_list[0:MAX_SAVE_CANDLE_COUNT] | |
return True | |
# μ£Όμ λΆλ΄ tr μμ² | |
def requestOpt10080(self, jongmok_code): | |
# λΆλ΄ tr μμ²μ κ²½μ° λ무 λ§μ λ°μ΄ν°λ₯Ό μμ²νλ―λ‘ νκ°μ© μν | |
candle_type_str = "5:5λΆ" | |
if( REQUEST_MINUTE_CANDLE_TYPE == 5): | |
candle_type_str = "5:5λΆ" | |
elif( REQUEST_MINUTE_CANDLE_TYPE == 3 ): | |
candle_type_str = "3:3λΆ" | |
self.setInputValue("μ’ λͺ©μ½λ", jongmok_code ) | |
self.setInputValue("ν±λ²μ", candle_type_str) | |
self.setInputValue("μμ μ£Όκ°κ΅¬λΆ","1") | |
# rQName μ λ°μ΄ν°λ‘ μΈλΆμμ μ¬μ© | |
ret = self.commRqData(jongmok_code , "opt10080", 0, kw_util.send5minScreenNo) | |
errorString = None | |
if( ret != 0 ): | |
errorString = jongmok_code + " commRqData() " + kw_util.parseErrorCode(str(ret)) | |
print(util.whoami() + errorString ) | |
util.save_log(errorString, util.whoami(), folder = "log" ) | |
return False | |
return True | |
# λΆλ΄ λ°μ΄ν° μμ± | |
def makeOpt10080Info(self, rQName): | |
jongmok_code = rQName | |
jongmok_info_dict = self.getConditionOccurList() | |
if( jongmok_info_dict == None ): | |
return False | |
# νλ² μ½μΌλ©΄ 900κ° μ½ν | |
repeatCnt = self.getRepeatCnt("opt10080", rQName) | |
total_current_price_list = [] | |
# 3λΆλ΄ κΈ°μ€ 6.5 μκ° * 20 = 130 | |
for i in range(min(repeatCnt, MAX_SAVE_CANDLE_COUNT)): | |
line = [] | |
for item_name in kw_util.dict_jusik['TR:λΆλ΄']: | |
result = self.getCommData("opt10080", rQName, i, item_name) | |
if( item_name == "체결μκ°" ): | |
# 20191104145500 νμ | |
if( i == 0 ): | |
jongmok_info_dict['μ΅κ·Ό{}λΆλ΄μ²΄κ²°μκ°'.format(REQUEST_MINUTE_CANDLE_TYPE)] = result.strip() | |
line.append( result.strip() ) | |
else: | |
line.append( abs(int(result.strip()) )) | |
pass | |
total_current_price_list.append( line ) | |
key_minute_candle = '{}λΆ{}λ΄'.format(REQUEST_MINUTE_CANDLE_TYPE, MAX_SAVE_CANDLE_COUNT) | |
jongmok_info_dict[key_minute_candle] = total_current_price_list | |
if( jongmok_code in self.jangoInfo ): | |
self.jangoInfo[jongmok_code][key_minute_candle] = jongmok_info_dict[key_minute_candle] | |
return True | |
# μ μ’ λΆλ΄ tr μμ² | |
def requestOpt20005(self, yupjong_code): | |
self.setInputValue("μ μ’ μ½λ", yupjong_code ) | |
self.setInputValue("ν±λ²μ","5:5λΆ") | |
self.setInputValue("μμ μ£Όκ°κ΅¬λΆ","1") | |
ret = 0 | |
if( yupjong_code == '001'): | |
ret = self.commRqData(yupjong_code , "opt20005", 0, kw_util.sendReqYupjongKospiScreenNo) | |
else: | |
ret = self.commRqData(yupjong_code , "opt20005", 0, kw_util.sendReqYupjongKosdaqScreenNo) | |
errorString = None | |
if( ret != 0 ): | |
errorString = yupjong_code + " commRqData() " + kw_util.parseErrorCode(str(ret)) | |
print(util.whoami() + errorString ) | |
util.save_log(errorString, util.whoami(), folder = "log" ) | |
return False | |
return True | |
# μ μ’ λΆλ΄ λ°μ΄ν° μμ± | |
def makeOpt20005Info(self, rQName): | |
if( rQName == '001'): | |
yupjong_info_dict = self.yupjongInfo['μ½μ€νΌ'] | |
elif( rQName == '101'): | |
yupjong_info_dict = self.yupjongInfo['μ½μ€λ₯'] | |
else: | |
return | |
repeatCnt = self.getRepeatCnt("opt20005", rQName) | |
fivebong_sum = 0 | |
twentybong_sum = 0 | |
for i in range(min(repeatCnt, 20)): | |
line = [] | |
for item_name in kw_util.dict_jusik['TR:μ μ’ λΆλ΄']: | |
result = self.getCommData("opt20005", rQName, i, item_name) | |
if( item_name == "νμ¬κ°" ): | |
current_price = abs(int(result)) / 100 | |
if( i < 5 ): | |
fivebong_sum += current_price | |
twentybong_sum += current_price | |
line.append(str(current_price)) | |
else: | |
line.append(result.strip()) | |
key_value = '5λΆ {0}λ΄μ '.format(i) | |
yupjong_info_dict[key_value] = line | |
yupjong_info_dict['20λ΄νκ· '] = str(round(twentybong_sum / 20, 2)) | |
yupjong_info_dict['5λ΄νκ· '] = str(round(fivebong_sum / 5, 2)) | |
return True | |
# μ£Όμ κΈ°λ³Έ μ 보 μμ² | |
def requestOpt10001(self, jongmok_code): | |
# print(util.cur_time_msec() ) | |
self.setInputValue("μ’ λͺ©μ½λ", jongmok_code) | |
ret = self.commRqData(jongmok_code, "opt10001", 0, kw_util.sendGibonScreenNo) | |
errorString = None | |
if( ret != 0 ): | |
errorString = jongmok_code + " commRqData() " + kw_util.parseErrorCode(str(ret)) | |
print(util.whoami() + errorString ) | |
util.save_log(errorString, util.whoami(), folder = "log" ) | |
return False | |
return True | |
# μ£Όμ κΈ°λ³Έ λ°μ΄ν° ( multi data μλ ) | |
def makeOpt10001Info(self, rQName): | |
jongmok_info_dict = self.getConditionOccurList() | |
if( jongmok_info_dict == None): | |
return False | |
jongmok_code = rQName | |
for item_name in kw_util.dict_jusik['TR:κΈ°λ³Έμ 보']: | |
result = self.getCommData("opt10001", rQName, 0, item_name) | |
if( jongmok_code in self.jangoInfo ): | |
self.jangoInfo[jongmok_code][item_name] = result.strip() | |
jongmok_info_dict[item_name] = result.strip() | |
return True | |
@pyqtSlot() | |
def onTimerSystemTimeout(self): | |
self.currentTime = datetime.datetime.now() | |
jang_choban_start_time = datetime.time( hour = 9, minute = 0, second = 30 ) | |
jang_choban_end_time = datetime.time( hour = 9, minute = 30 ) | |
jang_jungban_start_time = datetime.time( hour = 14, minute = 00 ) | |
current_time = self.currentTime.time() | |
isConditionRefreshed = False | |
if( current_time > jang_choban_start_time and current_time < jang_choban_end_time ): | |
if( self.current_condition_name != 'μ₯μ΄λ°' ): | |
isConditionRefreshed = True | |
self.current_condition_name = '30a' | |
elif( current_time > jang_jungban_start_time ): | |
if( self.current_condition_name != 'μ₯νλ°' ): | |
isConditionRefreshed = True | |
self.current_condition_name = '30a' | |
else: | |
if( self.current_condition_name != 'ν΄μ' ): | |
isConditionRefreshed = True | |
self.current_condition_name = '30a' | |
if(isConditionRefreshed == True): | |
self.sigReselectCondition.emit() | |
if( self.getConnectState() != 1 ): | |
util.save_log("Disconnected!", "μμ€ν ", folder = "log") | |
self.sigDisconnected.emit() | |
else: | |
if( datetime.time(*TRADING_INFO_GETTING_TIME) <= self.currentTime.time() ): | |
self.timerSystem.stop() | |
util.save_log("Stock Trade Terminate!\n\n\n\n\n", "μμ€ν ", folder = "log") | |
pass | |
else : | |
pass | |
pass | |
@pyqtSlot() | |
def quit(self): | |
print(util.whoami()) | |
self.commTerminate() | |
QApplication.quit() | |
# μλ¬μ½λμ λ©μμ§λ₯Ό μΆλ ₯νλ€. | |
@pyqtSlot(int, result=str) | |
def parseErrorCode(self, errCode): | |
return kw_util.parseErrorCode(errCode) | |
# event | |
# ν΅μ μ°κ²° μν λ³κ²½μ μ΄λ²€νΈ | |
# nErrCodeκ° 0μ΄λ©΄ λ‘κ·ΈμΈ μ±κ³΅, μμλ©΄ μ€ν¨ | |
def _OnEventConnect(self, errCode): | |
print(util.whoami() + '{}'.format(errCode)) | |
if errCode == 0: | |
self.sigConnected.emit() | |
else: | |
self.sigDisconnected.emit() | |
# μμ λ©μμ§ μ΄λ²€νΈ | |
def _OnReceiveMsg(self, scrNo, rQName, trCode, msg): | |
# print(util.whoami() + 'sScrNo: {}, sRQName: {}, sTrCode: {}, sMsg: {}' | |
# .format(scrNo, rQName, trCode, msg)) | |
# [107066] 맀μμ£Όλ¬Έμ΄ μλ£λμμ΅λλ€. | |
# [107048] 맀λμ£Όλ¬Έμ΄ μλ£λμμ΅λλ€ | |
# [571489] μ₯μ΄ μ΄λ¦¬μ§μλ λ μ λλ€ | |
# [100000] μ‘°νκ° μλ£λμμ΅λλ€ | |
printData = 'sScrNo: {}, sRQName: {}, sTrCode: {}, sMsg: {}'.format(scrNo, rQName, trCode, msg) | |
# buy νλ€κ° μ€λ₯ λκ²½μ° κ°μ λ‘ buy signal μμ± | |
# buy μ μ λ©μμ§λ 107066 | |
if( 'buy' in rQName and '107066' not in msg ): | |
self.sigWaitTr.emit() | |
# sell νλ€κ° μ€λ₯ λκ²½μ° κ°μ λ‘ buy signal μμ± | |
# sell μ μ λ©μμ§λ 107066 | |
if( 'sell' in rQName and '107048' not in msg ): | |
pass | |
# self.sigWaitTr.emit() | |
# sell νλ€κ° μ€λ₯ λκ²½μ° | |
# if( 'sell' in rQName and '맀λκ°λ₯μλ' in msg ): | |
# self.sigWaitTr.emit() | |
print(printData) | |
util.save_log(printData, "μμ€ν λ©μμ§", "log") | |
pass | |
# Tran μμ μ μ΄λ²€νΈ | |
def _OnReceiveTrData( self, scrNo, rQName, trCode, recordName, | |
prevNext, dataLength, errorCode, message, | |
splmMsg): | |
# print(util.whoami() + 'sScrNo: {}, rQName: {}, trCode: {}, prevNext {}' | |
# .format(scrNo, rQName, trCode, prevNext)) | |
if ( trCode == 'opw00018' ): | |
# κ²μ’ μ 보 μμ² rQName μ κ³μ’λ²νΈμ | |
if( self.makeOpw00018Info(rQName) ): | |
# μ°μ λ°μ΄ν° μ‘΄μ¬ νλ κ²½μ° μ¬ μ‘°ν | |
if( prevNext == "2" ) : | |
self.requestOpw00018(self.account_list[0], prevNext) | |
else: | |
QTimer.singleShot(TR_TIME_LIMIT_MS, self.sigRequestJangoComplete) | |
else: | |
self.sigError.emit() | |
pass | |
#μ£Όμ κΈ°λ³Έ μ 보 μμ² rQName μ κ°λ³ μ’ λͺ© μ½λμ | |
elif( trCode == "opt10001"): | |
if( self.makeOpt10001Info(rQName) ): | |
QTimer.singleShot(TR_TIME_LIMIT_MS, self.sigRequestEtcInfo) | |
else: | |
self.sigError.emit() | |
pass | |
#μ£Όμ μΌλ΄ μ 보 μμ² rqName μ κ°λ³ μ’ λͺ© μ½λμ | |
elif( trCode =='opt10081'): | |
if( self.makeOpt10081Info(rQName) ): | |
QTimer.singleShot(TR_TIME_LIMIT_MS, self.sigRequestEtcInfo) | |
self.makeJangoInfoFile() | |
pass | |
else: | |
self.sigError.emit() | |
# μ£Όμ λΆλ΄ μ 보 μμ² rQName κ°λ³ μ’ λͺ© μ½λ | |
elif( trCode == "opt10080"): | |
if( self.makeOpt10080Info(rQName) ) : | |
QTimer.singleShot(TR_TIME_LIMIT_MS, self.sigDetermineBuy ) | |
else: | |
self.sigError.emit() | |
pass | |
# μ μ’ λΆλ΄ rQName μ μ’ μ½λ | |
elif( trCode == "opt20005"): | |
if( self.makeOpt20005Info(rQName) ) : | |
QTimer.singleShot(TR_TIME_LIMIT_MS, self.sigRequestEtcInfo) | |
pass | |
else: | |
self.sigError.emit() | |
pass | |
# μ€μκ° μμΈ μ΄λ²€νΈ | |
def _OnReceiveRealData(self, jongmok_code, realType, realData): | |
# print(util.whoami() + 'jongmok_code: {}, {}, realType: {}' | |
# .format(jongmok_code, self.getMasterCodeName(jongmok_code), realType)) | |
# μ₯μ μλ μ£Όμ νΈκ° μλ κ°μ΄ μ¬μ μμΌλ―λ‘ μ μν΄μΌν¨ | |
if( realType == "μ£ΌμνΈκ°μλ"): | |
# print(util.whoami() + 'jongmok_code: {}, realType: {}, realData: {}' | |
# .format(jongmok_code, realType, realData)) | |
self.makeHogaJanRyangInfo(jongmok_code) | |
#μ£Όμ 체결λ‘λ μ¬κ³ νκΈ°μλ λ°μμ΄ λ무 λλ¦Ό | |
elif( realType == "μ£Όμ체결"): | |
# print(util.whoami() + 'jongmok_code: {}, realType: {}, realData: {}' | |
# .format(jongmok_code, realType, realData)) | |
self.makeBasicInfo(jongmok_code) | |
# WARNING: μ₯μ€μ κΈλ±μΌλ‘ κ±°λ μ μ§ λμ΄ λμ νΈκ°μ§νλλ κ²½μ°μ λλΉνμ¬ μ²΄κ²°κ° μ 보 λ°μνμλλ§ stoploss μ§νν¨. | |
self.processStopLoss(jongmok_code) | |
pass | |
elif( realType == "μ£ΌμμμΈ"): | |
# μ₯μ’ λ£ νμ λμ΄ | |
# print(util.whoami() + 'jongmok_code: {}, realType: {}, realData: {}' | |
# .format(jongmok_code, realType, realData)) | |
pass | |
elif( realType == "μ μ’ μ§μ" ): | |
# print(util.whoami() + 'jongmok_code: {}, realType: {}, realData: {}' | |
# .format(jongmok_code, realType, realData)) | |
result = '' | |
for col_name in kw_util.dict_jusik['μ€μκ°-μ μ’ μ§μ']: | |
result = self.getCommRealData(jongmok_code, kw_util.name_fid[col_name] ) | |
if( jongmok_code == '001'): | |
self.yupjongInfo['μ½μ€νΌ'][col_name] = result.strip() | |
elif( jongmok_code == '100'): | |
self.yupjongInfo['μ½μ€λ₯'][col_name] = result.strip() | |
pass | |
elif( realType == 'μ₯μμμκ°'): | |
# TODO: μ₯μμ 30λΆμ λΆν° μ€μκ° μ λ³΄κ° μ¬λΌμ€λλ° μ΄λ₯Ό ν λλ‘ κ°λ³μ μΌλ‘ μ₯μμμκ°μ κ°λ ν μ μλλ‘ κΈ°λ₯ μΆκ° νμ | |
# μ₯μ΄μꡬλΆ(0:μ₯μμμ , 2:μ₯μ’ λ£μ , 3:μ₯μμ, 4,8:μ₯μ’ λ£, 9:μ₯λ§κ°) | |
# λμνΈκ° μκ°μ 맀μ μ£Όλ¬Έ | |
result = self.getCommRealData(realType, kw_util.name_fid['μ₯μ΄μꡬλΆ'] ) | |
if( result == '2'): | |
self.sigTerminating.emit() | |
elif( result == '4' ): # μ₯μ’ λ£ ν 5λΆλ€μ νλ‘κ·Έλ¨ μ’ λ£ νκ² ν¨ | |
QTimer.singleShot(300000, self.sigStockComplete) | |
# print(util.whoami() + 'jongmok_code: {}, realType: {}, realData: {}' | |
# .format(jongmok_code, realType, realData)) | |
print(util.whoami() + 'jongmok_code: {}, realType: {}, realData: {}' | |
.format(jongmok_code, realType, realData)) | |
pass | |
def calculateSuik(self, jongmok_code, current_price): | |
current_jango = self.jangoInfo[jongmok_code] | |
maeip_price = abs(int(current_jango['맀μ κ°'])) | |
boyou_suryang = int(current_jango['보μ μλ']) | |
maeip_danga = maeip_price + maeip_price* 0.00015 | |
maedo_danga = current_price - current_price * 0.00015 - current_price * 0.0025 | |
suik_price = round( (maedo_danga - maeip_danga) * boyou_suryang , 2) | |
current_jango['μμ΅'] = suik_price | |
current_jango['μμ΅μ¨'] = round( ( (maedo_danga - maeip_danga) / maeip_danga ) * 100 , 2) | |
pass | |
# μ€μκ° νΈκ° μλ μ 보 | |
def makeHogaJanRyangInfo(self, jongmok_code): | |
#μ£Όμ νΈκ° μλ μ 보 μμ² | |
result = None | |
for col_name in kw_util.dict_jusik['μ€μκ°-μ£ΌμνΈκ°μλ']: | |
result = self.getCommRealData(jongmok_code, kw_util.name_fid[col_name] ) | |
if( jongmok_code in self.jangoInfo ): | |
self.jangoInfo[jongmok_code][col_name] = result.strip() | |
if( jongmok_code in self.getCodeListConditionOccurList() ): | |
self.setHogaConditionOccurList(jongmok_code, col_name, result.strip() ) | |
pass | |
# μ€μκ° μ²΄κ²°(κΈ°λ³Έ) μ 보 | |
def makeBasicInfo(self, jongmok_code): | |
#μ£Όμ νΈκ° μλ μ 보 μμ² | |
result = None | |
for col_name in kw_util.dict_jusik['μ€μκ°-μ£Όμ체결']: | |
result = self.getCommRealData(jongmok_code, kw_util.name_fid[col_name] ) | |
if( jongmok_code in self.jangoInfo ): | |
self.jangoInfo[jongmok_code][col_name] = result.strip() | |
if( jongmok_code in self.getCodeListConditionOccurList() ): | |
self.setHogaConditionOccurList(jongmok_code, col_name, result.strip() ) | |
pass | |
def isMinCandleExist(self, current_jango): | |
key_minute_candle = '{}λΆ{}λ΄'.format(REQUEST_MINUTE_CANDLE_TYPE, MAX_SAVE_CANDLE_COUNT) | |
if( key_minute_candle in current_jango | |
and len( current_jango[key_minute_candle] ) == MAX_SAVE_CANDLE_COUNT ): # λΆλ΄ μ 보 μ»μλμ§ νμΈ | |
return True | |
else: | |
return False | |
def isDayCandleExist(self, current_jango): | |
key_day_candle = 'μΌ{}λ΄'.format(MAX_SAVE_CANDLE_COUNT ) | |
if( key_day_candle in current_jango | |
# and len( current_jango[key_day_candle] ) == MAX_SAVE_CANDLE_COUNT | |
): # λΆλ΄ μ 보 μ»μλμ§ νμΈ | |
return True | |
else: | |
return False | |
def processStopLoss(self, jongmok_code): | |
jongmok_name = self.getMasterCodeName(jongmok_code) | |
if( self.isTradeAvailable() == False ): | |
print('-1', end = '') | |
return | |
# μμΈ μ²λ¦¬ 리μ€νΈμ΄λ©΄ μ’ λ£ | |
if( jongmok_code in EXCEPTION_LIST ): | |
# print('-2', end = '') | |
return | |
# μκ³ μ μλ μ’ λͺ©μ΄λ©΄ μ’ λ£ | |
if( jongmok_code not in self.jangoInfo ): | |
# print('-3', end = '') | |
return | |
current_jango = self.jangoInfo[jongmok_code] | |
key_day_candle = 'μΌ{}λ΄'.format(MAX_SAVE_CANDLE_COUNT ) | |
key_minute_candle = '{}λΆ{}λ΄'.format(REQUEST_MINUTE_CANDLE_TYPE, MAX_SAVE_CANDLE_COUNT) | |
first_bunhal_maesu_time_str = current_jango['λΆν 맀μμ΄λ ₯'][0].split(':')[0] #λ μ§:κ°κ²©:μλ | |
first_maeip_price = int(current_jango['λΆν 맀μμ΄λ ₯'][0].split(':')[1]) #λ μ§:κ°κ²©:μλ | |
last_maeip_date_time_str = current_jango['λΆν 맀μμ΄λ ₯'][-1].split(':')[0] #λ μ§:κ°κ²©:μλ | |
last_maeip_price = int(current_jango['λΆν 맀μμ΄λ ₯'][-1].split(':')[1]) #λ μ§:κ°κ²©:μλ | |
if( | |
'μμ κ°' not in current_jango or | |
'맀μνΈκ°1' not in current_jango or | |
'맀맀κ°λ₯μλ' not in current_jango | |
): | |
print('-4', end = '') | |
return | |
jangosuryang = int( current_jango['맀맀κ°λ₯μλ'] ) | |
# νΈκ° μ 보λ λ¬Έμμ΄λ‘ κΈ°μ€κ° λλΉ + , - κ°μ΄ λΆμ΄ λμ΄ | |
maesuHoga1 = abs(int(current_jango['맀μνΈκ°1'])) | |
maesuHogaAmount1 = int(current_jango['맀μνΈκ°μλ1']) | |
maesuHoga2 = abs(int(current_jango['맀μνΈκ°2'])) | |
maesuHogaAmount2 = int(current_jango['맀μνΈκ°μλ2']) | |
maesuHoga3 = abs(int(current_jango['맀μνΈκ°3'])) | |
maesuHogaAmount3 = int(current_jango['맀μνΈκ°μλ3']) | |
stop_plus = int(current_jango['μ΄μ΅μ€νκ°']) | |
stop_loss = int(current_jango['μμ κ°']) | |
maeipga = int(current_jango['맀μ κ°']) | |
# print( util.whoami() + maeuoga1 + " " + maesuHogaAmount1 + " " + maesuHoga2 + " " + maesuHogaAmount2 ) | |
totalAmount = maesuHoga1 * maesuHogaAmount1 + maesuHoga2 * maesuHogaAmount2 + maesuHoga3 * maesuHogaAmount3 | |
# 체결 κ°λ κ³μ° | |
if( "μ΅λ체결κ°λ" not in current_jango ): | |
current_jango['μ΅λ체결κ°λ'] = 0 | |
max_chegyeol_gangdo = int(current_jango['μ΅λ체결κ°λ']) | |
current_chegyeol_gagndo = float(current_jango['체결κ°λ']) | |
# if( max_chegyeol_gang > current_chegyeol_gagndo + 5 ): | |
# if( current_chegyeol_gagndo < 100 ): | |
# stop_loss = 99999999 | |
if( max_chegyeol_gangdo < current_chegyeol_gagndo ): | |
current_jango['μ΅λ체결κ°λ'] = current_chegyeol_gagndo | |
_today_open_price = current_jango.get('μκ°', None) | |
_today_high_price = current_jango.get('κ³ κ°', None) | |
_today_amount = current_jango.get('κ±°λλ', None) | |
######################################################################################## | |
# μΌλ΄ μ°μ° | |
# 1 λ΄μ΄ μ§μ λ΄μ΄λ―λ‘ νμ¬κ°λ₯Ό ν¬ν¨ν νκ· κ°λ₯Ό κ΅¬ν¨ | |
# if( self.isDayCandleExist(current_jango) == True ): # μΌλ΄ μ 보 μ»μλμ§ νμΈ | |
# current_price_index = kw_util.dict_jusik['TR:μΌλ΄'].index('νμ¬κ°') | |
# low_price_index = kw_util.dict_jusik['TR:μΌλ΄'].index('μ κ°') | |
# _4day_list = current_jango[key_day_candle][1:5] | |
# _9day_list = current_jango[key_day_candle][1:10] | |
# _19day_list = current_jango[key_day_candle][1:20] | |
# _5day_avr = ( sum(_4day_list) + maesuHoga1) / 5 | |
# _10day_avr = ( sum(_9day_list) + maesuHoga1) / 10 | |
# _20day_avr = ( sum(_19day_list) + maesuHoga1) / 20 | |
# pass | |
######################################################################################## | |
# λΆλ΄ μ°μ° | |
# 1 λ΄μ΄ μ§μ λ΄μ΄λ―λ‘ νμ¬κ°λ₯Ό ν¬ν¨ν νκ· κ°λ₯Ό κ΅¬ν¨ | |
min_current_price_index = kw_util.dict_jusik['TR:λΆλ΄'].index('νμ¬κ°') | |
min_close_price_index = kw_util.dict_jusik['TR:λΆλ΄'].index('νμ¬κ°') | |
min_low_price_index = kw_util.dict_jusik['TR:λΆλ΄'].index('μ κ°') | |
min_high_price_index = kw_util.dict_jusik['TR:λΆλ΄'].index('κ³ κ°') | |
min_open_price_index = kw_util.dict_jusik['TR:λΆλ΄'].index('μκ°') | |
min_amout_index = kw_util.dict_jusik['TR:λΆλ΄'].index('κ±°λλ') | |
time_index = kw_util.dict_jusik['TR:λΆλ΄'].index('체결μκ°') | |
updown_percentage = float(current_jango['λ±λ½μ¨']) | |
time_span = datetime.timedelta(days = 1) | |
expected_date = (self.currentTime - time_span).date() | |
_yesterday_open_price = 0 | |
_yesterday_close_price = 0 | |
_yesterday_low_price = 0 | |
_yesterday_amount = 0 | |
if( self.isMinCandleExist(current_jango) == True ): # λΆλ΄ μ 보 μ»μλμ§ νμΈ | |
_4min_list = current_jango[key_minute_candle][1:5] | |
_9min_list = current_jango[key_minute_candle][1:10] | |
_19min_list = current_jango[key_minute_candle][1:20] | |
_59min_list = current_jango[key_minute_candle][1:60] | |
_5min_avr = ( sum([ item[min_current_price_index] for item in _4min_list]) + maesuHoga1) / 5 | |
_10min_avr = ( sum([ item[min_current_price_index] for item in _9min_list]) + maesuHoga1) / 10 | |
_20min_avr = ( sum([ item[min_current_price_index] for item in _19min_list]) + maesuHoga1) / 20 | |
_60min_avr = ( sum([ item[min_current_price_index] for item in _59min_list]) + maesuHoga1) / 60 | |
########################################################################################################## | |
# 1μΌμ λΆλ΄ νμΈ | |
_yesterday_min_list = [] | |
for item in current_jango[key_minute_candle]: | |
# 20191104145500 νμ | |
item_date = datetime.datetime.strptime(item[time_index], '%Y%m%d%H%M%S').date() | |
# print(item_date) | |
# νΉμ λ΄λ§ ν¬ν¨ | |
# 곡ν΄μΌ μ£Όλ§ λΌλ κ²½μ°λ₯Ό λλΉν΄ μ΅κ·Ό item_date κΈ°μ€μΌλ‘ μΌμ | |
if( len( _yesterday_min_list) == 0 and item_date <= expected_date ): | |
expected_date = item_date | |
if( item_date == expected_date) : | |
_yesterday_min_list.append(item) | |
# 1μΌμ μ΅κ³ κ° κ³μ° | |
# _yesterday_high_price = max([ item[high_price_index] for item in _yesterday_min_list], default = 99999999 ) | |
# 1μΌμ μμκ° κ³μ° | |
if( len(_yesterday_min_list) > 0 ): | |
_yesterday_open_price = _yesterday_min_list[-1][min_open_price_index] | |
_yesterday_close_price = _yesterday_min_list[0][min_close_price_index] | |
_yesterday_low_price = min( [item[min_low_price_index] for item in _yesterday_min_list] ) | |
_yesterday_amount += sum( item[min_amout_index] for item in _yesterday_min_list) | |
first_bunhal_maesu_date_time = datetime.datetime.strptime( first_bunhal_maesu_time_str, '%Y%m%d%H%M%S').date() | |
if( expected_date >= first_bunhal_maesu_date_time): | |
# μ€μ μ’ λͺ© | |
# 1μΌμ λ μ§κ° 첫 맀μ λ μ§λ³΄λ€ ν¬κ±°λ κ°μ κ²½μ° 1μΌμ μ κ°λ‘ | |
stop_loss = _yesterday_low_price | |
# μ€μ μ’ λͺ©μΌλ‘ λΉμΌ λ±λ½μ¨ λ무 λμ κ²½μ° λ§€λ | |
# if( updown_percentage > 20 ): | |
# stop_loss = 99999999 | |
# pass | |
# stop_plus = 99999999 | |
# μλ΄μ κ±°λλμ΄ λ§μ΄λμ€λ©΄ μμ | |
# if( _today_amount < _yesterday_amount | |
# and _today_open_price < maesuHoga1 ): | |
# stop_loss = 99999999 | |
if( self.current_condition_name == "μ₯νλ°"): | |
pass | |
else: | |
# λΉμΌ 맀μ μ’ λͺ© | |
########################################################################################################## | |
last_bunhal_maesu_date_time = datetime.datetime.strptime(last_maeip_date_time_str, "%Y%m%d%H%M%S") | |
time_span = datetime.timedelta( minutes = 6 ) | |
stop_plus = 9999999 | |
# 맀μ νμ§ ? λΆμ΄ μ§λκ³ μμ΅μ΄ λμ§ μμΌλ©΄ μμ | |
# if( | |
# last_bunhal_maesu_date_time + time_span < self.currentTime | |
# and maesuHoga1 < maeipga | |
# ) : | |
# stop_loss = 999999999 | |
# if( self.current_condition_name == 'μ₯μ΄λ°'): | |
# if( maesuHoga1 > maeipga * 1.033 ): | |
# stop_plus = 0 | |
# if( maesuHoga1 < maeipga * 0.97 ): | |
# stop_loss = 99999999 | |
# if( self.current_condition_name == 'ν΄μ'): | |
# stop_loss = 99999999 | |
# pass | |
if( self.isMinCandleExist(current_jango) == True ): # λΆλ΄ μ 보 μ»μλμ§ νμΈ | |
last_min_open_price = current_jango[key_minute_candle][1][min_open_price_index] | |
last_min_low_price = current_jango[key_minute_candle][1][min_low_price_index] | |
last_min_high_price = current_jango[key_minute_candle][1][min_high_price_index] | |
last_min_close_price = current_jango[key_minute_candle][1][min_current_price_index] | |
# timecut μκ° μ΄ν μ§μ 1λ΄ μ κ° νΈλ μΌλ§ μ€ν | |
# if( | |
# last_bunhal_maesu_date_time + time_span < self.currentTime | |
# and maesuHoga1 < last_min_low_price ): | |
# if( maesuHoga1 < maeipga ): | |
# stop_loss = 99999999 | |
# else: | |
# stop_plus = 0 | |
######################################################################################## | |
isSell = False | |
printData = jongmok_code + ' {0:20} '.format(jongmok_name) | |
# μμ / μ΅μ κ³μ° | |
# μ 리λ, μμ μ κ²½μ° μμ₯κ°λ‘ νκ³ μ΅μ μ κ²½μ° λ³΄ν΅κ°λ‘ ν | |
isSijanga = False | |
maedo_type = '' | |
sell_amount = 0 | |
sell_amount = jangosuryang | |
if( stop_loss == 0 ): | |
maedo_type = "(μκ³ μ€λ₯)" | |
printData += maedo_type | |
isSijanga = False | |
isSell = False | |
elif ( stop_loss == 88888888 ): | |
maedo_type = "(λΆν 맀λ)" | |
printData += maedo_type | |
isSijanga = False | |
isSell = True | |
if( jangosuryang > 1 ): | |
sell_amount = jangosuryang / 2 | |
chegyeol_info = util.cur_date_time('%Y%m%d%H%M%S') + ":" + str(maesuHoga2) + ":" + str(sell_amount) | |
current_jango['λΆν 맀λμ΄λ ₯'] = chegyeol_info | |
# 20180410150510 νμ€μ°λ°μ΄μ€ μ€μκ° λ§€μ νΈκ°κ° 0μΌλ‘ λμ€λ κ²½μ° μμ | |
elif( stop_loss >= maesuHoga1 and maesuHoga1 > 0 ) : | |
maedo_type = "(μμ μ΄λ€)" | |
printData += maedo_type | |
isSijanga = True | |
isSell = True | |
elif( stop_plus < maesuHoga1 ) : | |
if( totalAmount >= TOTAL_BUY_AMOUNT): | |
maedo_type = "(μ΅μ μ΄λ€)" | |
printData += maedo_type | |
isSell = True | |
else: | |
maedo_type = "(μ΅μ λ―Έλ¬)" | |
printData += maedo_type | |
isSell = True | |
printData += ' μμ κ°: {0:7}/'.format(str(stop_loss)) + \ | |
' μ΄μ΅μ€νκ°: {0:7}/'.format(str(stop_plus)) + \ | |
' 맀μ κ°: {0:7}/'.format(str(maeipga)) + \ | |
' μκ³ μλ: {0:7}'.format(str(jangosuryang)) +\ | |
' 맀μνΈκ°1 {0:7}/'.format(str(maesuHoga1)) + \ | |
' 맀μνΈκ°μλ1 {0:7}/'.format(str(maesuHogaAmount1)) + \ | |
' 맀μνΈκ°2 {0:7}/'.format(str(maesuHoga2)) + \ | |
' 맀μνΈκ°μλ2 {0:7}/'.format(str(maesuHogaAmount2)) | |
# if( isSell == True ): | |
# # processStop μ κ²½μ° μ²΄κ²°λ λλ§λ€ νΈμΆλλ―λ‘ μ€λ³΅ μ£Όλ¬Έμ΄ λκ°μ§ μκ² ν¨ | |
# if( '맀λμ€' not in current_jango): | |
# current_jango['맀λμ€'] = maedo_type | |
# if( isSijanga == True ): | |
# result = self.sendOrder("sell_" + jongmok_code, kw_util.sendOrderScreenNo, objKiwoom.account_list[0], kw_util.dict_order["μ κ·λ§€λ"], | |
# jongmok_code, sell_amount, 0 , kw_util.dict_order["μμ₯κ°"], "") | |
# else: | |
# result = self.sendOrder("sell_" + jongmok_code, kw_util.sendOrderScreenNo, objKiwoom.account_list[0], kw_util.dict_order["μ κ·λ§€λ"], | |
# jongmok_code, sell_amount, maesuHoga2 , kw_util.dict_order["μ§μ κ°"], "") | |
# util.save_log(printData, '맀λ', 'log') | |
# print("S " + jongmok_code + ' ' + str(result), sep= "") | |
# pass | |
# pass | |
# 체결λ°μ΄ν°λ₯Ό λ°μ μμ μ μλ €μ€λ€. | |
# sGubun β 0:주문체결ν΅λ³΄, 1:μκ³ ν΅λ³΄, 3:νΉμ΄μ νΈ | |
# sFidList β λ°μ΄ν° ꡬλΆμ β;β μ΄λ€. | |
''' | |
_OnReceiveChejanData gubun: 1, itemCnt: 27, fidList: 9201;9001;917;916;302;10;930;931;932;933;945;946;950;951;27;28;307;8019;957;958;918;990;991;992;993;959;924 | |
{'μ’ λͺ©μ½λ': 'A010050', 'λΉμΌμ€νμμ΅λ₯ (μ κ°)': '0.00', 'λμΆμΌ': '00000000', 'λΉμΌμ€νμμ΅λ₯ (μ μ©)': '0.00', '(μ΅μ°μ )맀μνΈκ°': '+805', 'λΉμΌμ맀μμλ': '5', 'μ΄λ§€μ κ°': '4043', | |
'λΉμΌμ΄λ§€λμμΌ': '0', 'λ§κΈ°μΌ': '00000000', 'μ μ©κΈμ‘': '0', 'λΉμΌμ€νμμ΅(μ μ©)': '0', 'νμ¬κ°': '+806', 'κΈ°μ€κ°': '802', 'κ³μ’λ²νΈ': ', '보μ μλ': '5', | |
'μμκΈ': '0', 'μ£Όλ¬Έκ°λ₯μλ': '5', 'μ’ λͺ©λͺ ': 'μ°λ¦¬μ’ κΈ ', 'μμ΅μ¨': '0.00', 'λΉμΌμ€νμμ΅(μ κ°)': '0', 'λ΄λ³΄λμΆμλ': '0', '924': '0', | |
'맀μ λ¨κ°': '809', 'μ μ©κ΅¬λΆ': '00', '맀λ/맀μꡬλΆ': '2', '(μ΅μ°μ )맀λνΈκ°': '+806', 'μ μ©μ΄μ': '0'} | |
''' | |
def _OnReceiveChejanData(self, gubun, itemCnt, fidList): | |
# print(util.whoami() + 'gubun: {}, itemCnt: {}, fidList: {}' | |
# .format(gubun, itemCnt, fidList)) | |
if( gubun == "1"): # μκ³ μ 보 | |
# μκ³ μ 보μμλ 맀λ/맀μ ꡬλΆμ΄ λμ§ μμ | |
jongmok_code = self.getChejanData(kw_util.name_fid['μ’ λͺ©μ½λ'])[1:] | |
boyou_suryang = int(self.getChejanData(kw_util.name_fid['보μ μλ'])) | |
jumun_ganeung_suryang = int(self.getChejanData(kw_util.name_fid['μ£Όλ¬Έκ°λ₯μλ'])) | |
maeip_danga = int(self.getChejanData(kw_util.name_fid['맀μ λ¨κ°'])) | |
jongmok_name= self.getChejanData(kw_util.name_fid['μ’ λͺ©λͺ ']).strip() | |
current_price = abs(int(self.getChejanData(kw_util.name_fid['νμ¬κ°']))) | |
current_amount = abs(int(self.getChejanData(kw_util.name_fid['λΉμΌμ맀μμλ']))) | |
#미체결 μλμ΄ μλ κ²½μ° μκ³ μ 보 μ μ₯νμ§ μλλ‘ ν¨ | |
if( jongmok_code in self.michegyeolInfo): | |
if( self.michegyeolInfo[jongmok_code]['미체결μλ'] ): | |
return | |
else: | |
# 미체결 μλμ΄ μμΌλ―λ‘ μ 보 μμ | |
del ( self.michegyeolInfo[jongmok_code] ) | |
if( boyou_suryang == 0 ): | |
# 보μ μλμ΄ 0 μΈ κ²½μ° λ§€λ μνν κ²μ | |
self.jangoInfo.pop(jongmok_code) | |
self.removeConditionOccurList(jongmok_code) | |
else: | |
# 보μ μλμ΄ λμλ€λ κ²μ 맀μμννμΌλ©° μ΄μ TR μμ²μ λν λκΈ° μκ° νμ | |
self.sigWaitTr.emit() | |
# QTimer.singleShot(TR_TIME_LIMIT_MS, self.sigWaitTr) | |
# μλ μκ³ μ 보μ κ²½μ° TR:κ³μ’νκ°μκ³ λ΄μμμ² νλμ μΌμΉνκ² λ§λ€μ΄μΌ ν¨ | |
current_jango = {} | |
current_jango['보μ μλ'] = boyou_suryang | |
current_jango['맀맀κ°λ₯μλ'] = jumun_ganeung_suryang # TR μκ³ μμ 맀맀κ°λ₯ μλ μ΄λ μ΄λ¦μΌλ‘ μ¬μ©λλ―λ‘ | |
current_jango['맀μ κ°'] = maeip_danga | |
current_jango['μ’ λͺ©λ²νΈ'] = jongmok_code | |
current_jango['μ’ λͺ©λͺ '] = jongmok_name.strip() | |
current_jango['μ μ’ '] = self.getMasterStockInfo(jongmok_code) | |
chegyeol_info = util.cur_date_time('%Y%m%d%H%M%S') + ":" + str(current_price) + ":" + str(current_amount) | |
if( jongmok_code not in self.jangoInfo): | |
current_jango['λΆν 맀μμ΄λ ₯'] = [chegyeol_info] | |
self.jangoInfo[jongmok_code] = current_jango | |
else: | |
# 맀μκ° λΆν λ‘ λλ κ²½μ°μλ λΆν 맀μ μ΄λ ₯ μΆκ° μν¨ | |
last_chegyeol_info = self.jangoInfo[jongmok_code]['λΆν 맀μμ΄λ ₯'][-1] | |
last_price = int(last_chegyeol_info.split(':')[1]) | |
if( last_price != current_price ): | |
chegyeol_info_list = self.jangoInfo[jongmok_code]['λΆν 맀μμ΄λ ₯'] | |
chegyeol_info_list.append( chegyeol_info ) | |
current_jango['λΆν 맀μμ΄λ ₯'] = chegyeol_info_list | |
self.jangoInfo[jongmok_code].update(current_jango) | |
self.makeJangoInfoFile() | |
pass | |
elif ( gubun == "0"): | |
jumun_sangtae = self.getChejanData(kw_util.name_fid['μ£Όλ¬Έμν']) | |
jongmok_code = self.getChejanData(kw_util.name_fid['μ’ λͺ©μ½λ'])[1:] | |
michegyeol_suryang = int(self.getChejanData(kw_util.name_fid['미체결μλ'])) | |
# μ£Όλ¬Έ μν | |
# 맀μ μ μ μ(gubun-0) - 체결(gubun-0) - μκ³ (gubun-1) | |
# 맀λ μ μ μ(gubun-0) - μκ³ (gubun-1) - 체결(gubun-0) - μκ³ (gubun-1) μμ | |
# 미체결 μλ μ 보λ₯Ό μ λ ₯νμ¬ μκ³ μ 보 μ²λ¦¬μ 미체결 μλ μλ κ²½μ°μ λν μ²λ¦¬λ₯Ό νλλ‘ ν¨ | |
if( jongmok_code not in self.michegyeolInfo): | |
self.michegyeolInfo[jongmok_code] = {} | |
self.michegyeolInfo[jongmok_code]['미체결μλ'] = michegyeol_suryang | |
if( jumun_sangtae == "체결"): | |
self.makeChegyeolInfo(jongmok_code, fidList) | |
self.makeChegyeolInfoFile() | |
pass | |
pass | |
def makeChegyeolInfoFile(self): | |
# print(util.whoami()) | |
with open(CHEGYEOL_INFO_FILE_PATH, 'w', encoding = 'utf8' ) as f: | |
f.write(json.dumps(self.chegyeolInfo, ensure_ascii= False, indent= 2, sort_keys = True )) | |
pass | |
# μλ²μμ μ»μ μ μλ μΆκ° μ 보 μ μ₯ | |
# 첫 μκ³ μ 보 μμ²μ νΈμΆλ¨ | |
# 맀μ, 맀λν 체결 μ λ³΄λ‘ μκ³ μ 보 μ¬λ νΈμΆλ¨ | |
def makeEtcJangoInfo(self, jongmok_code): | |
if( jongmok_code not in self.jangoInfo): | |
return | |
current_jango = self.jangoInfo[jongmok_code] | |
# λΆν 맀μ μ΄λ ₯ λ°μ΄ν° νμΌλ‘λΆν° μ½μ΄μ€κ³ νμΌλ‘λΆν°λ μμΌλ©΄ default κ° μ λ ₯ | |
if( 'λΆν 맀μμ΄λ ₯' not in current_jango ): | |
current_jango['λΆν 맀μμ΄λ ₯'] = ['29991212091234:2:1'] | |
if( jongmok_code in self.jangoInfoFromFile): | |
if( 'λΆν 맀μμ΄λ ₯' in self.jangoInfoFromFile[jongmok_code] ): | |
current_jango['λΆν 맀μμ΄λ ₯'] = self.jangoInfoFromFile[jongmok_code].get('λΆν 맀μμ΄λ ₯', []) | |
# μ΄ λ§€μ κ°―μ κ²μ° | |
bunhal_maesu_list = current_jango['λΆν 맀μμ΄λ ₯'] | |
maesu_count = len(bunhal_maesu_list) | |
# μμ /μ΅μ κ° νΌμΌν°μ§ κ³μ° | |
stop_loss_percent = STOP_LOSS_PER_MAESU_COUNT[maesu_count -1] | |
stop_plus_percent = STOP_PLUS_PER_MAESU_COUNT[maesu_count -1] | |
maeip_price = current_jango['맀μ κ°'] | |
last_chegyeol_info = bunhal_maesu_list[-1] | |
last_maeip_price = int(last_chegyeol_info.split(':')[1]) #λ μ§:κ°κ²©:μλ | |
last_maeip_time = last_chegyeol_info.split(':')[0] | |
if( last_maeip_price == 0 ): | |
# λΆν 맀μ μ 보 λλ½λμ΄ κΈ°λ³ΈμΌλ‘ μΈν μλ₯Ό μν λλΉ | |
last_maeip_price = 99999999 | |
# κΈ°λ³Έ μμ κ° μΈ‘μ | |
gibon_stoploss = round( maeip_price * (1 + (stop_loss_percent + SLIPPAGE) / 100) , 2 ) | |
print("μ’ λͺ©μ΄λ¦:{}, κΈ°λ³Έμμ :{}".format(self.getMasterCodeName(jongmok_code), gibon_stoploss)) | |
############################################################################################### | |
current_jango['μμ κ°'] = gibon_stoploss | |
current_jango['μ΄μ΅μ€νκ°'] = round( maeip_price * (1 + ((stop_plus_percent + SLIPPAGE)/100) ) , 2) | |
# ? μΌ λμ μΆκ° 맀μ κΈμ§ μ‘°μΉ | |
base_time = datetime.datetime.strptime(last_maeip_time, '%Y%m%d%H%M%S') | |
# μΌκΈ°μ€μΌλ‘λ§ νκΈ° μν΄ μλΆμ΄ μ 보 μ κ±° | |
from_date = copy.deepcopy(base_time) | |
target_date = util.date_by_adding_business_days(from_date, BUNHAL_MAESU_PROHIBIT_DAYS ) | |
saved_date = datetime.date(year = target_date.year,month = target_date.month, day = target_date.day) | |
current_date = datetime.date(year = self.currentTime.year, month = self.currentTime.month, day = self.currentTime.day ) | |
if( saved_date > current_date): | |
if( jongmok_code not in self.prohibitCodeList): | |
self.prohibitCodeList.append(jongmok_code) | |
self.jangoInfo[jongmok_code].update(current_jango) | |
pass | |
@pyqtSlot() | |
def makeJangoInfoFile(self): | |
print(util.whoami()) | |
# κΈ°ν μ 보 μ λ°μ΄νΈ | |
for jongmok_code in self.jangoInfo.keys(): | |
self.makeEtcJangoInfo(jongmok_code) | |
temp = copy.deepcopy(self.jangoInfo) | |
# λΆνμ νλ μ κ±° | |
for jongmok_code, contents in temp.items(): | |
for key in self.jango_remove_keys: | |
if( key in contents): | |
del contents[key] | |
with open(JANGO_INFO_FILE_PATH, 'w', encoding = 'utf8' ) as f: | |
f.write(json.dumps(temp, ensure_ascii= False, indent= 2, sort_keys = True )) | |
pass | |
# self.makeInterestedStocksFile() | |
@pyqtSlot() | |
def makeInterestedStocksFile(self): | |
print(util.whoami()) | |
temp = copy.deepcopy(self.conditionOccurList) | |
# λΆνμ νλ μ κ±° | |
# condition list | |
for item in temp: | |
for key in self.jango_remove_keys: | |
if( key in item): | |
del item[key] | |
with open(INTERESTED_STOCKS_FILE_PATH, 'w', encoding = 'utf8' ) as f: | |
f.write(json.dumps(temp, ensure_ascii= False, indent= 2, sort_keys = True )) | |
pass | |
def makeChegyeolInfo(self, jongmok_code, fidList): | |
fids = fidList.split(";") | |
printData = "" | |
info = [] | |
# 미체결 μλμ΄ 0 μ΄ μλ κ²½μ° λ€μ 체결 μ λ³΄κ° μ¬λΌ μ€λ―λ‘ 0μΈκ²½μ° μ²λ¦¬ μν¨ | |
michegyeol_suryung = int(self.getChejanData(kw_util.name_fid['미체결μλ']).strip()) | |
if( michegyeol_suryung != 0 ): | |
return | |
nFid = kw_util.name_fid['맀λ맀μꡬλΆ'] | |
result = self.getChejanData(nFid).strip() | |
maedo_maesu_gubun = '맀λ' if result == '1' else '맀μ' | |
# 첫 맀μμλ μκ³ μ λ³΄κ° μμ μ μμΌλ―λ‘ | |
current_jango = self.jangoInfo.get(jongmok_code, {}) | |
bunhal_maesu_list = current_jango.get('λΆν 맀μμ΄λ ₯', []) | |
################################################################################################# | |
# μ¬μ©μ μ μ μ»¬λΌ μμ΅κ³Ό μμ΅μ¨ νλ μ±μ | |
if( maedo_maesu_gubun == '맀λ'): | |
# 체결κ°λ₯Ό ν΅ν΄ μμ΅μ¨ νλ μ λ°μ΄νΈ | |
current_price = int(self.getChejanData(kw_util.name_fid['체결κ°']).strip()) | |
self.calculateSuik(jongmok_code, current_price) | |
# 맀λμ 체결μ 보λ μμ΅μ¨ νλκ° μ‘΄μ¬ | |
profit = current_jango.get('μμ΅', '0') | |
profit_percent = current_jango.get('μμ΅μ¨', '0' ) | |
maesu_count = len(bunhal_maesu_list) | |
maedo_type = current_jango.get('맀λμ€', '') | |
if( maedo_type == ''): | |
maedo_type = '(μλ맀λ)' | |
info.append('{0:>10}'.format(profit_percent)) | |
info.append('{0:>10}'.format(profit)) | |
info.append(' 맀μνμ: {0:>1} '.format(maesu_count)) | |
info.append(' {0} '.format(maedo_type)) | |
pass | |
elif( maedo_maesu_gubun == '맀μ') : | |
# 맀μμ 체결μ 보λ μμ΅μ¨ / μμ΅ νλκ° | |
info.append('{0:>10}'.format('0')) | |
info.append('{0:>10}'.format('0')) | |
# 체결μλ 맀μ νμ μ λ³΄κ° μ λ°μ΄νΈ λμ§ μμκΈ° λλ¬Έμ +1 ν΄μ€ | |
# 첫맀μμ λν μ²λ¦¬λ ν¨ | |
maesu_count = len(bunhal_maesu_list) | |
info.append(' 맀μνμ: {0:>1} '.format(maesu_count + 1)) | |
info.append(' {0} '.format('(λ¨μ맀μ)')) | |
################################################################################################# | |
# kiwoom api 체결 μ 보 νλ | |
for col_name in kw_util.dict_jusik["체결μ 보"]: | |
nFid = None | |
result = "" | |
if( col_name not in kw_util.name_fid ): | |
continue | |
nFid = kw_util.name_fid[col_name] | |
if( str(nFid) in fids): | |
result = self.getChejanData(nFid).strip() | |
if( col_name == 'μ’ λͺ©μ½λ'): | |
result = result[1:] | |
if( col_name == '체결κ°' ): | |
result = '{0:>10}'.format(result) | |
if( col_name == '체결λ' or col_name == '미체결μλ'): | |
result = '{0:>7}'.format(result) | |
info.append(' {} '.format(result)) | |
printData += col_name + ": " + result + ", " | |
current_date = self.currentTime.date().strftime('%y%m%d') | |
if( current_date not in self.chegyeolInfo) : | |
self.chegyeolInfo[current_date] = [] | |
################################################################################################# | |
# 맀λμ 맀μ μ΄λ ₯ μ 보 νλ | |
if( maedo_maesu_gubun == '맀λ'): | |
info.append(' | '.join(current_jango['λΆν 맀μμ΄λ ₯'])) | |
pass | |
self.chegyeolInfo[current_date].append('|'.join(info)) | |
util.save_log(printData, "*체결μ 보", folder= "log") | |
pass | |
# λ‘컬μ μ¬μ©μ쑰건μ μ μ₯ μ±κ³΅μ¬λΆ μλ΅ μ΄λ²€νΈ | |
# 0:(μ€ν¨) 1:(μ±κ³΅) | |
def _OnReceiveConditionVer(self, ret, msg): | |
print(util.whoami() + 'ret: {}, msg: {}' | |
.format(ret, msg)) | |
if ret == 1: | |
self.sigGetConditionCplt.emit() | |
# 쑰건κ²μ μ‘°νμλ΅μΌλ‘ μ’ λͺ©λ¦¬μ€νΈλ₯Ό ꡬλΆμ(β;β)λ‘ λΆμ΄μ λ°λ μμ . | |
# LPCTSTR sScrNo : μ’ λͺ©μ½λ | |
# LPCTSTR strCodeList : μ’ λͺ©λ¦¬μ€νΈ(β;βλ‘ κ΅¬λΆ) | |
# LPCTSTR strConditionName : 쑰건λͺ | |
# int nIndex : 쑰건λͺ μΈλ±μ€ | |
# int nNext : μ°μμ‘°ν(2:μ°μμ‘°ν, 0:μ°μμ‘°νμμ) | |
def _OnReceiveTrCondition(self, scrNo, codeList, conditionName, index, next): | |
# print(util.whoami() + 'scrNo: {}, codeList: {}, conditionName: {} ' | |
# 'index: {}, next: {}' | |
# .format(scrNo, codeList, conditionName, index, next )) | |
codes = codeList.split(';')[:-1] | |
# λ§μ§λ§ split κ²°κ³Ό None μ΄λ―λ‘ μμ | |
for code in codes: | |
print('condition occur list add code: {} '.format(code) + self.getMasterCodeName(code)) | |
self.addConditionOccurList(code) | |
# νΈμ , μ΄ν μ’ λͺ©μ΄ μ€μκ°μΌλ‘ λ€μ΄μ΅λλ€. | |
# strCode : μ’ λͺ©μ½λ | |
# strType : νΈμ (βIβ), μ΄ν(βDβ) | |
# streonditionName : 쑰건λͺ | |
# strConditionIndex : 쑰건λͺ μΈλ±μ€ | |
def _OnReceiveRealCondition(self, code, type, conditionName, conditionIndex): | |
print(util.whoami() + 'code: {}, μ’ λͺ©μ΄λ¦: {}, type: {}, conditionName: {}, conditionIndex: {}' | |
.format(code, self.getMasterCodeName(code), type, conditionName, conditionIndex )) | |
if type == 'I': | |
self.addConditionOccurList(code) # 쑰건 λ°μν κ²½μ° ν΄λΉ λ΄μ© list μ μΆκ° | |
else: | |
self.conditionRevemoList.append(code) | |
pass | |
def addConditionOccurList(self, jongmok_code): | |
#λ°μμκ°, μ’ λͺ©μ½λ, μ’ λͺ©λͺ | |
jongmok_name = self.getMasterCodeName(jongmok_code) | |
ret_vals = [] | |
# μ€λ³΅ μ κ±° | |
for item_dict in self.conditionOccurList: | |
if( jongmok_code == item_dict['μ’ λͺ©μ½λ'] ): | |
ret_vals.append(True) | |
if( ret_vals.count(True) ): | |
pass | |
else: | |
self.conditionOccurList.append( {'μ’ λͺ©λͺ ': jongmok_name, 'μ’ λͺ©μ½λ': jongmok_code} ) | |
self.sigConditionOccur.emit() | |
pass | |
def removeConditionOccurList(self, jongmok_code): | |
for item_dict in self.conditionOccurList: | |
if( item_dict['μ’ λͺ©μ½λ'] == jongmok_code ): | |
self.conditionOccurList.remove(item_dict) | |
break | |
pass | |
def getConditionOccurList(self): | |
if( len(self.conditionOccurList ) ): | |
return self.conditionOccurList[0] | |
else: | |
return None | |
pass | |
def getCodeListConditionOccurList(self): | |
items = [] | |
for item_dict in self.conditionOccurList: | |
items.append(item_dict['μ’ λͺ©μ½λ']) | |
return items | |
def setHogaConditionOccurList(self, jongmok_code, col_name, value): | |
for index, item_dict in enumerate(self.conditionOccurList): | |
if( item_dict['μ’ λͺ©μ½λ'] == jongmok_code ): | |
item_dict[col_name] = value | |
# λ€μ codition list λ₯Ό κ°μ νκΈ° μν΄ μ’ λͺ© μκΈ° | |
def shuffleConditionOccurList(self): | |
jongmok_info_dict = self.getConditionOccurList() | |
jongmok_code = jongmok_info_dict['μ’ λͺ©μ½λ'] | |
self.removeConditionOccurList(jongmok_code) | |
self.conditionOccurList.append(jongmok_info_dict) | |
# μ€μκ° μ£Όμ μ 보 μμ² μμ²λ¦¬μ€νΈ κ°±μ | |
# WARNING: μ€μκ° μμ²λ TR μ²λΌ μ΄λΉ νμ μ νμ΄ μμΌλ―λ‘ μ μ¬μ©ν΄μΌν¨ | |
def refreshRealRequest(self): | |
# λ²κ·Έλ‘ λͺ¨λ μ§μ°κ³ μλ‘ λ±λ‘νκ² ν¨ | |
# print(util.whoami() ) | |
self.setRealRemove("ALL", "ALL") | |
codeList = [] | |
# 보μ μκ³ μ€μκ° μ 보 μ»κΈ° μν΄ μΆκ° | |
for code in self.jangoInfo.keys(): | |
if( code not in codeList): | |
codeList.append(code) | |
condition_list = self.getCodeListConditionOccurList() | |
for code in condition_list: | |
if( code not in codeList): | |
codeList.append(code) | |
if( len(codeList) == 0 ): | |
# μ’ λͺ© 미보μ λ‘ μ€μκ° μ²΄κ²° μμ² ν κ² μλ κ²½μ° μ½μ€λ₯ μ½μ€νΌ μ€μκ° μ²΄κ²°κ°κ° μ¬λΌμ€μ§ μμΌλ―λ‘ μμλ‘ νλ λ±λ‘ | |
codeList.append('044180') | |
else: | |
for code in codeList: | |
if ( code not in EXCEPTION_LIST): | |
self.addConditionOccurList(code) | |
# μ€μκ° νΈκ° μ 보 μμ² "0" μ μ΄μ κ±° μ μΈ νκ³ μλ‘ μμ² | |
if( len(codeList) ): | |
# WARNING: μ£Όμ μμΈ μ€μκ°μ 리ν΄λμ§ μμ! | |
# tmp = self.setRealReg(kw_util.sendRealRegSiseSrcNo, ';'.join(codeList), kw_util.type_fidset['μ£ΌμμμΈ'], "0") | |
tmp = self.setRealReg(kw_util.sendRealRegHogaScrNo, ';'.join(codeList), kw_util.type_fidset['μ£ΌμνΈκ°μλ'], "0") | |
tmp = self.setRealReg(kw_util.sendRealRegChegyeolScrNo, ';'.join(codeList), kw_util.type_fidset['μ£Όμ체결'], "0") | |
tmp = self.setRealReg(kw_util.sendRealRegUpjongScrNo, '001;101', kw_util.type_fidset['μ μ’ μ§μ'], "0") | |
def make_excel(self, file_path, data_dict): | |
result = False | |
result = os.path.isfile(file_path) | |
if( result == False): | |
with open( CHEGYEOL_INFO_EXCEL_FILE_PATH, 'w', encoding = 'utf8' ) as f: | |
f.write('') | |
# excel open | |
wb = xw.Book(file_path) | |
sheet_names = [sheet.name for sheet in wb.sheets] | |
insert_sheet_names = [] | |
# print(sheet_names) | |
for key, value in data_dict.items(): | |
# sheet name μ΄ μ‘΄μ¬ μνλ©΄ sheet add | |
sheet_name = key[0:4] | |
if( sheet_name not in sheet_names ): | |
if( sheet_name not in insert_sheet_names ): | |
insert_sheet_names.append(sheet_name) | |
for insert_sheet in insert_sheet_names: | |
wb.sheets.add(name = insert_sheet) | |
# sheet name μ YYMM νμ | |
sheet_names = [sheet.name for sheet in wb.sheets] | |
for sheet_name in sheet_names: | |
# key κ°μ΄ match λλκ²μ μ°Ύμ | |
row_count = 1 | |
excel_row_string = 'A{}' | |
for sorted_key in sorted(data_dict): | |
input_data_sheet_name = sorted_key[0:4] | |
if( input_data_sheet_name == sheet_name ): | |
wb.sheets[sheet_name].activate() | |
xw.Range(excel_row_string.format(row_count)).value = [ sorted_key, '-' * 156 ] | |
row_count += 1 | |
for line in data_dict[sorted_key]: | |
items = [ item.strip() for item in line.split('|') ] | |
# λΉμΉΈ λκ° μΆκ° | |
items.insert(0, '') | |
items.insert(0, '') | |
wb.sheets[sheet_name].activate() | |
xw.Range(excel_row_string.format(row_count)).value = items | |
row_count += 1 | |
# save | |
wb.save() | |
wb.app.quit() | |
# method | |
# λ‘κ·ΈμΈ | |
# 0 - μ±κ³΅, μμκ°μ μ€ν¨ | |
# λ¨μ API νΈμΆμ΄ λμλλ μλμλλλ§ νμΈ κ°λ₯ | |
@pyqtSlot(result=int) | |
def commConnect(self): | |
return self.ocx.dynamicCall("CommConnect()") | |
# λ‘κ·ΈμΈ μν νμΈ | |
# 0:λ―Έμ°κ²°, 1:μ°κ²°μλ£, κ·ΈμΈλ μλ¬ | |
@pyqtSlot(result=int) | |
def getConnectState(self): | |
return self.ocx.dynamicCall("GetConnectState()") | |
# λ‘κ·Έ μμ | |
@pyqtSlot() | |
def commTerminate(self): | |
self.ocx.dynamicCall("CommTerminate()") | |
# λ‘κ·ΈμΈν μ¬μ©μ μ 보λ₯Ό λ°ννλ€. | |
# βACCOUNT_CNTβ β μ 체 κ³μ’ κ°μλ₯Ό λ°ννλ€. | |
# "ACCNO" β μ 체 κ³μ’λ₯Ό λ°ννλ€. κ³μ’λ³ κ΅¬λΆμ β;βμ΄λ€. | |
# βUSER_IDβ - μ¬μ©μ IDλ₯Ό λ°ννλ€. | |
# βUSER_NAMEβ β μ¬μ©μλͺ μ λ°ννλ€. | |
# βKEY_BSECGBβ β ν€λ³΄λ보μ ν΄μ§μ¬λΆ. 0:μ μ, 1:ν΄μ§ | |
# βFIREW_SECGBβ β λ°©νλ²½ μ€μ μ¬λΆ. 0:λ―Έμ€μ , 1:μ€μ , 2:ν΄μ§ | |
@pyqtSlot(str, result=str) | |
def getLoginInfo(self, tag): | |
return self.ocx.dynamicCall("GetLoginInfo(QString)", [tag]) | |
# Tran μ λ ₯ κ°μ μλ²ν΅μ μ μ μ λ ₯κ°μΌ μ μ₯νλ€. | |
@pyqtSlot(str, str) | |
def setInputValue(self, id, value): | |
self.ocx.dynamicCall("SetInputValue(QString, QString)", id, value) | |
@pyqtSlot(str, result=str) | |
def getCodeListByMarket(self, sMarket): | |
return self.ocx.dynamicCall("GetCodeListByMarket(QString)", sMarket) | |
# ν΅μ λ°μ΄ν°λ₯Ό μ‘μ νλ€. | |
# 0μ΄λ©΄ μ μ | |
# OP_ERR_SISE_OVERFLOW β κ³Όλν μμΈμ‘°νλ‘ μΈν ν΅μ λΆκ° | |
# OP_ERR_RQ_STRUCT_FAIL β μ λ ₯ ꡬ쑰체 μμ± μ€ν¨ | |
# OP_ERR_RQ_STRING_FAIL β μμ²μ λ¬Έ μμ± μ€ν¨ | |
# OP_ERR_NONE β μ μμ²λ¦¬ | |
@pyqtSlot(str, str, int, str, result=int) | |
def commRqData(self, rQName, trCode, prevNext, screenNo): | |
return self.ocx.dynamicCall("CommRqData(QString, QString, int, QString)", rQName, trCode, prevNext, screenNo) | |
# μμ λ°μ λ°μ΄ν°μ λ°λ³΅ κ°μλ₯Ό λ°ννλ€. | |
@pyqtSlot(str, str, result=int) | |
def getRepeatCnt(self, trCode, recordName): | |
return self.ocx.dynamicCall("GetRepeatCnt(QString, QString)", trCode, recordName) | |
# Tran λ°μ΄ν°, μ€μκ° λ°μ΄ν°, 체결μκ³ λ°μ΄ν°λ₯Ό λ°ννλ€. | |
# 1. Tran λ°μ΄ν° | |
# 2. μ€μκ° λ°μ΄ν° | |
# 3. 체결 λ°μ΄ν° | |
# 1. Tran λ°μ΄ν° | |
# sJongmokCode : Tranλͺ | |
# sRealType : μ¬μ©μν¨ | |
# sFieldName : λ μ½λλͺ | |
# nIndex : λ°λ³΅μΈλ±μ€ | |
# sInnerFieldName: μμ΄ν λͺ | |
# 2. μ€μκ° λ°μ΄ν° | |
# sJongmokCode : Key Code | |
# sRealType : Real Type | |
# sFieldName : Item Index (FID) | |
# nIndex : μ¬μ©μν¨ | |
# sInnerFieldName:μ¬μ©μν¨ | |
# 3. 체결 λ°μ΄ν° | |
# sJongmokCode : μ²΄κ²°κ΅¬λΆ | |
# sRealType : β-1β | |
# sFieldName : μ¬μ©μν¨ | |
# nIndex : ItemIndex | |
# sInnerFieldName:μ¬μ©μν¨ | |
@pyqtSlot(str, str, str, int, str, result=str) | |
def commGetData(self, jongmok_code, realType, fieldName, index, innerFieldName): | |
return self.ocx.dynamicCall("CommGetData(QString, QString, QString, int, QString)", jongmok_code, realType, fieldName, index, innerFieldName).strip() | |
# strRealType β μ€μκ° κ΅¬λΆ | |
# nFid β μ€μκ° μμ΄ν | |
# Ex) νμ¬κ°μΆλ ₯ - openApi.GetCommRealData(βμ£ΌμμμΈβ, 10); | |
# μ°Έκ³ )μ€μκ° νμ¬κ°λ μ£ΌμμμΈ, μ£Όμ체결 λ± λ€λ₯Έ μ€μκ°νμ (RealType)μΌλ‘λ μμ κ°λ₯ | |
@pyqtSlot(str, int, result=str) | |
def getCommRealData(self, realType, fid): | |
return self.ocx.dynamicCall("GetCommRealData(QString, int)", realType, fid).strip() | |
# μ£Όμ μ£Όλ¬Έμ μλ²λ‘ μ μ‘νλ€. | |
# sRQName - μ¬μ©μ κ΅¬λΆ μμ² λͺ | |
# sScreenNo - νλ©΄λ²νΈ[4] | |
# sAccNo - κ³μ’λ²νΈ[10] | |
# nOrderType - μ£Όλ¬Έμ ν (1:μ κ·λ§€μ, 2:μ κ·λ§€λ, 3:맀μμ·¨μ, 4:맀λμ·¨μ, 5:맀μμ μ , 6:맀λμ μ ) | |
# sCode, - μ£Όμμ’ λͺ©μ½λ | |
# nQty β μ£Όλ¬Έμλ | |
# nPrice β μ£Όλ¬Έλ¨κ° | |
# sHogaGb - κ±°λκ΅¬λΆ | |
# sHogaGb β 00:μ§μ κ°, 03:μμ₯κ°, 05:쑰건λΆμ§μ κ°, 06:μ΅μ 리μ§μ κ°, 07:μ΅μ°μ μ§μ κ°, 10:μ§μ κ°IOC, 13:μμ₯κ°IOC, 16:μ΅μ 리IOC, 20:μ§μ κ°FOK, 23:μμ₯κ°FOK, 26:μ΅μ 리FOK, 61:μ₯μ μκ°μΈμ’ κ°, 62:μκ°μΈλ¨μΌκ°, 81:μ₯νμκ°μΈμ’ κ° | |
# β» μμ₯κ°, μ΅μ 리μ§μ κ°, μ΅μ°μ μ§μ κ°, μμ₯κ°IOC, μ΅μ 리IOC, μμ₯κ°FOK, μ΅μ 리FOK, μ₯μ μκ°μΈ, μ₯νμκ°μΈ μ£Όλ¬Έμ μ£Όλ¬Έκ°κ²©μ μ λ ₯νμ§ μμ΅λλ€. | |
# ex) | |
# μ§μ κ° λ§€μ - openApi.SendOrder(βRQ_1β, β0101β, β5015123410β, 1, β000660β, 10, 48500, β00β, ββ); | |
# μμ₯κ° λ§€μ - openApi.SendOrder(βRQ_1β, β0101β, β5015123410β, 1, β000660β, 10, 0, β03β, ββ); | |
# 맀μ μ μ - openApi.SendOrder(βRQ_1β,β0101β, β5015123410β, 5, β000660β, 10, 49500, β00β, β1β); | |
# 맀μ μ·¨μ - openApi.SendOrder(βRQ_1β, β0101β, β5015123410β, 3, β000660β, 10, β00β, β2β); | |
# sOrgOrderNo β μμ£Όλ¬Έλ²νΈ | |
@pyqtSlot(str, str, str, int, str, int, int, str, str, result=int) | |
def sendOrder(self, rQName, screenNo, accNo, orderType, code, qty, price, hogaGb, orgOrderNo): | |
return self.ocx.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)", [rQName, screenNo, accNo, orderType, code, qty, price, hogaGb, orgOrderNo]) | |
# 체결μκ³ λ°μ΄ν°λ₯Ό λ°ννλ€. | |
@pyqtSlot(int, result=str) | |
def getChejanData(self, fid): | |
return self.ocx.dynamicCall("GetChejanData(int)", fid) | |
# μλ²μ μ μ₯λ μ¬μ©μ 쑰건μμ κ°μ Έμ¨λ€. | |
@pyqtSlot(result=int) | |
def getConditionLoad(self): | |
return self.ocx.dynamicCall("GetConditionLoad()") | |
# 쑰건κ²μ 쑰건λͺ 리μ€νΈλ₯Ό λ°μμ¨λ€. | |
# 쑰건λͺ 리μ€νΈ(μΈλ±μ€^쑰건λͺ ) | |
# 쑰건λͺ 리μ€νΈλ₯Ό ꡬλΆ(β;β)νμ¬ λ°μμ¨λ€ | |
@pyqtSlot(result=str) | |
def getConditionNameList(self): | |
return self.ocx.dynamicCall("GetConditionNameList()") | |
# 쑰건κ²μ μ’ λͺ©μ‘°νTRμ‘μ νλ€. | |
# LPCTSTR strScrNo : νλ©΄λ²νΈ | |
# LPCTSTR strConditionName : 쑰건λͺ | |
# int nIndex : 쑰건λͺ μΈλ±μ€ | |
# int nSearch : μ‘°νꡬλΆ(0:μΌλ°μ‘°ν, 1:μ€μκ°μ‘°ν, 2:μ°μμ‘°ν) | |
# 1:μ€μκ°μ‘°νμ νλ©΄ κ°μμ μ΅λλ 10κ° | |
@pyqtSlot(str, str, int, int) | |
def sendCondition(self, scrNo, conditionName, index, search): | |
self.ocx.dynamicCall("SendCondition(QString,QString, int, int)", scrNo, conditionName, index, search) | |
# μ€μκ° μ‘°κ±΄κ²μμ μ€μ§ν©λλ€. | |
# β» νλ©΄λΉ μ€μκ° μ‘°κ±΄κ²μμ μ΅λ 10κ°λ‘ μ νλμ΄ μμ΄μ λ μ΄μ μ€μκ° μ‘°κ±΄κ²μμ μνμ§ μλ 쑰건μ μ€μ§ν΄μΌλ§ μΉ΄μ΄νΈ λμ§ μμ΅λλ€. | |
@pyqtSlot(str, str, int) | |
def sendConditionStop(self, scrNo, conditionName, index): | |
self.ocx.dynamicCall("SendConditionStop(QString, QString, int)", scrNo, conditionName, index) | |
# 볡μμ’ λͺ©μ‘°ν Tranμ μλ²λ‘ μ‘μ νλ€. | |
# OP_ERR_RQ_STRING β μμ² μ λ¬Έ μμ± μ€ν¨ | |
# OP_ERR_NONE - μ μμ²λ¦¬ | |
# | |
# sArrCode β μ’ λͺ©κ° ꡬλΆμ β;βμ΄λ€. | |
# nTypeFlag β 0:μ£Όμκ΄μ¬μ’ λͺ©μ 보, 3:μ λ¬Όμ΅μ κ΄μ¬μ’ λͺ©μ 보 | |
@pyqtSlot(str, bool, int, int, str, str) | |
def commKwRqData(self, arrCode, next, codeCount, typeFlag, rQName, screenNo): | |
self.ocx.dynamicCall("CommKwRqData(QString, QBoolean, int, int, QString, QString)", arrCode, next, codeCount, typeFlag, rQName, screenNo) | |
# μ€μκ° λ±λ‘μ νλ€. | |
# strScreenNo : νλ©΄λ²νΈ | |
# strCodeList : μ’ λͺ©μ½λ리μ€νΈ(ex: 039490;005930;β¦) | |
# strFidList : FIDλ²νΈ(ex:9001;10;13;β¦) | |
# 9001 β μ’ λͺ©μ½λ | |
# 10 - νμ¬κ° | |
# 13 - λμ κ±°λλ | |
# strOptType : νμ (β0β, β1β) | |
# νμ β0βμ νμ λ§μ§λ§μ λ±λ‘ν μ’ λͺ©λ€λ§ μ€μκ°λ±λ‘μ΄ λ©λλ€. | |
# νμ β1βμ μ΄μ μ μ€μκ° λ±λ‘ν μ’ λͺ©λ€κ³Ό ν¨κ» μ€μκ°μ λ°κ³ μΆμ μ’ λͺ©μ μΆκ°λ‘ λ±λ‘ν λ μ¬μ©ν©λλ€. | |
# β» μ’ λͺ©, FIDλ κ°κ° νλ²μ μ€μκ° λ±λ‘ ν μ μλ κ°μλ 100κ° μ λλ€. | |
@pyqtSlot(str, str, str, str, result=int) | |
def setRealReg(self, screenNo, codeList, fidList, optType): | |
return self.ocx.dynamicCall("SetRealReg(QString, QString, QString, QString)", screenNo, codeList, fidList, optType) | |
# μ’ λͺ©λ³ μ€μκ° ν΄μ | |
# strScrNo : νλ©΄λ²νΈ | |
# strDelCode : μ€μκ° ν΄μ ν μ’ λͺ©μ½λ | |
# -νλ©΄λ³ μ€μκ°ν΄μ | |
# μ¬λ¬ νλ©΄λ²νΈλ‘ κ±Έλ¦° μ€μκ°μ ν΄μ νλ €λ©΄ νλΌλ©ν°μ νλ©΄λ²νΈμ μ’ λͺ©μ½λμ βALLβλ‘ μ λ ₯νμ¬ νΈμΆνμλ©΄ λ©λλ€. | |
# SetRealRemove(βALLβ, βALLβ); | |
# κ°λ³νλ©΄λ³λ‘ μ€μκ° ν΄μ νμλ €λ©΄ νλΌλ©ν°μμ νλ©΄λ²νΈλ μ€μκ°ν΄μ ν | |
# νλ©΄λ²νΈμ μ’ λͺ©μ½λμλ βALLβλ‘ ν΄μ£Όμλ©΄ λ©λλ€. | |
# SetRealRemove(β0001β, βALLβ); | |
# -νλ©΄μ μ’ λͺ©λ³ μ€μκ°ν΄μ | |
# νλ©΄μ μ’ λͺ©λ³λ‘ μ€μκ° ν΄μ νλ €λ©΄ νλΌλ©ν°μ ν΄λΉνλ©΄λ²νΈμ ν΄μ ν | |
# μ’ λͺ©μ½λλ₯Ό μ λ ₯νμλ©΄ λ©λλ€. | |
# SetRealRemove(β0001β, β039490β); | |
# λ¬Έμμλ λ¬λ¦¬ return μμ | |
@pyqtSlot(str, str) | |
def setRealRemove(self, scrNo, delCode): | |
self.ocx.dynamicCall("SetRealRemove(QString, QString)", scrNo, delCode) | |
# μμ λ°μ΄ν°λ₯Ό λ°ννλ€. | |
# LPCTSTR strTrCode : μ‘°ννTRμ½λ | |
# LPCTSTR strRecordName: μ‘°νν TRλͺ | |
# nIndex : 볡μ λ°μ΄ν° μΈλ±μ€ | |
# strItemName: μμ΄ν λͺ | |
# λ°νκ°: μμ λ°μ΄ν° | |
@pyqtSlot(str, str, int, str, result=str) | |
def getCommData(self, trCode, recordName, index, itemName): | |
return self.ocx.dynamicCall("GetCommData(QString, QString, int, QString)", | |
trCode, recordName, index, itemName) | |
# μ°¨νΈ μ‘°νν λ°μ΄ν° μ λΆλ₯Ό λ°°μ΄λ‘ λ°μμ¨λ€. | |
# LPCTSTR strTrCode : μ‘°ννTRμ½λ | |
# LPCTSTR strRecordName: μ‘°νν TRλͺ | |
# β»νλͺ©μ μμΉλ KOA Studioμ TRλͺ©λ‘ μμλ‘ λ°μ΄ν°λ₯Ό κ°μ Έμ΅λλ€. | |
# μλ‘ OPT10080μ μ΄ν΄λ³΄λ©΄ OUTPUTμ λ©ν°λ°μ΄ν°μ νλͺ©μ²λΌ νμ¬κ°, κ±°λλ, 체결μκ°λ± μμΌλ‘ νλͺ©μ μμΉκ° 0λΆν° 1μ©μ¦κ°ν©λλ€. | |
@pyqtSlot(str, str, result=str) | |
def getCommDataEx(self, trCode, recordName): | |
return self.ocx.dynamicCall("GetCommDataEx(QString, QString)", trCode, recordName) | |
# λ¦¬μΌ μμΈλ₯Ό λλλ€. | |
# νλ©΄ λ΄ λͺ¨λ 리μΌλ°μ΄ν° μμ²μ μ κ±°νλ€. | |
# νλ©΄μ μ’ λ£ν λ λ°λμ μ ν¨μλ₯Ό νΈμΆν΄μΌ νλ€. | |
# Ex) openApi.DisconnectRealData(β0101β); | |
@pyqtSlot(str) | |
def disconnectRealData(self, scnNo): | |
self.ocx.dynamicCall("DisconnectRealData(QString)", scnNo) | |
# μ’ λͺ©μ½λμ νκΈλͺ μ λ°ννλ€. | |
# strCode β μ’ λͺ©μ½λ | |
# μ’ λͺ©νκΈλͺ | |
# μλ μ½λ μΌκ²½μ° empty λ₯Ό 리ν΄ν¨ | |
@pyqtSlot(str, result=str) | |
def getMasterCodeName(self, strCode): | |
return self.ocx.dynamicCall("GetMasterCodeName(QString)", strCode) | |
# μ’ λͺ©μ½λμ νλ€. | |
# strCode β μ’ λͺ©μ½λ | |
# μ λ ₯ν μ’ λͺ©μ λν λλΆλ₯, μ€λΆλ₯, μ μ’ κ΅¬λΆκ°μ ꡬλΆμλ‘ μ°κ²°ν λ¬Έμμ΄μ μ»μμ μμ΅λλ€.(μ¬κΈ°μ ꡬλΆμλ '|'μ ';'μ λλ€.) | |
# KOA_Functions("GetMasterStockInfo", μ’ λͺ©μ½λ) | |
# μμ₯ꡬλΆ0|μ½μ€λ₯|λ²€μ²κΈ°μ ;μμ₯ꡬλΆ1|μνμ£Ό;μ μ’ κ΅¬λΆ|μ μ‘°|κΈ°κ³/μ₯λΉ | |
# μμ₯ꡬλΆ0|κ±°λμ;μμ₯ꡬλΆ1|μ€νμ£Ό;μ μ’ κ΅¬λΆ|μλΉμ€μ ; | |
@pyqtSlot(str, result=str) | |
def getMasterStockInfo(self, strCode): | |
stock_info = self.ocx.dynamicCall("KOA_Functions(QString, QString)", "GetMasterStockInfo", strCode) | |
# api return λ²κ·Έλ‘ μΆκ° ν΄μ€ | |
kospi_kosdaq = '' | |
yupjong = '' | |
if( stock_info != ''): | |
if( stock_info[-1] == ';'): | |
stock_info = stock_info[0:-1] | |
kospi_kosdaq = stock_info.split(';')[0].split('|')[1] | |
yupjong = stock_info.split(';')[-1].split('|')[-1] | |
return kospi_kosdaq + ':' + yupjong | |
if __name__ == "__main__": | |
def test_buy(): | |
# λΉμ μ 맀μ (μμ₯κ°μ λ¨κ° λ£κΈ° ) μ°λ¦¬μ’ κΈ 1μ£Ό | |
# objKiwoom.sendOrder("buy", kw_util.sendOrderScreenNo, objKiwoom.account_list[0], kw_util.dict_order["μ κ·λ§€μ"], | |
# "010050", 1, 900 , kw_util.dict_order["μμ₯κ°"], "") | |
# μ μ 맀μ - kd κ±΄μ€ 1μ£Ό | |
objKiwoom.sendOrder("buy", kw_util.sendOrderScreenNo, objKiwoom.account_list[0], kw_util.dict_order["μ κ·λ§€μ"], | |
"044180", 1, 0 , kw_util.dict_order["μμ₯κ°"], "") | |
pass | |
def test_sell(): | |
#μ μ 맀λ - kd κ±΄μ€ 1μ£Ό | |
objKiwoom.sendOrder("sell", kw_util.sendOrderScreenNo, objKiwoom.account_list[0], kw_util.dict_order["μ κ·λ§€λ"], | |
"044180", 1, 0 , kw_util.dict_order["μμ₯κ°"], "") | |
pass | |
def test_condition(): | |
objKiwoom._OnReceiveRealCondition("044180", "I", "λ¨ν μΆμΈ", 1) | |
pass | |
def test_getCodeList(): | |
# μ½μ€νΌ μ½λ 리μ€νΈ | |
result = objKiwoom.getCodeListByMarket('0') | |
print(result) | |
# μ½μ€λ₯ μ½λ 리μ€νΈ | |
result = objKiwoom.getCodeListByMarket('10') | |
print(result) | |
pass | |
def test_jusikGibon(): | |
objKiwoom.requestOpt10001("044180") | |
pass | |
def test_jusik_condition_occur(): | |
objKiwoom.addConditionOccurList('044180') | |
pass | |
@pyqtSlot() | |
def test_make_jangoInfo(): | |
objKiwoom.makeJangoInfoFile() | |
pass | |
def test_make_chegyeolInfo(): | |
objKiwoom.makeChegyeolInfoFile() | |
def test_terminate(): | |
objKiwoom.sigTerminating.emit() | |
pass | |
def test_make_excel(): | |
file_path = r'd:\download\ν΅ν© λ¬Έμ2.xlsx' | |
test_data = { | |
"170822": [ | |
" 8.56| 8750| 맀μνμ: 1 | (μ΅μ μ΄λ€) | 210540 | -맀λ | 22200 | 5 | 141905 | λμμ΄νμ ", | |
" 0| 0| 맀μνμ: 1 | (λ¨μ맀μ) | 038870 | +맀μ | 10350 | 10 | 142205 | μμ½λ°μ΄μ€ " | |
], | |
"170824": [ | |
" 8.81| 9180| 맀μνμ: 1 | (μ΅μ μ΄λ€) | 033100 | -맀λ | 6300 | 18 | 090136 | μ 룑μ κΈ° ", | |
" 0| 0| 맀μνμ: 1 | (λ¨μ맀μ) | 069540 | +맀μ | 6200 | 17 | 090349 | λΌμ΄νΈλ‘ ", | |
" 8.55| 9010| 맀μνμ: 1 | (μ΅μ λ―Έλ¬) | 069540 | -맀λ | 6730 | 17 | 090557 | λΌμ΄νΈλ‘ ", | |
" 8.76| 8925| 맀μνμ: 1 | (μ΅μ λ―Έλ¬) | 226350 | -맀λ | 3165 | 35 | 090842 | μμ΄μ ν ", | |
" 0| 0| 맀μνμ: 1 | (λ¨μ맀μ) | 180400 | +맀μ | 14250 | 8 | 091259 | μ μ§λ©λ ", | |
" 0| 0| 맀μνμ: 1 | (λ¨μ맀μ) | 072470 | +맀μ | 8247 | 13 | 091845 | μ°λ¦¬μ°μ νλ©μ€ ", | |
" 0| 0| 맀μνμ: 4 | (λ¨μ맀μ) | 031860 | +맀μ | 5050 | 80 | 094752 | μμμ€μ " | |
], | |
"170914": [ | |
" 13.53| 14000| 맀μνμ: 1 | (μ΅μ μ΄λ€) | 038870 | -맀λ | 11750 | 10 | 090102 | μμ½λ°μ΄μ€ ", | |
" 0| 0| 맀μνμ: 1 | (λ¨μ맀μ) | 023800 | +맀μ | 6400 | 8 | 090105 | μΈμ§μ»¨νΈλ‘€μ€ ", | |
" 0| 0| 맀μνμ: 1 | (λ¨μ맀μ) | 042600 | +맀μ | 8420 | 6 | 090113 | μλ‘λμ€ ", | |
" 8.99| 4720| 맀μνμ: 1 | (μ΅μ λ―Έλ¬) | 161570 | -맀λ | 7150 | 8 | 093611 | λ―Έλμ€μ¨λ€λ§ ", | |
" 0| 0| 맀μνμ: 1 | (λ¨μ맀μ) | 005420 | +맀μ | 19050 | 3 | 093933 | μ½μ€λͺ¨νν " | |
] | |
} | |
objKiwoom.make_excel(file_path, test_data) | |
def test_business_day(): | |
base_time = datetime.datetime.strptime('20190920090011', '%Y%m%d%H%M%S') | |
target_day = util.date_by_adding_business_days(base_time, BUNHAL_MAESU_PROHIBIT_DAYS ) | |
print(target_day) | |
# putenv λ current process μ μν₯μ λͺ»λΌμΉλ―λ‘ environ μμ μ§μ μΈν | |
# qml debugging λ₯Ό μν΄ QML_IMPORT_TRACE νκ²½λ³μ 1λ‘ μΈν ν DebugView μμ λλ²κΉ λ©μμ§ νμΈ κ°λ₯ | |
os.environ['QML_IMPORT_TRACE'] = '1' | |
# print(os.environ['QML_IMPORT_TRACE']) | |
myApp = QtWidgets.QApplication(sys.argv) | |
objKiwoom = KiwoomConditon() | |
form = QtWidgets.QMainWindow() | |
ui = Ui_MainWindow() | |
ui.setupUi(form) | |
event_filter = CloseEventEater() | |
form.installEventFilter( event_filter ) | |
ui.btnMakeExcel.clicked.connect(objKiwoom.onBtnMakeExcelClicked ) | |
ui.btnStart.clicked.connect(objKiwoom.onBtnStartClicked) | |
ui.btnYupjong.clicked.connect(objKiwoom.onBtnYupjongClicked) | |
ui.btnJango.clicked.connect(objKiwoom.onBtnJangoClicked) | |
ui.btnChegyeol.clicked.connect(objKiwoom.onBtnChegyeolClicked) | |
ui.btnCondition.clicked.connect(objKiwoom.onBtnConditionClicked) | |
ui.lineCmd.textChanged.connect(objKiwoom.onLineCmdTextChanged) | |
ui.btnRun.clicked.connect(objKiwoom.onBtnRunClicked) | |
form.show() | |
# test_business_day() | |
logging.basicConfig(filename='system_err.log', filemode='a',format='%(asctime)s - %(message)s', level=logging.INFO) | |
# try: | |
# 1/0 | |
# except Exception as e: | |
# logging.exception("Error Occured") | |
sys.exit(myApp.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
μλ νμΈμ? μλ맀맀λ₯Ό μμνκΈ°μ μμ£Ό μ’μ μμ λ€μ. μ’μ μλ£ μ¬λ €μ£Όμ μ κ°μ¬ν©λλ€. κ·Έλ°λ° mainwindow_ui νμΌμ μ¬λΌμ μμ§ μμλ°μ. νΉμ μ΄ νμΌλ 곡μ ν΄ μ£Όμ€ μ μμΌμ€κΉμ? Qtμ open api μλ맀맀λ ν΄λ³Έμ μ΄ μμ΄μ μ¬λ €μ£Όμλ©΄ λ§μ λμμ΄ λ κ² κ°μ΅λλ€. κ°μ¬ν©λλ€.