This commit is contained in:
dosangyoon
2021-10-14 23:29:20 +09:00
parent 972d014ca7
commit b5232af02f
3 changed files with 503 additions and 504 deletions

259
hts/BS.py Normal file
View File

@@ -0,0 +1,259 @@
import pandas as pd
from stockpredictor.analysis.Common import Common
from stockpredictor.analysis.Stochastic import Stochastic
from stockpredictor.analysis.RSI import RSI
class BS:
common = None
stochastic = None
rsi = None
def __init__(self):
self.common = Common()
self.stochastic = Stochastic()
self.rsi = RSI()
return
def checkStatus(self, STOCK, last_index):
status = set()
# 정배열 체크
temp_status = self.common.check_RightArrange(STOCK, last_index)
if temp_status != "":
status.add(temp_status)
# 돌파 체크
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "20")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "60")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "120")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "240")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "60")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "120")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "240")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "60", "120")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "60", "240")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "120", "240")
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 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) # 하단 볼린저 밴드
window = 5
open = result["open"]
close = result["close"]
high = result["high"]
low = result["low"]
vol = result["vol"]
close_df = pd.DataFrame(close)
avg1_list = close_df.rolling(window=1).mean().fillna(close[0]).values.tolist()
avg1 = [item[0] for item in avg1_list]
avg2_list = close_df.rolling(window=2).mean().fillna(close[0]).values.tolist()
avg2 = [item[0] for item in avg2_list]
avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist()
avg5 = [item[0] for item in avg5_list]
avg10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist()
avg10 = [item[0] for item in avg10_list]
avg20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist()
avg20 = [item[0] for item in avg20_list]
avg30_list = close_df.rolling(window=30).mean().fillna(close[0]).values.tolist()
avg30 = [item[0] for item in avg30_list]
avg40_list = close_df.rolling(window=40).mean().fillna(close[0]).values.tolist()
avg40 = [item[0] for item in avg40_list]
avg50_list = close_df.rolling(window=50).mean().fillna(close[0]).values.tolist()
avg50 = [item[0] for item in avg50_list]
avg60_list = close_df.rolling(window=60).mean().fillna(close[0]).values.tolist()
avg60 = [item[0] for item in avg60_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"]
STOCK = []
for i in range(len(result["open"])):
STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i],
'high': high[i], 'low': low[i], 'avg5': avg2[i],
'avg20': avg5[i], 'avg60': avg10[i], 'avg120': avg20[i],
'avg240': avg30[i]})
# stochastic 계산
stochastic_df = self.stochastic.apply(pd.DataFrame(STOCK))
stochastic_df = stochastic_df.fillna(100)
fast_k = stochastic_df['fast_k'].values.tolist()
slow_k = stochastic_df['slow_k'].values.tolist()
slow_d = stochastic_df['slow_d'].values.tolist()
# rsi 계산
rsi_df = self.rsi.apply(pd.DataFrame(STOCK))
rsi_df = rsi_df.fillna(100)
rsi = rsi_df['rsi'].values.tolist()
rsis = rsi_df['rsis'].values.tolist()
temp = {"Date": point_temp,
"Open": open, "High": high, "Low": low, "Close": close, "Volume": vol,
"upper": upper, "lower": lower,
"avg1": avg1, "avg2": avg2, "avg5": avg5, "avg10": avg10, "avg20": avg20, "avg30": avg30, "avg40": avg40, "avg50": avg50, "avg60": avg60,
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
"rsi": rsi, "rsis": rsis}
data = pd.DataFrame(temp)
df_final_time = pd.DatetimeIndex(point_temp)
data.index = df_final_time
return data

View File

