init
This commit is contained in:
259
hts/BS.py
Normal file
259
hts/BS.py
Normal 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
|
||||||
549
hts/HTS.py
549
hts/HTS.py
@@ -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
199
hts/Simulation.py
Normal 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...")
|
||||||
Reference in New Issue
Block a user