init
This commit is contained in:
@@ -3,7 +3,7 @@ from stockpredictor.analysis.Common import Common
|
||||
from stockpredictor.analysis.Stochastic import Stochastic
|
||||
from stockpredictor.analysis.RSI import RSI
|
||||
|
||||
class BS:
|
||||
class BuySellChecker:
|
||||
|
||||
common = None
|
||||
stochastic = None
|
||||
@@ -207,16 +207,16 @@ class BS:
|
||||
# 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]:
|
||||
buy = data["Low"][i]
|
||||
weight = 3
|
||||
weight = 4
|
||||
if data["rsi"][i] < 10:
|
||||
weight = 3
|
||||
weight = 4
|
||||
|
||||
if data["slow_k"][i] in (0, 1, 2, 3):
|
||||
weight = 2.5
|
||||
weight = 3
|
||||
if data["slow_k"][i] in (4, 5, 6, 7, 8):
|
||||
weight = 2
|
||||
weight = 2.5
|
||||
elif data["slow_k"][i] in (9, 10, 11, 12, 13):
|
||||
weight = 1.5
|
||||
weight = 2
|
||||
elif data["slow_k"][i] in (14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25):
|
||||
weight = 1
|
||||
|
||||
81
hts/HTS.py
81
hts/HTS.py
@@ -1,29 +1,14 @@
|
||||
import win32com.client
|
||||
import time
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
import pandas as pd
|
||||
from enum import Enum
|
||||
|
||||
from BS import BS
|
||||
from OrderType import OrderType
|
||||
from OrderItem import OrderItem
|
||||
|
||||
# enum 주문 상태 세팅용
|
||||
class EorderBS(Enum):
|
||||
buy = 1 # 매수
|
||||
sell= 2 # 매도
|
||||
none =3
|
||||
|
||||
class orderData:
|
||||
def __init__(self):
|
||||
self.dicEx = {EorderBS.buy: "매수", EorderBS.sell: "매도", EorderBS.none: "없음"}
|
||||
self.orderNum = 0
|
||||
self.bs = EorderBS.none # 0 : buy 1: sell
|
||||
self.code = ""
|
||||
self.amount = 0
|
||||
self.price = 0
|
||||
|
||||
def debugPrint(self):
|
||||
print(self.dicEx.get(self.bs), self.code, self.orderNum, self.amount, self.price)
|
||||
from BuySellChecker import BuySellChecker
|
||||
from OrderChecker import OrderChecker
|
||||
|
||||
|
||||
class HTS:
|
||||
@@ -31,10 +16,10 @@ class HTS:
|
||||
objCpCybos = None
|
||||
objCpCodeMgr = None
|
||||
|
||||
bs = None
|
||||
buySellChecker = None
|
||||
|
||||
def __init__(self):
|
||||
self.bs = BS()
|
||||
self.buySellChecker = BuySellChecker()
|
||||
#self.connect()
|
||||
return
|
||||
|
||||
@@ -189,13 +174,13 @@ class HTS:
|
||||
nRet = objStockOrder.BlockRequest()
|
||||
if (nRet != 0):
|
||||
print("order error", nRet)
|
||||
return
|
||||
return None
|
||||
|
||||
rqStatus = objStockOrder.GetDibStatus()
|
||||
rqRet = objStockOrder.GetDibMsg1()
|
||||
print("통신상태", rqStatus, rqRet)
|
||||
if rqStatus != 0:
|
||||
return
|
||||
return None
|
||||
|
||||
orderNum = objStockOrder.GetHeaderValue(0)
|
||||
|
||||
@@ -330,7 +315,7 @@ class HTS:
|
||||
break
|
||||
|
||||
for i in range(cnt):
|
||||
item = orderData()
|
||||
item = OrderItem()
|
||||
item.orderNum = objResult.GetDataValue(1, i)
|
||||
item.orderPrev = objResult.GetDataValue(2, i)
|
||||
item.code = objResult.GetDataValue(3, i) # 종목코드
|
||||
@@ -356,9 +341,7 @@ class HTS:
|
||||
return orderList
|
||||
|
||||
# 미체결 취소하기
|
||||
def cancelOrderList(self):
|
||||
#주문 리스트를 가져온다.
|
||||
orderList = self.requestOrderList()
|
||||
def cancelOrderList(self, orderList):
|
||||
|
||||
if len(orderList) < 1:
|
||||
return
|
||||
@@ -534,7 +517,7 @@ class HTS:
|
||||
if i < 5:
|
||||
return -1, -1, -1
|
||||
|
||||
buy, weight, sell = self.bs.getPriceAndWeight1(data, i)
|
||||
buy, weight, sell = self.buySellChecker.getPriceAndWeight1(data, i)
|
||||
return buy, weight, sell
|
||||
|
||||
def getSellingPrice(self, final_price):
|
||||
@@ -563,6 +546,9 @@ class HTS:
|
||||
return 0, 0
|
||||
|
||||
def buyRealTime(self, stock_code, given_day):
|
||||
orderChecker = OrderChecker()
|
||||
BASE_COUNT = 100
|
||||
|
||||
timecheckList = pd.read_csv("timecheck.csv").values.tolist()
|
||||
timecheck = {given_day + " " + str(second).zfill(6):False for second, check in timecheckList}
|
||||
|
||||
@@ -587,19 +573,25 @@ class HTS:
|
||||
self.getRealTime(stock_code, given_day, result)
|
||||
|
||||
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.bs.analyze(result)
|
||||
data = self.buySellChecker.analyze(result)
|
||||
# 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다.
|
||||
bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data)
|
||||
data_size = len(data["Close"])
|
||||
final_price = data["Close"][data_size-1]
|
||||
|
||||
if bs_buy_price > 0:
|
||||
BUY_COUNT = int(200 * bs_weight)
|
||||
# 기본 100 주에 가중치를 추가해서 매수한다.
|
||||
BUY_COUNT = int(BASE_COUNT * bs_weight)
|
||||
|
||||
# 매수 전에 모든 미체결을 취소한다.
|
||||
# self.cancelOrderList()
|
||||
# 현재까지 매입금액이 7백만원 이하일 때만 매수를 한다.
|
||||
self.requestOrder("2", stock_code, bs_weight * BUY_COUNT , bs_buy_price)
|
||||
# 매수를 주문한다.
|
||||
orderNum = self.requestOrder(OrderType.buy, stock_code, BUY_COUNT , bs_buy_price)
|
||||
# 미체결 기록을 가져온다.
|
||||
orderList = self.requestOrderList()
|
||||
# 매수 주문을 기록한다.
|
||||
orderListToCancel = orderChecker.add("2", orderNum, BUY_COUNT, bs_buy_price, orderList)
|
||||
# 두 시간 이전 미체결을 취소한다.
|
||||
self.cancelOrderList(orderListToCancel)
|
||||
# 로그 출력
|
||||
print("BUY", second, BUY_COUNT, bs_buy_price)
|
||||
|
||||
if bs_sell_price > 0:
|
||||
@@ -607,20 +599,31 @@ class HTS:
|
||||
selling_count, selling_price = self.getSellingPrice(final_price)
|
||||
# 분석되 가격으로 매도 요청한다.
|
||||
if selling_count != 0 and selling_price != 0:
|
||||
self.requestOrder("1", stock_code, selling_count, selling_price)
|
||||
orderNum = self.requestOrder(OrderType.sell, stock_code, selling_count, selling_price)
|
||||
# 미체결 기록을 가져온다.
|
||||
orderList = self.requestOrderList()
|
||||
# 매도 주문을 기록한다.
|
||||
orderListToCancel = orderChecker.add(OrderType.sell, orderNum, selling_count, selling_price, orderList)
|
||||
# 두 시간 이전 미체결을 취소한다.
|
||||
self.cancelOrderList(orderListToCancel)
|
||||
# 로그 출력
|
||||
print("SELL", second, selling_count, selling_price)
|
||||
|
||||
# 로그 출력
|
||||
print("TIMECHECK", second, final_price, data["Low"][data_size-1], data["slow_k"][data_size-1], data["slow_d"][data_size-1])
|
||||
timecheck[second] = True
|
||||
|
||||
if datetime.strptime(given_day + " 151000", '%Y%m%d %H%M%S') < datetime.now():
|
||||
# 15:10:00 이후라면 모든 미체결 취소
|
||||
self.cancelOrderList()
|
||||
# 주문 리스트를 가져온다.
|
||||
orderList = self.requestOrderList()
|
||||
# 15:10:00 이후라면 모든 미체결 취소한다.
|
||||
self.cancelOrderList(orderList)
|
||||
# 매도 가격을 가져온다.
|
||||
selling_count, selling_price = self.getSellingPrice(final_price)
|
||||
# 분석되 가격으로 매도 요청한다.
|
||||
if selling_count != 0 and selling_price !=0:
|
||||
self.requestOrder("1", stock_code, selling_count, selling_price)
|
||||
orderNum = self.requestOrder(OrderType.sell, stock_code, selling_count, selling_price)
|
||||
# 로그 출력
|
||||
print("SELL", second, selling_count, selling_price)
|
||||
|
||||
break
|
||||
|
||||
58
hts/OrderChecker.py
Normal file
58
hts/OrderChecker.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from OrderItem import OrderItem
|
||||
|
||||
class OrderChecker:
|
||||
|
||||
order_df = None # 매수/매도구분, orderNum, 금액, 시각
|
||||
saveFileName = None
|
||||
|
||||
def __init__(self):
|
||||
self.saveFileName = "./order/"+datetime.today().strftime("%Y%m%d")+".csv"
|
||||
self.read(self.saveFileName)
|
||||
return
|
||||
|
||||
def read(self, fileName):
|
||||
if os.path.isfile(fileName):
|
||||
self.order_df = pd.read_csv(fileName)
|
||||
else:
|
||||
self.order_df = None
|
||||
|
||||
def add(self, type, orderNum, count, price, orderList):
|
||||
orderListToCancel = []
|
||||
|
||||
if self.order_df is None:
|
||||
self.order_df = pd.DataFrame()
|
||||
else:
|
||||
# 두 시간 전
|
||||
before_two_hour = datetime.now() - timedelta(hours=2)
|
||||
|
||||
# 두 시간 전 주문을 찾는다.
|
||||
if len(orderList) > 0:
|
||||
# 만약 두시간 전 주문을 찾는다.
|
||||
orderNum_df = self.order_df.loc[self.order_df["datetime"] <= before_two_hour]
|
||||
orderNumSet = set(list(orderNum_df["orderNum"]))
|
||||
for item in orderList:
|
||||
if item.orderNum in orderNumSet:
|
||||
orderListToCancel.append(item)
|
||||
# 해당 orderNum 제외하기
|
||||
self.order_df = self.order_df.loc[self.order_df["orderNum"] != item.orderNum]
|
||||
|
||||
self.order_df = self.order_df.append({"type": type, "orderNum": orderNum, "count": count, "price": price, "datetime": datetime.now()}, ignore_index=True)
|
||||
self.order_df.to_csv(self.saveFileName)
|
||||
|
||||
return orderListToCancel
|
||||
|
||||
if __name__ == "__main__":
|
||||
orderChecker = OrderChecker()
|
||||
|
||||
a = pd.DataFrame(columns=["a", "b", "c", "d", "e"])
|
||||
a = a.append({"a": 0, "b": 1, "c": 3, "d": 7, "e": 8}, ignore_index=True)
|
||||
a = a.append({"a": 1, "b": 3, "c": 0, "d": 6, "e": 6}, ignore_index=True)
|
||||
a = a.append({"a": 2, "b": 3, "c": 0, "d": 3, "e": 9}, ignore_index=True)
|
||||
a = a.append({"a": 3, "b": 9, "c": 9, "d": 8, "e": 4}, ignore_index=True)
|
||||
|
||||
a = a.loc[a["c"] != 9]
|
||||
print(a.tail())
|
||||
25
hts/OrderItem.py
Normal file
25
hts/OrderItem.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from OrderType import OrderType
|
||||
|
||||
class OrderItem:
|
||||
|
||||
def __init__(self):
|
||||
self.dicEx = {OrderType.buy: "매수", OrderType.sell: "매도", OrderType.none: "없음"}
|
||||
|
||||
self.orderNum = None
|
||||
self.orderPrev = None
|
||||
self.code = None # 종목코드
|
||||
self.name = None # 종목명
|
||||
self.orderDesc = None # 주문구분내용
|
||||
self.amount = None # 주문수량
|
||||
self.price = None # 주문단가
|
||||
self.ContAmount = None # 체결수량
|
||||
self.credit = None # 신용구분
|
||||
self.modAvali = None # 정정취소 가능수량
|
||||
self.buysell = None # 매매구분코드
|
||||
self.creditdate = None # 대출일
|
||||
self.orderFlagDesc = None # 주문호가구분코드내용
|
||||
self.orderFlag = None # 주문호가구분코드
|
||||
|
||||
|
||||
def debugPrint(self):
|
||||
print(self.dicEx.get(self.buysell), self.code, self.orderNum, self.amount, self.price)
|
||||
8
hts/OrderType.py
Normal file
8
hts/OrderType.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from enum import Enum
|
||||
|
||||
# enum 주문 상태 세팅용
|
||||
class OrderType(Enum):
|
||||
|
||||
none = "0" # None
|
||||
sell = "1" # 매도
|
||||
buy = "2" # 매수
|
||||
@@ -1,16 +1,16 @@
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
import pandas as pd
|
||||
import plotly.graph_objects as go
|
||||
from plotly import subplots
|
||||
|
||||
from BS import BS
|
||||
from BuySellChecker import BuySellChecker
|
||||
|
||||
class Simulation:
|
||||
|
||||
bs = None
|
||||
buySellChecker = None
|
||||
def __init__(self):
|
||||
self.bs = BS()
|
||||
self.buySellChecker = BuySellChecker()
|
||||
#self.connect()
|
||||
return
|
||||
|
||||
@@ -50,7 +50,7 @@ class Simulation:
|
||||
bsLine['sell'] = [-1 for i in range(size)]
|
||||
|
||||
for i in range(6, size-5):
|
||||
buy, weight, sell = self.bs.getPriceAndWeight1(data, i)
|
||||
buy, weight, sell = self.buySellChecker.getPriceAndWeight1(data, i)
|
||||
bsLine['buy'][i] = buy
|
||||
bsLine['weight'][i] = weight
|
||||
bsLine['sell'][i] = sell
|
||||
@@ -97,6 +97,7 @@ class Simulation:
|
||||
avg5 = go.Scatter(x=data['Date'], y=data["avg5"], name="avg5", 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')
|
||||
volume_line = go.Scatter(x=data['Date'], y=data["Volume"], mode='lines', name='Volume')
|
||||
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')
|
||||
@@ -105,6 +106,7 @@ class Simulation:
|
||||
|
||||
#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, avg5, buy_check, sell_check]
|
||||
volume_data = [volume_line]
|
||||
stochastic_data = [slow_k_line, slow_d_line]
|
||||
rsi_data = [rsi_line, rsis_line]
|
||||
|
||||
@@ -115,13 +117,15 @@ class Simulation:
|
||||
fig.show()
|
||||
"""
|
||||
|
||||
fig = subplots.make_subplots(rows=3, cols=1, subplot_titles=('캔들', "스토캐스틱", "RSI"))
|
||||
fig = subplots.make_subplots(rows=4, cols=1, subplot_titles=('캔들', "거래량", "스토캐스틱", "RSI"))
|
||||
for trace in candle_data:
|
||||
fig.append_trace(trace, 1, 1)
|
||||
for trace in stochastic_data:
|
||||
for trace in volume_data:
|
||||
fig.append_trace(trace, 2, 1)
|
||||
for trace in rsi_data:
|
||||
for trace in stochastic_data:
|
||||
fig.append_trace(trace, 3, 1)
|
||||
for trace in rsi_data:
|
||||
fig.append_trace(trace, 4, 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)
|
||||
@@ -142,7 +146,7 @@ class Simulation:
|
||||
self.getCSV("./data/"+stock_code+"_"+given_day+".csv", given_day, result)
|
||||
|
||||
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
|
||||
data = self.bs.analyze(result)
|
||||
data = self.buySellChecker.analyze(result)
|
||||
|
||||
# 사야 할 시점과 팔아야 할 시점을 체크한다.
|
||||
bsLine = self.checkTransaction(data)
|
||||
|
||||
Reference in New Issue
Block a user