init
This commit is contained in:
@@ -31,12 +31,6 @@ class HTS_122630 (HTS):
|
||||
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)]
|
||||
|
||||
buy, weight, sell = -1, -1, -1
|
||||
last_index = size - 1
|
||||
sell, weight = self.buySellChecker.getSellPriceAndWeight_15000(data, last_index)
|
||||
buy, weight = self.buySellChecker.getBuyPriceAndWeight_15000(data, last_index)
|
||||
@@ -77,34 +71,41 @@ class HTS_122630 (HTS):
|
||||
|
||||
return 0, 0
|
||||
|
||||
def buyRealTime(self, lastday, today):
|
||||
def buyRealTime(self, today):
|
||||
|
||||
timecheckList = pd.read_csv("hts/timecheck.csv").values.tolist()
|
||||
timecheck = {today + " " + str(second).zfill(6):False for second, check in timecheckList}
|
||||
|
||||
print ("START...")
|
||||
THIS_TIME = datetime.now()
|
||||
final_sell_check = False
|
||||
while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100",
|
||||
'%Y%m%d %H%M%S'):
|
||||
LAST_DATA = self.getLastData(self.stock_code, today)
|
||||
|
||||
while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'):
|
||||
|
||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
|
||||
# 3시 까지만 매수를 시도한다.
|
||||
|
||||
if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]:
|
||||
|
||||
# 데이터를 가지고 온다.
|
||||
result = self.getRealTime(self.stock_code, lastday, today)
|
||||
result = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||
|
||||
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.buySellChecker.analyze(result)
|
||||
# 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.buySellChecker.analyzeByRule(result)
|
||||
|
||||
# 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다.
|
||||
bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data)
|
||||
bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, True)
|
||||
bs_buy_price = bsLine['buy']
|
||||
bs_weight = bsLine['buy_weight']
|
||||
bs_sell_price = bsLine['sell']
|
||||
|
||||
data_size = len(data["close"])
|
||||
final_price = data["close"][data_size-1]
|
||||
|
||||
if bs_buy_price > 0:
|
||||
# 기본 100 주에 가중치를 추가해서 매수한다.
|
||||
#33BUY_COUNT = int(self.buy_count * bs_weight)
|
||||
BUY_COUNT = int(self.buy_count * 1)
|
||||
BUY_COUNT = int(self.buy_count * bs_weight)
|
||||
|
||||
# 매수를 주문한다.
|
||||
orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT, bs_buy_price)
|
||||
@@ -118,6 +119,7 @@ class HTS_122630 (HTS):
|
||||
# 로그 출력
|
||||
print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), BUY_COUNT, bs_buy_price, len(orderListToCancel), len(ORDER_LIST))
|
||||
|
||||
|
||||
if bs_sell_price > 0:
|
||||
# 미체결 기록을 가져온다.
|
||||
ORDER_LIST = self.requestOrderList()
|
||||
@@ -136,9 +138,9 @@ class HTS_122630 (HTS):
|
||||
# 로그 출력
|
||||
print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), selling_count, selling_price, len(orderListToCancel), len(ORDER_LIST))
|
||||
|
||||
|
||||
# 로그 출력
|
||||
print(
|
||||
"TIMECHECK: %s, price: %d, open: %d, high: %d, low: %d, avg3: %.2f, avg5: %.2f, avg10: %.2f, avg20: %.2f, avg30: %.2f, avg60: %.2f,\n lower: %.2f, upper: %.2f, macd: %.2f, macds: %.2f, macdo: %.2f,\n rsi: %.2f, rsis: %.2f, fast_k: %.2f, slow_k: %.2f, slow_d: %.2f" %
|
||||
print("TIMECHECK: %s, price: %d, open: %d, high: %d, low: %d, avg3: %.2f, avg5: %.2f, avg10: %.2f, avg20: %.2f, avg30: %.2f, avg60: %.2f,\n lower: %.2f, upper: %.2f, macd: %.2f, macds: %.2f, macdo: %.2f,\n rsi: %.2f, rsis: %.2f, fast_k: %.2f, slow_k: %.2f, slow_d: %.2f" %
|
||||
(str(THIS_TIME), final_price, data["open"][data_size - 1], data["high"][data_size - 1],
|
||||
data["low"][data_size - 1],
|
||||
data["avg3"][data_size - 1], data["avg5"][data_size - 1], data["avg10"][data_size - 1],
|
||||
@@ -151,10 +153,11 @@ class HTS_122630 (HTS):
|
||||
timecheck[THIS_TIME] = True
|
||||
|
||||
elif datetime.strptime(today + " 151530", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151600", '%Y%m%d %H%M%S'):
|
||||
# 3시 15분 30초부터 3시 16분 사이는 잔량을 매도한다.
|
||||
|
||||
if not final_sell_check:
|
||||
####
|
||||
# 손해 보지 않는 가격에 매도한다.
|
||||
# 손해봐도 매도한다.
|
||||
####
|
||||
|
||||
# 주문 리스트를 가져온다.
|
||||
@@ -163,9 +166,12 @@ class HTS_122630 (HTS):
|
||||
self.cancelOrderList(orderList)
|
||||
|
||||
# 매도 가격을 가져온다.
|
||||
result = self.getRealTime(self.stock_code, lastday, today)
|
||||
result = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||
final_price = result["close"][len(result["close"]) - 1]
|
||||
|
||||
selling_count, selling_price = self.getFinalSellingPrice(final_price)
|
||||
# selling_count, selling_price = self.getSellingPrice(final_price)
|
||||
|
||||
# 분석되 가격으로 매도 요청한다.
|
||||
if selling_count != 0 and selling_price != 0:
|
||||
orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price)
|
||||
@@ -193,15 +199,8 @@ if __name__ == "__main__":
|
||||
|
||||
hts = HTS_122630(RESOURCE_PATH, stock_code, buy_count)
|
||||
today_str = today.strftime('%Y%m%d')
|
||||
lastday_str = ""
|
||||
for i in range(1, 10):
|
||||
lastday_str = (today - timedelta(i)).strftime('%Y%m%d')
|
||||
last_hts_data_filename = os.path.join(RESOURCE_PATH, "hts", stock_code + "_" + lastday_str + ".csv")
|
||||
if os.path.isfile(last_hts_data_filename):
|
||||
break
|
||||
|
||||
hts.buyRealTime(lastday_str, today_str)
|
||||
#hts.writeStockData(stock_code, today_str)
|
||||
hts.buyRealTime(today_str)
|
||||
|
||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||
hts.insertStockData(db_filename, stock_code, stock_name, today_str)
|
||||
|
||||
@@ -29,20 +29,6 @@ class HTS_252670 (HTS):
|
||||
self.buySellChecker = BuySellChecker()
|
||||
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)]
|
||||
|
||||
last_index = size - 1
|
||||
#buy, weight, sell = self.buySellChecker.getPriceAndWeight3(hts, last_index)
|
||||
sell, weight = self.buySellChecker.getSellPriceAndWeight_3000(data, last_index)
|
||||
buy, weight = self.buySellChecker.getBuyPriceAndWeight_3000(data, last_index)
|
||||
return buy, weight, sell
|
||||
|
||||
def getSellingPrice(self, final_price):
|
||||
# 만약 잔고가 있으면 장부가보다 5원 높게 매도한다.
|
||||
jangoDic = self.requstJango()
|
||||
@@ -78,7 +64,7 @@ class HTS_252670 (HTS):
|
||||
|
||||
return 0, 0
|
||||
|
||||
def buyRealTime(self, lastday, today):
|
||||
def buyRealTime(self, today):
|
||||
|
||||
timecheckList = pd.read_csv("hts/timecheck.csv").values.tolist()
|
||||
timecheck = {today + " " + str(second).zfill(6):False for second, check in timecheckList}
|
||||
@@ -86,29 +72,33 @@ class HTS_252670 (HTS):
|
||||
print ("START...")
|
||||
THIS_TIME = datetime.now()
|
||||
final_sell_check = False
|
||||
LAST_DATA = self.getLastData(self.stock_code, today)
|
||||
|
||||
while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'):
|
||||
|
||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 150000", '%Y%m%d %H%M%S'):
|
||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
|
||||
# 3시 까지만 매수를 시도한다.
|
||||
|
||||
if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]:
|
||||
|
||||
# 데이터를 가지고 온다.
|
||||
result = self.getRealTime(self.stock_code, lastday, today)
|
||||
result = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||
|
||||
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.buySellChecker.analyze(result)
|
||||
# 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.buySellChecker.analyzeByRule(result)
|
||||
|
||||
# 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다.
|
||||
bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data)
|
||||
bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, True)
|
||||
bs_buy_price = bsLine['buy']
|
||||
bs_weight = bsLine['buy_weight']
|
||||
bs_sell_price = bsLine['sell']
|
||||
|
||||
data_size = len(data["close"])
|
||||
final_price = data["close"][data_size-1]
|
||||
|
||||
if bs_buy_price > 0:
|
||||
# 기본 100 주에 가중치를 추가해서 매수한다.
|
||||
BUY_COUNT = int(self.buy_count * bs_weight)
|
||||
#BUY_COUNT = int(self.buy_count * 1)
|
||||
|
||||
|
||||
# 매수를 주문한다.
|
||||
orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT , bs_buy_price)
|
||||
@@ -159,6 +149,9 @@ class HTS_252670 (HTS):
|
||||
# 3시 15분 30초부터 3시 16분 사이는 잔량을 매도한다.
|
||||
|
||||
if not final_sell_check:
|
||||
####
|
||||
# 손해 보지 않는 가격에 매도한다.
|
||||
####
|
||||
|
||||
# 주문 리스트를 가져온다.
|
||||
orderList = self.requestOrderList()
|
||||
@@ -166,10 +159,12 @@ class HTS_252670 (HTS):
|
||||
self.cancelOrderList(orderList)
|
||||
|
||||
# 매도 가격을 가져온다.
|
||||
result = self.getRealTime(self.stock_code, lastday, today)
|
||||
result = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||
final_price = result["close"][len(result["close"]) - 1]
|
||||
|
||||
#selling_count, selling_price = self.getFinalSellingPrice(final_price)
|
||||
selling_count, selling_price = self.getSellingPrice(final_price)
|
||||
|
||||
# 분석된 가격으로 매도 요청한다.
|
||||
if selling_count != 0 and selling_price != 0:
|
||||
orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price)
|
||||
@@ -197,15 +192,8 @@ if __name__ == "__main__":
|
||||
|
||||
hts = HTS_252670(RESOURCE_PATH, stock_code, buy_count)
|
||||
today_str = today.strftime('%Y%m%d')
|
||||
lastday_str = ""
|
||||
for i in range(1, 10):
|
||||
lastday_str = (today - timedelta(i)).strftime('%Y%m%d')
|
||||
last_hts_data_filename = os.path.join(RESOURCE_PATH, "hts", stock_code + "_" + lastday_str + ".csv")
|
||||
if os.path.isfile(last_hts_data_filename):
|
||||
break
|
||||
|
||||
hts.buyRealTime(lastday_str, today_str)
|
||||
#hts.writeStockData(stock_code, today_str)
|
||||
hts.buyRealTime(today_str)
|
||||
|
||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||
hts.insertStockData(db_filename, stock_code, stock_name, today_str)
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
from math import nan
|
||||
from datetime import datetime, timedelta
|
||||
import csv
|
||||
import copy
|
||||
import pandas as pd
|
||||
import plotly.graph_objects as go
|
||||
from plotly import subplots
|
||||
import sqlite3
|
||||
import os
|
||||
|
||||
from hts.HTS import HTS
|
||||
from hts.BuySellChecker import BuySellChecker
|
||||
|
||||
class Simulation:
|
||||
class Simulation (HTS):
|
||||
|
||||
buySellChecker = None
|
||||
stock_code = None
|
||||
|
||||
def __init__(self, RESOURCE_PATH, stock_code):
|
||||
super().__init__(RESOURCE_PATH)
|
||||
|
||||
self.buySellChecker = BuySellChecker()
|
||||
self.stock_code = stock_code
|
||||
@@ -22,59 +24,6 @@ class Simulation:
|
||||
#self.connect()
|
||||
return
|
||||
|
||||
def getCSV(self, fileName, given_day, result):
|
||||
with open(fileName, 'r', encoding='utf-8') as infp:
|
||||
reader = csv.reader(infp)
|
||||
next(reader)
|
||||
|
||||
for rows in reader:
|
||||
days = rows[0] # hts.날짜
|
||||
time = rows[1] # hts.시간
|
||||
open_v = rows[2] # hts.시가
|
||||
high = rows[3] # hts.고가
|
||||
low = rows[4] # hts.저가
|
||||
close = rows[5] # hts.종가
|
||||
vol = rows[6] # hts.거래량
|
||||
start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S')
|
||||
|
||||
temp = datetime.strptime(str(days) + " " + str(time).zfill(4)+"00", '%Y%m%d %H%M%S')
|
||||
#if temp < start_time:
|
||||
# continue
|
||||
|
||||
result["time"].append(temp)
|
||||
result["open"].append(int(open_v))
|
||||
result["close"].append(int(close))
|
||||
result["high"].append(int(high))
|
||||
result["low"].append(int(low))
|
||||
result["vol"].append(int(vol))
|
||||
return
|
||||
|
||||
def getDBData(self, stock_code, lastday, result):
|
||||
tableName = 'hts'
|
||||
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, lastday,))
|
||||
db_result = cursor.fetchall()
|
||||
for rows in db_result:
|
||||
ymd = rows[0] # hts.날짜
|
||||
hms = rows[1] # hts.시간
|
||||
open = rows[2] # hts.시가
|
||||
high = rows[3] # hts.고가
|
||||
low = rows[4] # hts.저가
|
||||
close = rows[5] # hts.종가
|
||||
vol = rows[6] # hts.거래량
|
||||
|
||||
temp = datetime.strptime(str(ymd) + " " + str(hms).zfill(4) + "00", '%Y%m%d %H%M%S')
|
||||
|
||||
result["time"].append(temp)
|
||||
result["open"].append(int(open))
|
||||
result["close"].append(int(close))
|
||||
result["high"].append(int(high))
|
||||
result["low"].append(int(low))
|
||||
result["vol"].append(int(vol))
|
||||
return
|
||||
|
||||
def draw(self, stock_code, given_day, data, bsLine):
|
||||
# 어제 데이터는 지운다.
|
||||
data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])]
|
||||
@@ -180,30 +129,27 @@ class Simulation:
|
||||
|
||||
return
|
||||
|
||||
def getRealTime(self, stock_code, today, LAST_DATA=None):
|
||||
if LAST_DATA is not None:
|
||||
result = copy.deepcopy(LAST_DATA)
|
||||
else:
|
||||
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": []}
|
||||
|
||||
self.getDBData(stock_code, today, result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def simulate(self, today):
|
||||
result = {"check": set(),
|
||||
"time": [],
|
||||
"open": [],
|
||||
"close": [],
|
||||
"high": [],
|
||||
"low": [],
|
||||
"vol": []}
|
||||
LAST_DATA = self.getLastData(self.stock_code, today)
|
||||
|
||||
# 데이터를 가지고 온다.
|
||||
#self.getCSV(path + "/" + self.stock_code + "_" + last_day + ".csv", last_day, result)
|
||||
#self.getCSV(path + "/" + self.stock_code + "_" + today + ".csv", last_day, result)
|
||||
for i in range(1, 10):
|
||||
last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
|
||||
self.getDBData(self.stock_code, last_day, result)
|
||||
if len(result['time']) > 0:
|
||||
break
|
||||
self.getDBData(self.stock_code, today, result)
|
||||
result = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||
|
||||
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.buySellChecker.analyze(result)
|
||||
# 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.buySellChecker.analyzeByRule(result)
|
||||
|
||||
# 사야 할 시점과 팔아야 할 시점을 체크한다.
|
||||
bsLine = self.buySellChecker.checkTransaction(data, self.stock_code)
|
||||
bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, False)
|
||||
|
||||
# 그래프를 그린다.
|
||||
self.draw(self.stock_code, today, data, bsLine)
|
||||
|
||||
@@ -10,6 +10,7 @@ class BuySellChecker:
|
||||
common = None
|
||||
stochastic = None
|
||||
rsi = None
|
||||
macd = None
|
||||
ichimokuCloud = None
|
||||
|
||||
def __init__(self):
|
||||
@@ -752,7 +753,7 @@ class BuySellChecker:
|
||||
|
||||
|
||||
|
||||
def analyze(self, result):
|
||||
def analyzeByRule(self, result):
|
||||
open = result["open"]
|
||||
close = result["close"]
|
||||
high = result["high"]
|
||||
@@ -835,10 +836,30 @@ class BuySellChecker:
|
||||
|
||||
return data
|
||||
|
||||
def checkTransaction(self, data, stock_code):
|
||||
size = len(data["close"])
|
||||
def checkTransaction(self, data, stock_code, type=True):
|
||||
# 4일치 중에서 앞에 2일은 제거한다.
|
||||
date = data['date'].dt.date.unique().tolist()
|
||||
data = data[data['date'].dt.date != date[0]]
|
||||
data = data[data['date'].dt.date != date[1]]
|
||||
|
||||
# 어제 오늘 데이터로 분석
|
||||
bsLine = {}
|
||||
size = len(data["close"])
|
||||
if type:
|
||||
last_index = size - 1
|
||||
|
||||
if stock_code == "252670":
|
||||
sell, weight = self.getSellPriceAndWeight_3000(data, last_index)
|
||||
buy, weight = self.getBuyPriceAndWeight_3000(data, last_index)
|
||||
else:
|
||||
sell, weight = self.getSellPriceAndWeight_15000(data, last_index)
|
||||
buy, weight = self.getBuyPriceAndWeight_15000(data, last_index)
|
||||
|
||||
bsLine['buy'] = buy
|
||||
bsLine['buy_weight'] = weight
|
||||
bsLine['sell'] = sell
|
||||
bsLine['sell_weight'] = weight
|
||||
else:
|
||||
bsLine['buy'] = [-1 for i in range(size)]
|
||||
bsLine['weight'] = [-1 for i in range(size)]
|
||||
bsLine['sell'] = [-1 for i in range(size)]
|
||||
@@ -855,4 +876,4 @@ class BuySellChecker:
|
||||
bsLine['weight'][i] = weight
|
||||
bsLine['sell'][i] = sell
|
||||
|
||||
return bsLine
|
||||
return bsLine, data
|
||||
|
||||
51
hts/HTS.py
51
hts/HTS.py
@@ -1,10 +1,12 @@
|
||||
import os.path
|
||||
|
||||
import copy
|
||||
import platform
|
||||
if platform.system().lower().find("window") >= 0:
|
||||
import win32com.client
|
||||
import csv
|
||||
import time
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from hts.OrderItem import OrderItem
|
||||
|
||||
class HTS:
|
||||
@@ -546,12 +548,12 @@ class HTS:
|
||||
result["vol"].append(int(vol))
|
||||
return
|
||||
|
||||
def getDBData(self, stock_code, lastday, result):
|
||||
def getDBData(self, stock_code, day, result):
|
||||
tableName = 'hts'
|
||||
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, lastday,))
|
||||
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, day,))
|
||||
db_result = cursor.fetchall()
|
||||
for rows in db_result:
|
||||
ymd = rows[0] # hts.날짜
|
||||
@@ -570,10 +572,21 @@ class HTS:
|
||||
result["high"].append(int(high))
|
||||
result["low"].append(int(low))
|
||||
result["vol"].append(int(vol))
|
||||
|
||||
return
|
||||
|
||||
# 주식 현재가 조회
|
||||
def getRealTime(self, stock_code, lastday, today):
|
||||
def isValidYMD(self, stock_code, day):
|
||||
tableName = 'hts'
|
||||
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT ymd, count(*) as cnt FROM ' + tableName + ' WHERE CODE=? and ymd=?', (stock_code, day,))
|
||||
db_result = cursor.fetchone()
|
||||
if db_result[1] > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getLastData(self, stock_code, today, n=3):
|
||||
result = {"check": set(),
|
||||
"time": [],
|
||||
"open": [],
|
||||
@@ -582,9 +595,29 @@ class HTS:
|
||||
"low": [],
|
||||
"vol": []}
|
||||
|
||||
#last_stock_filename = os.path.join(self.RESOURCE_PATH, "hts", stock_code + "_" + lastday + ".csv")
|
||||
#self.getCSV(last_stock_filename, result)
|
||||
self.getDBData(stock_code, lastday, result)
|
||||
days = []
|
||||
for i in range(1, 10):
|
||||
last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
|
||||
isValid = self.isValidYMD(stock_code, last_day)
|
||||
if isValid:
|
||||
days.append(last_day)
|
||||
if len(days) >= 3:
|
||||
break
|
||||
|
||||
days.sort()
|
||||
for day in days:
|
||||
self.getDBData(stock_code, day, result)
|
||||
|
||||
return result
|
||||
|
||||
# 주식 현재가 조회
|
||||
def getRealTime(self, stock_code, today, LAST_DATA=None):
|
||||
if LAST_DATA is not None:
|
||||
result = copy.deepcopy(LAST_DATA)
|
||||
else:
|
||||
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": []}
|
||||
|
||||
self.getDBData(stock_code, today, result)
|
||||
|
||||
int_given_day = int(today)
|
||||
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
|
||||
|
||||
@@ -1,15 +1,184 @@
|
||||
import os
|
||||
import sqlite3
|
||||
from datetime import datetime, timedelta
|
||||
import pandas as pd
|
||||
|
||||
from stock.analysis.Common import Common
|
||||
from stock.analysis.Stochastic import Stochastic
|
||||
from stock.analysis.RSI import RSI
|
||||
from stock.analysis.MACD import MACD
|
||||
from stock.analysis.IchimokuCloud import IchimokuCloud
|
||||
|
||||
class Stock2Vector:
|
||||
|
||||
def __init__(self):
|
||||
RESOURCE_PATH = None
|
||||
|
||||
common = None
|
||||
stochastic = None
|
||||
rsi = None
|
||||
macd = None
|
||||
ichimokuCloud = None
|
||||
|
||||
def __init__(self, RESOURCE_PATH):
|
||||
self.RESOURCE_PATH = RESOURCE_PATH
|
||||
|
||||
self.common = Common()
|
||||
self.stochastic = Stochastic()
|
||||
self.rsi = RSI()
|
||||
self.macd = MACD()
|
||||
self.ichimokuCloud = IchimokuCloud()
|
||||
return
|
||||
|
||||
def read(self, fileName):
|
||||
return None
|
||||
def analyze(self, result):
|
||||
open = result["open"]
|
||||
close = result["close"]
|
||||
high = result["high"]
|
||||
low = result["low"]
|
||||
vol = result["vol"]
|
||||
|
||||
def process(self, vector):
|
||||
close_df = pd.DataFrame(close)
|
||||
avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist()
|
||||
avg3 = [item[0] for item in avg3_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]
|
||||
avg60_list = close_df.rolling(window=60).mean().fillna(close[0]).values.tolist()
|
||||
avg60 = [item[0] for item in avg60_list]
|
||||
|
||||
df = pd.DataFrame(close)
|
||||
max20 = df.rolling(window=20).mean()
|
||||
stddev20 = df.rolling(window=20).std()
|
||||
upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드
|
||||
lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드
|
||||
|
||||
upper, lower = [], []
|
||||
for i in range(len(upper_df)):
|
||||
if i < 10:
|
||||
upper.append(upper_df.values[0][0])
|
||||
lower.append(lower_df.values[0][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(open)):
|
||||
STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
|
||||
'avg3': avg3[i], 'avg5': avg5[i],'avg10': avg10[i],'avg20': avg20[i],'avg30': avg30[i],'avg60': avg60[i]})
|
||||
|
||||
# stochastic 계산
|
||||
stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5)
|
||||
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()
|
||||
|
||||
# macd 계산
|
||||
macd_df = self.macd.apply(STOCK, short=12, long=26, t=9)
|
||||
macd_df = macd_df.fillna(100)
|
||||
macd = macd_df['macd'].values.tolist()
|
||||
macds = macd_df['macds'].values.tolist()
|
||||
macdo = macd_df['macdo'].values.tolist()
|
||||
|
||||
# rsi 계산
|
||||
rsi_df = self.rsi.apply(STOCK, period=30, window=5)
|
||||
rsi_df = rsi_df.fillna(100)
|
||||
rsi = rsi_df['rsi'].values.tolist()
|
||||
rsis = rsi_df['rsis'].values.tolist()
|
||||
|
||||
# ichimokuCloud 계산
|
||||
# ichimokuCloud_df = self.ichimokuCloud.apply(STOCK, c=9, b=26, l=52)
|
||||
# ichimokuCloud_df = rsi_df.fillna(100)
|
||||
# changeLine = rsi_df['changeLine'].values.tolist()
|
||||
# baseLine = rsi_df['baseLine'].values.tolist()
|
||||
# leadingSpan1 = rsi_df['leadingSpan1'].values.tolist()
|
||||
# leadingSpan2 = rsi_df['leadingSpan2'].values.tolist()
|
||||
|
||||
temp = {"date": point_temp,
|
||||
"open": open, "high": high, "low": low, "close": close, "volume": vol, "upper": upper, "lower": lower,
|
||||
"avg3": avg3, "avg5": avg5, "avg10": avg10, "avg20": avg20, "avg30": avg30, "avg60": avg60,
|
||||
"macd": macd, "macds": macds, "macdo": macdo,
|
||||
"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
|
||||
|
||||
data.fillna(0)
|
||||
|
||||
return data
|
||||
|
||||
def getDBData(self, stock_code, lastday, result):
|
||||
tableName = 'hts'
|
||||
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, lastday,))
|
||||
db_result = cursor.fetchall()
|
||||
for rows in db_result:
|
||||
ymd = rows[0] # hts.날짜
|
||||
hms = rows[1] # hts.시간
|
||||
open = rows[2] # hts.시가
|
||||
high = rows[3] # hts.고가
|
||||
low = rows[4] # hts.저가
|
||||
close = rows[5] # hts.종가
|
||||
vol = rows[6] # hts.거래량
|
||||
|
||||
temp = datetime.strptime(str(ymd) + " " + str(hms).zfill(4) + "00", '%Y%m%d %H%M%S')
|
||||
|
||||
result["time"].append(temp)
|
||||
result["open"].append(int(open))
|
||||
result["close"].append(int(close))
|
||||
result["high"].append(int(high))
|
||||
result["low"].append(int(low))
|
||||
result["vol"].append(int(vol))
|
||||
return
|
||||
|
||||
def vectorize(self, stock_code, given_day):
|
||||
result = {"check": set(),
|
||||
"time": [],
|
||||
"open": [],
|
||||
"close": [],
|
||||
"high": [],
|
||||
"low": [],
|
||||
"vol": []}
|
||||
|
||||
for i in range(1, 10):
|
||||
last_day = (datetime.strptime(given_day, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
|
||||
self.getDBData(stock_code, last_day, result)
|
||||
if len(result['time']) > 0:
|
||||
break
|
||||
self.getDBData(stock_code, given_day, result)
|
||||
|
||||
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.analyze(result)
|
||||
|
||||
return data
|
||||
|
||||
if __name__ == "__main__":
|
||||
stock2Vector = Stock2Vector()
|
||||
fileName = "./resources/hts/252670_20220726.csv"
|
||||
PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__))))))
|
||||
RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources")
|
||||
|
||||
stock2Vector = Stock2Vector(RESOURCE_PATH)
|
||||
|
||||
# to check bying
|
||||
stock_codes = {
|
||||
# 252670
|
||||
# 122630
|
||||
"122630": ['20220725'],
|
||||
}
|
||||
|
||||
for stock_code in stock_codes:
|
||||
|
||||
for given_day in stock_codes[stock_code]:
|
||||
stock2Vector.vectorize(stock_code, given_day)
|
||||
|
||||
print ("done...")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user