@@ -1,14 +1,11 @@
#import win32com.client import win32com.client
import time import time
import os import os
from datetime import datetime, timedelta from datetime import datetime, timedelta
import pandas as pd import pandas as pd
from enum import Enum from enum import Enum
import plotly.graph_objects as go
from stockpredictor.analysis.Common import Common
from stockpredictor.analysis.Stochastic import Stochastic from BS import BS
from stockpredictor.analysis.RSI import RSI
# enum 주문 상태 세팅용 # enum 주문 상태 세팅용
class EorderBS(Enum): class EorderBS(Enum):
@@ -33,16 +30,11 @@ class HTS:
objCpCybos = None objCpCybos = None
objCpCodeMgr = None objCpCodeMgr = None
common = None
stochastic = None bs = None
rsi = None
def __init__(self): def __init__(self):
self.common = Common() self.bs = BS()
self.stochastic = Stochastic()
self.rsi = RSI()
#self.connect() #self.connect()
return return
@@ -530,492 +522,54 @@ class HTS:
return return
def getCSV(self, fileName, given_day, result): def checkTransaction(self, data):
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) # 하단 볼린저 밴드
window = 5
open = result["open"]
close = result["close"]
high = result["high"]
low = result["low"]
vol = result["vol"]
close_df = pd.DataFrame(close)
avg1_list = close_df.rolling(window=1).mean().fillna(close[0]).values.tolist()
avg1 = [item[0] for item in avg1_list]
avg2_list = close_df.rolling(window=2).mean().fillna(close[0]).values.tolist()
avg2 = [item[0] for item in avg2_list]
avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist()
avg5 = [item[0] for item in avg5_list]
avg10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist()
avg10 = [item[0] for item in avg10_list]
avg20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist()
avg20 = [item[0] for item in avg20_list]
avg30_list = close_df.rolling(window=30).mean().fillna(close[0]).values.tolist()
avg30 = [item[0] for item in avg30_list]
avg40_list = close_df.rolling(window=40).mean().fillna(close[0]).values.tolist()
avg40 = [item[0] for item in avg40_list]
avg50_list = close_df.rolling(window=50).mean().fillna(close[0]).values.tolist()
avg50 = [item[0] for item in avg50_list]
avg60_list = close_df.rolling(window=60).mean().fillna(close[0]).values.tolist()
avg60 = [item[0] for item in avg60_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"]
STOCK = []
for i in range(len(result["open"])):
STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i],
'high': high[i], 'low': low[i], 'avg5': avg2[i],
'avg20': avg5[i], 'avg60': avg10[i], 'avg120': avg20[i],
'avg240': avg30[i]})
# stochastic 계산
stochastic_df = self.stochastic.apply(pd.DataFrame(STOCK))
stochastic_df = stochastic_df.fillna(0)
fast_k = stochastic_df['fast_k'].values.tolist()
slow_k = stochastic_df['slow_k'].values.tolist()
slow_d = stochastic_df['slow_d'].values.tolist()
# rsi 계산
rsi_df = self.rsi.apply(pd.DataFrame(STOCK))
rsi_df = rsi_df.fillna(0)
rsi = rsi_df['rsi'].values.tolist()
rsis = rsi_df['rsis'].values.tolist()
temp = {"Date": point_temp,
"Open": open, "High": high, "Low": low, "Close": close, "Volume": vol,
"avg1": avg1, "avg2": avg2, "avg5": avg5, "avg10": avg10, "avg20": avg20, "avg30": avg30, "avg40": avg40, "avg50": avg50, "avg60": avg60,
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
"rsi": rsi, "rsis": rsis}
data = pd.DataFrame(temp)
df_final_time = pd.DatetimeIndex(point_temp)
data.index = df_final_time
return data, upper, lower
def draw(self, stock_code, 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['avg1'] = pd.to_numeric(data['avg1'])
data['avg2'] = pd.to_numeric(data['avg2'])
data['avg5'] = pd.to_numeric(data['avg5'])
data['avg10'] = pd.to_numeric(data['avg10'])
data['avg20'] = pd.to_numeric(data['avg20'])
data['avg30'] = pd.to_numeric(data['avg30'])
data['avg40'] = pd.to_numeric(data['avg40'])
data['avg50'] = pd.to_numeric(data['avg50'])
data['avg60'] = pd.to_numeric(data['avg60'])
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')
avg1 = go.Scatter(x=data['Date'], y=data['avg1'], name="avg1", line_color='#FF0000')
avg2 = go.Scatter(x=data['Date'], y=data['avg2'], name="avg2", line_color='#A200FF')
avg5 = go.Scatter(x=data['Date'], y=data['avg5'], name="avg5", line_color='#0800FF')
avg10 = go.Scatter(x=data['Date'], y=data['avg10'], name="avg10", line_color='#FF7C00')
avg20 = go.Scatter(x=data['Date'], y=data['avg20'], name="avg20", line_color='#00AAFF')
avg30 = go.Scatter(x=data['Date'], y=data['avg30'], name="avg30", line_color='#FFD100')
avg40 = go.Scatter(x=data['Date'], y=data['avg40'], name="avg40", line_color='#A600FF')
avg50 = go.Scatter(x=data['Date'], y=data['avg50'], name="avg50", line_color='#FF00E0')
avg60 = go.Scatter(x=data['Date'], y=data['avg60'], name="avg60", 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, avg1, avg2, avg5, avg10, avg20, avg30, avg40, avg50, avg60])
fig.update_layout(title=stock_code + "_" + given_day)
fig.show()
return
def checkStatus(self, STOCK, last_index):
status = set()
# 정배열 체크
temp_status = self.common.check_RightArrange(STOCK, last_index)
if temp_status != "":
status.add(temp_status)
# 돌파 체크
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "20")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "60")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "120")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "240")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "60")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "120")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "240")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "60", "120")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "60", "240")
if temp_status != "":
status.add(temp_status)
temp_status = self.common.check_Dolpa(STOCK, last_index, "120", "240")
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"]) size = len(data["Close"])
STOCK = []
for i in range(size):
STOCK.append({'volume': data['Volume'][i], 'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'avg2': data["avg2"][i], 'avg5': data["avg5"][i], 'avg10': data["avg10"][i], 'avg20': data["avg20"][i], 'avg30': data["avg30"], 'avg40': data["avg40"], 'avg50': data["avg50"], 'avg60': data["avg60"][i]})
bsLine = {} bsLine = {}
bsLine['buy'] = [-1 for i in range(size)] bsLine['buy'] = [-1 for i in range(size)]
bsLine['weight'] = [-1 for i in range(size)]
bsLine['sell'] = [-1 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)]
i = size - 1 i = size - 1
""" if i > 20:
status = self.checkStatus(STOCK, i) if data["High"][i] > data["upper"][i]:
count_1 = 0 bsLine['sell'][i] = data["High"][i]
# if "GOLDEN#2_" in status: count_1 += 1
# if "arrange_" in status: count_1 += 1
# if "UMYANG_" in status: count_1 += 1
# if "5-20_" in status: count_1 += 1
if "5_20_" in status: count_1 += 1
if "5_60_" in status: count_1 += 1
if "5_120_" in status: count_1 += 1
if "5_240_" in status: count_1 += 1
if "20_60_" in status: count_1 += 1
if "20_120_" in status: count_1 += 1
if "20_240_" in status: count_1 += 1
if "60_120_" in status: count_1 += 1
if "60_240_" in status: count_1 += 1
if "120_240_" 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 "GOLDEN#3_" 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
# real time 에서는 현재 기점에 사고 파는 가격을 표기한다. if data["slow_k"][i] <= 36:
if count_0 == 0 and count_1 > 0: if data["Low"][i] < data["lower"][i]:
bsLine['buy'][i] = STOCK[i]['close'] - 5 bsLine['buy'][i] = data["Close"][i] - 5
bsLine['sell'][i] = STOCK[i]['close'] if data["slow_k"][i] <= 25:
if count_0 > 0: if data["slow_k"][i - 1] < data["slow_d"][i - 1] and data["slow_d"][i] < data["slow_k"][i]:
bsLine['buy'][i] = 0 bsLine['buy'][i] = data["Close"][i] - 5
bsLine['sell'][i] = STOCK[i]['close'] + 5
"""
if STOCK[i]['low'] < lower[i]: # rsi가 rsis 위로 올라오며 15 이하일 경우 10배로 주문함 (14:30 이전)
bsLine['buy'][i] = STOCK[i]['close'] - 5 if data["rsi"][i] < 15 and data["rsis"][i] < 15 and data["rsi"][i - 1] < data["rsis"][i - 1] and data["rsis"][i] < data["rsi"][i]:
if STOCK[i]['close'] > upper[i]: bsLine['buy'][i] = data["Close"][i] - 5
bsLine['sell'][i] = STOCK[i]['close'] + 5 bsLine['weight'][i] = 10
return bsLine['buy'][i], bsLine['sell'][i]
if data["slow_k"][i] == 1:
bsLine['weight'][i] = 8
elif data["slow_k"][i] in(2,3):
bsLine['weight'][i] = 7
elif data["slow_k"][i] in(4,5,6):
bsLine['weight'][i] = 6
elif data["slow_k"][i] in(7,8,9,10):
bsLine['weight'][i] = 5
elif data["slow_k"][i] in(11,12,13,14,15):
bsLine['weight'][i] = 4
elif data["slow_k"][i] in(16,17,18,19,20,21):
bsLine['weight'][i] = 3
elif data["slow_k"][i] in(22,23,24,25,26,27,28):
bsLine['weight'][i] = 2
elif data["slow_k"][i] in(29,30,31,32,33,34,35,36):
bsLine['weight'][i] = 1
if data["rsi"][i] < 10:
bsLine['weight'][i] = 8
if i<=20:
bsLine['weight'][i] = 1
def checkTransaction_Simulation(self, data, upper, lower): return bsLine['buy'][i], bsLine['weight'][i], bsLine['sell'][i]
size = len(data["Close"])
STOCK = []
for i in range(size):
STOCK.append({'volume': data['Volume'][i], 'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'avg5': data["avg2"][i], 'avg20': data["avg5"][i], 'avg60': data["avg10"][i], 'avg120': data["avg20"][i], 'avg240': data["avg30"][i]})
bsLine = {}
bsLine['buy'] = [-1 for i in range(len(lower))]
bsLine['sell'] = [-1 for i in range(len(lower))]
for i in range(5, size-5):
"""
status = self.checkStatus(STOCK, i)
count_1 = 0
#if "GOLDEN#2_" in status: count_1 += 1
#if "arrange_" in status: count_1 += 1
#if "UMYANG_" in status: count_1 += 1
#if "5-20_" in status: count_1 += 1
if "5_20_" in status: count_1 += 1
if "5_60_" in status: count_1 += 1
if "5_120_" in status: count_1 += 1
if "5_240_" in status: count_1 += 1
if "20_60_" in status: count_1 += 1
if "20_120_" in status: count_1 += 1
if "20_240_" in status: count_1 += 1
if "60_120_" in status: count_1 += 1
if "60_240_" in status: count_1 += 1
if "120_240_" 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 "GOLDEN#3_" 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 count_0 == 0 and count_1 > 0:
bsLine['buy'][i + 1] = STOCK[i]['close'] - 5
#bsLine['sell'][i + 2] = STOCK[i]['close']
#if count_0 > 0:
# bsLine['sell'][i + 2] = STOCK[i]['close'] + 5
if data["avg60"][i - 1] > data["avg60"][i]:
bsLine['sell'][i] = STOCK[i]['close']
"""
if STOCK[i]['low'] < lower[i]:
bsLine['buy'][i] = STOCK[i]['close'] - 5
if STOCK[i]['close'] > upper[i]:
bsLine['sell'][i] = STOCK[i]['close'] + 5
return bsLine
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("./data/"+stock_code+"_"+given_day+".csv", given_day, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data, upper, lower = self.analyze(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다.
bsLine = self.checkTransaction_Simulation(data, upper, lower)
# 그래프를 그린다.
self.draw(stock_code, given_day, data, upper, lower, bsLine)
# 가져온 만큼 데이터를 누적해서 파일로 작성한다.
# self.write(given_day, result)
return
def getSellingPrice(self, final_price): def getSellingPrice(self, final_price):
# 만약 잔고가 있으면 장부가보다 5원 높게 매도한다. # 만약 잔고가 있으면 장부가보다 5원 높게 매도한다.
@@ -1071,9 +625,9 @@ class HTS:
self.getRealTime(stock_code, given_day, result) self.getRealTime(stock_code, given_day, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다. # 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data, upper, lower = self.analyze(result) data = self.bs.analyze(result)
# 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다. # 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다.
bs_buy_price, bs_sell_price = self.checkTransaction_Realtime(data, upper, lower) bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data)
final_price = data["Close"][len(data["Close"])-1] final_price = data["Close"][len(data["Close"])-1]
if bs_buy_price > 0: if bs_buy_price > 0:
@@ -1131,23 +685,10 @@ if __name__ == "__main__":
PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__)))) 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") RESOURCE_DIR = PROJECT_HOME + "/resources/analysis/"+today.strftime("%Y%m%d")
stock_codes = ["252670", "122630"]
given_days = ['20210901','20210902','20210903','20210906','20210907','20210908','20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929','20210930','20211001', '20211005']
given_days = ['20210901']
hts = HTS() hts = HTS()
stock_codes = ["252670", "122630"]
#hts.all_stocks() given_day = datetime.today().strftime('%Y%m%d')
#hts.getChartData(stock_codes)
#hts.currentStock(stock_codes)
#for given_day in given_days:
#hts.writeStockData(stock_codes, given_day)
#for stock_code in stock_codes:
#hts.simulate(stock_code, given_day)
#given_day = datetime.today().strftime('%Y%m%d')
#hts.writeStockData(stock_codes, given_day) #hts.writeStockData(stock_codes, given_day)
hts.simulate(stock_codes[0], given_days[0]) hts.buyRealTime(stock_codes[0], given_day)
#hts.buyRealTime(stock_codes[0], given_day)
print ("done...") print ("done...")

199
hts/Simulation.py Normal file
View File

@@ -0,0 +1,199 @@
import os
from datetime import datetime, timedelta
import pandas as pd
import plotly.graph_objects as go
from plotly import subplots
from BS import BS
class Simulation:
bs = None
def __init__(self):
self.bs = BS()
#self.connect()
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 checkTransaction(self, data):
size = len(data["Close"])
bsLine = {}
bsLine['buy'] = [-1 for i in range(size)]
bsLine['weight'] = [-1 for i in range(size)]
bsLine['sell'] = [-1 for i in range(size)]
for i in range(21, size-5):
if data["High"][i] > data["upper"][i]:
bsLine['sell'][i] = data["High"][i]
if data["slow_k"][i] <= 36:
if data["Low"][i] < data["lower"][i]:
bsLine['buy'][i] = data["Close"][i] - 5
if data["slow_k"][i] <= 25:
if data["slow_k"][i - 1] < data["slow_d"][i - 1] and data["slow_d"][i] < data["slow_k"][i]:
bsLine['buy'][i] = data["Close"][i] - 5
# rsi가 rsis 위로 올라오며 15 이하일 경우 10배로 주문함 (14:30 이전)
if data["rsi"][i] < 15 and data["rsis"][i] < 15 and data["rsi"][i - 1] < data["rsis"][i - 1] and data["rsis"][i] < data["rsi"][i]:
bsLine['buy'][i] = data["Close"][i] - 5
bsLine['weight'][i] = 10
if data["slow_k"][i] == 1:
bsLine['weight'][i] = 8
elif data["slow_k"][i] in(2,3):
bsLine['weight'][i] = 7
elif data["slow_k"][i] in(4,5,6):
bsLine['weight'][i] = 6
elif data["slow_k"][i] in(7,8,9,10):
bsLine['weight'][i] = 5
elif data["slow_k"][i] in(11,12,13,14,15):
bsLine['weight'][i] = 4
elif data["slow_k"][i] in(16,17,18,19,20,21):
bsLine['weight'][i] = 3
elif data["slow_k"][i] in(22,23,24,25,26,27,28):
bsLine['weight'][i] = 2
elif data["slow_k"][i] in(29,30,31,32,33,34,35,36):
bsLine['weight'][i] = 1
if data["rsi"][i] < 10:
bsLine['weight'][i] = 8
if i<=20:
bsLine['weight'][i] = 1
return bsLine
def draw(self, stock_code, given_day, data, 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["fast_k"] = pd.to_numeric(data['fast_k'])
data["slow_k"] = pd.to_numeric(data['slow_k'])
data["slow_d"] = pd.to_numeric(data['slow_d'])
data["rsi"] = pd.to_numeric(data['rsi'])
data["rsis"] = pd.to_numeric(data['rsis'])
buy_colors = []
for i in range(len(buy_line)):
if buy_line[i] < 0:
buy_colors.append("#ffffff")
buy_line[i] = data["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] = data["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=data["upper"], name="upper", line_color='#8B4513')
bolinger_lower = go.Scatter(x=data['Date'], y=data["lower"], name="lower", line_color='#8B4513')
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')
fast_k_line = go.Scatter(x=data['Date'], y=data["fast_k"], mode='lines', name='fast_k')
slow_k_line = go.Scatter(x=data['Date'], y=data["slow_k"], mode='lines', name='slow_k')
slow_d_line = go.Scatter(x=data['Date'], y=data["slow_d"], mode='lines', name='slow_d')
rsi_line = go.Scatter(x=data['Date'], y=data["rsi"], mode='lines', name='rsi')
rsis_line = go.Scatter(x=data['Date'], y=data["rsis"], mode='lines', name='rsis')
#candle_data = [candle_stick, bolinger_upper, bolinger_lower, buy_check, sell_check, avg1, avg2, avg5, avg10, avg20, avg30, avg40, avg50, avg60]
candle_data = [candle_stick, bolinger_upper, bolinger_lower, buy_check, sell_check]
stochastic_data = [slow_k_line, slow_d_line]
rsi_data = [rsi_line, rsis_line]
# 그래프를 그린다.
"""
fig = go.Figure(data=candle_data)
fig.update_layout(title=stock_code + "_" + given_day)
fig.show()
"""
fig = subplots.make_subplots(rows=3, cols=1, subplot_titles=('캔들', "스토캐스틱", "RSI"))
for trace in candle_data:
fig.append_trace(trace, 1, 1)
for trace in stochastic_data:
fig.append_trace(trace, 2, 1)
for trace in rsi_data:
fig.append_trace(trace, 3, 1)
#fig.update_xaxes(nticks=5)
#fig.update_layout(height=1800, title=stock_code + "_" + given_day, xaxis_rangeslider_visible=False)
fig.update_layout(height=1800, title=stock_code + "_" + given_day)
fig.show()
return
def simulate(self, stock_code, given_day):
result = {"check": set(),
"time": [],
"open": [],
"close": [],
"high": [],
"low": [],
"vol": []}
# 데이터를 가지고 온다.
self.getCSV("./data/"+stock_code+"_"+given_day+".csv", given_day, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.bs.analyze(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다.
bsLine = self.checkTransaction(data)
# 그래프를 그린다.
self.draw(stock_code, given_day, data, bsLine)
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_codes = ["252670", "122630"]
given_days = ['20210901','20210902','20210903','20210906','20210907','20210908','20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929','20210930','20211001', '20211005']
given_days = ['20211008']
simulation = Simulation()
simulation.simulate(stock_codes[0], given_days[0])
print ("done...")