def collect_code_list(): ebest = EBest("DEMO") mongodb = MongoDBHandler() ebest.login() result = ebest.get_code_list("ALL") mongodb.delete_items({}, "stock", "m_code_info") mongodb.insert_items(result, "stock", "m_code_info")
def collect_stock_info(): ebest = EBest("DEMO") mongodb = MongoDBHandler() ebest.login() code_list = mongodb.find_items({}, "stock", "m_code_info") target_code = set([item["단축코드"] for item in code_list]) today = datetime.today().strftime("%Y%m%d") print(today) collect_list = mongodb.find_items({"날짜":today}, "stock", "price_info") \ .distinct("code") for col in collect_list: target_code.remove(col) for code in target_code: time.sleep(1) print("code:", code) result_price = ebest.get_stock_price_by_code(code, "1") if len(result_price) > 0: print(result_price) mongodb.insert_items(result_price, "stock", "price_info") result_credit = ebest.get_credit_trend_by_code(code, today) if len(result_credit) > 0: mongodb.insert_items(result_credit, "stock", "credit_info") result_short = ebest.get_short_trend_by_code(code, sdate=today, edate=today) if len(result_short) > 0: mongodb.insert_items(result_short, "stock", "short_info") result_agent = ebest.get_agent_trend_by_code(code, fromdt=today, todt=today) if len(result_agent) > 0: mongodb.insert_items(result_agent, "stock", "agent_info")
def __init__(self): self.starttime = time.time( ) # 시작 시간 저장 print("time :", time.time() - start) # 현재시각 - 시작시간 = 실행 시간 self.mongodb = MongoDBHandler() self.db_name = "stock1" self.log = Logger() self.ebest = EBest("DEMO") self.ebest.login() self.ebest.change_field_lang('E') self.ins_date = datetime.today().strftime("%Y%m%d") self.ins_time = datetime.today().strftime("%H%M%S") self.day_90 = (datetime.today() - timedelta(days=90)).strftime("%Y%m%d") self.day_search_signal = (datetime.today() - timedelta(days=6)).strftime("%Y%m%d") self.wd = WorkDate() self.tradingday = self.wd.find_working_day(self.ins_date, 0) self.befoneday = self.wd.find_working_day(self.ins_date, 30) self.momt_dates = []
class DataCollector(object): def __init__(self): self.starttime = time.time( ) # 시작 시간 저장 print("time :", time.time() - start) # 현재시각 - 시작시간 = 실행 시간 self.mongodb = MongoDBHandler() self.db_name = "stock1" self.log = Logger() self.ebest = EBest("DEMO") self.ebest.login() self.ebest.change_field_lang('E') self.ins_date = datetime.today().strftime("%Y%m%d") self.ins_time = datetime.today().strftime("%H%M%S") self.day_90 = (datetime.today() - timedelta(days=90)).strftime("%Y%m%d") self.day_search_signal = (datetime.today() - timedelta(days=6)).strftime("%Y%m%d") self.wd = WorkDate() self.tradingday = self.wd.find_working_day(self.ins_date, 0) self.befoneday = self.wd.find_working_day(self.ins_date, 30) self.momt_dates = [] def __del__(self): # self.ebest.logout() print("classs__del__") def clear_data_base(self): self.mongodb.delete_items({}, self.db_name, "m_stock_code") self.mongodb.delete_items({}, self.db_name, "m_code_info") self.mongodb.delete_items({}, self.db_name, "daily_price") self.mongodb.delete_items({}, self.db_name, "Naver_news") def calc_avg_volume(self, shcode, volume): if int(volume) < 10000: return int(volume) tot_volume = 0 cond = { 'shcode': shcode, 'date': { '$gte': self.befoneday, '$lte': self.tradingday } } price_list = list( self.mongodb.find_items(cond, self.db_name, "daily_price")) if len(price_list): for i, price in enumerate(price_list): if int(price['jdiff_vol']): tot_volume = tot_volume + int(price['jdiff_vol']) if i: avg_volume = round(tot_volume / i) else: avg_volume = 0 return avg_volume def get_processing_date(self): # 모멘텀을 계산을 위해 주식거래일 추출(1일, 20일, 60일 등) offset = [0, 30, 90, 180, 360] self.momt_dates = self.wd.get_trading_day_list(self.tradingday, offset) def calc_bollingerBand_by_code(self, code): cond = { 'shcode': code['shcode'], 'date': { '$gte': self.day_90, '$lte': self.ins_date } } results = list( self.mongodb.find_items(cond, self.db_name, "daily_price")) if not len(results): return # JSON => dataframe으로 변환 df = pd.DataFrame.from_dict(results, orient='columns') df['close'] = df['close'].astype(float) df['high'] = df['high'].astype(float) df['low'] = df['low'].astype(float) df['volume'] = df['jdiff_vol'].astype(float) df['MA20'] = df['close'].rolling(window=20).mean() df['stddev'] = df['close'].rolling(window=20).std() df['upper'] = df['MA20'] + (df['stddev'] * 2) df['lower'] = df['MA20'] - (df['stddev'] * 2) df['PB'] = (df['close'] - df['lower']) / (df['upper'] - df['lower']) # 고가, 저가, 종가의 합을 3으로 나눠서 중심가격 구함. df['TP'] = (df['high'] + df['low'] + df['close']) / 3 df['PMF'] = 0 df['NMF'] = 0 # range함수는 마지막 값을 포함하지 않으므로 0부터 종가개수 -2까지 반복 for i in range(len(df.close) - 1): if df.TP.values[i] < df.TP.values[i + 1]: # 긍정적 현금흐름 : 중심가격이 전날보다 상승한 날들의 현금흐름의 합 df.PMF.values[i + 1] = df.TP.values[i + 1] * df.volume.values[i + 1] df.NMF.values[i + 1] = 0 else: # 긍정적 현금흐름 : 중심가격이 전날보다 하락한 날들의 현금흐름의 합 df.NMF.values[i + 1] = df.TP.values[i + 1] * df.volume.values[i + 1] df.PMF.values[i + 1] = 0 df['MFR'] = (df.PMF.rolling(window=10).sum() / df.NMF.rolling(window=10).sum()) df['MFI10'] = 100 - 100 / (1 + df['MFR']) df = df[19:] # 상승 하락유무 체크 df_up = df.loc[(df.date.values > self.day_search_signal) & (df.PB.values > 0.8) & (df.MFI10.values > 80), ["date", "PB", "MFI10"]] df_dw = df.loc[(df.date.values > self.day_search_signal) & (df.PB.values < 0.2) & (df.MFI10.values < 20), ["date", "PB", "MFI10"]] ins_bolband = {} if not df_up.empty or not df_dw.empty: signal = 'UP' if not df_dw.empty: signal = 'DW' # 주간, 월간, 3개월 상승율 계산 ret_1w = 0 ret_4w = 0 ret_8w = 0 ret_12w = 0 if len(df.close) - 1 - 5 > 0: ret_1w = round( (df.close.values[len(df.close) - 1] / df.close.values[len(df.close) - 1 - 5] - 1) * 100, 2) # 1주간 수익율 if len(df.close) - 1 - 20 > 0: ret_4w = round( (df.close.values[len(df.close) - 1] / df.close.values[len(df.close) - 1 - 20] - 1) * 100, 2) # 20일 한달 수익율 if len(df.close) - 1 - 40 > 0: ret_8w = round( (df.close.values[len(df.close) - 1] / df.close.values[len(df.close) - 1 - 40] - 1) * 100, 2) # 40일 두달 수익율 if len(df.close) > 0: ret_12w = round( (df.close.values[len(df.close) - 1] / df.close.values[0] - 1) * 100, 2) # 60일 두달 수익율 ins_bolband = { "shcode": code["shcode"], "hname": code["hname"], "signal": signal, "search_date": self.day_search_signal, "insdate": self.ins_date, "instime": self.ins_time, "ret_1w": ret_1w, "ret_4w": ret_4w, "ret_8w": ret_8w, "ret_12w": ret_12w } return ins_bolband def calc_momentum(self, code): if len(self.momt_dates) != 5: self.log.error("모멘텀 계산날짜가 잘못 되었습니다. !!df_dates[%d]" % len(self.momt_dates)) return {} cond = {"shcode": code['shcode'], 'date': {'$in': self.momt_dates}} price_list = list( self.mongodb.find_items(cond, self.db_name, "daily_price")) if len(price_list) != 5: self.log.error("모멘텀 계산 - 데이터 부족 !!momt_dates[%s][%d]" % (code['shcode'], len(price_list))) return {} df = pd.DataFrame.from_dict(price_list, orient='columns') df.date.sort_values() df['close'] = df['close'].astype(float) ret_1mon = round((df.close.values[4] / df.close.values[3] - 1) * 100, 2) ret_3mon = round((df.close.values[4] / df.close.values[2] - 1) * 100, 2) ret_6mon = round((df.close.values[4] / df.close.values[1] - 1) * 100, 2) ret_12mon = round((df.close.values[4] / df.close.values[0] - 1) * 100, 2) ins_code = {} if ret_1mon > 0 and ret_3mon > 0: ins_code = { "shcode": code["shcode"], "hname": code["hname"], "ret_1mon": ret_1mon, "ret_3mon": ret_3mon, "ret_6mon": ret_6mon, "ret_12mon": ret_12mon, "insdate": self.ins_date, "instime": self.ins_time } return ins_code # ins_list.append(ins_code) # c += 1 # # print('\ncount :{} \nins_list : {}'.format(c, ins_list)) # if (c % 100) == 0: # 100건 처리하고 등록 # if ins_list : # self.mongodb.insert_items(ins_list, self.db_name, "a2_momentum") # print(ins_list) # ins_list.clear() # print('\n전체 {} 건 / {} 건 처리 중....'.format(len(code_list), c)) def collect_daily_stock_data_from_ebest(self, init=False, tradingday=None): if tradingday: self.tradingday = tradingday # stock_code 업데이트 if init: self.get_stock_code_from_ebest() # code_info, daily_price 업데이트 daily_prices = [] # 일별 거래정보 code_info = list( self.mongodb.find_items({"insdate": self.ins_date}, self.db_name, "m_code_info")) if init or not code_info: code_list = list( self.mongodb.find_items({"bu12gubun": "01"}, self.db_name, "m_stock_code")) i = 0 str_codes = "" result_ext_all = [] # 종목별 거래정보 읽어오기 for code in code_list: str_codes = str_codes + code["shcode"] i = i + 1 if len(str_codes) >= 300 or len(code_list) == i: result_ext = self.ebest.get_current_price_by_shcodes( str_codes) result_ext_all.extend(result_ext) self.log.info("result_ext_all 건수[%d]" % len(result_ext_all)) str_codes = "" # 일일 종목별 가격 업데이트 (daily_price) for extend in result_ext_all: daily_price = { 'date': self.tradingday, 'time': "", 'open': extend['open'], 'high': extend['high'], 'low': extend['low'], "close": extend['bidho'], "jdiff_vol": extend['volume'], "value": extend['value'], "shcode": extend['shcode'], "hname": extend['hname'], "insdate": self.ins_date, "instime": self.ins_time } daily_prices.append(daily_price) if daily_prices: self.mongodb.delete_items({'date': self.tradingday}, self.db_name, "daily_price") self.mongodb.insert_items(daily_prices, self.db_name, "daily_price") self.log.info("daily_prices 등록.[%d]" % (len(daily_prices))) daily_prices.clear() df_code = pd.DataFrame.from_dict(code_list, orient='columns') df_exp = pd.DataFrame.from_dict(result_ext_all, orient='columns') df_exp.drop(['hname'], axis=1, inplace=True) df_exp['avg_volume'] = df_exp.apply( lambda x: self.calc_avg_volume(x['shcode'], x['volume']), axis=1) df_exp['insdate'] = self.ins_date df_exp['instime'] = self.ins_time df_all = pd.merge(df_code, df_exp, how='outer', on='shcode') code_list = df_all.to_dict(orient='records') if code_list: self.mongodb.delete_items({}, self.db_name, "m_code_info") self.mongodb.insert_items(code_list, self.db_name, "m_code_info") if not code_info: code_info = list( self.mongodb.find_items({"bu12gubun": "01"}, self.db_name, "m_code_info")) # 1. update code_info # - 주식종목 기본 + 추가 정보(전일거래량, 시가, 종가 등) # - 거래량이 만주 이하인 종목 제외 if not code_info: self.log.error("데이터 검색을 위한 자료가 없습니다.") return self.log.info("************데이터 분석 시작*********************") # 데이터 검색을 위한 날짜 초기화 self.get_processing_date() daily_prices = [] # 일별 거래정보 inc_vol_codes = [] # 거래량 증가 정보 inc_bol_bands = [] # 볼린저밴트 종목 검색 inc_momentums = [] # 종목 모멘텀 분석 # 코드정보와 주식현재가 추가, 일별 주가정보(daily_price) 업데이트 for icnt, code in enumerate(code_info): # 거래량 만주 이하인 종목은 분석하지 않음. if code['avg_volume'] is NaN: continue if code['avg_volume'] is np.NaN: continue avg_volume = int(code['avg_volume']) if avg_volume < 10000: continue # 1. 거래량 증가 종목 검색 if int(code['avg_volume']) > 0: inc_rate = int(code['volume']) / int(code['avg_volume']) else: inc_rate = 0 if inc_rate > 5: inc_code = { "shcode": code["shcode"], "hname": code["hname"], "sdate": self.tradingday, "avg_volume": int(avg_volume), "volume": int(code['volume']), "insdate": self.ins_date, "instime": self.ins_time } inc_vol_codes.append(inc_code) # 2. 볼린저밴드 종목 검색 inc_bol_band = self.calc_bollingerBand_by_code(code) if inc_bol_band: inc_bol_bands.append(inc_bol_band) # 3. 모멘텀 종목 검색 inc_momentum = self.calc_momentum(code) if inc_momentum: inc_momentums.append(inc_momentum) self.log.debug( "종목 검색 중..[%d]/[%d][%s][%s]" % (icnt, len(code_info), code["shcode"], code["hname"])) if inc_bol_bands: self.mongodb.delete_items({'insdate': self.ins_date}, self.db_name, "a1_bollband") self.mongodb.insert_items(inc_bol_bands, self.db_name, "a1_bollband") self.log.info("inc_bol_bands 등록.[%d]" % (len(inc_bol_bands))) if inc_momentums: self.mongodb.delete_items({'insdate': self.ins_date}, self.db_name, "a2_momentum") self.mongodb.insert_items(inc_momentums, self.db_name, "a2_momentum") self.log.info("inc_momentums 등록.[%d]" % (len(inc_momentums))) if inc_vol_codes: self.mongodb.delete_items({'date': self.tradingday}, self.db_name, "a3_inc_volume") self.mongodb.insert_items(inc_vol_codes, self.db_name, "a3_inc_volume") self.log.info("inc_vol_codes 등록.[%d]" % (len(inc_vol_codes))) self.insert_exec_job_list('EB', '종목코드 + 현재가 반영 작업', 'code_info', str(len(code_info)) + " 건이 정상처리 되었습니다.") pass def get_stock_code_from_ebest(self): """ :주식 종목 코드 가져오기 """ # stocks = self.mongodb.find_items({}, self.db_name, "m_stock_code") results = list(self.ebest.get_code_list("ALL")) # !!@@나중에 업그레이드 하자, db에 없는 종목만 업데이트 # for i, result in results: # for stock in stocks: # if stock['shcode'] == result['shcode']: # del self.mongodb.delete_items({}, self.db_name, "m_stock_code") self.mongodb.insert_items(results, self.db_name, "m_stock_code") self.insert_exec_job_list('EB', '종목코드 가져오기', 'm_stock_code', str(len(results)) + " 건이 정상처리 되었습니다.") def get_code_info_from_ebest(self): """ 주식 종목에 현재 가격, 거래량 정보 추가 """ result_cod = self.ebest.get_code_list("ALL") self.log.info("get_code_list%d" % len(result_cod)) result_ext_all = [] i = 0 if len(result_cod) > 0: self.log.info("t8407 주식현재가 시작") str_codes = "" for code in result_cod: str_codes = str_codes + code["shcode"] i = i + 1 if len(str_codes) >= 300 or len(result_cod) == i: result_ext = self.ebest.get_current_price_by_shcodes( str_codes) result_ext_all.extend(result_ext) self.log.info("result_ext_all 건수[%d]" % len(result_ext_all)) str_codes = "" # 코드정보와 주식현재가 병합 for code in result_cod: for extend in result_ext_all: if code["shcode"] == extend["shcode"]: code.update(extend) self.log.info("종목코드 + 주식 현재가 반영 : {} 건".format(len(result_cod))) # self.mongodb.delete_items({}, self.db_name, "m_code_info") # self.mongodb.insert_items(result_cod, self.db_name, "m_code_info") self.insert_exec_job_list('EB', '종목코드 + 현재가 반영 작업', 'code_info', str(len(result_cod)) + " 건이 정상처리 되었습니다.") def search_increase_vol_by_code(self): """ 거래량 증가 종목 검색 : 한달 평균 거래량 보다 5배 증가한 종목 수집(check_volume) """ # 증권그룹 '01' code_list = list( self.mongodb.find_items({"bu12gubun": "01"}, self.db_name, "m_code_info")) self.log.info("CODE_LIST[%d]" % len(code_list)) today = datetime.today().strftime("%Y%m%d") fromday = (datetime.today() - timedelta(days=30)).strftime("%Y%m%d") inc_codes = [] vol_codes = [] loop_cnt = 0 for code in code_list: if int(code["volume"]) < 10000: continue loop_cnt = loop_cnt + 1 if loop_cnt % 100 == 0 and len(inc_codes) > 0: print(str(loop_cnt % 100) + "//" + str(len(inc_codes))) print(code["shcode"] + "진행율 : " + str((loop_cnt / len(code_list) * 100))) self.mongodb.insert_items(inc_codes, self.db_name, "check_volume") inc_codes.clear() results = self.ebest.get_stock_chart_by_code( code["shcode"], "2", fromday, today) time.sleep(1) if len(results) > 0: # 평균 거래량 계산 tot_volume = 0 i_count = 0 for result in results: if int(result['jdiff_vol']) != 0: tot_volume = tot_volume + int(result['jdiff_vol']) i_count = i_count + 1 if i_count == 0 or tot_volume == 0: continue avg_volume = tot_volume / i_count inc_rate = int(result['jdiff_vol']) / avg_volume inc_code = { "shcode": code["shcode"], "hname": code["hname"], "sdate": today, "avg_volume": int(avg_volume), "volume": int(result['jdiff_vol']), "inc_rate": inc_rate } vol_codes.append(inc_code) print("체크 종목 :" + code["shcode"] + " 거래량 [" + result['jdiff_vol'] + "] 평균 [" + str(avg_volume) + "] 비율[" + str(inc_rate) + "]") # 거래량이 5배 이상이면 종목 추가 if inc_rate > 5: inc_codes.append(inc_code) print("추가된 종목 :" + code["shcode"] + " 건수 : " + str(len(inc_codes))) if len(inc_codes) > 0: self.mongodb.insert_items(inc_codes, self.db_name, "check_volume") if len(vol_codes) > 0: self.mongodb.insert_items(vol_codes, self.db_name, "volume") self.insert_exec_job_list('TA', '거래량 급증가 종목 검색', 'check_volume', str(len(vol_codes)) + " 건이 정상처리 되었습니다.") def insert_exec_job_list(self, jobtype, jobname, tablelist, logmsg): """ 작업로그 기록 : jobtype -> 'EB' : EBEST, 'FA': 재무분석작업, 'TA' : 기술적 분석 작업, : 'ML' : 머신러닝 예측작업, 'MA' : 재료분석 작업 """ jobs = [] today = datetime.today().strftime("%Y%m%d") totime = datetime.today().strftime("%H%M%S") job = { "jobtype": jobtype, "jobdate": today, "jobtime": totime, "jobname": jobname, "tablelist": tablelist, "logmsg": logmsg } jobs.append(job) self.mongodb.insert_items(jobs, self.db_name, "job_list") print(jobs) @staticmethod def ins_daily_price_from_ebest(self, start_date, code_list): daily_price = [] today = datetime.today().strftime("%Y%m%d") totime = datetime.today().strftime("%H%M%S") for code in code_list: results = self.ebest.get_stock_chart_by_code( code['shcode'], "2", start_date, today) for result in results: result['shcode'] = code['shcode'] result['hname'] = code['hname'] result['insdate'] = today result['instime'] = totime daily_price.append(result) if len(daily_price) > 0: self.mongodb.insert_items(daily_price, self.db_name, "daily_price") daily_price.clear() self.insert_exec_job_list('EB', '일일 주식거래정보(Candle Chart형)', 'daily_price', str(len(code_list)) + " 건이 정상처리 되었습니다.") def insert_daily_price_from_ebest(self, init=None, start_date=None, shcode=None): #### # 일일 주식 거래정보(candle chart형) # init : 1 -> 모든 종목 초기화 후 재생성, 2 -> 입력받은 코드만 조건대로 시작일 부터 갱신 #### today = datetime.today().strftime("%Y%m%d") totime = datetime.today().strftime("%H%M%S") if init == 1: #데이터 삭제 self.mongodb.delete_items({}, self.db_name, "daily_price") code_list = list( self.mongodb.find_items({"bu12gubun": "01"}, self.db_name, "m_stock_code")) if len(code_list): self.ins_daily_price_from_ebest(self, start_date, code_list) else: print("No Data!!") elif init == 2: if shcode: cond = { 'shcode': shcode, 'date': { '$gte': start_date, '$lte': today } } else: cond = {'date': {'$gte': start_date, '$lte': today}} self.mongodb.delete_items(cond, self.db_name, "daily_price") if shcode: cond = {'shcode': shcode} else: cond = {"bu12gubun": "01"} print("조건", cond) code_list = list( self.mongodb.find_items(cond, self.db_name, "m_stock_code")) if len(code_list): self.ins_daily_price_from_ebest(self, start_date, code_list) else: print("No Data !!") else: print("init error No Data !!") def search_bollingerBand_by_code(self, search_date, order_type): """볼린저 밴드 매수, 매도 시그널이 있는 종목 검색 : search_date : 검색 시작일자, order_type : 1 -> 매수, 2 -> 매도, 0 -> ALL """ today = datetime.today().strftime("%Y%m%d") totime = datetime.today().strftime("%H%M%S") fromday = (datetime.today() - timedelta(days=90)).strftime("%Y%m%d") # 기존 작업 삭제 cond = {'insdate': today} self.mongodb.delete_items(cond, self.db_name, "a1_bollband") # 증권그룹 '01' 종목리스트 조회 code_list = list( self.mongodb.find_items({"bu12gubun": "01"}, self.db_name, "m_stock_code")) print("CODE_LIST", len(code_list)) c = 0 # count ins_list = [] for code in code_list: cond = { 'shcode': code['shcode'], 'date': { '$gte': fromday, '$lte': today } } results = list( self.mongodb.find_items(cond, self.db_name, "daily_price")) if not len(results): continue # JSON => dataframe으로 변환 df = pd.DataFrame.from_dict(results, orient='columns') df['close'] = df['close'].astype(float) df['high'] = df['high'].astype(float) df['low'] = df['low'].astype(float) df['volume'] = df['jdiff_vol'].astype(float) df['MA20'] = df['close'].rolling(window=20).mean() df['stddev'] = df['close'].rolling(window=20).std() df['upper'] = df['MA20'] + (df['stddev'] * 2) df['lower'] = df['MA20'] - (df['stddev'] * 2) df['PB'] = (df['close'] - df['lower']) / (df['upper'] - df['lower']) # 고가, 저가, 종가의 합을 3으로 나눠서 중심가격 구함. df['TP'] = (df['high'] + df['low'] + df['close']) / 3 df['PMF'] = 0 df['NMF'] = 0 # range함수는 마지막 값을 포함하지 않으므로 0부터 종가개수 -2까지 반복 for i in range(len(df.close) - 1): if df.TP.values[i] < df.TP.values[i + 1]: # 긍정적 현금흐름 : 중심가격이 전날보다 상승한 날들의 현금흐름의 합 df.PMF.values[ i + 1] = df.TP.values[i + 1] * df.volume.values[i + 1] df.NMF.values[i + 1] = 0 else: # 긍정적 현금흐름 : 중심가격이 전날보다 하락한 날들의 현금흐름의 합 df.NMF.values[ i + 1] = df.TP.values[i + 1] * df.volume.values[i + 1] df.PMF.values[i + 1] = 0 df['MFR'] = (df.PMF.rolling(window=10).sum() / df.NMF.rolling(window=10).sum()) df['MFI10'] = 100 - 100 / (1 + df['MFR']) df = df[19:] # 상승 하락유무 체크 df_up = df.loc[(df.date.values > search_date) & (df.PB.values > 0.8) & (df.MFI10.values > 80), ["date", "PB", "MFI10"]] df_dw = df.loc[(df.date.values > search_date) & (df.PB.values < 0.2) & (df.MFI10.values < 20), ["date", "PB", "MFI10"]] if not df_up.empty or not df_dw.empty: signal = 'UP' if not df_dw.empty: signal = 'DW' # 주간, 월간, 3개월 상승율 계산 ret_1w = round( (df.close.values[len(df.close) - 1] / df.close.values[len(df.close) - 1 - 5] - 1) * 100, 2) # 1주간 수익율 ret_4w = round( (df.close.values[len(df.close) - 1] / df.close.values[len(df.close) - 1 - 20] - 1) * 100, 2) # 20일 한달 수익율 ret_8w = round( (df.close.values[len(df.close) - 1] / df.close.values[len(df.close) - 1 - 40] - 1) * 100, 2) # 40일 두달 수익율 ret_12w = round( (df.close.values[len(df.close) - 1] / df.close.values[0] - 1) * 100, 2) # 60일 두달 수익율 ins_code = { "shcode": code["shcode"], "hname": code["hname"], "signal": signal, "search_date": search_date, "insdate": today, "instime": totime, "ret_1w": ret_1w, "ret_4w": ret_1w, "ret_8w": ret_8w, "ret_12w": ret_12w } ins_list.append(ins_code) # for i in range(len(df.close)): # if df.PB.values[i] > 0.8 and df.MFI10.values[i] > 80: # ① # print("매수신호") # elif df.PB.values[i] < 0.2 and df.MFI10.values[i] < 20: # ③ # print("매도신호") c += 1 # print('\ncount :{} \nins_list : {}'.format(c, ins_list)) # if ins_list: # return if (c % 100) == 0: # 100건 처리하고 등록 if ins_list: self.mongodb.insert_items(ins_list, self.db_name, "a1_bollband") print(ins_list) ins_list.clear() print('\n전체 {} 건 / {} 건 처리 중....'.format(len(code_list), c)) self.insert_exec_job_list('TA', '볼린저 밴드 매수 시그날 종목 검색', 'a1_bollband', str(len(code_list)) + " 건이 정상처리 되었습니다.") def search_momentum(self): """ 모멘텀 종목 검색 : """ today = datetime.today().strftime("%Y%m%d") totime = datetime.today().strftime("%H%M%S") fromday = (datetime.today() - timedelta(days=90)).strftime("%Y%m%d") # 기존 작업 삭제 cond = {'insdate': today} self.mongodb.delete_items(cond, self.db_name, "a2_momentum") # 네이버 조회를 통해 모멘텀 계산할 일자 조회 price_list = list( self.mongodb.find_items({"shcode": "035420"}, self.db_name, "daily_price")) if not price_list: print("Not found price Data !!") return df = pd.DataFrame.from_dict(price_list, orient='columns') df_dates = df.iloc[[ len(df.close) - 1, len(df.close) - 21, len(df.close) - 61, len(df.close) - 121, len(df.close) - 241 ], ] if len(df_dates) != 5: print("Not correct dates !!") return # 증권그룹 '01' 종목리스트 조회 code_list = list( self.mongodb.find_items({"bu12gubun": "01"}, self.db_name, "m_stock_code")) print("CODE_LIST", len(code_list)) c = 0 # count ins_list = [] # 종목별 상승율 계산 for code in code_list: cond = { "shcode": code['shcode'], 'date': { '$in': df_dates.date.values.tolist() } } price_list = list( self.mongodb.find_items(cond, self.db_name, "daily_price")) df = pd.DataFrame.from_dict(price_list, orient='columns') df.date.sort_values() df['close'] = df['close'].astype(float) ret_1mon = round( (df.close.values[4] / df.close.values[3] - 1) * 100, 2) ret_3mon = round( (df.close.values[4] / df.close.values[2] - 1) * 100, 2) ret_6mon = round( (df.close.values[4] / df.close.values[1] - 1) * 100, 2) ret_12mon = round( (df.close.values[4] / df.close.values[0] - 1) * 100, 2) if ret_1mon > 0 and ret_3mon > 0: ins_code = { "shcode": code["shcode"], "hname": code["hname"], "insdate": today, "instime": totime, "ret_1mon": ret_1mon, "ret_3mon": ret_3mon, "ret_6mon": ret_6mon, "ret_12mon": ret_12mon } ins_list.append(ins_code) c += 1 # print('\ncount :{} \nins_list : {}'.format(c, ins_list)) if (c % 100) == 0: # 100건 처리하고 등록 if ins_list: self.mongodb.insert_items(ins_list, self.db_name, "a2_momentum") print(ins_list) ins_list.clear() print('\n전체 {} 건 / {} 건 처리 중....'.format(len(code_list), c)) self.insert_exec_job_list('TA', '모멘텀 상승 종목 검색', 'a2_momentum', str(len(code_list)) + " 건이 정상처리 되었습니다.") def collect_stock_info(self): code_list = self.mongodb.find_items({}, self.db_name, "m_code_info") target_code = set([item["단축코드"] for item in code_list]) today = datetime.today().strftime("%Y%m%d") collect_list = self.mongodb.find_items({ "날짜": today }, self.db_name, "price_info").distinct("code") for col in collect_list: target_code.remove(col) for code in target_code: result_price = self.ebest.get_stock_price_by_code(code, "1") time.sleep(1) if len(result_price) > 0: self.mongodb.insert_items(result_price, self.db_name, "price_info") def collect_theme_info(self): # 테마 정보 분석 # tm_momt_date : 테마 모멘텀 분석 비교일자 # 테마코드 조회(마스터) tm_list = self.ebest.get_theme_by_tmcode("", "") # 특이 테마 조회 tm_momt_list = self.ebest.find_special_theme("1", self.day_search_signal) tm_price_list = [] # 테마 마스터와 특이테마 merge for i, tm in enumerate(tm_list): for tm_momt in tm_momt_list: if tm['tmcode'] == tm_momt['tmcode']: tm.update(tm_momt) tm.update({ "insdate": self.ins_date, "instime": self.ins_time }) if i < 70: tm_result = self.ebest.get_price_by_theme(tm['tmcode']) for tm_re in tm_result: tm_re.update({ "tmcode": tm['tmcode'], "tmname": tm['tmname'], "insdate": self.ins_date, "instime": self.ins_time }) tm_price_list.extend(tm_result) # 거래량, # print(tm_list) df = pd.DataFrame.from_dict(tm_list, orient='columns') df_price_list = pd.DataFrame.from_dict(tm_price_list, orient='columns') df['rank_avgdiff'] = df['avgdiff'].rank(method='min', ascending=False) df['rank_uprate'] = df['uprate'].rank(method='min', ascending=False) df['rank_diff_vol'] = df['diff_vol'].rank(method='min', ascending=False) df['rank_sum'] = df['rank_avgdiff'] + df['rank_diff_vol'] + df[ 'rank_uprate'] df_rank = df.sort_values(by='rank_sum').head(40) print("df_rank", df_rank) print("\ndf_price_list", df_price_list) # tm_code = df_rank['tmcode'] # print("df_rank", tm_code) # df_ddd = df_price_list[tm_code] # print("\ndf_rank", df_ddd) df_merge = pd.merge(df_rank, df_price_list, how='inner', on='tmcode') df_merge = df_merge.astype({'marketcap': 'float'}) # 중복 컬럼 삭제 df_merge.drop(['tmname_y'], axis=1, inplace=True) df_merge.drop(['insdate_y'], axis=1, inplace=True) df_merge.drop(['instime_y'], axis=1, inplace=True) df_merge.rename(columns={ 'tmname_x': 'tmname', 'insdate_x': 'insdate', 'instime_x': 'instime' }, inplace=True) # df_rank.join(df_price_list, how='inner') if not df_merge.empty: df_merge['rank_by_code'] = df_merge.groupby( 'tmcode')['marketcap'].rank(method='min', ascending=False) df_tm_rank = df_merge[df_merge['rank_by_code'] < 10] tm_rank_list = df_tm_rank.to_dict(orient='records') self.mongodb.delete_items({'insdate': self.ins_date}, self.db_name, "a4_theme_momentum") self.mongodb.insert_items(tm_rank_list, self.db_name, "a4_theme_momentum") self.log.info("a4_theme_momentum 등록.[%d]" % (len(tm_rank_list))) tm_list.clear() tm_list = df.to_dict(orient='records') if tm_list: self.mongodb.delete_items({'insdate': self.ins_date}, self.db_name, "m_theme_code") self.mongodb.insert_items(tm_list, self.db_name, "m_theme_code") self.log.info("m_theme_code 등록.[%d]" % (len(tm_list))) if tm_price_list: self.mongodb.delete_items({'insdate': self.ins_date}, self.db_name, "theme_price") self.mongodb.insert_items(tm_price_list, self.db_name, "theme_price") self.log.info("theme_price 등록.[%d]" % (len(tm_price_list))) # print(df_head) pass def counting_event(self, h1, h2, h3, h4): count = 0 if not h1 is NaN: count += 1 if not h2 is NaN: count += 1 if not h3 is NaN: count += 1 if not h4 is NaN: count += 1 return count def run_technical_analysis(self): # self.tradingday = '20210609' print(self.tradingday) a1_list = list( self.mongodb.find_items({ 'insdate': self.ins_date, 'signal': 'UP' }, self.db_name, "a1_bollband")) a2_list = list( self.mongodb.find_items({'insdate': self.ins_date}, self.db_name, "a2_momentum")) a3_list = list( self.mongodb.find_items({'insdate': self.ins_date}, self.db_name, "a3_inc_volume")) a4_list = list( self.mongodb.find_items({'insdate': self.ins_date}, self.db_name, "a4_theme_momentum")) df_a1 = pd.DataFrame.from_dict(a1_list, orient='columns') df_a2 = pd.DataFrame.from_dict(a2_list, orient='columns') df_a3 = pd.DataFrame.from_dict(a3_list, orient='columns') df_a4 = pd.DataFrame.from_dict(a4_list, orient='columns') print("a1_list", a1_list) print("df_a1", df_a1) df_a1 = df_a1[['shcode', 'hname']] df_a2 = df_a2[['shcode', 'hname']] df_a3 = df_a3[['shcode', 'hname', 'volume']] df_a4 = df_a4[['shcode', 'hname', 'tmcode', 'tmname']] df_a2.rename(columns={'hname': 'hname_a2'}, inplace=True) df_a3.rename(columns={'hname': 'hname_a3'}, inplace=True) df_a4.rename(columns={'hname': 'hname_a4'}, inplace=True) df_merge = pd.merge(df_a1, df_a2, how='outer', left_on='shcode', right_on='shcode') df_merge = pd.merge(df_merge, df_a3, how='outer', left_on='shcode', right_on='shcode') df_merge = pd.merge(df_merge, df_a4, how='outer', left_on='shcode', right_on='shcode') # df_a1.drop(['search_date'], axis=1, inplace=True) # df_a1.drop(['insdate'], axis=1, inplace=True) # df_a1.drop(['instime'], axis=1, inplace=True) # df_a2.drop(['hname'], axis=1, inplace=True) # df_a2.drop(['insdate'], axis=1, inplace=True) # df_a2.drop(['instime'], axis=1, inplace=True) # df_a3.drop(['hname'], axis=1, inplace=True) # df_a3.drop(['insdate'], axis=1, inplace=True) # df_a3.drop(['instime'], axis=1, inplace=True) # df_a4.drop(['hname'], axis=1, inplace=True) # df_a4.drop(['insdate'], axis=1, inplace=True) # df_a4.drop(['instime'], axis=1, inplace=True) # df_merge = pd.merge(df_a1, df_a2, df_a3, df_a4, how='outer',on='shcode') df_merge['event_cnt'] = df_merge.apply(lambda x: self.counting_event( x['hname'], x['hname_a2'], x['hname_a3'], x['hname_a4']), axis=1) df_merge.sort_values(by=['event_cnt'], axis=0, ascending=False, inplace=True) print('df_merge', df_merge.head(30)) pass
def setUp(self): self.ebest = EBest("DEMO") self.ebest.login() self.ebest.change_field_lang('E') self.mongodb = MongoDBHandler()
class TestEbest(unittest.TestCase): def setUp(self): self.ebest = EBest("DEMO") self.ebest.login() self.ebest.change_field_lang('E') self.mongodb = MongoDBHandler() # self.job = Job() # 주식 코드 가져오기 # def test_collect_code_list(self): # print("start") # result = self.ebest.get_code_list("ALL") # print(result) # self.mongodb.delete_items({}, "stock", "m_stock_code") # self.mongodb.insert_items(result, "stock", "m_stock_code") def test_get_current_price_by_code(self): start = datetime.now() code_list = list( self.mongodb.find_items({"bu12gubun": "01"}, "stock1", "m_stock_code")) result_ext_all = list( self.mongodb.find_items({}, "stock1", "m_code_info")) start = datetime.now() # totCount = len(code_list) # for i, item in enumerate( code_list ): # result = self.ebest.get_current_price_by_code(item['shcode']) # print("처리중[%d] / [%d]" %(i, totCount)) # if i > 100 : break print(len(code_list)) # print(code_list) df_code = pd.DataFrame.from_dict(code_list, orient='columns') df_exp = df_code #pd.DataFrame.from_dict(result_ext_all, orient='columns') # df_exp.columns = df_exp.columns.str.capitalize() print(df_code.columns) print(df_exp.columns) df_exp.drop(['hname'], axis=1, inplace=True) # df_exp.drop(df_code.columns, axis=1, inplace=True) # df_all = pd.merge(df_code, df_exp, how='outer',on='shcode') print(df_exp.head()) codelist = df_code.to_json(default_handler=str, orient='records') print(len(df_code)) print(len(codelist)) # for code in codelist : # pass # print(codelist) print("프로그램 종료시간", datetime.now() - start) # 현재일자 검색과 daily_price 업데이트 최종업데이트 일자 # def test_get_last_day(self): # fromday = (datetime.today() - timedelta(days=10)).strftime("%Y%m%d") # today = datetime.today().strftime("%Y%m%d") # result_sc = self.ebest.get_stock_chart_by_code('035420', "2", fromday, today) # # result_sc.sort('date') # print(result_sc) # tradingday = '' # for sc in result_sc: # if sc['date'] > tradingday: # tradingday = sc['date'] # print("dddddddddd", tradingday) # cond = {'shcode': '035420', 'date': tradingday} # results = list(self.mongodb.find_items(cond, 'stock1', "daily_price")) # if len(results) > 0: # flag_daily_price = True # print("\n results", results) # Naver 일별 주식 가져오기 테스트 # def test_get_daily_price(self): # self.ebest.change_field_lang('E') # results = self.ebest.get_stock_chart_by_code('035420', "2", '20200101', '20210507') # naver # for result in results: # # print(result) # result['shcode'] ='035420' # self.mongodb.delete_items({}, "stock", "daily_price") # self.mongodb.insert_items(results, "stock", "daily_price") # results = self.ebest.get_stock_chart_by_code('036570', "2", '20200101', '20210507') # 엔씨소프트 # for result in results: # # print(result) # result['shcode'] ='036570' # # print(results) # self.mongodb.insert_items(results, "stock", "daily_price") # def test_getcurrent_price(self): # result = self.job.get(4) # result = self.ebest.get_code_list("ALL") # print(result) # result = self.ebest.get_current_price_by_shcodes("000225005930") # print("start") # result = self.ebest.get_code_list("ALL") # print(result) # self.mongodb.delete_items({}, "stock", "m_code_info") # self.mongodb.insert_items(result, "stock", "m_code_info") # def test_get_stock_chart_by_code(self): # print("start get_stock_chart_by_code") # code_list = list(self.mongodb.find_items({}, "stock", "m_code_info")) # target_code = set([item["단축코드"] for item in code_list]) # # print(target_code) # today = datetime.today().strftime("%Y%m%d") # fromday = (datetime.today() - timedelta(days=30)).strftime("%Y%m%d") # inc_codes = [] # # print(code_list) # loop_cnt = 0 # for code in code_list: # loop_cnt = loop_cnt + 1 # if loop_cnt % 100 == 0 and len(inc_codes) > 0 : # print(str(loop_cnt % 100) + "//" + str(len(inc_codes))) # print(code["단축코드"]+ "진행율 : " + str((loop_cnt / len(code_list) * 100))) # self.mongodb.insert_items(inc_codes, "stock", "check_volume") # inc_codes.clear() # print(code["단축코드"]) # results = self.ebest.get_stock_chart_by_code(code["단축코드"], "2", fromday, today) # time.sleep(1) # if len(results) > 0: # # 평균 거래량 계산 # tot_volume = 0 # i_count = 0 # for result in results: # if int(result['거래량']) != 0 : # tot_volume = tot_volume + int(result['거래량']) # i_count= i_count + 1 # if i_count == 0 or tot_volume == 0: # continue # avg_volume = tot_volume / i_count # inc_rate = int(result['거래량']) / avg_volume # print("체크 종목 :" + code["종목명"] + " 거래량 [" + result['거래량'] + "] 평균 [" + str(avg_volume) + "] 비율[" + str(inc_rate) + "]") # # 거래량이 5배 이상이면 종목 추가 # if inc_rate > 5 : # inc_code = {"code": code["단축코드"], "종목명": code["종목명"], "sdate": today, "avg_volume": int(avg_volume), "volume":int(result['거래량'])} # inc_codes.append(inc_code) # print("추가된 종목 :" + code["종목명"] + " 건수 : " + str(len(inc_codes))) # if len(inc_codes) > 0 : # self.mongodb.insert_items(inc_codes, "stock", "check_volume") # def test_get_company_fi_rank(self): # print("start get_company_fi_rank") # result = self.ebest.get_company_fi_rank("ALL", "1") # # print(result) # print(len(result)) # def test_get_code_list(self): # fromday = (datetime.today() - timedelta(days=30)).strftime("%Y%m%d") # print(fromday) # print(inspect.stack()[0][3]) # result = self.ebest.get_code_list("ALL") # assert result is not None # print(len(result)) # def test_get_account_info(self): # print("start!!") # result = self.ebest.get_account_info() # assert result is not None # print(result) # def test_get_account_stock_info(self): # result = self.ebest.get_account_stock_info() # assert result is not None # print(result) # def test_get_stock_price_by_code(self): # print(inspect.stack()[0][3]) # result = self.ebest.get_stock_price_by_code("005930", "30") # assert result is not None # print(result) # result = self.ebest.get_code_list("ALL") # print(result) def tearDown(self): self.ebest.logout() print("tearDown")
def get(self, id=None): if id: print("get method id :" + str(id)) # 종목코드 가져오기 if id == 1: ebest = EBest("DEMO") ebest.login() result_cod = ebest.get_code_list("ALL") print("get_code_list", len(result_cod)) result_ext_all = [] i = 0 if len(result_cod) > 0: print("t8407 주식현재가 시작") str_codes = "" for code in result_cod: str_codes = str_codes + code["단축코드"] i = i + 1 if len(str_codes) >= 300 or len(result_cod) == i: result_ext = ebest.get_current_price_by_shcodes( str_codes) result_ext_all.extend(result_ext) print("result_ext_all 건수", len(result_ext_all)) str_codes = "" # 코드정보와 주식현재가 병합 for code in result_cod: for extend in result_ext_all: if code["단축코드"] == extend["종목코드"]: code.update(extend) print("result_cod 건수", len(result_cod)) mongodb = MongoDBHandler() mongodb.delete_items({}, "stock", "m_code_info") mongodb.insert_items(result_cod, "stock", "m_code_info") # collect_code_list() # collect_stock_info() return { "errcode": 0, "errmsg": str(len(result_cod)) + " 건이 정상처리 되었습니다." } # 종목가격정보 가져오기 elif id == 2: ebest = EBest("DEMO") ebest.login() code_list = mongodb.find_items({}, "stock", "m_code_info") target_code = set([item["단축코드"] for item in code_list]) today = datetime.today().strftime("%Y%m%d") collect_list = mongodb.find_items({ "날짜": today }, "stock", "price_info").distinct("code") for col in collect_list: target_code.remove(col) for code in target_code: result_price = ebest.get_stock_price_by_code(code, "1") time.sleep(1) if len(result_price) > 0: mongodb.insert_items(result_price, "stock", "price_info") return { "errcode": 0, "errmsg": str(len(result)) + " 건이 정상처리 되었습니다." } # 모든 종목정보 가져오기 elif id == 3: ebest = EBest("DEMO") mongodb = MongoDBHandler() ebest.login() code_list = mongodb.find_items({}, "stock", "m_code_info") target_code = set([item["단축코드"] for item in code_list]) today = datetime.today().strftime("%Y%m%d") print(today) collect_list = mongodb.find_items({ "날짜": today }, "stock", "price_info").distinct("code") for col in collect_list: target_code.remove(col) for code in target_code: time.sleep(1) print("code:", code) result_price = ebest.get_stock_price_by_code(code, "1") if len(result_price) > 0: print(result_price) mongodb.insert_items(result_price, "stock", "price_info") result_credit = ebest.get_credit_trend_by_code(code, today) if len(result_credit) > 0: mongodb.insert_items(result_credit, "stock", "credit_info") result_short = ebest.get_short_trend_by_code(code, sdate=today, edate=today) if len(result_short) > 0: mongodb.insert_items(result_short, "stock", "short_info") result_agent = ebest.get_agent_trend_by_code(code, fromdt=today, todt=today) if len(result_agent) > 0: mongodb.insert_items(result_agent, "stock", "agent_info") # 일자별 주가정보에서 평균 거래량 가져오기(거래량 증가 종목 찾기) elif id == 4: ebest = EBest("DEMO") ebest.login() mongodb = MongoDBHandler() code_list = list(mongodb.find_items({}, "stock", "m_code_info")) print(len(code_list)) target_code = set([item["단축코드"] for item in code_list]) # print(target_code) today = datetime.today().strftime("%Y%m%d") fromday = (datetime.today() - timedelta(days=30)).strftime("%Y%m%d") inc_codes = [] vol_codes = [] loop_cnt = 0 for code in code_list: if int(code["누적거래량"]) < 10000: continue loop_cnt = loop_cnt + 1 if loop_cnt % 100 == 0 and len(inc_codes) > 0: print(str(loop_cnt % 100) + "//" + str(len(inc_codes))) print(code["단축코드"] + "진행율 : " + str((loop_cnt / len(code_list) * 100))) mongodb.insert_items(inc_codes, "stock", "check_volume") inc_codes.clear() results = ebest.get_stock_chart_by_code( code["단축코드"], "2", fromday, today) time.sleep(1) if len(results) > 0: # 평균 거래량 계산 tot_volume = 0 i_count = 0 for result in results: if int(result['거래량']) != 0: tot_volume = tot_volume + int(result['거래량']) i_count = i_count + 1 if i_count == 0 or tot_volume == 0: continue avg_volume = tot_volume / i_count inc_rate = int(result['거래량']) / avg_volume inc_code = { "code": code["단축코드"], "종목명": code["종목명"], "sdate": today, "avg_volume": int(avg_volume), "volume": int(result['거래량']) } vol_codes.append(inc_code) print("체크 종목 :" + code["종목명"] + " 거래량 [" + result['거래량'] + "] 평균 [" + str(avg_volume) + "] 비율[" + str(inc_rate) + "]") # 거래량이 5배 이상이면 종목 추가 if inc_rate > 5: inc_codes.append(inc_code) print("추가된 종목 :" + code["종목명"] + " 건수 : " + str(len(inc_codes))) if len(inc_codes) > 0: mongodb.insert_items(inc_codes, "stock", "check_volume") if len(vol_codes) > 0: mongodb.insert_items(vol_codes, "stock", "volume") return { "errcode": 0, "errmsg": str(len(vol_codes)) + " 건이 정상처리 되었습니다." } elif id == 5: print("Error Id : " + str(id)) else: print("Error Id : " + str(id)) else: print("list of users") # collect_code_list() # collect_stock_info() return "list of users"
from datetime import datetime import time from common.agent.ebest import EBest from common.db_handler.mongodb_handler import MongoDBHandler mongodb = MongoDBHandler() ebest = EBest("DEMO") ebest.login() def collect_code_list(): result = ebest.get_code_list("ALL") mongodb.delete_items({}, "stock", "m_code_info") mongodb.insert_items(result, "stock", "m_code_info") def collect_stock_info(): code_list = mongodb.find_items({}, "stock", "m_code_info") target_code = set([item["단축코드"] for item in code_list]) today = datetime.today().strftime("%Y%m%d") collect_list = mongodb.find_items({ "날짜": today }, "stock", "price_info").distinct("code") for col in collect_list: target_code.remove(col) for code in target_code: result_price = ebest.get_stock_price_by_code(code, "1") time.sleep(1) if len(result_price) > 0: mongodb.insert_items(result_price, "stock", "price_info")