def T1452(idx=0, isToday=1): # Exit Condition idxTemp = int(idx) print("idxTemp = ", idxTemp) if idxTemp >= 280: return instXAQueryT1452 = win32com.client.DispatchWithEvents( "XA_DataSet.XAQuery", XAQueryEventsT1452) instXAQueryT1452.ResFileName = "Res\\t1452.res" instXAQueryT1452.SetFieldData("t1452InBlock", "gubun", 0, "1") # 1: KOPSPI 2:KOSDAQ instXAQueryT1452.SetFieldData("t1452InBlock", "jnilgubun", 0, isToday) instXAQueryT1452.SetFieldData("t1452InBlock", "ediff", 0, "7") instXAQueryT1452.SetFieldData("t1452InBlock", "jc_num", 0, "139608960") instXAQueryT1452.SetFieldData("t1452InBlock", "eprice", 0, "100000") instXAQueryT1452.SetFieldData("t1452InBlock", "idx", 0, idx) instXAQueryT1452.Request(1) while instXAQueryT1452.query_state == 0: pythoncom.PumpWaitingMessages() time.sleep(0.1) XAQueryEventsT1452.query_state = 0 # 중요 idx = instXAQueryT1452.GetFieldData("t1452OutBlock", "idx", 0) count = instXAQueryT1452.GetBlockCount("t1452OutBlock1") print("idx = ", idx, " count = ", count) #sql = "insert into DailyVolume(hname,price,sign,diff,volume,vol,shcode,jnilvolume,bef_diff,date) values (?,?,?,?,?,?, ?,?,?,?)" tempDate = "%04d-%02d-%02d" % (now.tm_year, now.tm_mon, now.tm_mday) for i in range(count): hname = instXAQueryT1452.GetFieldData("t1452OutBlock1", "hname", i) price = instXAQueryT1452.GetFieldData("t1452OutBlock1", "price", i) sign = instXAQueryT1452.GetFieldData("t1452OutBlock1", "sign", i) diff = instXAQueryT1452.GetFieldData("t1452OutBlock1", "diff", i) volume = instXAQueryT1452.GetFieldData("t1452OutBlock1", "volume", i) # 누적거래량 vol = instXAQueryT1452.GetFieldData("t1452OutBlock1", "vol", i) # 회전율 shcode = instXAQueryT1452.GetFieldData("t1452OutBlock1", "shcode", i) jnilvolume = instXAQueryT1452.GetFieldData("t1452OutBlock1", "jnilvolume", i) bef_diff = instXAQueryT1452.GetFieldData("t1452OutBlock1", "bef_diff", i) listT1452[idxTemp + i] = [ hname, price, sign, diff, volume, vol, shcode, jnilvolume, bef_diff ] print(i, hname, price, sign, diff, volume, vol, shcode, jnilvolume, bef_diff) print( "------------------------------------------------------------------------" ) print("재귀호출] idx ", idx) if int( idx ) == 0: # Xing API 응답에서 40개 미만의 데이터를 주고 끝나는 경우 idx가 0으로 응답된다. 무한재귀 호출에 빠지지 않도록 idx에 끝값을 대입한다. T1452(280, isToday=1) else: T1452(idx, isToday=1) # recursive call
def ttsAlert(self, alertCode, hname, diff): client = texttospeech.TextToSpeechClient() # Set the text input to be synthesized tmpStr = hname + " 매도 경고" # + str(diff) print(tmpStr + str(diff)) synthesis_input = texttospeech.SynthesisInput(text=tmpStr) if not os.path.exists("alert"): os.mkdir("alert") if os.path.isfile("alert/" + alertCode + ".mp3") == True: playsound("alert/" + alertCode + ".mp3") else: # 해당 종목코드 mp3가 존재하지 않을경우, # Build the voice request, select the language code ("en-US") and the ssml # voice gender ("neutral") voice = texttospeech.VoiceSelectionParams( language_code="ko-KR", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL) # Select the type of audio file you want returned audio_config = texttospeech.AudioConfig( audio_encoding=texttospeech.AudioEncoding.MP3) # Perform the text-to-speech request on the text input with the selected # voice parameters and audio file type response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config) with open("alert/" + alertCode + ".mp3", "wb") as out: # Write the response to the output file. out.write(response.audio_content) playsound("alert/" + alertCode + ".mp3")
def upperLimitCheck(self, shcode): df1475 = orderManager.t1475(shcode) if df1475.shape[0] == 0: print("t1475 responded null") return 0 if float(df1475['등락율'].values[0]) > 23: print("전일대비 과열(23% 초과)로 매수 제외:", float(df1475['등락율'].values[0])) return 1
def strategy2(_shcode, tempDate, refname=''): print("종목명:", refname) if checkExcludedList(refname) == True: return now = time.localtime() strTempTime = "%02d%02d%02d" % (now.tm_hour, now.tm_min, now.tm_sec) # tdf8412 = orderManager.t8412(단축코드=_shcode, 단위="10", 요청건수="60", 시작일자="", 종료일자="99999999", cts_date="", # comp_yn="N") # if tdf8412.shape[0] == 0: # print('[ERR] 8412 주식차트(10분) 조회 불가') # return # tempX = list(range(tdf8412.shape[0])) # tempY = list(map(int, tdf8412["종가"])) # tempX = tempX[-10:-1] # tempY = tempY[-10:-1] # grad, intercept, r_square, p_value, std_err = stats.linregress(tempX, tempY) # print(grad, intercept, r_square, p_value, std_err) # # if grad < 0: # return # # ma60 = ta.MA(np.asarray(tdf8412['종가']), timeperiod=60) # ma60 = ma60[~np.isnan(ma60)] # if len(ma60) == 0: # print("MA60 Error") # return # print("regression result(10분봉): ", grad, intercept, r_square, p_value, std_err) # print("10분봉 종가", tdf8412["종가"].values[-1], "VS 60MA", ma60[-1]) # if int(tdf8412["종가"].values[-1]) <= int(ma60[-1]): # return rsiRes = rsiCheck(_shcode=_shcode, hname=refname) if rsiRes == 2 or rsiRes == 3: close15mma = "0" # round(tdf8412["종가"].values[-1], 2) close60dma = "0" # round(ma60[-1], 2) beepsound(freq=1000, dur=1500) now = time.localtime() if now.tm_hour <= 15: if now.tm_hour == 15 and now.tm_min >= 30: pass else: dbInstance.insertObserverList(_shcode, tempDate, strTempTime, '', '', '', '', "1", str(rsiRes)) tmpStr = "KOSPI 종목: " + refname + " 포착시각 : " + str( now.tm_hour) + ":" + str( now.tm_min) # +" 현재가: "+str(tdf8412["종가"].values[-1]) print(tmpStr) # botManager.sendTeleMsg(tmpStr) dbInstance.insertDailyRecommendList(_shcode, tempDate, "KOSPI", str(close15mma), str(close60dma), str(g_rsiTgt), str(g_simpleMA9Tgt), strTempTime, refname, str(rsiRes))
def msmdVolumeCheck(self, _shcode): df1471o, df1471ob = orderManager.t1471( 종목코드=_shcode, 분구분="00", 자료개수="001") # 30초 단위 매수/매도 호가물량 점검 totofferrem = df1471ob["총매도"].values[0] totbidrem = df1471ob["총매수"].values[0] msrate = df1471ob["매수비율"].values[0] print("현재가", df1471o["현재가"].values[0], "총매도:", totofferrem, "총매수:", totbidrem, "체결강도:", msrate, "매도우선잔량", df1471ob["매도우선잔량"].values[0], "매수우선잔량", df1471ob["매수우선잔량"].values[0]) if totofferrem * 2 < totbidrem or float(msrate) < 100.0: return True
def rollout(): now = time.localtime() start = time.time() tempDate = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) dbInstance = dbManager.dbManager() res = dbInstance.selectDailyRecommendList("KOSPI", tempDate) for idx, row in enumerate(res): print(">>>", idx, "shcode", row["shcode"]) # strategy1(row["shcode"], tempDate, '', '', '', '',skip=False, refname=row["hname"]) strategy2(row["shcode"], tempDate, row["hname"]) # time.sleep(3) print("rollout 수행 시간: ", time.time() - start)
def prgCheck(self, _shcode=""): dbInstance = dbManager.dbManager() res = dbInstance.selectGubunRecommendList(_shcode) if len(res) != 0: gubun = res[0]["gubun"] == "KOSPI" and "0" or "1" else: print("no info exists in recommendList") return False df = orderManager.t1636(구분=gubun, 종목코드=_shcode) tmpDf = df['종목코드'] == _shcode df = df[tmpDf] if df.shape[0] == 0: print("프로그램 추세 정보 알 수 없음(%s)" % _shcode) return False # for i in range(0, df.shape[0]): # if df["종목코드"].values[i] == _shcode: print("종목명:", df["종목명"].values[0], "종목코드:", _shcode) print("순위:", df["순위"].values[0], "종목명:", df["종목명"].values[0], "현재가:", df["현재가"].values[0], \ "대비구분:", df["대비구분"].values[0], "대비:", df["대비"].values[0], "등락률:", df["등락률"].values[0], \ "거래량:", df["거래량"].values[0], "순매수수량:", df["순매수수량"].values[0], "비중:", df["비중"].values[0], "순매수금액", df["순매수금액"].values[0], "매수금액", df["매수금액"].values[0]) if float(df["순매수금액"].values[0]) <= 0: return True # 매도 else: return False
def calcADI(df): res = [] for i in range(0, df.shape[0]): # print(df['종가'].values[i], df['시가'].values[i], df['고가'].values[i], df['저가'].values[i]) tmp = float(df['종가'].values[i]) - float(df['시가'].values[i]) if float(df['고가'].values[i]) == float(df['저가'].values[i]): print("[ADI] 고가 = 저가", df['고가'].values[i], float(df['저가'].values[i])) tmp /= 1 else: tmp /= (float(df['고가'].values[i]) - float(df['저가'].values[i])) tmp *= float(df['거래량'].values[i]) res.append(tmp) adi = DataFrame(data=res, columns=["ADI"]) return adi
def searchCandidates(condtion=1): now = time.localtime() tempDate = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) # strategy1("078860", tempDate, '', '', '', '', skip=False, refname="아이오케이") if condtion == 1: dft1533 = orderManager.t1533("1") for i in range(0, 3): df = orderManager.t1537(dft1533["테마코드"].values[i]) for j in range(0, df.shape[0]): print("[테마] 종목명", df["종목명"].values[j], "종목코드", df["종목코드"].values[j]) strategy2(df["종목코드"].values[j], tempDate, refname=df["종목명"].values[j]) df1, df2 = orderManager.t1825(검색코드="6412", 구분="2") #양음양 6006 # 거래량 6412 for i in range(0, df2.shape[0]): # strategy1(df2["종목코드"].values[i], tempDate, '', '', '', '',skip=False,refname=df2["종목명"].values[i]) strategy2(df2["종목코드"].values[i], tempDate, refname=df2["종목명"].values[i]) df1, df2 = orderManager.t1825(검색코드="6306", 구분="2") #프로그램순매수 100 for i in range(0, df2.shape[0]): # strategy1(df2["종목코드"].values[i], tempDate, '', '', '', '', skip=True, refname=df2["종목명"].values[i]) strategy2(df2["종목코드"].values[i], tempDate, refname=df2["종목명"].values[i]) else: for idx, row in enumerate(listT1452): # t1471i = T1471.XAT1471() # ret = T1471.T1471_SearchBuyCandidates(row[6]) # if ret == None: # pass # else: # (_shcode, tempDate, strTempTime, msrate, bidrem1, offerrem1, price) = ret # strategy1(_shcode, tempDate, strTempTime, msrate, bidrem1, offerrem1, price) print(">>>", idx, row[0]) if row[0] == "null": return # strategy1(row[6], tempDate, '', '', '', '',skip=False, refname=row[0]) strategy2(row[6], tempDate, row[0])
def checkBaseLine(self, df='', curPrice=0): # dfnew = dfnew.apply(pd.to_numeric) if df.shape[0] < 10: print("df size is under 10") return False df = df.iloc[:10, :] print(df.shape[0]) for i in range(df.shape[0] - 1, 2, -1): print(i) print("종가", df["종가"].values[i], "종가 -1봉", df["종가"].values[i - 1], "종가 -2봉", df["종가"].values[i - 2]) if float(df["종가"].values[i]) >= float( df["종가"].values[i - 1]) * 1.01 or float( df["종가"].values[i]) >= float( df["종가"].values[i - 2]) * 1.01: basePrice = float(df["종가"].values[i]) / 2 if basePrice > curPrice: print("저지선", basePrice, "> 현재가", curPrice) return True return False
def getOneUnderHoga(self, shcode, price): # 1: KOPSI, 2:KOSDAQ price = int(price) ret = price dbInstance = dbManager.dbManager() res = dbInstance.selectGubunRecommendList(shcode) if len(res) == 0: print("unknown code yet in recommend list") return ret print("[호가조정] 종목명: ", res[0]['hname'], " 구분: ", res[0]['gubun']) gubun = res[0]['gubun'] if price < 1000: ret -= 1 elif price >= 1000 and price < 5000: ret -= 5 elif price >= 5000 and price < 10000: ret -= 10 elif price >= 10000 and price < 50000: ret -= 50 elif price >= 50000 and price < 100000: ret -= 100 elif price >= 100000 and price < 500000: temp = gubun == 1 and 500 or 100 ret -= temp elif price >= 500000: temp = gubun == 1 and 1000 or 100 ret -= temp else: print("호가 알 수 없음") return str(ret)
def weirdConditionCheck(self, shcode, hname): totcnt = 0 totmdvolume = totmsvolume = 0 for i in range(0, 5): if i == 0: df, df1 = orderManager.t1310(종목번호=shcode) # print(df1.head(20)) else: df, df1 = orderManager.t1310(종목번호=shcode, 종료시간=df["시간CTS"].values[0], CTS=df["시간CTS"].values[0]) # print(df1.head(20)) if df1.shape[0] == 0: print("t1310 responded null and we skip abnormal tr check") return False df1 = df1.apply(pd.to_numeric) tmpdf = df1[df1['체결수량'].lt(12)] totcnt += int(tmpdf.shape[0]) totmdvolume += (df1['매도체결수량'].values[0] - df1['매도체결수량'].values[-1]) totmsvolume += (df1['매수체결수량'].values[0] - df1['매수체결수량'].values[-1]) print("이상 매매 건수:", totcnt, "총매도체결수량:", totmdvolume, "총매수체결수량:", totmsvolume) if totmdvolume > totmsvolume: print("매도세 우위로 매수 포기") SellAgent.ttsAlert(self, shcode, hname, totmdvolume - totmsvolume) return True else: return False
def T8430(gubun=1): instXAQueryT8430 = win32com.client.DispatchWithEvents( "XA_DataSet.XAQuery", XAQueryEventsT8430) instXAQueryT8430.ResFileName = "C:\\eBEST\\xingAPI\\Res\\t8430.res" instXAQueryT8430.SetFieldData("t8430InBlock", "gubun", 0, gubun) instXAQueryT8430.Request(0) while XAQueryEventsT8430.query_state == 0: pythoncom.PumpWaitingMessages() XAQueryEventsT8430.query_state = 0 count = instXAQueryT8430.GetBlockCount("t8430OutBlock") print("# of codes = ", count) myShcode = [] for i in range(count): hname = instXAQueryT8430.GetFieldData("t8430OutBlock", "hname", i) shcode = instXAQueryT8430.GetFieldData("t8430OutBlock", "shcode", i) #expcode = instXAQueryT8430.GetFieldData("t8430OutBlock", "expcode", i) #etfgubun = instXAQueryT8430.GetFieldData("t8430OutBlock", "etfgubun", i) myShcode.append(shcode) print(i, hname, shcode) return myShcode
def upperBoundCheck(self, df, upper, middle, low, curPrice): print("볼린저 상:", upper[-1], "중", middle[-1], "하", low[-1], "종가:", df['종가'].values[-1], "현재가", curPrice) if float(upper[-1]) < float(curPrice) or float(upper[-1]) < float( df['종가'].values[-1]): print("BB 상한 초과") return 2 # elif float(middle[-1]) >= float(df['종가'].values[-1]): # print("BB 중간 이하") # return 0 # elif float(df['종가'].values[-1]) * 1.013 >= float(upper[-1]) : # print("종가 수익예상이 BB 상한 초과") # return 1 elif (float(upper[-1]) + float(middle[-1])) / 2 >= float(curPrice) or ( float(upper[-1]) + float(middle[-1])) / 2 >= float( df['종가'].values[-1]): print("BB 중상 이하") return 0 # 매수 가능 else: print("BB 중상 이상") return 1
def checkAccount(self): # [START] 자산 조회 로직 0424는 추정단계, 12300은 확정단계 orderInstance = orderManager.t0424(BuyAgent.accountNumber, BuyAgent.accountPwd) # 계좌번호, 비밀번호 if orderInstance[0].shape[0] == 0: print("0424 account record info error") return False df1, df2 = orderManager.CSPAQ12200(레코드갯수='1', 관리지점번호='', 계좌번호=BuyAgent.accountNumber, 비밀번호=BuyAgent.accountPwd, 잔고생성구분='0') # BuyAgent.balanced2 = orderInstance[0]["추정D2예수금"].values[0] BuyAgent.netAssest = orderInstance[0]["추정순자산"].values[0] if df2.shape[0] == 0: print("CSPAQ12200 info error") return False BuyAgent.balanced2 = df2['D2예수금'].values[0] print("예수금(D2) : ", BuyAgent.balanced2, "추정순자산 : ", BuyAgent.netAssest) # [END] 자산 조회 로직 # [START] 미체결 주문금액을 반영한 자산 반영 로직 -> 13700 오동작 # res1, res2, res3 = orderManager.CSPAQ13700(계좌번호=BuyAgent.accountNumber, 입력비밀번호=BuyAgent.password) # balanced2 에서 미체결 주문금액을 빼야 함 # db 조회 후, 확인한 종목코드, 주문수량, 주문총액 - 해당 종목의 t0425 totrem now = time.localtime() tempDate = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) dbInstance = dbManager.dbManager() res = dbInstance.selectbuylistford2(tempDate, '2') tempAmount = 0 for i in res: time.sleep(2) shcode = i["shcode"] ordqty = i["ordqty"] ordprc = i["ordprc"] df, df1 = orderManager.t0425(계좌번호=BuyAgent.accountNumber, 비밀번호=BuyAgent.accountPwd, 종목번호=shcode, 체결구분='2', 매매구분='2', 정렬순서='2', 주문번호='') tmpCnt = 0 while df.shape[0] == 0: #if df.shape[0] == 0 : time.sleep(2) df, df1 = orderManager.t0425(계좌번호=BuyAgent.accountNumber, 비밀번호=BuyAgent.accountPwd, 종목번호=shcode, 체결구분='2', 매매구분='2', 정렬순서='2', 주문번호='') tmpCnt += 1 if tmpCnt > 2: dbInstance.updateBuyListford2(shcode, tempDate) # 미체결 수량 없음 break # else: # now = time.localtime() for i in range(0, df1.shape[0]): tmpOrderTime = df1['주문시간'].values[i] print("주문번호:", df1['주문번호'].values[i], " 종목번호:", df1['종목번호'].values[i], "주문시간", tmpOrderTime, " 주문수량:", df1['주문수량'].values[i]) print("현재 시각: ", now.tm_hour, ":", now.tm_min) delayedCancel = False if now.tm_hour - int(tmpOrderTime[:2]) == 1: print(int(now.tm_min) + 60 - int(tmpOrderTime[2:4])) if int(now.tm_min) + 60 - int(tmpOrderTime[2:4]) >= 2: delayedCancel = True elif now.tm_hour - int(tmpOrderTime[:2]) > 1: delayedCancel = True elif int(tmpOrderTime[:2]) == now.tm_hour and int( now.tm_min) != int(tmpOrderTime[2:4]): if int(now.tm_min) - int(tmpOrderTime[2:4]) >= 2: delayedCancel = True else: tempAmount += ((int(ordprc) / int(ordqty)) * int(df['총미체결수량'].values[0])) print('[미체결 정보] 종목번호', shcode, '주문수량', ordqty, '주문가격', ordprc, '미체결수량', df['총미체결수량'].values[0]) print('누적 미체결 금액 : ', tempAmount) if delayedCancel == True: now = time.localtime() print("매수취소 시도: ", now.tm_hour, ":", now.tm_min) calcelRes = orderManager.CSPAT00800( df1['주문번호'].values[i], BuyAgent.accountNumber, BuyAgent.accountPwd, df1['종목번호'].values[i], df['총미체결수량'].values[0]) #df1['주문수량'].values[i]) if calcelRes[1]["주문번호"].values[0] == 0: print("매수취소 주문접수 불가") tempAmount += ((int(ordprc) / int(ordqty)) * int(df['총미체결수량'].values[0])) print('[미체결 정보] 종목번호', shcode, '주문수량', ordqty, '주문가격', ordprc, '미체결수량', df['총미체결수량'].values[0]) print('누적 미체결 금액 : ', tempAmount) else: print("매수취소 주문접수 완료") print(df1['종목번호'].values[i], df1['주문수량'].values[i], "0", df1['주문번호'].values[i], tempDate, calcelRes[1]["주문시각"].values[0], calcelRes[1]["종목명"].values[0], "3", "0") # `shcode`, `ordqty`, `ordprc`, `ordno`, `orderdate`, `ordtime`, `isunm`,`bnstpcode`,`strategy`) #dbInstance.insertOrderList(str(df1['종목번호'].values[i]), str(df1['주문수량'].values[i]), "0", str(df1['주문번호'].values[i]), tempDate, str(calcelRes[1]["주문시각"].values[0]), str(calcelRes[1]["종목명"].values[0]), "3","0") # 취소 dbInstance.deleteOrderList(tempDate, df1['종목번호'].values[i]) BuyAgent.balanced2 -= tempAmount print("미체결금액 반영한 D2 : ", BuyAgent.balanced2) # [END] 미체결 주문금액을 반영한 자산 반영 로직 return True
def rsiCheck(_shcode="", hname=''): global g_rsiTgt global g_simpleMA9Tgt now = time.localtime() tempToday = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) if not os.path.exists(tempToday): os.mkdir(tempToday) df1475 = orderManager.t1475(_shcode) if df1475.shape[0] == 0: print("t1475 responded null") elif df1475.shape[0] != 0 and float(df1475['당일VP'].values[0]) < 100: strTemp = "체결강도 100 미만으로 후보 탈락:" + hname print(strTemp) # botManager.sendTeleMsg(strTemp) return 0 df = orderManager.t8412(단축코드=_shcode, 단위="2", 요청건수="36") if df.shape[0] > 0: # rsi 9 구하기 try: taadx = ta.ADX(df['고가'], df['저가'], df['종가'], 9) taadxSig = ta.MA(taadx, timeperiod=9) taadx = np.asarray(taadx) taadxSig = np.asarray(taadxSig) print("ADX ", taadx) print("ADX Sig", taadxSig) if float(taadx[-1]) <= float(taadxSig[-1]): print("ADX condition mismatched") return 0 adxgrad, intercept, adi_r_square, p_value, std_err = stats.linregress( list(range(len(taadx[-30:-1]))), taadx[-30:-1]) if adxgrad < 0: print("ADX downturn") return 0 except Exception as e: print("Exception Occur : ", e) # adi = calcADI(df) # # mincond = adi['ADI'] < 0 # # adi = adi[mincond] # tempY = list(map(float, np.asarray(adi))) # sortTemp = sorted(tempY) # sortTemp = sortTemp[0:5] # print("저점 ADI: ",sortTemp) # newTempY = [] # for i in tempY: # if i in sortTemp: # newTempY.append(i) # print("저점 정렬 ADI: ", newTempY) # tempX = list(range(len(newTempY))) # adigrad, intercept, adi_r_square, p_value, std_err = stats.linregress(tempX, newTempY) # print("adi 저점정보", adigrad, intercept, adi_r_square, p_value, std_err) rsi9 = ta.RSI(np.asarray(df['종가']), 9) rsi9 = rsi9[~np.isnan(rsi9)] # remove nan if rsi9.size == 0: print("rsi size exception") return 0 rsiTgt = rsi9[-1] simpleMA9 = ta.MA(rsi9, timeperiod=9) simpleMA9Tgt = simpleMA9[-1] print('----------[RSI SIGNAL JUDGE]----------') if int(rsiTgt) < int(simpleMA9Tgt): # or int(rsiTgt) >= 75: print('rsi', rsiTgt, 'signal', simpleMA9Tgt) return 1 # elif int(rsiTgt) > int(simpleMA9Tgt) and int(rsiTgt) <= 30: # print('rsi > ', rsiTgt, '>', 'signal', simpleMA9Tgt) # g_rsiTgt = round(rsiTgt, 2) # g_simpleMA9Tgt = round(simpleMA9Tgt,2) # return 2 obv = ta.OBV(np.asarray(df['종가'], dtype=np.double), np.asarray(df['거래량'], dtype=np.double)) if obv[-1] < 8000: print("latest obv cut", obv[-1]) return 1 if obv[-1] - obv[-3] <= 0 or obv[-1] - obv[-2] <= 0: print("obv is downturned") return 1 obvSignal = ta.MA(obv, timeperiod=9) #obvSignal = obvSignal[~np.isnan(obvSignal)] # if obvSignal[-1] < 0: # print("latest obv signal is under zero") # return 1 tempX = list(range(len(obv))) tempY = list(map(float, obv)) obvgrad, intercept, r_square, p_value, std_err = stats.linregress( tempX, tempY) print("OBV ", obvgrad, intercept, r_square, p_value, std_err) if obvgrad <= 0: print("OBV grad <= 0") return 1 tempXSignal = list(range(len(obvSignal))) tempYSignal = list(map(float, obvSignal)) tempXSignal = tempXSignal[-16:-1] tempYSignal = tempYSignal[-16:-1] obvSignalgrad, intercept, r_square, p_value, std_err = stats.linregress( tempXSignal, tempYSignal) print("OBV Signal ", obvSignalgrad, intercept, r_square, p_value, std_err) # if obvSignalgrad <=0: # print("obvSignalgrad grad <= 0") # return 1 # plt.show() # print(obv) # print(obvSignal) #obv always above 0, but signal can be lower than 0 if obv[-1] < obvSignal[-1] or obv[-2] < obvSignal[-2]: print("Signal Condition Unsuited") return 1 # if abs(obvSignal[-1]) / (obv[-1] + (obvSignal[-1] < 0 and abs(obvSignal[-1]) or 0)) > 0.9 or abs(obvSignal[-2]) / (obv[-2]+(obvSignal[-1] < 0 and abs(obvSignal[-1]) or 0)) > 0.9: # print("OBV Gap Flattened") # return 1 # RSI Gap Condition Check : reg grad +, abs(gap[-1]) < 10 # rsiGap = rsi9 - simpleMA9 # rsiGap = rsiGap[~np.isnan(rsiGap)] # rsiGap = abs(rsiGap) # print("rsi gap : ", rsiGap) # tempX = list(range(len(rsiGap))) # tempY = list(map(float, rsiGap)) # tempX = tempX[-8:-1] # tempY = tempY[-8:-1] # g_rsiTgt = round(rsiTgt, 2) # g_simpleMA9Tgt = round(simpleMA9Tgt, 2) # grad, intercept, r_square, p_value, std_err = stats.linregress(tempX, tempY) # print("regression result: ", grad, intercept, r_square, p_value, std_err) # print("type rsi... ",type(rsi9[-1])) if rsi9[-1] - rsi9[-3] <= 0 or rsi9[-1] - rsi9[-2] <= 0: print("rsi is downturned") return 0 print("type simpleMA9... ", type(simpleMA9[-1])) # if grad <= 0 and rsi9[-1] > simpleMA9[-1] and rsi9[-2] > simpleMA9[-2]: # and r_square <= -0.6 and p_value < 0.05 and rsiGap[-2] >= rsiGap[-1]: if rsi9[-1] > simpleMA9[-1] and rsi9[-2] > simpleMA9[ -2]: # and r_square <= -0.6 and p_value < 0.05 and rsiGap[-2] >= rsiGap[-1]: # gapFlag = 0 # for i in tempY: # if i > 11: # gapFlag += 1 # if gapFlag < 2: # print("no rsi condition(gap flag is flatten) matched") # return 0 print("RSI Gap Condition Check OK") plt.figure(figsize=(30, 30)) plt.subplot(221) plt.title(str(_shcode)) plt.plot(obv) plt.plot(obvSignal) plt.text(0, 10, "og:" + str(format(obvgrad, "8.2%"))) plt.legend(["obv", "obv signal"]) # tempStr = tempToday + "/" + str(_shcode) + " obv" + ".png" # plt.savefig(tempStr) # botManager.sendImage(tempStr) plt.subplot(222) plt.plot(rsi9) plt.plot(simpleMA9) # plt.text(0, 10, "rg:" + str(format(grad, "3.2%"))) plt.legend(["rsi", "rsi signal"]) # plt.subplot(413) # plt.plot(newTempY) # plt.text(0, newTempY[0], "g"+str(format(adigrad,"3.2%"))+"r^2:" + str(format(adi_r_square*adi_r_square,"3.2%"))) # plt.legend(["new adi"]) plt.subplot(223) plt.plot(taadx) plt.plot(taadxSig) plt.text(20, taadxSig[-1], "g:" + str(format(adxgrad, "3.2%"))) plt.legend(["adx", "adx sig"]) ax = plt.subplot(224) dfnew = df[['시가', '고가', '저가', '종가']] day_list = range(len(df)) dfnew.insert(0, '시각', day_list) #dfnew = dfnew.set_index('날짜') dfnew = dfnew.apply(pd.to_numeric) candlestick_ohlc(ax, dfnew.values, width=0.5, colorup='r', colordown='b') plt.grid() tempStr = tempToday + "/" + str(_shcode) + " " + hname + ".png" plt.savefig(tempStr) plt.close() # botManager.sendImage(tempStr) # msrate check added return 3 else: print("no rsi condition matched") return 0 print("RSI Calc Err") return 0
def msquantityCheck(self, shcode): # 매수잔량 검사(매수벽 확인) df1101 = orderManager.t1101(shcode) df1101 = df1101.apply(pd.to_numeric) print(df1101.head()) tot = df1101.sum(axis=1).values[0] print('매수호가수량1', df1101['매수호가수량1'].values[0], '매수호가수량2', df1101['매수호가수량2'].values[0], '총매수잔량', tot) if df1101['매수호가수량1'].values[0] < 2000 or df1101['매수호가수량2'].values[ 0] < 2000: print("매수잔량 점검 부적격 < 2000") return True if df1101['매수호가수량1'].values[0] < tot * 0.005 or df1101[ '매수호가수량2'].values[0] < tot * 0.005: print("매수잔량 점검 부적격") return True df1471o, df1471ob = orderManager.t1471( 종목코드=shcode, 분구분="00", 자료개수="001") # 30초 단위 매수/매도 호가물량 점검 totofferrem = df1471ob["총매도"].values[0] totbidrem = df1471ob["총매수"].values[0] msrate = df1471ob["매수비율"].values[0] print("현재가", df1471o["현재가"].values[0], "총매도:", totofferrem, "총매수:", totbidrem, "체결강도:", msrate, "매도우선잔량", df1471ob["매도우선잔량"].values[0], "매수우선잔량", df1471ob["매수우선잔량"].values[0]) if int(totofferrem) * 2 < int(totbidrem): print("총매수/매도 확인 점검 부적격") return True if float(msrate) < 100.0: print("순간 체결 강도 100 미만 부적격") return True
def weirdConditionCheck(self, shcode): totcnt = 0 totmdvolume = totmsvolume = 0 price = 0 for i in range(0, 3): if i == 0: df, df1 = orderManager.t1310(종목번호=shcode) print(df1.tail()) price = int(df1['현재가'].values[0]) if price > 100000: # 현재가 100000 초과인 경우 체결빈도, 단주매매 검사 스킵 return False tmpTopHour = int(df1['시간'].values[0][:2]) tmpBottomHour = int(df1['시간'].values[-1][:2]) tmpGap = 0 if tmpTopHour == tmpBottomHour: tmpGap = int(df1['시간'].values[0]) - int( df1['시간'].values[-1]) else: tmpGap = int(df1['시간'].values[0]) - 4000 - int( df1['시간'].values[-1]) # 1시간 빼고 , 60분 더해주고. print("tmpTopHour", tmpTopHour, "tmpBottomHour", tmpBottomHour, " 20개 체결 간격: ", tmpGap) if tmpGap > 70: # 100 at 1 ea / 3 sec print("체결 빈도 검사에서 탈락 :", tmpGap) return True else: df, df1 = orderManager.t1310(종목번호=shcode, 종료시간=df["시간CTS"].values[0], CTS=df["시간CTS"].values[0]) print(df1.tail()) tmpTopHour = int(df1['시간'].values[0][:2]) tmpBottomHour = int(df1['시간'].values[-1][:2]) tmpGap = 0 if tmpTopHour == tmpBottomHour: tmpGap = int(df1['시간'].values[0]) - int( df1['시간'].values[-1]) else: tmpGap = int(df1['시간'].values[0]) - 4000 - int( df1['시간'].values[-1]) print("tmpTopHour", tmpTopHour, "tmpBottomHour", tmpBottomHour, " 20개 체결 간격: ", tmpGap) if tmpGap > 50: # 100 at 1 ea / 3 sec print("체결 빈도 검사에서 탈락") return True if df1.shape[0] == 0: print("t1310 responded null and we skip abnormal tr check") return False df1 = df1.apply(pd.to_numeric) tmpdf = df1[df1['체결수량'].lt(12)] totcnt += int(tmpdf.shape[0]) totmdvolume += (df1['매도체결수량'].values[0] - df1['매도체결수량'].values[-1]) totmsvolume += (df1['매수체결수량'].values[0] - df1['매수체결수량'].values[-1]) print("이상 매매 건수:", totcnt, "총매도체결수량:", totmdvolume, "총매수체결수량:", totmsvolume) if totcnt >= 30: print("이상 매매 건수 초과로 매수 포기") return True elif totmdvolume > totmsvolume: print("매도세 우위로 매수 포기") return True else: return False
def checkmsBaseLine(df='', curPrice=0): dfnew = df.apply(pd.to_numeric) dfnew = dfnew.iloc[:20, :] # dfnew['종가'].argmax() print(dfnew.head()) basePrice = 0 max = tmp = 0 for i in range(1, df.shape[0]): # print("종가",df["종가"].values[i],"종가 -1봉", df["종가"].values[i-1], "종가 -2봉",df["종가"].values[i-2] ) if float(df["고가"].values[i]) >= float( df["저가"].values[i]) and float(df["고가"].values[i]) >= float( df["저가"].values[i - 1]) * 1.05: print("장대양봉 고가:", df["고가"].values[i], "저가:", df["저가"].values[i]) tmp = float(df["고가"].values[i]) - float(df["저가"].values[i]) if max < tmp: max = tmp basePrice = float(df["고가"].values[i]) / 2 print('저지선: ', basePrice) if basePrice > curPrice: print("저지선", basePrice, "> 현재가", curPrice) return True if (float(df["고가"].values[i]) - float(df["종가"].values[i])) / ( float(df["고가"].values[i]) - float(df["저가"].values[i])) >= 0.8: print("상승 저항이 강력하여 매수 포기") print("고가:", df["고가"].values[i], "종가:", df["종가"].values[i], "저가", df["저가"].values[i]) return True if basePrice == 0 or curPrice == 0: print("이전 20봉 이내 장대양봉 없음") return False return False
def run(self): pythoncom.CoInitialize() orderManager.Login(id=SellAgent.accountId, pwd=SellAgent.password, cert=SellAgent.pkpwd) # instXAQueryT1471 = win32com.client.DispatchWithEvents("XA_DataSet.XAQuery", XAQueryEventsT1471) # instXAQueryT1471.ResFileName = "C:\\eBEST\\xingAPI\\Res\\t1471.res" now = time.localtime() tempDate = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) dbInstance = dbManager.dbManager() cnt = 0 while True: # print(cnt, "회전(Sell Manager)") # botManager.queryMine(isToday=True) # ,date='20201209') cnt += 1 df1, df2 = orderManager.t0424(SellAgent.accountNumber, SellAgent.accountPwd, 체결구분='2') # 계좌번호, 비밀번호 while df2.shape[0] == 0: df1, df2 = orderManager.t0424(SellAgent.accountNumber, SellAgent.accountPwd, 체결구분='2') # 계좌번호, 비밀번호 print("보유 종목 갯수 : ", df2.shape[0]) time.sleep(1) sellyn = False sellHalfYn = False for i in range(0, df2.shape[0]): tmpres = dbInstance.selectUserControlListByShcode( df2["종목번호"].values[i], tempDate) if len(tmpres) != 0 and tmpres[0]['undercontrol'] == 'Lock': print('수동 컨트럴 중으로 skip') continue print("종목번호:", df2["종목번호"].values[i],"종목명:", df2["종목명"].values[i],"평균단가:", df2["평균단가"].values[i], \ "현재가:", df2["현재가"].values[i],"매도가능수량:", df2["매도가능수량"].values[i],"잔고수량:", df2["잔고수량"].values[i]) if df2["매도가능수량"].values[i] != df2["잔고수량"].values[i]: # 기존 매도주문 취소 및 reset (잔고수량과 매도가능수량이 다른 경우는 이미 매도주문이 들어가서 부분 매도된 경우이다.) # 이러한 경우는 남은 물량을 현재가로 정정주문(매도) 한다. # 잔고 수량 - 매도가능수량 # 모의투자 정정주문은 시장가 지정 불가능 ordno = dbInstance.selectOrdNo(str(df2["종목번호"].values[i]), tempDate) if len(ordno) == 0: # HTS 등 타 시스템에서 주문한 경우 스킵 continue print("[정정주문] 원주문번호: ", ordno[0]['ordno']) orderRes = orderManager.CSPAT00700( ordno[0]['ordno'], SellAgent.accountNumber, SellAgent.accountPwd, str(df2["종목번호"].values[i]), str(df2["잔고수량"].values[i] - df2["매도가능수량"].values[i]), '00', '0', SellAgent.getOneUnderHoga(self, str(df2["종목번호"].values[i]), str(df2["현재가"].values[i]))) if orderRes[1]["주문번호"].values[ 0] == 0: # 장 종료 또는 기존주문 미체결 상태 등의 사유 print("정정 주문접수 불가") # 일단 취소, 상위 반복문에서 다시 매도 시도로 연결됨 calcelRes = orderManager.CSPAT00800( ordno[0]['ordno'], SellAgent.accountNumber, SellAgent.accountPwd, str(df2["종목번호"].values[i]), str( int(df2["잔고수량"].values[i]) - int(df2["매도가능수량"].values[i]))) if calcelRes[1]["주문번호"].values[0] == 0: print("취소 주문접수 불가") else: dbInstance.insertOrderList( str(orderRes[0]["종목번호"].values[0]), str(orderRes[0]["주문수량"].values[0]), "0", str(orderRes[1]["모주문번호"].values[0]), tempDate, str(orderRes[1]["주문시각"].values[0]), str(orderRes[1]["종목명"].values[0]), "3", "0") # 취소 else: print(orderRes[1]["주문번호"].values[0]) dbInstance.insertOrderList( str(orderRes[0]["종목번호"].values[0]), str(orderRes[0]["주문수량"].values[0]), str(orderRes[1]["주문금액"].values[0]), str(orderRes[1]["주문번호"].values[0]), tempDate, str(orderRes[1]["주문시각"].values[0]), str(orderRes[1]["종목명"].values[0]), "1", "4") # 정정 continue if df2["매도가능수량"].values[i] == 0: #매도가능한 수량이 없기 때문에 이후 로직을 검사할 필요가 없다. continue # 판단1 : 평단 < 현재가 * (1.033 - tolerance) # 매도잔량: 7273 매수잔량: 23468 체결강도: 458.71 if SellAgent.weirdConditionCheck(self, df2["종목번호"].values[i], df2["종목명"].values[i]) == True: print("!!!!!!!!!!!!!!!!매도 경고!!!!!!!!!!!!!!!!") if float(df2["평균단가"].values[i]) * ( 1 - (SellAgent.principalNfee - SellAgent.tolerance)) > df2["현재가"].values[i]: print("한계 초과로 매도") sellyn = True if sellyn == False and float( df2["평균단가"].values[i]) * 1.013 <= float( df2["현재가"].values[i]): print("1% 수익 확보, 50% 매도시도") sellyn = True sellHalfYn = True # if sellyn == False and SellAgent.weirdConditionCheck(self, df2["종목번호"].values[i]) == True: # sellyn = True if sellyn == False: #if (float(totbidrem1) >= float(totofferrem1) and float(msrate) <= SellAgent.stdmsrate) or float(msrate) <= SellAgent.stdmsrate - 50 : rsiChkRet = SellAgent.rsiCheck( self, df2["평균단가"].values[i], _shcode=df2["종목번호"].values[i], curPrice=df2["현재가"].values[i]) if rsiChkRet == 1: print("RSI 조건에 의하여 매도") #dbInstance.insertObserverList(df2["종목번호"].values[i], tempDate, strTempTime, msrate, bidrem1, offerrem1, price) dbInstance.updateObserverList(df2["종목번호"].values[i], tempDate) sellyn = True elif rsiChkRet == 2: dbInstance.updateObserverList(df2["종목번호"].values[i], tempDate) sellyn = True sellHalfYn = True # if sellyn == False: #and SellAgent.prgCheck(self, _shcode=df2["종목번호"].values[i]) == True : # print("프로그램 순매도 조건으로 매도") # sellyn = True # elif float(bidrem1) >= (float(offerrem1) * 3 ) : # print("매수잔량 >= 매도잔량 * 2 매도") # dbInstance.insertObserverList(df2["종목번호"].values[i], tempDate, strTempTime, msrate, bidrem1, # offerrem1, price) # dbInstance.updateObserverList(df2["종목번호"].values[i]) # sellyn = True if sellyn == True: # 매도 sellQuantity = sellHalfYn == True and str( int(int(df2["매도가능수량"].values[i]) / 2)) or df2["매도가능수량"].values[i] if sellHalfYn == True and sellQuantity == '0': # 매도가능수량이 1인 경우 예외처리 sellQuantity = df2["매도가능수량"].values[i] try: orderRes = orderManager.CSPAT00600( SellAgent.accountNumber, SellAgent.accountPwd, df2["종목번호"].values[i], sellQuantity, '', '1', '03', '000', '0') # 시장가로 매도, df2["현재가"].values[i] if orderRes[1]["주문번호"].values[0] == 0: # 장 종료 등의 사유 print("주문접수 불가") else: print(orderRes[1]["주문번호"].values[0]) dbInstance.insertOrderList( str(orderRes[0]["종목번호"].values[0]), str(orderRes[1]["실물주문수량"].values[0]), str(orderRes[1]["주문금액"].values[0]), str(orderRes[1]["주문번호"].values[0]), tempDate, str(orderRes[1]["주문시각"].values[0]), str(orderRes[1]["종목명"].values[0]), "1", "0") except Exception as e: print("Exception Occur : ", e) sellyn = False sellHalfYn = False time.sleep(SellAgent.sleeptime) pythoncom.CoUninitialize()
g_rsiTgt = 0 g_simpleMA9Tgt = 0 inXASession = win32com.client.DispatchWithEvents("XA_Session.XASession", XASessionEvents) inXASession.ConnectServer(server_addr, server_port) inXASession.Login(user_id, user_pass, user_certificate_pass, server_type, 0) dbInstance = dbManager.dbManager() while XASessionEvents.logInState == 0: pythoncom.PumpWaitingMessages() num_account = inXASession.GetAccountListCount() for i in range(num_account): account = inXASession.GetAccountList(i) print(account) #listT1452=[["null" for col in range(5)] for row in range(120)] listT1452 = [["null" for col in range(1)] for row in range(280)] # 전날 데이터 수신 (1: today 2: yesterday) def T1452(idx=0, isToday=1): # Exit Condition idxTemp = int(idx) print("idxTemp = ", idxTemp) if idxTemp >= 280: return instXAQueryT1452 = win32com.client.DispatchWithEvents( "XA_DataSet.XAQuery", XAQueryEventsT1452) instXAQueryT1452.ResFileName = "Res\\t1452.res"
def OnDisconnect(self): print("OnDisconnect method is called")
def strategy1(_shcode, tempDate, msrate, bidrem1, offerrem1, price, skip=False, refname=''): print("PG 순매수 스킵여부 :", skip, "종목명:", refname) now = time.localtime() strTempTime = "%02d%02d%02d" % (now.tm_hour, now.tm_min, now.tm_sec) prognetbuy = 0 if skip == False: df = orderManager.t1636(구분="0", 종목코드=_shcode) tmpDf = df['종목코드'] == _shcode df = df[tmpDf] if df.shape[0] == 0: print("프로그램 추세 정보 알 수 없음(%s)" % _shcode) return # for i in range(0, df.shape[0]): # if df["종목코드"].values[i] == _shcode: print("종목명:", df["종목명"].values[0], "종목코드:", _shcode) print("순위:", df["순위"].values[0], "종목명:", df["종목명"].values[0], "현재가:", df["현재가"].values[0], \ "대비구분:", df["대비구분"].values[0], "대비:", df["대비"].values[0], "등락률:", df["등락률"].values[0], \ "거래량:", df["거래량"].values[0], "순매수수량:", df["순매수수량"].values[0], "비중:", df["비중"].values[0], "순매수금액", df["순매수금액"].values[0], "매수금액", df["매수금액"].values[0]) prognetbuy = float(df["순매수금액"].values[0]) if skip == True or prognetbuy > 0: # float(df["등락률"].values[0]) > 0 and float(df["순매수금액"].values[0]) > 0: tdf8412 = orderManager.t8412(단축코드=_shcode, 단위="15", 요청건수="1", 시작일자="", 종료일자="99999999", cts_date="", comp_yn="N") if tdf8412.shape[0] == 0: print('[ERR] 8412 주식차트(분) 조회 불가') return close15mma = tdf8412.iloc[-1]['종가'] print('close15mma', close15mma) tdf8413 = orderManager.t8413(단축코드=_shcode, 요청건수='60') if tdf8413.shape[0] == 0: print('[ERR] 8413 주식차트(일) 조회 불가') return pandas_ma60 = tdf8413['종가'].rolling( window=60).mean() # tdf8413.종가.rolling(window=60).mean() close60dma = pandas_ma60.iloc[-1] print('close60dma', close60dma) if np.isnan(close60dma) == True: return if int(close15mma) > int(close60dma): tdf8412 = orderManager.t8412(단축코드=_shcode, 단위="10", 요청건수="10", 시작일자="", 종료일자="99999999", cts_date="", comp_yn="N") if tdf8412.shape[0] == 0: print('[ERR] 8412 주식차트(10분) 조회 불가') return tempX = list(range(tdf8412.shape[0])) tempY = list(map(int, tdf8412["종가"])) grad, intercept, r_square, p_value, std_err = stats.linregress( tempX, tempY) print(grad, intercept, r_square, p_value, std_err) if grad < 0: return tdf8412 = orderManager.t8412(단축코드=_shcode, 단위="10", 요청건수="60", 시작일자="", 종료일자="99999999", cts_date="", comp_yn="N") ma60 = ta.MA(np.asarray(tdf8412['종가']), timeperiod=60) ma60 = ma60[~np.isnan(ma60)] print("regression result(10분봉): ", grad, intercept, r_square, p_value, std_err) print("10분봉 종가", tdf8412["종가"].values[-1], "VS 60MA", ma60[-1]) if int(tdf8412["종가"].values[-1]) <= int(ma60[-1]): return rsiRes = rsiCheck(_shcode=_shcode, hname=refname) if rsiRes == 2 or rsiRes == 3: close15mma = round(close15mma, 2) close60dma = round(close60dma, 2) beepsound(freq=500, dur=500) beepsound(freq=1500, dur=500) now = time.localtime() if now.tm_hour <= 15: if now.tm_hour == 15 and now.tm_min >= 30: pass else: dbInstance.insertObserverList( _shcode, tempDate, strTempTime, msrate, bidrem1, offerrem1, price, "1", str(rsiRes)) if skip == True: print("종목: ", refname, "포착시각 : ", now.tm_hour, ":", now.tm_min) dbInstance.insertDailyRecommendList( _shcode, tempDate, "KOSPI", str(close15mma), str(close60dma), str(g_rsiTgt), str(g_simpleMA9Tgt), strTempTime, refname, str(rsiRes)) else: print("종목: ", df["종목명"].values[0], "포착시각 : ", now.tm_hour, ":", now.tm_min) dbInstance.insertDailyRecommendList( _shcode, tempDate, "KOSPI", str(close15mma), str(close60dma), str(g_rsiTgt), str(g_simpleMA9Tgt), strTempTime, df["종목명"].values[0], str(rsiRes))
def OnLogout(self): print("OnLogout method is called")
def rsiCheck(self, msprice, _shcode="", curPrice=0): df = orderManager.t8412(단축코드=_shcode, 단위="2", 요청건수="36") if df.shape[0] > 0: # rsi 9 구하기 upper, middle, low = ta.BBANDS(df['종가'], 20, 2, 2) upper = np.asarray(upper) # middle = np.asarray(middle) print("볼린저 상한:", upper[-1], "종가:", df['종가'].values[-1]) dbInstance = dbManager.dbManager() now = time.localtime() tempDate = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) if float(upper[-1]) <= float( df['종가'].values[-1]): # mark that record dbInstance.updateOrdListBB(_shcode, tempDate) if msprice * 1.013 <= df['종가'].values[-1]: print("RSI 조건(BB상단 돌파 및 1% 수익)에 의하여 50%매도") return 2 elif float(upper[-1]) > float(df['종가'].values[-1]): res = dbInstance.selectOrdListBB(_shcode, tempDate) if len(res) != 0: print("BB 상한 돌파 이력 조회 결과:", res[0]['reserve2']) if res[0]['reserve2'] == '1': print("BB 상한 + -> - 로 매도") return 1 rsi9 = ta.RSI(np.asarray(df['종가']), 9) rsi9 = rsi9[~np.isnan(rsi9)] # remove nan if rsi9.size == 0: print("rsi size exception") return -1 rsiTgt = rsi9[-1] simpleMA9 = ta.MA(rsi9, timeperiod=9) simpleMA9Tgt = simpleMA9[-1] # print('----------[RSI SIGNAL JUDGE]----------') if rsiTgt < simpleMA9Tgt: print('rsi', rsiTgt, '<', 'signal', simpleMA9Tgt) #df = orderManager.t8412(단축코드=_shcode, 단위="5", 요청건수="36") simpleMA5 = ta.MA(np.asarray(df['종가'], dtype=np.double), timeperiod=5) simpleMA20 = ta.MA(np.asarray(df['종가'], dtype=np.double), timeperiod=20) print("종가:", df['종가'].values[-1], "5MA: ", simpleMA5[-1], "20MA", simpleMA20[-1]) taadx = ta.ADX(df['고가'], df['저가'], df['종가'], 9) taadxSig = ta.MA(taadx, timeperiod=9) taadx = np.asarray(taadx) taadxSig = np.asarray(taadxSig) if float(taadx[-1]) <= float(taadxSig[-1]): if float(simpleMA5[-1]) <= float(df['종가'].values[-1]): return 0 else: if float(simpleMA20[-1]) <= float(df['종가'].values[-1]): return 0 return 1 # 매도 # elif rsiTgt >= 75 and rsiTgt <= 80: # 75 # df = orderManager.t8412(단축코드=_shcode, 단위="2", 요청건수="3") # if df.shape[0] == 0 : # print("분봉 정보 조회 불가") # return False # if df['종가'].values[-1] < df['종가'].values[-2] and df['종가'].values[-2] < df['종가'].values[-3] : # print("RSI 75~80 에서 하락 2봉으로 매도") # return True # SellAgent.sleeptime = 60 # return False elif rsiTgt > 75: # df = orderManager.t8412(단축코드=_shcode, 단위="2", 요청건수="36") # check if close price > BB upper bound if df['종가'].values[-1] < df['종가'].values[-2] and df[ '종가'].values[-2] < df['종가'].values[-3]: simpleMA5 = ta.MA(np.asarray(df['종가'], dtype=np.double), timeperiod=5) if float(df['종가'].values[-1]) < float(simpleMA5[-1]): print("RSI 75 초과에서 하락 2봉 + 5MA(2min) 이하로 매도 ", simpleMA5[-1]) return 1 else: return 0 # 매수 1,2 호가 물량 체크 # elif SellAgent.msmdVolumeCheck(self, _shcode) == True: # print("총매수 잔량 조건으로 50% 매도") # return 2 simpleMA10 = ta.MA(np.asarray(df['종가'], dtype=np.double), timeperiod=10) print("종가:", df['종가'].values[-1], "10MA(2Min.): ", simpleMA10[-1]) if float(simpleMA10[-1]) > float(df['종가'].values[-1]): return 1 return 0 # 장대양봉 존재할 경우, 장대양봉의 중간 지지선 붕괴 여부 검사 elif SellAgent.checkBaseLine(self, df, float(curPrice)) == True: print("장대양봉의 지지선 붕괴로 매도") return 1 else: print('rsi > ', rsiTgt, '>', 'signal', simpleMA9Tgt) return 0 return 0
def run(self): #pythoncom.CoInitialize() orderManager.Login(id=BuyAgent.accountId, pwd=BuyAgent.password, cert=BuyAgent.pkpwd) now = time.localtime() tempDate = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) # dbInstance = dbManager.dbManager() while False == buy.checkAccount(): time.sleep(1) cnt = 0 while True: dbInstance = dbManager.dbManager() res = dbInstance.selectObserverList(tempDate, '1', tempDate) if cnt != 0 and cnt % 3 == 0: BuyAgent.checkAccount(self) orderPrice = 0 #print(res) for i in res: nPortfolio = BuyAgent.numberOfPortfolio # time.sleep(5) df1, df2, df3 = orderManager.CSPAQ12300( 레코드갯수='1', 계좌번호=BuyAgent.accountNumber, 비밀번호=BuyAgent.accountPwd, 잔고생성구분='0', 수수료적용구분='1', D2잔고기준조회구분='0', 단가구분='0') tmpdf = df3[(df3['종목번호'] == i["shcode"])] if tmpdf.shape[0] > 0: print("현재 보유 중, Skip") continue # nPortfolio -= df3.shape[0] # if nPortfolio <= 0 : # print("포트폴리오 초과 매수불가") # continue tmpres = dbInstance.selectUserControlListByShcode( i["shcode"], tempDate) if len(tmpres) != 0 and tmpres[0]['undercontrol'] == 'Lock': print('수동 컨트럴 중으로 skip') continue df8407 = orderManager.t8407(종목코드=i["shcode"]) print(df8407["종목명"].values[0], df8407["현재가"].values[0]) if int(df8407["현재가"].values[0]) < 1000: print("동전주 skip") continue client = texttospeech.TextToSpeechClient() # Set the text input to be synthesized synthesis_input = texttospeech.SynthesisInput( text=df8407["종목명"].values[0]) if not os.path.exists("audio"): os.mkdir("audio") # 해당 종목코드 mp3가 존재한다면, if os.path.isfile("audio/" + i["shcode"] + ".mp3") == True: playsound("audio/" + i["shcode"] + ".mp3") else: # 해당 종목코드 mp3가 존재하지 않을경우, # Build the voice request, select the language code ("en-US") and the ssml # voice gender ("neutral") voice = texttospeech.VoiceSelectionParams( language_code="ko-KR", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL) # Select the type of audio file you want returned audio_config = texttospeech.AudioConfig( audio_encoding=texttospeech.AudioEncoding.MP3) # Perform the text-to-speech request on the text input with the selected # voice parameters and audio file type response = client.synthesize_speech( input=synthesis_input, voice=voice, audio_config=audio_config) with open("audio/" + i["shcode"] + ".mp3", "wb") as out: # Write the response to the output file. out.write(response.audio_content) playsound("audio/" + i["shcode"] + ".mp3") # os.remove("output.mp3") # playsound(None) # if BuyAgent.checkExcludedList(self, df8407["종목명"].values[0]) == True : # print("인덱스 종목 제외 ",df8407["종목명"].values[0]) # continue BuyAgent.checkAccount(self) #BuyAgent.ordqty = int((min(BuyAgent.balanced2, BuyAgent.netAssest) / nPortfolio) / int(df8407["현재가"].values[0])) BuyAgent.ordqty = int( (min(BuyAgent.balanced2, BuyAgent.netAssest)) / int(df8407["현재가"].values[0])) print("[INFO] ", "포폴# ", nPortfolio, "D2추정: ", BuyAgent.balanced2, "추정순자산", BuyAgent.netAssest) #if BuyAgent.ordqty < 1 or df2["D2예수금"].values[0] < (BuyAgent.ordqty * float(i["price"])) : if BuyAgent.ordqty < 1 or BuyAgent.balanced2 < ( BuyAgent.ordqty * float(df8407["현재가"].values[0])): print( "[잔고부족] ", "#종목코드", str(i["shcode"]), "예수금 ", df2["D2예수금"].values[0], "VS. 물량 ", str(BuyAgent.ordqty), "가격", str(df8407["현재가"].values[0]), ) dbInstance.updateObserverList(i["shcode"], tempDate) continue # 상한가 임박 or 단주 매수 필터 아웃 if BuyAgent.upperLimitCheck( self, i["shcode"] ) == 1 or True == BuyAgent.weirdConditionCheck( self, i["shcode"]) or True == BuyAgent.msquantityCheck( self, i["shcode"]): print("매수 포기") dbInstance.updateObserverList(i["shcode"], tempDate) continue orderPrice = int(df8407["현재가"].values[0]) # 이전 장대양봉 기준선(중간값)이하일 경우 매수 포기하는 로직 -> 주석 처리 210110 # df = orderManager.t8412(단축코드=i["shcode"], 단위="2", 요청건수="36") # if BuyAgent.checkmsBaseLine(df,float(df8407["현재가"].values[0]) ) == True: # print("장대양봉 기준선 이하로 매수 포기") # dbInstance.updateObserverList(i["shcode"], tempDate) # continue # 볼린저 밴드 상한 초과시 포기, 중상일 경우 호가를 골드라인으로 조정 -> 로직 주석 처리 210110 df8412 = orderManager.t8412(단축코드=i["shcode"], 단위="2", 요청건수="36") upper, middle, low = ta.BBANDS( df8412['종가'], 20, 2, 2) # 2 sigma 에서 3 sigma로 변경 210118 upper = np.asarray(upper) middle = np.asarray(middle) low = np.array(low) tmpUpperCheck = BuyAgent.upperBoundCheck( self, df8412, upper, middle, low, df8407["현재가"].values[0]) orderPrice = int(df8407["현재가"].values[0]) if tmpUpperCheck == 1: print("매수 호가 하향 조정 시도, 현재가:", orderPrice) while (float(upper[-1]) + float(middle[-1])) / 2 < orderPrice: orderPrice = int( BuyAgent.getOneUnderHoga(self, i["shcode"], orderPrice)) print("orderPrice: ", orderPrice) elif tmpUpperCheck == 2: print("매수 포기") dbInstance.updateObserverList(i["shcode"], tempDate) continue print("매수시도 종목코드: ", i["shcode"], " 수량: ", BuyAgent.ordqty, " 가격: ", orderPrice) try: orderRes = orderManager.CSPAT00600(BuyAgent.accountNumber, BuyAgent.accountPwd, i["shcode"], BuyAgent.ordqty, str(orderPrice), '2', '00', '000', '0') if orderRes[1]["주문번호"].values[0] == 0: # 장 종료 등의 사유 # observerList 테이블에서 해당 Row의 excluded칼럼을 1로 업데이트 dbInstance.updateObserverList(i["shcode"], tempDate) continue else: print(orderRes[1]["주문번호"].values[0]) # bnstpcode 2: 매수, strategy 1: 전략1 dbInstance.insertOrderList( orderRes[0]["종목번호"].values[0], str(BuyAgent.ordqty), str(orderRes[1]["주문금액"].values[0]), str(orderRes[1]["주문번호"].values[0]), tempDate, str(orderRes[1]["주문시각"].values[0]), str(orderRes[1]["종목명"].values[0]), "2", "1") #dbInstance.deleteOrderList(tempDate,i["shcode"]) client = texttospeech.TextToSpeechClient() # Set the text input to be synthesized tmpStr = df8407["종목명"].values[0] + " 매수하겠습니다." synthesis_input = texttospeech.SynthesisInput( text=tmpStr) # Build the voice request, select the language code ("en-US") and the ssml # voice gender ("neutral") voice = texttospeech.VoiceSelectionParams( language_code="ko-KR", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL) # Select the type of audio file you want returned audio_config = texttospeech.AudioConfig( audio_encoding=texttospeech.AudioEncoding.MP3) # Perform the text-to-speech request on the text input with the selected # voice parameters and audio file type response = client.synthesize_speech( input=synthesis_input, voice=voice, audio_config=audio_config) with open("output.mp3", "wb") as out: # Write the response to the output file. out.write(response.audio_content) print('Audio content written to file "output.mp3"') playsound("output.mp3") os.remove("output.mp3") except Exception as e: print("Exception Occur : ", e) time.sleep(5) cnt += 1 print(str(cnt), " 회전(Buy Manager)")
def OnLogin(self, code, msg): print("OnLogin method is called") print(str(code)) print(str(msg)) if str(code) == '0000': XASessionEvents.logInState = 1