From 69acec2a8cc45a63425cedc9294894ff19b49915 Mon Sep 17 00:00:00 2001 From: dosangyoon Date: Fri, 1 Oct 2021 23:08:55 +0900 Subject: [PATCH] init --- hts/20211001.csv | 2 +- hts/HTS.py | 590 ++++++++-------- hts/HTS_5min.py | 1047 +++++++++++++++++++++++++++++ stockpredictor/analysis/Common.py | 3 + 4 files changed, 1316 insertions(+), 326 deletions(-) create mode 100644 hts/HTS_5min.py diff --git a/hts/20211001.csv b/hts/20211001.csv index 7c0d085..0a2870f 100644 --- a/hts/20211001.csv +++ b/hts/20211001.csv @@ -379,4 +379,4 @@ 20211001,1518,2255,2255,2250,2255,228391 20211001,1519,2250,2255,2250,2250,283367 20211001,1520,2255,2255,2250,2255,537260 -20211001,1530,2255,2255,2255,2255,3911937 \ No newline at end of file +20211001,1530,2255,2255,2255,2255,3911937 diff --git a/hts/HTS.py b/hts/HTS.py index c3b3f4e..70a2793 100644 --- a/hts/HTS.py +++ b/hts/HTS.py @@ -5,7 +5,7 @@ from datetime import datetime, timedelta import pandas as pd from enum import Enum import plotly.graph_objects as go - +from stockpredictor.analysis.Common import Common # enum 주문 상태 세팅용 class EorderBS(Enum): @@ -30,10 +30,12 @@ class HTS: objCpCybos = None objCpCodeMgr = None + common = None stock = [] def __init__(self): + self.common = Common() #self.connect() return @@ -505,25 +507,23 @@ class HTS: size = len(result["open"]) window = 5 - open = [result["open"][i] for i in range(0, size, window)] - close = [result["close"][i-1] for i in range(window-1, size, window)] - for i in range(len(open)-len(close)): - close.append(result["close"][len(result["close"])-1]) - high = [max(result["high"][i:i+window]) for i in range(0, size, window)] - low = [min(result["low"][i:i+window]) for i in range(0, size, window)] - vol = [sum(result["vol"][i:i+window]) for i in range(0, size, window)] + open = result["open"] + close = result["close"] + high = result["high"] + low = result["low"] + vol = result["vol"] close_df = pd.DataFrame(close) - ma2_list = close_df.rolling(window=2).mean().fillna(close[0]).values.tolist() - ma2 = [item[0] for item in ma2_list] - ma5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist() - ma5 = [item[0] for item in ma5_list] - ma10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist() - ma10 = [item[0] for item in ma10_list] - ma15_list = close_df.rolling(window=15).mean().fillna(close[0]).values.tolist() - ma15 = [item[0] for item in ma15_list] - ma20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist() - ma20 = [item[0] for item in ma20_list] + avg5_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist() + avg5 = [item[0] for item in avg5_list] + avg20_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist() + avg20 = [item[0] for item in avg20_list] + avg60_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist() + avg60 = [item[0] for item in avg60_list] + avg120_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist() + avg120 = [item[0] for item in avg120_list] + avg240_list = close_df.rolling(window=40).mean().fillna(close[0]).values.tolist() + avg240 = [item[0] for item in avg240_list] upper, lower = [], [] for i in range(len(upper_df)): @@ -534,16 +534,14 @@ class HTS: upper.append(upper_df.values[i][0]) lower.append(lower_df.values[i][0]) - point_temp = [result["time"][i] for i in range(size) if i % window == 0] - upper_temp = [upper[i] for i in range(size) if i % window == 0] - lower_temp = [lower[i] for i in range(size) if i % window == 0] + point_temp = result["time"] - temp = {"Date": point_temp, "Open": open, "High": high, "Low": low, "Close": close, "Volume": vol, "ma2": ma2, "ma5": ma5, "ma10": ma10, "ma15": ma15, "ma20": ma20} + temp = {"Date": point_temp, "Open": open, "High": high, "Low": low, "Close": close, "Volume": vol, "avg5": avg5, "avg20": avg20, "avg60": avg60, "avg120": avg120, "avg240": avg240} data = pd.DataFrame(temp) df_final_time = pd.DatetimeIndex(point_temp) data.index = df_final_time - return data, upper_temp, lower_temp + return data, upper, lower def draw(self, given_day, data, upper, lower, bsLine): buy_line = bsLine['buy'] @@ -555,11 +553,11 @@ class HTS: data['Low'] = pd.to_numeric(data['Low']) data['Close'] = pd.to_numeric(data['Close']) data['Volume'] = pd.to_numeric(data['Volume']) - data['ma2'] = pd.to_numeric(data['ma2']) - data['ma5'] = pd.to_numeric(data['ma5']) - data['ma10'] = pd.to_numeric(data['ma10']) - data['ma15'] = pd.to_numeric(data['ma15']) - data['ma20'] = pd.to_numeric(data['ma20']) + data['avg5'] = pd.to_numeric(data['avg5']) + data['avg20'] = pd.to_numeric(data['avg20']) + data['avg60'] = pd.to_numeric(data['avg60']) + data['avg120'] = pd.to_numeric(data['avg120']) + data['avg240'] = pd.to_numeric(data['avg240']) buy_colors = [] for i in range(len(buy_line)): @@ -581,290 +579,246 @@ class HTS: sell_check = go.Scatter(x=data['Date'], y=sell_line, mode='markers', name="sell", marker=dict(size=14, color=sell_colors, line_width=0)) bolinger_upper = go.Scatter(x=data['Date'], y=upper, name="upper", line_color='#8B4513') bolinger_lower = go.Scatter(x=data['Date'], y=lower, name="lower", line_color='#8B4513') - ma2 = go.Scatter(x=data['Date'], y=data['ma2'], name="ma2", line_color='#FF0000') - ma5 = go.Scatter(x=data['Date'], y=data['ma5'], name="ma5", line_color='#F43B86') - ma10 = go.Scatter(x=data['Date'], y=data['ma10'], name="ma10", line_color='#F0A500') - ma15 = go.Scatter(x=data['Date'], y=data['ma15'], name="ma15", line_color='#14279B') - ma20 = go.Scatter(x=data['Date'], y=data['ma20'], name="ma20", line_color='#000000') + avg5 = go.Scatter(x=data['Date'], y=data['avg5'], name="avg5", line_color='#FF0000') + avg20 = go.Scatter(x=data['Date'], y=data['avg20'], name="avg20", line_color='#F43B86') + avg60 = go.Scatter(x=data['Date'], y=data['avg60'], name="avg60", line_color='#F0A500') + avg120 = go.Scatter(x=data['Date'], y=data['avg120'], name="avg120", line_color='#14279B') + avg240 = go.Scatter(x=data['Date'], y=data['avg240'], name="avg240", line_color='#000000') candle_stick = go.Candlestick(x=data['Date'], open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], increasing_line_color='red', decreasing_line_color='blue') # 그래프를 그린다. - fig = go.Figure(data=[candle_stick, bolinger_upper, bolinger_lower, buy_check, sell_check, ma2, ma10, ma15, ma20]) + fig = go.Figure(data=[candle_stick, bolinger_upper, bolinger_lower, buy_check, sell_check, avg5, avg20, avg60, avg120, avg240]) fig.update_layout(title=given_day + "_2x") fig.show() return - def checkTransaction(self, data, upper, lower): - low = data["Low"] - high = data["High"] - close = data["Close"] - open = data["Open"] - ma2 = data["ma2"] - ma10 = data["ma10"] - ma15 = data["ma15"] - ma20 = data["ma20"] + def checkStatus(self, STOCK, last_index): + status = set() + + # 정배열 체크 + temp_status = self.common.check_RightArrange(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 20일선 돌파 + temp_status = self.common.check_Dolpa_Jiji(STOCK, last_index, '20') + if temp_status != "": + status.add(temp_status) + + # 60일선 돌파 + temp_status = self.common.check_Dolpa_Jiji(STOCK, last_index, '60') + if temp_status != "": + status.add(temp_status) + + # 120일선 돌파 + temp_status = self.common.check_Dolpa_Jiji(STOCK, last_index, '120') + if temp_status != "": + status.add(temp_status) + + # 240일선 돌파 + temp_status = self.common.check_Dolpa_Jiji(STOCK, last_index, '240') + if temp_status != "": + status.add(temp_status) + + # 20일선 지지 매수가 추천 + temp_status = self.common.check_Dolpa_Jiji_20(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 음봉인데 어제보다 종가가 더 높은 경우 + # 이 경우 정배열 상태인지도 함께 체크를 한다. + higher_umbong_status = self.common.checkHigherUmbong(STOCK, last_index) + if higher_umbong_status != "": + status.add(temp_status) + + # GOLDENCROSS#1은 바로 매수하지 않고, 이 시점 이후로 5일선이 20일선을 하방으로 뚫었다가 다시 20일선을 상방으로 뚫는 순간 매수를 시도한다. + # GOLDENCROSS#2은 바로 매수 가능 + # GOLDENCROSS#3은 바로 매수 가능 + temp_status = self.common.check_golded_cross(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # YANGBONG + # 어제 음봉 이후 장대양봉이었다면, 매수 + temp_status = self.common.checkLongYangBongAfterUmBong(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # Doji + # 하락 추세에서 도지가 나오면 매수 + temp_status = self.common.checkDoji(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # Gravestone + # 상승 추세에서 그레이브스톤이 나오면 매도 + temp_status = self.common.checkGravestone(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # Dragonfly + # 하락 추세에서 드레곤플라이가 나오면 매수 + temp_status = self.common.checkDragonfly(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # Hammer + temp_status = self.common.checkHammer(STOCK, last_index) + # 하락 추세에서 해머가 나오면 매수 + if temp_status != "": + status.add(temp_status) + + # Hangingman + temp_status = self.common.checkHangingman(STOCK, last_index) + # 상승 추세에서 행잉맨이 나오면 매도 + if temp_status != "": + status.add(temp_status) + + # 상승장악형 (Engulfing) - 다음 날도 양봉이라면 매수 + # 하락 추세에서 상승장악형이 나오면 매수 + temp_status = self.common.checkEngulfingHigh(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 하락장악형 (Engulfing) + # 상승 추세에서 하락장악형이 나오면 매도 + temp_status = self.common.checkEngulfingLow(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 상승 포아형 (Harami) + # 하락 추세에서 상승포아형이 나오면 매수 + temp_status = self.common.checkHaramiHigh(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 하락 포아형 (Harami) + # 상승 추세에서 하락포아형이 나오면 매도 + temp_status = self.common.checkHaramiLow(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 관통형 (piercing) + # 하락 추세에서 관통형이 나오면 매수 + temp_status = self.common.checkPiercing(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 흑운형 (Dark-cloud) + # 상승 추세에서 흑운형이 나오면 매도 + temp_status = self.common.checkDarkCloud(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 샛별 (Morning start) + # 하락 추세에서 샛별형이 나오면 매수 + temp_status = self.common.checkMorningstar(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + # 저녁별 (Evening start) + # 상승 추세에서 저녁별형이 나오면 매도 + temp_status = self.common.checkEveningstar(STOCK, last_index) + if temp_status != "": + status.add(temp_status) + + return status + + def checkTransaction_Realtime(self, data, upper, lower): + size = len(data["Close"]) + STOCK = [] + for i in range(size): + STOCK.append({'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'avg5': data["avg5"][i], 'avg20': data["avg20"][i], 'avg60': data["avg60"][i], 'avg120': data["avg120"][i]}) bsLine = {} bsLine['buy'] = [-1 for i in range(len(lower))] bsLine['sell'] = [-1 for i in range(len(lower))] - # buy 체크 - for i in range(3, len(lower)): - #1 - if close[i] < ma2[i] < lower[i]: - if low[i-2] == open[i-2] < close[i-2] < high[i-2]: - if low[i-1] == close[i-1] < open[i-1] < high[i-1]: - if low[i] == close[i] < open[i] < high[i]: - bsLine['buy'][i+1] = close[i] + 5 - bsLine['sell'][i + 1] = close[i] + 15 - continue - #2 - if lower[i-2] > lower[i-1] and lower[i-1] < lower[i]: - if lower[i-2] > low[i-2]: - if open[i-2] < close[i-2] and open[i-1] < close[i-1] and open[i] < close[i]: - bsLine['buy'][i + 1] = open[i] - bsLine['sell'][i + 1] = open[i] + 10 - continue + i = size - 1 + status = self.checkStatus(STOCK, i) + count_1 = 0 + if "arrange_" in status: count_1 += 1 + if "arrange_" in status and "HIGHERUMBONG_" in status: count_1 += 1 + if "20_" in status: count_1 += 1 + if "60_" in status: count_1 += 1 + if "120_" in status: count_1 += 1 + if "240_" in status: count_1 += 1 + if "5-20_" in status: count_1 += 1 + if "GOLDEN#2_" in status: count_1 += 1 + if "GOLDEN#3_" in status: count_1 += 1 + if "UMYANG_" in status: count_1 += 1 + if "DOJI_" in status: count_1 += 1 + if "DRAGONEFLY_" in status: count_1 += 1 + if "HAMMER_" in status: count_1 += 1 + if "ENHIGH_" in status: count_1 += 1 + if "HAHIGH_" in status: count_1 += 1 + if "PIERCING_" in status: count_1 += 1 + if "MORNINGSTAR_" in status: count_1 += 1 + count_0 = 0 + if "GRAVESTONE_" in status: count_0 += 1 + if "HANGINGMAN_" in status: count_0 += 1 + if "ENLOW_" in status: count_0 += 1 + if "HALOW_" in status: count_0 += 1 + if "DARKCLOUD_" in status: count_0 += 1 + if "EVENINGSTAR" in status: count_0 += 1 - if lower[i-2] > lower[i-1] > lower[i]: - # 3 - if high[i-2] == open[i-2] > close[i-2] > low[i-2] and close[i-2] < ma2[i-2]: - if high[i-1] > open[i-1] > close[i-1] == low[i-1] and close[i-1] < ma2[i-1]: - if ma2[i-1] == ma2[i] and low[i] == open[i] < close[i] < high[i]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 10 - continue + if count_0 == 0 and count_1 > 0: + bsLine['buy'][i + 1] = STOCK[i]['close'] - 5 + bsLine['sell'][i + 1] = STOCK[i]['close'] + if count_0 > 0: + bsLine['sell'][i + 1] = STOCK[i]['close'] + 5 - #4 - if upper[i] < upper[i-2] < upper[i-1]: - if ma10[i-2] > ma10[i-1] > ma2[i-2] > ma2[i-1] == ma2[i]: - if high[i-2] == open[i-2] > close[i-2] == low[i-2]: - if high[i-1] == open[i-1] > close[i-1] == low[i-1]: - if high[i] > close[i] > open[i] == low[i]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 5 - continue - - #5 - if upper[i-2] > upper[i-1] and upper[i-1] < upper[i]: - if lower[i - 2] > lower[i - 1] and lower[i - 1] < lower[i]: - if open[i-1] < ma2[i-1] and open[i-1]==low[i-1] < close[i-1]==high[i-1]: - if open[i]==low[i] < close[i] == high[i]: - if close[i] > ma2[i] and close[i] > ma10[i] and close[i] > ma15[i] and close[i] > ma20[i]: - bsLine['buy'][i+1] = close[i] + 5 - bsLine['sell'][i + 1] = close[i] + 25 - continue - - #6 - if lower[i] < lower[i-2] < lower[i-1]: - if lower[i-2] < low[i-2] < close[i-2] < open[i-2] == high[i-2]: - if low[i-1] < lower[i-1] < close[i-1]==open[i-1] < high[i-1]: - if low[i] < lower[i] < close[i] == open[i] < high[i]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 5 - continue - - #7 - if low[i-2] < open[i-2] == close[i-2] == high[i-2]: - if low[i - 1] < open[i - 1] == close[i - 1] == high[i - 1]: - if low[i] < open[i] < close[i] == high[i]: - if ma2[i] < close[i] and ma10[i] < close[i] and ma15[i] < close[i] and ma20[i] < close[i]: - if lower[i-2] < lower[i-1] < lower[i]: - if upper[i-2] > upper[i-1] > upper[i]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 10 - continue - - #8 - if low[i-2] < close[i-2] < open[i-2] == high[i-2]: - if low[i-1] < open[i-1] < close[i-1] == high[i-1]: - if low[i] < open[i] < close[i] == high[i]: - if lower[i-1] < lower[i] < lower[i-2]: - if upper[i] < upper[i-2] < upper[i-1]: - bsLine['buy'][i + 1] = open[i] - bsLine['sell'][i + 1] = open[i] + 5 - continue - - #9 - if low[i-2] == open[i-2] < close[i-2] < high[i-2]: - if low[i-1] == close[i-1] < open[i-1] < high[i-1]: - if low[i] < open[i] == close[i] < high[i] and close[i-1] < close[i]: - if low[i-2] == low[i-1] and open[i-2] == close[i-1] and close[i-2] == open[i-1] and high[i-2] == high[i-1]: - bsLine['buy'][i + 1] = open[i] - bsLine['sell'][i + 1] = open[i] + 15 - continue - - #10 - if low[i-2] == close[i-2] < open[i-2] == high[i-2]: - if low[i-1] == open[i-1] < close[i-1] == high[i-1]: - if low[i] == close[i] < open[i] == high[i]: - if high[i-2] == high[i-1] == high[i]: - if low[i-2] == low[i] < low[i-1]: - bsLine['buy'][i + 1] = open[i-1] - bsLine['sell'][i + 1] = open[i-1] + 5 - continue - - # 11 - if low[i-2] < close[i-2] == open[i-2] < high[i-2]: - if low[i-1] < close[i - 1] < open[i - 1] == high[i - 1]: - if low[i] < close[i] == open[i] < high[i]: - if low[i-2] == low[i] and high[i-2] == high[i] and low[i-1] < low[i-2] and high[i-1] < high[i-2]: - if ma2[i - 2] > ma2[i - 1] > ma2[i]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 15 - continue - - # 12 - if low[i - 2] < close[i - 2] < open[i - 2] < high[i - 2]: - if low[i - 1] == open[i - 1] < close[i - 1] < high[i - 1]: - if low[i] == open[i] < close[i] == high[i]: - if lower[i-2] > lower[i-1] and ma2[i-2] > ma2[i-1] and ma2[i-1] < ma2[i]: - bsLine['buy'][i + 1] = close[i-1] - bsLine['sell'][i + 1] = close[i-1] + 5 - continue - - # 13 - if low[i-2] == open[i-2] < close[i-2] < high[i-2]: - if low[i-1] == close[i-1] < open[i-1] == high[i-1]: - if low[i] == open[i] < close[i] < high[i]: - if low[i-2] == low[i] > low[i-1]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 5 - continue - - # 14 - if low[i-2] < open[i-2] == close[i-2] < high[i-2]: - if low[i-1] < open[i-1] == close[i-1] < high[i-1]: - if low[i] < open[i] == close[i] < high[i]: - if low[i-2] < ma2[i-2] < high[i-2] and low[i-1] < ma2[i-1] < high[i-1] and low[i] < ma2[i] < high[i]: - if high[i - 2] < ma10[i - 2] and high[i - 1] < ma10[i - 1] and high[i] < ma10[i]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 5 - continue - - # 15 - if low[i - 2] < close[i - 2] < open[i - 2] == high[i - 2]: - if low[i-2] < lower[i-2] and high[i-2] < upper[i-2]: - if low[i - 1] == open[i - 1] < close[i - 1] <= high[i - 1]: - if low[i - 1] > lower[i - 1] and high[i - 1] < upper[i - 1]: - if low[i] <= open[i] < close[i] == high[i]: - if low[i] > lower[i] and high[i] > upper[i]: - bsLine['buy'][i + 1] = close[i] - 5 - bsLine['sell'][i + 1] = close[i] + 5 - continue - - # 16 - if low[i - 3] < close[i - 3] < open[i - 3] == high[i - 3]: - if low[i-3] > lower[i-3] and high[i-3] < upper[i-3]: - if low[i - 2] < close[i - 2] < open[i - 2] == high[i - 2]: - if low[i - 2] < lower[i - 2] and high[i - 2] < upper[i - 2]: - if low[i - 1] <= open[i - 1] < close[i - 1] == high[i - 1]: - if low[i - 1] < lower[i - 1] and high[i - 1] > upper[i - 1]: - if low[i] < open[i] == close[i] < high[i]: - if low[i] < lower[i]: - bsLine['buy'][i + 1] = close[i] - 5 - bsLine['sell'][i + 1] = close[i] + 5 - continue - - # 16 - if low[i - 2] == close[i - 2] == open[i - 2] < high[i - 2]: - if low[i - 2] < lower[i - 2]: - if low[i - 1] == close[i - 1] == open[i - 1] < high[i - 1]: - if low[i] == open[i] < close[i] == high[i]: - bsLine['buy'][i + 1] = close[i] - bsLine['sell'][i + 1] = close[i] + 20 - continue - - # 17 - if low[i - 3] == open[i - 3] == close[i - 3] < high[i - 3]: - if high[i - 3] > upper[i - 3]: - if low[i - 2] < open[i - 2] == close[i - 2] < high[i - 2]: - if high[i - 2] > upper[i - 2] and low[i - 2] < lower[i - 2]: - if low[i - 1] < open[i - 1] == close[i - 1] < high[i - 1]: - if low[i - 1] < lower[i - 1]: - if low[i] == open[i] < close[i] <= high[i]: - bsLine['buy'][i + 1] = close[i] + 5 - bsLine['sell'][i + 1] = close[i] + 20 - continue - - # 18 - if open[i - 3] > close[i - 3]: - if low[i - 3] < lower[i - 3] and low[i - 3] < ma2[i - 3]: - if low[i - 2] == close[i - 2] < open[i - 2] <= high[i - 2]: - if low[i - 2] < lower[i - 2] and low[i - 2] < ma2[i - 2]: - if low[i - 1] < open[i - 1] == close[i - 1] <= high[i - 1]: - if close[i - 2] < close[i - 1]: - if low[i] < open[i] == close[i] <= high[i]: - if close[i - 1] < close[i]: - bsLine['buy'][i + 1] = close[i]+5 - bsLine['sell'][i + 1] = close[i] + 20 - continue - - # 19 - if low[i-3] < open[i - 3] < close[i - 3] == high[i-3] < ma20[i-3]: - if low[i - 2] < close[i - 2] == open[i - 2] <= high[i - 2] < ma20[i-2]: - if low[i - 1] < open[i - 1] <= close[i - 1] == high[i - 1] < ma20[i-1]: - if low[i] <= open[i] < close[i] == high[i]: - if open[i-3] <= open[i-2] <= open[i-1] or close[i-2] <= close[i-1] <= close[i]: - bsLine['buy'][i + 1] = close[i]+5 - bsLine['sell'][i + 1] = close[i] + 15 - continue return bsLine - """ - def checkTransaction(self, data, upper, lower): - low = data["Low"] - high = data["High"] - close = data["Close"] - open = data["Open"] - ma2 = data["ma2"] - ma5 = data["ma5"] - ma10 = data["ma10"] - ma15 = data["ma15"] - ma20 = data["ma20"] - # 살 시점인지 체크 - # 볼린저밴드 하단에 연속으로 같은 가격이 왔을 때, - # 해당 하단 가격 + 5원에 매수를 시도함 - check = False - buy_line = [-1 for i in range(len(lower))] - for i in range(3, len(lower)): - # 하락 추세에서는 매수하지 않는다. - if ma2[i] < ma5[i] < ma10[i]: - continue + def checkTransaction_Simulation(self, data, upper, lower): + size = len(data["Close"]) + STOCK = [] + for i in range(size): + STOCK.append({'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'volume':data["Volume"][i], 'avg5': data["avg5"][i], 'avg20': data["avg20"][i], 'avg60': data["avg60"][i], 'avg120': data["avg120"][i], 'avg240': data["avg240"][i]}) - for j in range(i-3, i): - if (low[j] < lower[j]) and (low[i] < lower[i] and low[j] == low[i]): - #buy_line[i] = low[i] - check = True - break - if check and i < len(lower) - 1: - buy_line[i+1] = low[i] + 5 - check = False + bsLine = {} + bsLine['buy'] = [-1 for i in range(len(lower))] + bsLine['sell'] = [-1 for i in range(len(lower))] - if low[i-2] < lower[i-2] and low[i-1] < lower[i-1] and low[i] < open[i] == close[i] < high[i] and open[i] - low[i] == high [i] - open[i]: - if not (open[i-2] < close[i-2] and open[i-1] < close[i-1]) and not (open[i-2] == close[i-2] or open[i-1] == close[i-1]): - buy_line[i+1] = high[i] + for i in range(5, size-1): + status = self.checkStatus(STOCK, i) + count_1 = 0 + if "arrange_" in status: count_1 += 1 + if "arrange_" in status and "HIGHERUMBONG_" in status: count_1 += 1 + if "20_" in status: count_1 += 1 + if "60_" in status: count_1 += 1 + if "120_" in status: count_1 += 1 + if "240_" in status: count_1 += 1 + if "5-20_" in status: count_1 += 1 + if "GOLDEN#2_" in status: count_1 += 1 + if "GOLDEN#3_" in status: count_1 += 1 + if "UMYANG_" in status: count_1 += 1 + if "DOJI_" in status: count_1 += 1 + if "DRAGONEFLY_" in status: count_1 += 1 + if "HAMMER_" in status: count_1 += 1 + if "ENHIGH_" in status: count_1 += 1 + if "HAHIGH_" in status: count_1 += 1 + if "PIERCING_" in status: count_1 += 1 + if "MORNINGSTAR_" in status: count_1 += 1 + count_0 = 0 + if "GRAVESTONE_" in status: count_0 += 1 + if "HANGINGMAN_" in status: count_0 += 1 + if "ENLOW_" in status: count_0 += 1 + if "HALOW_" in status: count_0 += 1 + if "DARKCLOUD_" in status: count_0 += 1 + if "EVENINGSTAR" in status: count_0 += 1 - # 2일과 5일선이 10일 선 위로 올라오면 매수한다. - if (ma2[i-1] < ma10[i-1] and ma5[i-1] < ma10[i-1]) and (ma10[i] < ma5[i] < ma2[i]): - buy_line[i+1] = low[i] + 5 + if count_0 == 0 and count_1 > 0: + bsLine['buy'][i + 1] = STOCK[i]['close'] - 5 + bsLine['sell'][i + 1] = STOCK[i]['close'] + if count_0 > 0: + bsLine['sell'][i+1] = STOCK[i]['close'] + 5 - # 팔 시점 체크 - # 산 가격에 5원 위로 매도를 건다. - sell_line = [-1 for i in range(len(lower))] - for i in range(len(buy_line)): - if buy_line[i] > 0: - for j in range(i+1, len(buy_line)): - # 5원 이득을 보고 판다. - if close[j] >= buy_line[i] + 5: - sell_line[j] = buy_line[i] + 5 - break + return bsLine - return buy_line, sell_line - """ def simulate(self, stock_code, given_day): #timecheckList = pd.read_csv("timecheck.csv").values.tolist() @@ -885,7 +839,7 @@ class HTS: data, upper, lower = self.analyze(result) # 사야 할 시점과 팔아야 할 시점을 체크한다. - bsLine = self.checkTransaction(data, upper, lower) + bsLine = self.checkTransaction_Simulation(data, upper, lower) # 그래프를 그린다. self.draw(given_day, data, upper, lower, bsLine) @@ -930,7 +884,7 @@ class HTS: data, upper, lower = self.analyze(result) # 사야 할 시점과 팔아야 할 시점을 체크한다. - bsLine = self.checkTransaction(data, upper, lower) + bsLine = self.checkTransaction_Realtime(data, upper, lower) buy_line = bsLine['buy'] @@ -959,7 +913,7 @@ class HTS: if total_byu_amt < 7000000: self.requestOrder("2", stock_code, buy_count , price) - ## 매도 주문 (아래 잔고를 체킇서 매도를 호출하는 것으로 시도한다.) + ## 매도 주문 (아래 잔고를 체크해서 매도를 호출하는 것으로 시도한다.) #time.sleep(60) #self.requestOrder("1", stock_code, buy_count , price + 5) print("BUY", second, price) @@ -980,39 +934,27 @@ class HTS: if jangoDic and len(jangoDic.keys()) > 0: for code in jangoDic: total_byu_amt = jangoDic[code]['매입금액'] - if jangoDic[code]['매도가능'] > 0: - # 가장 마지막 현재가를 가져온다. - if len(result['close']) > 0: - last_price = result['close'][len(result['close'])-1] - else: - last_price = 0 - # 현재가가 장부가보다 크다면 현재가 + 5원 매도한다. - if last_price > int(jangoDic[code]['장부가']): - # 현재가가 장부가보다 크다면, - self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], last_price) - else: - # 장부가가 현재가보다 크다면, - # 장부가의 마지막 자리수를 가져온다. - last_number = int(jangoDic[code]['장부가']) % 10 - # 장부가 가격의 마지막 자리를 0으로 만든다. (2092 -> 2090, 2098 -> 2090) - sell_price = int(jangoDic[code]['장부가'] / 10) * 10 - # 만약 오후 1시 이전이라면 한 호가 (5원) 더 올려서 매도한다. - if datetime.now() < datetime.strptime(given_day + " 104000", '%Y%m%d %H%M%S'): - if lower != None: - if lower[len(lower)-2] < lower[len(lower)-1]: - sell_price += 5 + # 장부가 가격의 마지막 자리를 0으로 만든다. (2090 -> 2090, 2092 -> 2090, 2098 -> 2090) + sell_price = int(jangoDic[code]['장부가'] / 10) * 10 + # 만약 오후 1시 이전이라면 한 호가 (5원) 더 올려서 매도한다. + if datetime.strptime(given_day + " 092000", '%Y%m%d %H%M%S') < datetime.now() < datetime.strptime(given_day + " 104000", '%Y%m%d %H%M%S'): + lower_size = len(lower) + if lower != None and lower_size > 3: + if lower[lower_size-3] < lower[lower_size-2] < lower[lower_size-1]: + sell_price += 5 - if last_number in [0, 1, 2]: - # 장부가의 마지막 자리수가 0,1,2 라면 (2090, 2091, 2092 -> 2095 에 매도) - self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 5) - elif last_number in [3, 4, 5, 6]: - - # 장부가의 마지막 자리수가 3,4,5,6 라면 (2093, 2094, 2095, 2096 -> 2100 에 매도) - self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 10) - else: - # 장부가의 마지막 자리수가 7,8,9 라면 (2097, 2098, 2099 -> 2105 에 매도) - self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 15) + # 장부가의 마지막 자리수를 가져온다. + last_number = int(jangoDic[code]['장부가']) % 10 + if last_number in [0, 1, 2]: + # 장부가의 마지막 자리수가 0,1,2 라면 (2090, 2091, 2092 -> 2095 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 5) + elif last_number in [3, 4, 5, 6]: + # 장부가의 마지막 자리수가 3,4,5,6 라면 (2093, 2094, 2095, 2096 -> 2100 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 10) + else: + # 장부가의 마지막 자리수가 7,8,9 라면 (2097, 2098, 2099 -> 2105 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 15) time.sleep(0.9) @@ -1035,9 +977,7 @@ if __name__ == "__main__": #hts.currentStock(stock_code) #hts.printStockData(stock_code, given_day) - given_days = ['20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929','20210930'] - given_days = ['20210909','20210913','20210914','20210915','20210916'] - given_days = ['20210913'] + given_days = ['20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929','20210930','20211001'] for given_day in given_days: hts.simulate(stock_code, given_day) diff --git a/hts/HTS_5min.py b/hts/HTS_5min.py new file mode 100644 index 0000000..c434de6 --- /dev/null +++ b/hts/HTS_5min.py @@ -0,0 +1,1047 @@ +#import win32com.client +import time +import os +from datetime import datetime, timedelta +import pandas as pd +from enum import Enum +import plotly.graph_objects as go + + +# enum 주문 상태 세팅용 +class EorderBS(Enum): + buy = 1 # 매수 + sell= 2 # 매도 + none =3 + +class orderData: + def __init__(self): + self.dicEx = {EorderBS.buy: "매수", EorderBS.sell: "매도", EorderBS.none: "없음"} + self.orderNum = 0 + self.bs = EorderBS.none # 0 : buy 1: sell + self.code = "" + self.amount = 0 + self.price = 0 + + def debugPrint(self): + print(self.dicEx.get(self.bs), self.code, self.orderNum, self.amount, self.price) + + +class HTS: + + objCpCybos = None + objCpCodeMgr = None + + stock = [] + + def __init__(self): + #self.connect() + return + + def connect(self): + # 연결 여부 체크 + self.objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") + bConnect = self.objCpCybos.IsConnect + if (bConnect == 0): + print("PLUS가 정상적으로 연결되지 않음. ") + exit() + return + + def all_stocks(self): + # 종목코드 리스트 구하기 + self.objCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr") + codeList = self.objCpCodeMgr.GetStockListByMarket(1) # 거래소 + codeList2 = self.objCpCodeMgr.GetStockListByMarket(2) # 코스닥 + + print("거래소 종목코드", len(codeList)) + for i, code in enumerate(codeList): + secondCode = self.objCpCodeMgr.GetStockSectionKind(code) + name = self.objCpCodeMgr.CodeToName(code) + stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) + print(i, code, secondCode, stdPrice, name) + + print("코스닥 종목코드", len(codeList2)) + for i, code in enumerate(codeList2): + secondCode = self.objCpCodeMgr.GetStockSectionKind(code) + name = self.objCpCodeMgr.CodeToName(code) + stdPrice = self.objCpCodeMgr.GetStockStdPrice(code) + print(i, code, secondCode, stdPrice, name) + + print("거래소 + 코스닥 종목코드 ", len(codeList) + len(codeList2)) + return + + # 차트 데이터 구하기 + def getChartData(self, stock_code): + # 차트 객체 구하기 + objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") + + objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 + objStockChart.SetInputValue(1, ord('2')) # 개수로 조회 + objStockChart.SetInputValue(4, 100) # 최근 100일 치 + objStockChart.SetInputValue(5, [0, 2, 3, 4, 5, 8]) # 날짜,시가,고가,저가,종가,거래량 + objStockChart.SetInputValue(6, ord('D')) # '차트 주가 - 일간 차트 요청 + objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 + objStockChart.BlockRequest() + + len = objStockChart.GetHeaderValue(3) + + print("날짜", "시가", "고가", "저가", "종가", "거래량") + print("==============================================-") + + for i in range(len): + day = objStockChart.GetDataValue(0, i) + open = objStockChart.GetDataValue(1, i) + high = objStockChart.GetDataValue(2, i) + low = objStockChart.GetDataValue(3, i) + close = objStockChart.GetDataValue(4, i) + vol = objStockChart.GetDataValue(5, i) + print(day, open, high, low, close, vol) + + return + + # 주식 현재가 조회 + def currentStock(self, stock_code): + # 현재가 객체 구하기 + self.objStockMst = win32com.client.Dispatch("DsCbo1.StockMst") + self.objStockMst.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자 + self.objStockMst.BlockRequest() + + # 현재가 통신 및 통신 에러 처리 + rqStatus = self.objStockMst.GetDibStatus() + rqRet = self.objStockMst.GetDibMsg1() + print("통신상태", rqStatus, rqRet) + if rqStatus != 0: + exit() + + # 현재가 정보 조회 + code = self.objStockMst.GetHeaderValue(0) # 종목코드 + name = self.objStockMst.GetHeaderValue(1) # 종목명 + time = self.objStockMst.GetHeaderValue(4) # 시간 + cprice = self.objStockMst.GetHeaderValue(11) # 종가 + diff = self.objStockMst.GetHeaderValue(12) # 대비 + open = self.objStockMst.GetHeaderValue(13) # 시가 + high = self.objStockMst.GetHeaderValue(14) # 고가 + low = self.objStockMst.GetHeaderValue(15) # 저가 + offer = self.objStockMst.GetHeaderValue(16) # 매도호가 + bid = self.objStockMst.GetHeaderValue(17) # 매수호가 + vol = self.objStockMst.GetHeaderValue(18) # 거래량 + vol_value = self.objStockMst.GetHeaderValue(19) # 거래대금 + + # 예상 체결관련 정보 + exFlag = self.objStockMst.GetHeaderValue(58) # 예상체결가 구분 플래그 + exPrice = self.objStockMst.GetHeaderValue(55) # 예상체결가 + exDiff = self.objStockMst.GetHeaderValue(56) # 예상체결가 전일대비 + exVol = self.objStockMst.GetHeaderValue(57) # 예상체결수량 + + print("코드", code) + print("이름", name) + print("시간", time) + print("종가", cprice) + print("대비", diff) + print("시가", open) + print("고가", high) + print("저가", low) + print("매도호가", offer) + print("매수호가", bid) + print("거래량", vol) + print("거래대금", vol_value) + + if (exFlag == ord('0')): + print("장 구분값: 동시호가와 장중 이외의 시간") + elif (exFlag == ord('1')): + print("장 구분값: 동시호가 시간") + elif (exFlag == ord('2')): + print("장 구분값: 장중 또는 장종료") + + print("예상체결가 대비 수량") + print("예상체결가", exPrice) + print("예상체결가 대비", exDiff) + print("예상체결수량", exVol) + + return + + # 주식 현금 매수주문 + def requestOrder(self, type, stock_code, count, price): + # type = 2: buy, type=1: sell + # 주문 초기화 + objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") + initCheck = objTrade.TradeInit(0) + if (initCheck != 0): + print("주문 초기화 실패") + exit() + + # 주식 매수 주문 + acc = objTrade.AccountNumber[0] # 계좌번호 + accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 + # acc = "782446178" + # accFlag[0] = "01" + objStockOrder = win32com.client.Dispatch("CpTrade.CpTd0311") + objStockOrder.SetInputValue(0, type) # 1: 매도, 2: 매수 + objStockOrder.SetInputValue(1, acc) # 계좌번호 + objStockOrder.SetInputValue(2, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 + objStockOrder.SetInputValue(3, "A"+stock_code) # 종목코드 + objStockOrder.SetInputValue(4, count) # 매수수량 count주 + objStockOrder.SetInputValue(5, price) # 주문단가 - price 원 + objStockOrder.SetInputValue(7, "0") # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK + objStockOrder.SetInputValue(8, "01") # 주문호가 구분코드 - 01: 보통 + + # 매수 주문 요청 + nRet = objStockOrder.BlockRequest() + if (nRet != 0): + print("order error", nRet) + return + + rqStatus = objStockOrder.GetDibStatus() + rqRet = objStockOrder.GetDibMsg1() + print("통신상태", rqStatus, rqRet) + if rqStatus != 0: + return + + orderNum = objStockOrder.GetHeaderValue(0) + + if (type == "1"): + print ("(SELL", count, price, ")") + else: + print ("(BUY", count, price, ")") + return orderNum + + # 계좌 잔고 확인 + def requstJango(self): + jangoDic = {} + + objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") + initCheck = objTrade.TradeInit(0) + if (initCheck != 0): + print("주문 초기화 실패") + exit() + + # 주식 매수 주문 + acc = objTrade.AccountNumber[0] # 계좌번호 + accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 + + objRq = win32com.client.Dispatch("CpTrade.CpTd6033") + + objRq.SetInputValue(0, acc) # 계좌번호 + objRq.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 + objRq.SetInputValue(2, 50) # 요청 건수(최대 50) + dicflag1 = {ord(' '): '현금', + ord('Y'): '융자', + ord('D'): '대주', + ord('B'): '담보', + ord('M'): '매입담보', + ord('P'): '플러스론', + ord('I'): '자기융자', + } + while True: + objRq.BlockRequest() + # 통신 및 통신 에러 처리 + rqStatus = objRq.GetDibStatus() + rqRet = objRq.GetDibMsg1() + #print("통신상태", rqStatus, rqRet) + if rqStatus != 0: + return False + + cnt = objRq.GetHeaderValue(7) + if cnt > 3: + return jangoDic + + for i in range(cnt): + item = {} + code = objRq.GetDataValue(12, i) # 종목코드 + item['종목코드'] = code + item['종목명'] = objRq.GetDataValue(0, i) # 종목명 + item['대출일'] = objRq.GetDataValue(2, i) # 대출일 + item['잔고수량'] = objRq.GetDataValue(7, i) # 체결잔고수량 + item['매도가능'] = objRq.GetDataValue(15, i) + item['장부가'] = objRq.GetDataValue(17, i) # 체결장부단가 + # item['평가금액'] = self.objRq.GetDataValue(9, i) # 평가금액(천원미만은 절사 됨) + # item['평가손익'] = self.objRq.GetDataValue(11, i) # 평가손익(천원미만은 절사 됨) + # 매입금액 = 장부가 * 잔고수량 + item['매입금액'] = item['장부가'] * item['잔고수량'] + item['현재가'] = 0 + item['대비'] = 0 + item['거래량'] = 0 + + # 잔고 추가 + # key = (code, item['현금신용'],item['대출일'] ) + key = code + jangoDic[key] = item + + if len(jangoDic) >= 3: # 최대 3 종목만, + break + + if len(jangoDic) >= 3: + break + + if (objRq.Continue == False): + break + + check = False + for item in jangoDic: + if item: + check = True + break + if not check: + return None + return jangoDic + + # 예약 주문 내역 조회 및 미체결 리스트 구하기 + def requestOrderList(self): + # type = 2: buy, type=1: sell + orderList = [] + # 주문 초기화 + objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil") + initCheck = objTrade.TradeInit(0) + if (initCheck != 0): + print("주문 초기화 실패") + exit() + + # 주식 매수 주문 + acc = objTrade.AccountNumber[0] # 계좌번호 + accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분 + + objResult = win32com.client.Dispatch("CpTrade.CpTd9065") + objResult.SetInputValue(0, acc) # 계좌번호 + objResult.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째 + objResult.SetInputValue(2, 20) + + while True: + objResult.BlockRequest() + if objResult.GetDibStatus() != 0: + print("통신상태", objResult.GetDibStatus(), objResult.GetDibMsg1()) + return False + + cnt = objResult.GetHeaderValue(4) + if cnt == 0: + break + + for i in range(cnt): + i1 = objResult.GetDataValue(1, i) # 주문구분(매수 또는 매도) + i2 = objResult.GetDataValue(2, i) # 코드 + i3 = objResult.GetDataValue(3, i) # 주문 수량 + i4 = objResult.GetDataValue(4, i) # 주문호가구분 + i5 = objResult.GetDataValue(6, i) # 예약번호 + i6 = objResult.GetDataValue(12, i) # 처리구분내용 - 주문취소 또는 주문예정 + i7 = objResult.GetDataValue(9, i) # 주문단가 + i8 = objResult.GetDataValue(11, i) # 주문번호 + i9 = objResult.GetDataValue(12, i) # 처리구분코드 + i10 = objResult.GetDataValue(13, i) # 거부코드 + i11 = objResult.GetDataValue(14, i) # 거부내용 + print(i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11) + + # 미체결 + if (i6 == "주문예정"): + item = orderData() + item.orderNum = i5 + if (i1 == "매수"): + item.bs = EorderBS.buy + else: + item.bs = EorderBS.sell + item.code = i2 + item.amount = i3 + item.price = i7 + + orderList.append(item) + + # 연속 처리 체크 - 다음 데이터가 없으면 중지 + if objResult.Continue == False: + break + + return orderList + + # 주식 현재가 조회 + def printStockData(self, stock_code, day): + objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") + bConnect = objCpCybos.IsConnect + if (bConnect == 0): + print("PLUS가 정상적으로 연결되지 않음. ") + exit() + + # 차트 객체 구하기 + objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") + + objStockChart.SetInputValue(0, 'A' + stock_code) # 종목 코드 + objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회 + objStockChart.SetInputValue(2, day) # 기간 조회 시, 시작일 + objStockChart.SetInputValue(3, day) # 기간 조회 시, 종료일 + objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수 + objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량 + objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청 + objStockChart.SetInputValue(7, 1) + objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 + objStockChart.BlockRequest() + + size = objStockChart.GetHeaderValue(3) + + print("%s,%s,%s,%s,%s,%s,%s" % ("날짜", "시간", "시가", "고가", "저가", "종가", "거래량")) + for i in range(size - 1, -1, -1): + day = objStockChart.GetDataValue(0, i) + time = objStockChart.GetDataValue(1, i) + open = objStockChart.GetDataValue(2, i) + high = objStockChart.GetDataValue(3, i) + low = objStockChart.GetDataValue(4, i) + close = objStockChart.GetDataValue(5, i) + vol = objStockChart.GetDataValue(6, i) + print("%d,%s,%d,%d,%d,%d,%d" % (day, str(time).zfill(4), open, high, low, close, vol)) + + return + + + def write(self, day, result): + #날짜,시간,시가,고가,저가,종가,거래량 + #20210909,900,2070,2070,2070,2070,0 + + outFp = open(day+".csv", mode="w", encoding="UTF-8") + outFp.write("날짜,시간,시가,고가,저가,종가,거래량\n") + for i in range(len(result["time"])): + outFp.write("%s,%s,%s,%s,%s,%s,%s\n"%( + result["time"][i].strftime('%Y%m%d'), + result["time"][i].strftime('%H%M'), + result["open"][i], + result["high"][i], + result["low"][i], + result["close"][i], + result["vol"][i])) + outFp.close() + return + + # 주식 현재가 조회 + def getRealTime(self, stock_code, given_day, result): + int_given_day = int(given_day) + objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") + bConnect = objCpCybos.IsConnect + if (bConnect == 0): + print("PLUS가 정상적으로 연결되지 않음. ") + exit() + + # 차트 객체 구하기 + objStockChart = win32com.client.Dispatch("CpSysDib.StockChart") + + objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 + objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회 + objStockChart.SetInputValue(2, given_day) # 기간 조회 시, 시작일 + objStockChart.SetInputValue(3, given_day) # 기간 조회 시, 종료일 + objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수 + objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량 + objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청 + objStockChart.SetInputValue(7, 1) + objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용 + objStockChart.BlockRequest() + + size = objStockChart.GetHeaderValue(3) + + #print("날짜", "시간", "시가", "고가", "저가", "종가", "거래량") + start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S') + for i in range(size-1, -1, -1): + int_day = objStockChart.GetDataValue(0, i) + int_time = objStockChart.GetDataValue(1, i) + + if int_day < int_given_day: + continue + time = datetime.strptime(str(int_day)+" "+str(int_time).zfill(4)+"00", '%Y%m%d %H%M%S') + if time < start_time: + continue + + open = objStockChart.GetDataValue(2, i) + close = objStockChart.GetDataValue(5, i) + high = objStockChart.GetDataValue(3, i) + low = objStockChart.GetDataValue(4, i) + vol = objStockChart.GetDataValue(6, i) + + if len(result["check"]) == 0: + result["check"].add(start_time) + result["time"].append(start_time) + result["open"].append(open) + result["close"].append(open) + result["high"].append(open) + result["low"].append(open) + result["vol"].append(0) + + if time not in result["check"]: + result["check"].add(time) + result["time"].append(time) + + result["open"].append(open) + result["close"].append(close) + result["high"].append(high) + result["low"].append(low) + result["vol"].append(vol) + + return + + def getCSV(self, fileName, given_day, result): + data = pd.read_csv(fileName) + + days = data.날짜 + time = data.시간 + open = data.시가 + close = data.종가 + high = data.고가 + low = data.저가 + vol = data.거래량 + start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S') + + for i in range(len(data)): + temp = datetime.strptime(str(days[i]) + " " + str(time[i]).zfill(4)+"00", '%Y%m%d %H%M%S') + if temp < start_time: + continue + + if temp not in result["check"]: + result["check"].add(temp) + result["time"].append(temp) + result["open"].append(open[i]) + result["close"].append(close[i]) + result["high"].append(high[i]) + result["low"].append(low[i]) + result["vol"].append(vol[i]) + return + + def analyze(self, result): + df = pd.DataFrame(result["close"]) + + max20 = df.rolling(window=10).mean() + stddev20 = df.rolling(window=10).std() + upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드 + lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드 + + size = len(result["open"]) + window = 5 + open = [result["open"][i] for i in range(0, size, window)] + close = [result["close"][i-1] for i in range(window-1, size, window)] + for i in range(len(open)-len(close)): + close.append(result["close"][len(result["close"])-1]) + high = [max(result["high"][i:i+window]) for i in range(0, size, window)] + low = [min(result["low"][i:i+window]) for i in range(0, size, window)] + vol = [sum(result["vol"][i:i+window]) for i in range(0, size, window)] + + close_df = pd.DataFrame(close) + ma2_list = close_df.rolling(window=2).mean().fillna(close[0]).values.tolist() + ma2 = [item[0] for item in ma2_list] + ma5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist() + ma5 = [item[0] for item in ma5_list] + ma10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist() + ma10 = [item[0] for item in ma10_list] + ma15_list = close_df.rolling(window=15).mean().fillna(close[0]).values.tolist() + ma15 = [item[0] for item in ma15_list] + ma20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist() + ma20 = [item[0] for item in ma20_list] + + upper, lower = [], [] + for i in range(len(upper_df)): + if i < window: + upper.append(upper_df.values[window - 1][0]) + lower.append(lower_df.values[window - 1][0]) + else: + upper.append(upper_df.values[i][0]) + lower.append(lower_df.values[i][0]) + + point_temp = [result["time"][i] for i in range(size) if i % window == 0] + upper_temp = [upper[i] for i in range(size) if i % window == 0] + lower_temp = [lower[i] for i in range(size) if i % window == 0] + + temp = {"Date": point_temp, "Open": open, "High": high, "Low": low, "Close": close, "Volume": vol, "ma2": ma2, "ma5": ma5, "ma10": ma10, "ma15": ma15, "ma20": ma20} + data = pd.DataFrame(temp) + df_final_time = pd.DatetimeIndex(point_temp) + data.index = df_final_time + + return data, upper_temp, lower_temp + + def draw(self, given_day, data, upper, lower, bsLine): + buy_line = bsLine['buy'] + sell_line = bsLine['sell'] + + # 그래프 설정을 위한 변수를 생성한다. + data['Open'] = pd.to_numeric(data['Open']) + data['High'] = pd.to_numeric(data['High']) + data['Low'] = pd.to_numeric(data['Low']) + data['Close'] = pd.to_numeric(data['Close']) + data['Volume'] = pd.to_numeric(data['Volume']) + data['ma2'] = pd.to_numeric(data['ma2']) + data['ma5'] = pd.to_numeric(data['ma5']) + data['ma10'] = pd.to_numeric(data['ma10']) + data['ma15'] = pd.to_numeric(data['ma15']) + data['ma20'] = pd.to_numeric(data['ma20']) + + buy_colors = [] + for i in range(len(buy_line)): + if buy_line[i] < 0: + buy_colors.append("#ffffff") + buy_line[i] = lower[0] + else: + buy_colors.append("#ff00ff") + sell_colors = [] + for i in range(len(sell_line)): + if sell_line[i] < 0: + sell_colors.append("#ffffff") + sell_line[i] = lower[0] + else: + sell_colors.append("#00ced1") + + # 그래프를 설정한다. + buy_check = go.Scatter(x=data['Date'], y=buy_line, mode='markers', name="buy", marker=dict(size=14, color=buy_colors, line_width=0)) + sell_check = go.Scatter(x=data['Date'], y=sell_line, mode='markers', name="sell", marker=dict(size=14, color=sell_colors, line_width=0)) + bolinger_upper = go.Scatter(x=data['Date'], y=upper, name="upper", line_color='#8B4513') + bolinger_lower = go.Scatter(x=data['Date'], y=lower, name="lower", line_color='#8B4513') + ma2 = go.Scatter(x=data['Date'], y=data['ma2'], name="ma2", line_color='#FF0000') + ma5 = go.Scatter(x=data['Date'], y=data['ma5'], name="ma5", line_color='#F43B86') + ma10 = go.Scatter(x=data['Date'], y=data['ma10'], name="ma10", line_color='#F0A500') + ma15 = go.Scatter(x=data['Date'], y=data['ma15'], name="ma15", line_color='#14279B') + ma20 = go.Scatter(x=data['Date'], y=data['ma20'], name="ma20", line_color='#000000') + + + candle_stick = go.Candlestick(x=data['Date'], open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], increasing_line_color='red', decreasing_line_color='blue') + + # 그래프를 그린다. + fig = go.Figure(data=[candle_stick, bolinger_upper, bolinger_lower, buy_check, sell_check, ma2, ma10, ma15, ma20]) + fig.update_layout(title=given_day + "_2x") + fig.show() + return + + def checkTransaction(self, data, upper, lower): + low = data["Low"] + high = data["High"] + close = data["Close"] + open = data["Open"] + ma2 = data["ma2"] + ma10 = data["ma10"] + ma15 = data["ma15"] + ma20 = data["ma20"] + + bsLine = {} + bsLine['buy'] = [-1 for i in range(len(lower))] + bsLine['sell'] = [-1 for i in range(len(lower))] + + # buy 체크 + for i in range(3, len(lower)): + #1 + if close[i] < ma2[i] < lower[i]: + if low[i-2] == open[i-2] < close[i-2] < high[i-2]: + if low[i-1] == close[i-1] < open[i-1] < high[i-1]: + if low[i] == close[i] < open[i] < high[i]: + bsLine['buy'][i+1] = close[i] + 5 + bsLine['sell'][i + 1] = close[i] + 15 + continue + + #2 + if lower[i-2] > lower[i-1] and lower[i-1] < lower[i]: + if lower[i-2] > low[i-2]: + if open[i-2] < close[i-2] and open[i-1] < close[i-1] and open[i] < close[i]: + bsLine['buy'][i + 1] = open[i] + bsLine['sell'][i + 1] = open[i] + 10 + continue + + if lower[i-2] > lower[i-1] > lower[i]: + # 3 + if high[i-2] == open[i-2] > close[i-2] > low[i-2] and close[i-2] < ma2[i-2]: + if high[i-1] > open[i-1] > close[i-1] == low[i-1] and close[i-1] < ma2[i-1]: + if ma2[i-1] == ma2[i] and low[i] == open[i] < close[i] < high[i]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 10 + continue + + #4 + if upper[i] < upper[i-2] < upper[i-1]: + if ma10[i-2] > ma10[i-1] > ma2[i-2] > ma2[i-1] == ma2[i]: + if high[i-2] == open[i-2] > close[i-2] == low[i-2]: + if high[i-1] == open[i-1] > close[i-1] == low[i-1]: + if high[i] > close[i] > open[i] == low[i]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 5 + continue + + #5 + if upper[i-2] > upper[i-1] and upper[i-1] < upper[i]: + if lower[i - 2] > lower[i - 1] and lower[i - 1] < lower[i]: + if open[i-1] < ma2[i-1] and open[i-1]==low[i-1] < close[i-1]==high[i-1]: + if open[i]==low[i] < close[i] == high[i]: + if close[i] > ma2[i] and close[i] > ma10[i] and close[i] > ma15[i] and close[i] > ma20[i]: + bsLine['buy'][i+1] = close[i] + 5 + bsLine['sell'][i + 1] = close[i] + 25 + continue + + #6 + if lower[i] < lower[i-2] < lower[i-1]: + if lower[i-2] < low[i-2] < close[i-2] < open[i-2] == high[i-2]: + if low[i-1] < lower[i-1] < close[i-1]==open[i-1] < high[i-1]: + if low[i] < lower[i] < close[i] == open[i] < high[i]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 5 + continue + + #7 + if low[i-2] < open[i-2] == close[i-2] == high[i-2]: + if low[i - 1] < open[i - 1] == close[i - 1] == high[i - 1]: + if low[i] < open[i] < close[i] == high[i]: + if ma2[i] < close[i] and ma10[i] < close[i] and ma15[i] < close[i] and ma20[i] < close[i]: + if lower[i-2] < lower[i-1] < lower[i]: + if upper[i-2] > upper[i-1] > upper[i]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 10 + continue + + #8 + if low[i-2] < close[i-2] < open[i-2] == high[i-2]: + if low[i-1] < open[i-1] < close[i-1] == high[i-1]: + if low[i] < open[i] < close[i] == high[i]: + if lower[i-1] < lower[i] < lower[i-2]: + if upper[i] < upper[i-2] < upper[i-1]: + bsLine['buy'][i + 1] = open[i] + bsLine['sell'][i + 1] = open[i] + 5 + continue + + #9 + if low[i-2] == open[i-2] < close[i-2] < high[i-2]: + if low[i-1] == close[i-1] < open[i-1] < high[i-1]: + if low[i] < open[i] == close[i] < high[i] and close[i-1] < close[i]: + if low[i-2] == low[i-1] and open[i-2] == close[i-1] and close[i-2] == open[i-1] and high[i-2] == high[i-1]: + bsLine['buy'][i + 1] = open[i] + bsLine['sell'][i + 1] = open[i] + 15 + continue + + #10 + if low[i-2] == close[i-2] < open[i-2] == high[i-2]: + if low[i-1] == open[i-1] < close[i-1] == high[i-1]: + if low[i] == close[i] < open[i] == high[i]: + if high[i-2] == high[i-1] == high[i]: + if low[i-2] == low[i] < low[i-1]: + bsLine['buy'][i + 1] = open[i-1] + bsLine['sell'][i + 1] = open[i-1] + 5 + continue + + # 11 + if low[i-2] < close[i-2] == open[i-2] < high[i-2]: + if low[i-1] < close[i - 1] < open[i - 1] == high[i - 1]: + if low[i] < close[i] == open[i] < high[i]: + if low[i-2] == low[i] and high[i-2] == high[i] and low[i-1] < low[i-2] and high[i-1] < high[i-2]: + if ma2[i - 2] > ma2[i - 1] > ma2[i]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 15 + continue + + # 12 + if low[i - 2] < close[i - 2] < open[i - 2] < high[i - 2]: + if low[i - 1] == open[i - 1] < close[i - 1] < high[i - 1]: + if low[i] == open[i] < close[i] == high[i]: + if lower[i-2] > lower[i-1] and ma2[i-2] > ma2[i-1] and ma2[i-1] < ma2[i]: + bsLine['buy'][i + 1] = close[i-1] + bsLine['sell'][i + 1] = close[i-1] + 5 + continue + + # 13 + if low[i-2] == open[i-2] < close[i-2] < high[i-2]: + if low[i-1] == close[i-1] < open[i-1] == high[i-1]: + if low[i] == open[i] < close[i] < high[i]: + if low[i-2] == low[i] > low[i-1]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 5 + continue + + # 14 + if low[i-2] < open[i-2] == close[i-2] < high[i-2]: + if low[i-1] < open[i-1] == close[i-1] < high[i-1]: + if low[i] < open[i] == close[i] < high[i]: + if low[i-2] < ma2[i-2] < high[i-2] and low[i-1] < ma2[i-1] < high[i-1] and low[i] < ma2[i] < high[i]: + if high[i - 2] < ma10[i - 2] and high[i - 1] < ma10[i - 1] and high[i] < ma10[i]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 5 + continue + + # 15 + if low[i - 2] < close[i - 2] < open[i - 2] == high[i - 2]: + if low[i-2] < lower[i-2] and high[i-2] < upper[i-2]: + if low[i - 1] == open[i - 1] < close[i - 1] <= high[i - 1]: + if low[i - 1] > lower[i - 1] and high[i - 1] < upper[i - 1]: + if low[i] <= open[i] < close[i] == high[i]: + if low[i] > lower[i] and high[i] > upper[i]: + bsLine['buy'][i + 1] = close[i] - 5 + bsLine['sell'][i + 1] = close[i] + 5 + continue + + # 16 + if low[i - 3] < close[i - 3] < open[i - 3] == high[i - 3]: + if low[i-3] > lower[i-3] and high[i-3] < upper[i-3]: + if low[i - 2] < close[i - 2] < open[i - 2] == high[i - 2]: + if low[i - 2] < lower[i - 2] and high[i - 2] < upper[i - 2]: + if low[i - 1] <= open[i - 1] < close[i - 1] == high[i - 1]: + if low[i - 1] < lower[i - 1] and high[i - 1] > upper[i - 1]: + if low[i] < open[i] == close[i] < high[i]: + if low[i] < lower[i]: + bsLine['buy'][i + 1] = close[i] - 5 + bsLine['sell'][i + 1] = close[i] + 5 + continue + + # 16 + if low[i - 2] == close[i - 2] == open[i - 2] < high[i - 2]: + if low[i - 2] < lower[i - 2]: + if low[i - 1] == close[i - 1] == open[i - 1] < high[i - 1]: + if low[i] == open[i] < close[i] == high[i]: + bsLine['buy'][i + 1] = close[i] + bsLine['sell'][i + 1] = close[i] + 20 + continue + + # 17 + if low[i - 3] == open[i - 3] == close[i - 3] < high[i - 3]: + if high[i - 3] > upper[i - 3]: + if low[i - 2] < open[i - 2] == close[i - 2] < high[i - 2]: + if high[i - 2] > upper[i - 2] and low[i - 2] < lower[i - 2]: + if low[i - 1] < open[i - 1] == close[i - 1] < high[i - 1]: + if low[i - 1] < lower[i - 1]: + if low[i] == open[i] < close[i] <= high[i]: + bsLine['buy'][i + 1] = close[i] + 5 + bsLine['sell'][i + 1] = close[i] + 20 + continue + + # 18 + if open[i - 3] > close[i - 3]: + if low[i - 3] < lower[i - 3] and low[i - 3] < ma2[i - 3]: + if low[i - 2] == close[i - 2] < open[i - 2] <= high[i - 2]: + if low[i - 2] < lower[i - 2] and low[i - 2] < ma2[i - 2]: + if low[i - 1] < open[i - 1] == close[i - 1] <= high[i - 1]: + if close[i - 2] < close[i - 1]: + if low[i] < open[i] == close[i] <= high[i]: + if close[i - 1] < close[i]: + bsLine['buy'][i + 1] = close[i]+5 + bsLine['sell'][i + 1] = close[i] + 20 + continue + + # 19 + if low[i-3] < open[i - 3] < close[i - 3] == high[i-3] < ma20[i-3]: + if low[i - 2] < close[i - 2] == open[i - 2] <= high[i - 2] < ma20[i-2]: + if low[i - 1] < open[i - 1] <= close[i - 1] == high[i - 1] < ma20[i-1]: + if low[i] <= open[i] < close[i] == high[i]: + if open[i-3] <= open[i-2] <= open[i-1] or close[i-2] <= close[i-1] <= close[i]: + bsLine['buy'][i + 1] = close[i]+5 + bsLine['sell'][i + 1] = close[i] + 15 + continue + return bsLine + + """ + def checkTransaction(self, data, upper, lower): + low = data["Low"] + high = data["High"] + close = data["Close"] + open = data["Open"] + ma2 = data["ma2"] + ma5 = data["ma5"] + ma10 = data["ma10"] + ma15 = data["ma15"] + ma20 = data["ma20"] + + # 살 시점인지 체크 + # 볼린저밴드 하단에 연속으로 같은 가격이 왔을 때, + # 해당 하단 가격 + 5원에 매수를 시도함 + check = False + buy_line = [-1 for i in range(len(lower))] + for i in range(3, len(lower)): + # 하락 추세에서는 매수하지 않는다. + if ma2[i] < ma5[i] < ma10[i]: + continue + + for j in range(i-3, i): + if (low[j] < lower[j]) and (low[i] < lower[i] and low[j] == low[i]): + #buy_line[i] = low[i] + check = True + break + if check and i < len(lower) - 1: + buy_line[i+1] = low[i] + 5 + check = False + + if low[i-2] < lower[i-2] and low[i-1] < lower[i-1] and low[i] < open[i] == close[i] < high[i] and open[i] - low[i] == high [i] - open[i]: + if not (open[i-2] < close[i-2] and open[i-1] < close[i-1]) and not (open[i-2] == close[i-2] or open[i-1] == close[i-1]): + buy_line[i+1] = high[i] + + # 2일과 5일선이 10일 선 위로 올라오면 매수한다. + if (ma2[i-1] < ma10[i-1] and ma5[i-1] < ma10[i-1]) and (ma10[i] < ma5[i] < ma2[i]): + buy_line[i+1] = low[i] + 5 + + # 팔 시점 체크 + # 산 가격에 5원 위로 매도를 건다. + sell_line = [-1 for i in range(len(lower))] + for i in range(len(buy_line)): + if buy_line[i] > 0: + for j in range(i+1, len(buy_line)): + # 5원 이득을 보고 판다. + if close[j] >= buy_line[i] + 5: + sell_line[j] = buy_line[i] + 5 + break + + return buy_line, sell_line + """ + + def simulate(self, stock_code, given_day): + #timecheckList = pd.read_csv("timecheck.csv").values.tolist() + #timecheck = {datetime.strptime(given_day + " " + str(second).zfill(6), '%Y%m%d %H%M%S'): False for second, check in timecheckList} + + result = {"check": set(), + "time": [], + "open": [], + "close": [], + "high": [], + "low": [], + "vol": []} + + # 데이터를 가지고 온다. + self.getCSV(given_day+".csv", given_day, result) + + # 분석을 통해서 볼린저밴드 상/하단을 계산한다. + data, upper, lower = self.analyze(result) + + # 사야 할 시점과 팔아야 할 시점을 체크한다. + bsLine = self.checkTransaction(data, upper, lower) + + # 그래프를 그린다. + self.draw(given_day, data, upper, lower, bsLine) + + # 가져온 만큼 데이터를 누적해서 파일로 작성한다. + self.write(given_day, result) + + return + + def buyRealTime(self, stock_code, given_day): + data, upper, lower = None, None, None + + previous_price = 0 + buy_count = 260 + total_byu_amt = 0 + + logFp = open(given_day+".log", "w") + + timecheckList = pd.read_csv("timecheck.csv").values.tolist() + timecheck = {given_day + " " + str(second).zfill(6):False for second, check in timecheckList} + + result = {"check": set(), + "time": [], + "open": [], + "close": [], + "high": [], + "low": [], + "vol": []} + + while datetime.strptime(given_day + " 083000", '%Y%m%d %H%M%S') < datetime.now() < datetime.strptime(given_day + " 151000", '%Y%m%d %H%M%S'): + second = datetime.now().strftime('%Y%m%d %H%M%S') + + if second in timecheck and not timecheck[second]: + print("TIMECHECK", second) + logFp.write("%s,%s,\n" %("TIMECHECK", second)) + logFp.flush() + + # 데이터를 가지고 온다. + self.getRealTime(stock_code, given_day, result) + + # 분석을 통해서 볼린저밴드 상/하단을 계산한다. + data, upper, lower = self.analyze(result) + + # 사야 할 시점과 팔아야 할 시점을 체크한다. + bsLine = self.checkTransaction(data, upper, lower) + + buy_line = bsLine['buy'] + + # 주문 및 매도 처리 + price = bsLine['buy'][len(buy_line)-1] + + # 매수신청과 5원 높여서 매도신청 + if price > 0: + if previous_price > 0: + if previous_price > price: + if buy_count < 200: + buy_count = 200 + buy_count += 40 + if buy_count > 500: + buy_count = 500 + elif previous_price < price: + if buy_count > 400: + buy_count = 400 + buy_count -= 40 + if buy_count < 100: + buy_count = 100 + previous_price = price + + # 매수 주문 + # 현재까지 매입금액이 7백만원 이하일 때만 매수를 한다. + if total_byu_amt < 7000000: + self.requestOrder("2", stock_code, buy_count , price) + + ## 매도 주문 (아래 잔고를 체킇서 매도를 호출하는 것으로 시도한다.) + #time.sleep(60) + #self.requestOrder("1", stock_code, buy_count , price + 5) + print("BUY", second, price) + logFp.write("%s,%s, %d\n" % ("BUY", second, price)) + logFp.flush() + + # 가져온 만큼 데이터를 누적해서 파일로 작성한다. + self.write(given_day, result) + + timecheck[second] = True + else: + #print("NONE", second) + logFp.write("%s,%s,\n" % ("NONE", second)) + logFp.flush() + + # 만약 잔고가 있으면 장부가보다 5원 높게 매도한다. + jangoDic = self.requstJango() + if jangoDic and len(jangoDic.keys()) > 0: + for code in jangoDic: + total_byu_amt = jangoDic[code]['매입금액'] + + if jangoDic[code]['매도가능'] > 0: + # 가장 마지막 현재가를 가져온다. + if len(result['close']) > 0: + last_price = result['close'][len(result['close'])-1] + else: + last_price = 0 + # 현재가가 장부가보다 크다면 현재가 + 5원 매도한다. + if last_price > int(jangoDic[code]['장부가']): + # 현재가가 장부가보다 크다면, + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], last_price) + else: + # 장부가가 현재가보다 크다면, + # 장부가의 마지막 자리수를 가져온다. + last_number = int(jangoDic[code]['장부가']) % 10 + # 장부가 가격의 마지막 자리를 0으로 만든다. (2092 -> 2090, 2098 -> 2090) + sell_price = int(jangoDic[code]['장부가'] / 10) * 10 + # 만약 오후 1시 이전이라면 한 호가 (5원) 더 올려서 매도한다. + if datetime.now() < datetime.strptime(given_day + " 104000", '%Y%m%d %H%M%S'): + if lower != None: + if lower[len(lower)-2] < lower[len(lower)-1]: + sell_price += 5 + + if last_number in [0, 1, 2]: + # 장부가의 마지막 자리수가 0,1,2 라면 (2090, 2091, 2092 -> 2095 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 5) + elif last_number in [3, 4, 5, 6]: + + # 장부가의 마지막 자리수가 3,4,5,6 라면 (2093, 2094, 2095, 2096 -> 2100 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 10) + else: + # 장부가의 마지막 자리수가 7,8,9 라면 (2097, 2098, 2099 -> 2105 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 15) + + time.sleep(0.9) + + logFp.close() + return + +if __name__ == "__main__": + + today = datetime.today() + + PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__)))) + RESOURCE_DIR = PROJECT_HOME + "/resources/analysis/"+today.strftime("%Y%m%d") + + stock_code = "252670" + given_day = datetime.today().strftime('%Y%m%d') + + hts = HTS() + #hts.all_stocks() + #hts.getChartData(stock_code) + #hts.currentStock(stock_code) + #hts.printStockData(stock_code, given_day) + + given_days = ['20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929','20210930'] + given_days = ['20210909','20210913','20210914','20210915','20210916'] + given_days = ['20210913'] + for given_day in given_days: + hts.simulate(stock_code, given_day) + + #hts.buyRealTime(stock_code, given_day) + + print ("done...") diff --git a/stockpredictor/analysis/Common.py b/stockpredictor/analysis/Common.py index 45d0dd6..3eeaabd 100644 --- a/stockpredictor/analysis/Common.py +++ b/stockpredictor/analysis/Common.py @@ -128,6 +128,8 @@ class Common: return score + # YANGBONG + # 어제 음봉 이후 장대양봉이었다면, 매수 def checkLongYangBongAfterUmBong(self, stock, i): if i > 0: if stock[i-1]['close'] < stock[i-1]['open']: # 어제가 음봉인지 체크 @@ -160,6 +162,7 @@ class Common: return "GRAVESTONE_" return "" + # 하락 추세에서 드레곤플라이가 나오면 매수 def checkDragonfly(self, stock, i): # 하락 추세이고, 그저께, 어제 음봉이고, 오늘 드레곤플라이인지 체크한다 if i > 1: