init
This commit is contained in:
@@ -199,9 +199,15 @@ class BuySellChecker:
|
|||||||
################
|
################
|
||||||
### buy 분석 ###
|
### buy 분석 ###
|
||||||
################
|
################
|
||||||
# 1. slow_k가 20 아래 있으면 매수한다.
|
# 1. slow_k가 10 아래 있으면 매수한다.
|
||||||
if i < 30:
|
if i < 30:
|
||||||
if data["slow_k"][i] <= 19:
|
if data["slow_k"][i] <= 10:
|
||||||
|
if data["Close"][i] < data["avg5"][i]:
|
||||||
|
buy = data["Close"][i]
|
||||||
|
else:
|
||||||
|
buy = data["Low"][i]
|
||||||
|
elif 30 <= i < 60:
|
||||||
|
if data["slow_k"][i] <= 15:
|
||||||
if data["Close"][i] < data["avg5"][i]:
|
if data["Close"][i] < data["avg5"][i]:
|
||||||
buy = data["Close"][i]
|
buy = data["Close"][i]
|
||||||
else:
|
else:
|
||||||
@@ -212,6 +218,7 @@ class BuySellChecker:
|
|||||||
buy = data["Close"][i]
|
buy = data["Close"][i]
|
||||||
else:
|
else:
|
||||||
buy = data["Low"][i]
|
buy = data["Low"][i]
|
||||||
|
|
||||||
if data["rsi"][i-1] < 10 and data["rsi"][i-1] < data["rsis"][i-1] and data["rsis"][i] < data["rsi"][i]:
|
if data["rsi"][i-1] < 10 and data["rsi"][i-1] < data["rsis"][i-1] and data["rsis"][i] < data["rsi"][i]:
|
||||||
if data["Close"][i] < data["avg5"][i]:
|
if data["Close"][i] < data["avg5"][i]:
|
||||||
buy = data["Close"][i]
|
buy = data["Close"][i]
|
||||||
@@ -229,12 +236,12 @@ class BuySellChecker:
|
|||||||
weight = 4
|
weight = 4
|
||||||
|
|
||||||
if data["slow_k"][i] in (0, 1, 2, 3):
|
if data["slow_k"][i] in (0, 1, 2, 3):
|
||||||
|
weight = 4
|
||||||
|
if data["slow_k"][i] in (4, 5, 6, 7):
|
||||||
weight = 3
|
weight = 3
|
||||||
if data["slow_k"][i] in (4, 5, 6, 7, 8):
|
elif data["slow_k"][i] in (8, 9, 10, 11, 12, 13):
|
||||||
weight = 2.5
|
|
||||||
elif data["slow_k"][i] in (9, 10, 11, 12, 13):
|
|
||||||
weight = 2
|
weight = 2
|
||||||
elif data["slow_k"][i] in (14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25):
|
elif data["slow_k"][i] in (14, 15, 16, 17, 18, 19, 20):
|
||||||
weight = 1
|
weight = 1
|
||||||
|
|
||||||
return buy, weight, sell
|
return buy, weight, sell
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from BuySellChecker import BuySellChecker
|
|||||||
from OrderChecker import OrderChecker
|
from OrderChecker import OrderChecker
|
||||||
|
|
||||||
|
|
||||||
class HTS:
|
class HTS_122630:
|
||||||
|
|
||||||
objCpCybos = None
|
objCpCybos = None
|
||||||
objCpCodeMgr = None
|
objCpCodeMgr = None
|
||||||
@@ -546,9 +546,8 @@ class HTS:
|
|||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
||||||
def buyRealTime(self, stock_code, GIVEN_DAY):
|
def buyRealTime(self, stock_code, GIVEN_DAY):
|
||||||
orderChecker = OrderChecker()
|
orderChecker = OrderChecker(stock_code)
|
||||||
BASE_COUNT = 100
|
BASE_COUNT = 100
|
||||||
ORDER_LIST = None
|
|
||||||
|
|
||||||
timecheckList = pd.read_csv("timecheck.csv").values.tolist()
|
timecheckList = pd.read_csv("timecheck.csv").values.tolist()
|
||||||
timecheck = {GIVEN_DAY + " " + str(second).zfill(6):False for second, check in timecheckList}
|
timecheck = {GIVEN_DAY + " " + str(second).zfill(6):False for second, check in timecheckList}
|
||||||
@@ -566,7 +565,7 @@ class HTS:
|
|||||||
THIS_TIME = datetime.now()
|
THIS_TIME = datetime.now()
|
||||||
while datetime.strptime(GIVEN_DAY + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 15200", '%Y%m%d %H%M%S'):
|
while datetime.strptime(GIVEN_DAY + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 15200", '%Y%m%d %H%M%S'):
|
||||||
|
|
||||||
if datetime.strptime(GIVEN_DAY + " 090100", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 151000", '%Y%m%d %H%M%S'):
|
if datetime.strptime(GIVEN_DAY + " 090100", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 151500", '%Y%m%d %H%M%S'):
|
||||||
if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]:
|
if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]:
|
||||||
|
|
||||||
# 데이터를 가지고 온다.
|
# 데이터를 가지고 온다.
|
||||||
@@ -579,26 +578,27 @@ class HTS:
|
|||||||
data_size = len(data["Close"])
|
data_size = len(data["Close"])
|
||||||
final_price = data["Close"][data_size-1]
|
final_price = data["Close"][data_size-1]
|
||||||
|
|
||||||
if bs_buy_price > 0 or bs_sell_price > 0:
|
|
||||||
# 미체결 기록을 가져온다.
|
|
||||||
ORDER_LIST = self.requestOrderList()
|
|
||||||
|
|
||||||
if bs_buy_price > 0:
|
if bs_buy_price > 0:
|
||||||
# 기본 100 주에 가중치를 추가해서 매수한다.
|
# 기본 100 주에 가중치를 추가해서 매수한다.
|
||||||
BUY_COUNT = int(BASE_COUNT * bs_weight)
|
BUY_COUNT = int(BASE_COUNT * bs_weight)
|
||||||
|
|
||||||
# 매수를 요청한다.
|
# 매수를 주문한다.
|
||||||
orderNum = self.requestOrder(OrderType.buy, stock_code, BUY_COUNT , bs_buy_price)
|
orderNum = self.requestOrder(OrderType.buy, stock_code, BUY_COUNT , bs_buy_price)
|
||||||
|
|
||||||
|
# 미체결 기록을 가져온다.
|
||||||
|
ORDER_LIST = self.requestOrderList()
|
||||||
# 매수 주문을 기록한다.
|
# 매수 주문을 기록한다.
|
||||||
orderListToCancel = orderChecker.add(OrderType.buy, orderNum, BUY_COUNT, bs_buy_price, ORDER_LIST)
|
orderListToCancel = orderChecker.add(stock_code, OrderType.buy, orderNum, BUY_COUNT, bs_buy_price, ORDER_LIST)
|
||||||
# 두 시간 이전 미체결을 모두 취소한다.
|
# 두 시간 이전 미체결을 모두 취소한다.
|
||||||
self.cancelOrderList(orderListToCancel)
|
self.cancelOrderList(orderListToCancel)
|
||||||
# 로그 출력
|
# 로그 출력
|
||||||
print("BUY", THIS_TIME, BUY_COUNT, bs_buy_price)
|
print("BUY", THIS_TIME, BUY_COUNT, bs_buy_price)
|
||||||
|
|
||||||
if bs_sell_price > 0:
|
if bs_sell_price > 0:
|
||||||
|
# 미체결 기록을 가져온다.
|
||||||
|
ORDER_LIST = self.requestOrderList()
|
||||||
# 매도 주문을 기록을 가져온다.
|
# 매도 주문을 기록을 가져온다.
|
||||||
orderListToCancel = orderChecker.remove(OrderType.sell, ORDER_LIST)
|
orderListToCancel = orderChecker.remove(stock_code, OrderType.sell, ORDER_LIST)
|
||||||
# 매도 미체결을 모두 취소한다.
|
# 매도 미체결을 모두 취소한다.
|
||||||
self.cancelOrderList(orderListToCancel)
|
self.cancelOrderList(orderListToCancel)
|
||||||
|
|
||||||
@@ -608,10 +608,7 @@ class HTS:
|
|||||||
if selling_count != 0 and selling_price != 0:
|
if selling_count != 0 and selling_price != 0:
|
||||||
# 매도를 요청한다.
|
# 매도를 요청한다.
|
||||||
orderNum = self.requestOrder(OrderType.sell, stock_code, selling_count, selling_price)
|
orderNum = self.requestOrder(OrderType.sell, stock_code, selling_count, selling_price)
|
||||||
# 매도 주문을 기록한다.
|
|
||||||
orderListToCancel = orderChecker.add(OrderType.sell, orderNum, selling_count, selling_price, ORDER_LIST)
|
|
||||||
# 두 시간 이전 미체결을 취소한다.
|
|
||||||
self.cancelOrderList(orderListToCancel)
|
|
||||||
# 로그 출력
|
# 로그 출력
|
||||||
print("SELL", THIS_TIME, selling_count, selling_price)
|
print("SELL", THIS_TIME, selling_count, selling_price)
|
||||||
|
|
||||||
@@ -619,7 +616,7 @@ class HTS:
|
|||||||
print("TIMECHECK", THIS_TIME, final_price, data["Low"][data_size-1], data["slow_k"][data_size-1], data["slow_d"][data_size-1])
|
print("TIMECHECK", THIS_TIME, final_price, data["Low"][data_size-1], data["slow_k"][data_size-1], data["slow_d"][data_size-1])
|
||||||
timecheck[THIS_TIME] = True
|
timecheck[THIS_TIME] = True
|
||||||
|
|
||||||
if datetime.strptime(GIVEN_DAY + " 151000", '%Y%m%d %H%M%S') < THIS_TIME:
|
if datetime.strptime(GIVEN_DAY + " 151500", '%Y%m%d %H%M%S') < THIS_TIME:
|
||||||
# 주문 리스트를 가져온다.
|
# 주문 리스트를 가져온다.
|
||||||
orderList = self.requestOrderList()
|
orderList = self.requestOrderList()
|
||||||
# 15:10:00 이후라면 모든 미체결 취소한다.
|
# 15:10:00 이후라면 모든 미체결 취소한다.
|
||||||
@@ -645,9 +642,11 @@ 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")
|
||||||
|
|
||||||
hts = HTS()
|
# KODEX 레버리지
|
||||||
stock_codes = ["252670", "122630"]
|
hts = HTS_122630()
|
||||||
|
stock_codes = ["122630"]
|
||||||
given_day = datetime.today().strftime('%Y%m%d')
|
given_day = datetime.today().strftime('%Y%m%d')
|
||||||
|
|
||||||
#hts.writeStockData(stock_codes, "20211015")
|
#hts.writeStockData(stock_codes, "20211015")
|
||||||
hts.buyRealTime(stock_codes[0], given_day)
|
hts.buyRealTime(stock_codes[0], given_day)
|
||||||
|
|
||||||
653
hts/HTS_252670.py
Normal file
653
hts/HTS_252670.py
Normal file
@@ -0,0 +1,653 @@
|
|||||||
|
import win32com.client
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
from OrderType import OrderType
|
||||||
|
from OrderItem import OrderItem
|
||||||
|
|
||||||
|
from BuySellChecker import BuySellChecker
|
||||||
|
from OrderChecker import OrderChecker
|
||||||
|
|
||||||
|
|
||||||
|
class HTS_252670:
|
||||||
|
|
||||||
|
objCpCybos = None
|
||||||
|
objCpCodeMgr = None
|
||||||
|
|
||||||
|
buySellChecker = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.buySellChecker = BuySellChecker()
|
||||||
|
#self.connect()
|
||||||
|
return
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
# 연결 여부 체크
|
||||||
|
self.objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
|
||||||
|
bConnect = self.objCpCybos.IsConnect
|
||||||
|
if (bConnect == 0):
|
||||||
|
print("PLUS가 정상적으로 연결되지 않음. ")
|
||||||
|
exit()
|
||||||
|
return
|
||||||
|
|
||||||
|
def all_stocks(self):
|
||||||
|
# 종목코드 리스트 구하기
|
||||||
|
self.objCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")
|
||||||
|
codeList = self.objCpCodeMgr.GetStockListByMarket(1) # 거래소
|
||||||
|
codeList2 = self.objCpCodeMgr.GetStockListByMarket(2) # 코스닥
|
||||||
|
|
||||||
|
print("거래소 종목코드", len(codeList))
|
||||||
|
for i, code in enumerate(codeList):
|
||||||
|
secondCode = self.objCpCodeMgr.GetStockSectionKind(code)
|
||||||
|
name = self.objCpCodeMgr.CodeToName(code)
|
||||||
|
stdPrice = self.objCpCodeMgr.GetStockStdPrice(code)
|
||||||
|
print(i, code, secondCode, stdPrice, name)
|
||||||
|
|
||||||
|
print("코스닥 종목코드", len(codeList2))
|
||||||
|
for i, code in enumerate(codeList2):
|
||||||
|
secondCode = self.objCpCodeMgr.GetStockSectionKind(code)
|
||||||
|
name = self.objCpCodeMgr.CodeToName(code)
|
||||||
|
stdPrice = self.objCpCodeMgr.GetStockStdPrice(code)
|
||||||
|
print(i, code, secondCode, stdPrice, name)
|
||||||
|
|
||||||
|
print("거래소 + 코스닥 종목코드 ", len(codeList) + len(codeList2))
|
||||||
|
return
|
||||||
|
|
||||||
|
# 차트 데이터 구하기
|
||||||
|
def getChartData(self, stock_code):
|
||||||
|
# 차트 객체 구하기
|
||||||
|
objStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
|
||||||
|
|
||||||
|
objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자
|
||||||
|
objStockChart.SetInputValue(1, ord('2')) # 개수로 조회
|
||||||
|
objStockChart.SetInputValue(4, 100) # 최근 100일 치
|
||||||
|
objStockChart.SetInputValue(5, [0, 2, 3, 4, 5, 8]) # 날짜,시가,고가,저가,종가,거래량
|
||||||
|
objStockChart.SetInputValue(6, ord('D')) # '차트 주가 - 일간 차트 요청
|
||||||
|
objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용
|
||||||
|
objStockChart.BlockRequest()
|
||||||
|
|
||||||
|
len = objStockChart.GetHeaderValue(3)
|
||||||
|
|
||||||
|
print("날짜", "시가", "고가", "저가", "종가", "거래량")
|
||||||
|
print("==============================================-")
|
||||||
|
|
||||||
|
for i in range(len):
|
||||||
|
day = objStockChart.GetDataValue(0, i)
|
||||||
|
open = objStockChart.GetDataValue(1, i)
|
||||||
|
high = objStockChart.GetDataValue(2, i)
|
||||||
|
low = objStockChart.GetDataValue(3, i)
|
||||||
|
close = objStockChart.GetDataValue(4, i)
|
||||||
|
vol = objStockChart.GetDataValue(5, i)
|
||||||
|
print(day, open, high, low, close, vol)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
# 주식 현재가 조회
|
||||||
|
def currentStock(self, stock_code):
|
||||||
|
# 현재가 객체 구하기
|
||||||
|
self.objStockMst = win32com.client.Dispatch("DsCbo1.StockMst")
|
||||||
|
self.objStockMst.SetInputValue(0, 'A'+stock_code) # 종목 코드 - 삼성전자
|
||||||
|
self.objStockMst.BlockRequest()
|
||||||
|
|
||||||
|
# 현재가 통신 및 통신 에러 처리
|
||||||
|
rqStatus = self.objStockMst.GetDibStatus()
|
||||||
|
rqRet = self.objStockMst.GetDibMsg1()
|
||||||
|
print("통신상태", rqStatus, rqRet)
|
||||||
|
if rqStatus != 0:
|
||||||
|
exit()
|
||||||
|
|
||||||
|
# 현재가 정보 조회
|
||||||
|
code = self.objStockMst.GetHeaderValue(0) # 종목코드
|
||||||
|
name = self.objStockMst.GetHeaderValue(1) # 종목명
|
||||||
|
time = self.objStockMst.GetHeaderValue(4) # 시간
|
||||||
|
cprice = self.objStockMst.GetHeaderValue(11) # 종가
|
||||||
|
diff = self.objStockMst.GetHeaderValue(12) # 대비
|
||||||
|
open = self.objStockMst.GetHeaderValue(13) # 시가
|
||||||
|
high = self.objStockMst.GetHeaderValue(14) # 고가
|
||||||
|
low = self.objStockMst.GetHeaderValue(15) # 저가
|
||||||
|
offer = self.objStockMst.GetHeaderValue(16) # 매도호가
|
||||||
|
bid = self.objStockMst.GetHeaderValue(17) # 매수호가
|
||||||
|
vol = self.objStockMst.GetHeaderValue(18) # 거래량
|
||||||
|
vol_value = self.objStockMst.GetHeaderValue(19) # 거래대금
|
||||||
|
|
||||||
|
# 예상 체결관련 정보
|
||||||
|
exFlag = self.objStockMst.GetHeaderValue(58) # 예상체결가 구분 플래그
|
||||||
|
exPrice = self.objStockMst.GetHeaderValue(55) # 예상체결가
|
||||||
|
exDiff = self.objStockMst.GetHeaderValue(56) # 예상체결가 전일대비
|
||||||
|
exVol = self.objStockMst.GetHeaderValue(57) # 예상체결수량
|
||||||
|
|
||||||
|
print("코드", code)
|
||||||
|
print("이름", name)
|
||||||
|
print("시간", time)
|
||||||
|
print("종가", cprice)
|
||||||
|
print("대비", diff)
|
||||||
|
print("시가", open)
|
||||||
|
print("고가", high)
|
||||||
|
print("저가", low)
|
||||||
|
print("매도호가", offer)
|
||||||
|
print("매수호가", bid)
|
||||||
|
print("거래량", vol)
|
||||||
|
print("거래대금", vol_value)
|
||||||
|
|
||||||
|
if (exFlag == ord('0')):
|
||||||
|
print("장 구분값: 동시호가와 장중 이외의 시간")
|
||||||
|
elif (exFlag == ord('1')):
|
||||||
|
print("장 구분값: 동시호가 시간")
|
||||||
|
elif (exFlag == ord('2')):
|
||||||
|
print("장 구분값: 장중 또는 장종료")
|
||||||
|
|
||||||
|
print("예상체결가 대비 수량")
|
||||||
|
print("예상체결가", exPrice)
|
||||||
|
print("예상체결가 대비", exDiff)
|
||||||
|
print("예상체결수량", exVol)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
# 주식 현금 매수주문
|
||||||
|
def requestOrder(self, type, stock_code, count, price):
|
||||||
|
# type = 2: buy, type=1: sell
|
||||||
|
# 주문 초기화
|
||||||
|
objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil")
|
||||||
|
initCheck = objTrade.TradeInit(0)
|
||||||
|
if (initCheck != 0):
|
||||||
|
print("주문 초기화 실패")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
# 주식 매수 주문
|
||||||
|
acc = objTrade.AccountNumber[0] # 계좌번호
|
||||||
|
accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분
|
||||||
|
# acc = "782446178"
|
||||||
|
# accFlag[0] = "01"
|
||||||
|
objStockOrder = win32com.client.Dispatch("CpTrade.CpTd0311")
|
||||||
|
objStockOrder.SetInputValue(0, type.value) # 1: 매도, 2: 매수
|
||||||
|
objStockOrder.SetInputValue(1, acc) # 계좌번호
|
||||||
|
objStockOrder.SetInputValue(2, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째
|
||||||
|
objStockOrder.SetInputValue(3, "A"+stock_code) # 종목코드
|
||||||
|
objStockOrder.SetInputValue(4, count) # 매수수량 count주
|
||||||
|
objStockOrder.SetInputValue(5, price) # 주문단가 - price 원
|
||||||
|
objStockOrder.SetInputValue(7, "0") # 주문 조건 구분 코드, 0: 기본 1: IOC 2:FOK
|
||||||
|
objStockOrder.SetInputValue(8, "01") # 주문호가 구분코드 - 01: 보통
|
||||||
|
|
||||||
|
# 매수 주문 요청
|
||||||
|
nRet = objStockOrder.BlockRequest()
|
||||||
|
if (nRet != 0):
|
||||||
|
print("order error", nRet)
|
||||||
|
return None
|
||||||
|
|
||||||
|
rqStatus = objStockOrder.GetDibStatus()
|
||||||
|
rqRet = objStockOrder.GetDibMsg1()
|
||||||
|
print("통신상태", rqStatus, rqRet)
|
||||||
|
if rqStatus != 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
orderNum = objStockOrder.GetHeaderValue(0)
|
||||||
|
|
||||||
|
if (type == "1"):
|
||||||
|
print ("(SELL", count, price, ")")
|
||||||
|
else:
|
||||||
|
print ("(BUY", count, price, ")")
|
||||||
|
return orderNum
|
||||||
|
|
||||||
|
# 계좌 잔고 확인
|
||||||
|
def requstJango(self):
|
||||||
|
jangoDic = {}
|
||||||
|
|
||||||
|
objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil")
|
||||||
|
initCheck = objTrade.TradeInit(0)
|
||||||
|
if (initCheck != 0):
|
||||||
|
print("주문 초기화 실패")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
# 주식 매수 주문
|
||||||
|
acc = objTrade.AccountNumber[0] # 계좌번호
|
||||||
|
accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분
|
||||||
|
|
||||||
|
objRq = win32com.client.Dispatch("CpTrade.CpTd6033")
|
||||||
|
|
||||||
|
objRq.SetInputValue(0, acc) # 계좌번호
|
||||||
|
objRq.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째
|
||||||
|
objRq.SetInputValue(2, 50) # 요청 건수(최대 50)
|
||||||
|
dicflag1 = {ord(' '): '현금',
|
||||||
|
ord('Y'): '융자',
|
||||||
|
ord('D'): '대주',
|
||||||
|
ord('B'): '담보',
|
||||||
|
ord('M'): '매입담보',
|
||||||
|
ord('P'): '플러스론',
|
||||||
|
ord('I'): '자기융자',
|
||||||
|
}
|
||||||
|
while True:
|
||||||
|
objRq.BlockRequest()
|
||||||
|
# 통신 및 통신 에러 처리
|
||||||
|
rqStatus = objRq.GetDibStatus()
|
||||||
|
rqRet = objRq.GetDibMsg1()
|
||||||
|
#print("통신상태", rqStatus, rqRet)
|
||||||
|
if rqStatus != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
cnt = objRq.GetHeaderValue(7)
|
||||||
|
if cnt > 3:
|
||||||
|
return jangoDic
|
||||||
|
|
||||||
|
for i in range(cnt):
|
||||||
|
item = {}
|
||||||
|
code = objRq.GetDataValue(12, i) # 종목코드
|
||||||
|
item['종목코드'] = code
|
||||||
|
item['종목명'] = objRq.GetDataValue(0, i) # 종목명
|
||||||
|
item['대출일'] = objRq.GetDataValue(2, i) # 대출일
|
||||||
|
item['잔고수량'] = objRq.GetDataValue(7, i) # 체결잔고수량
|
||||||
|
item['매도가능'] = objRq.GetDataValue(15, i)
|
||||||
|
item['장부가'] = objRq.GetDataValue(17, i) # 체결장부단가
|
||||||
|
# item['평가금액'] = self.objRq.GetDataValue(9, i) # 평가금액(천원미만은 절사 됨)
|
||||||
|
# item['평가손익'] = self.objRq.GetDataValue(11, i) # 평가손익(천원미만은 절사 됨)
|
||||||
|
# 매입금액 = 장부가 * 잔고수량
|
||||||
|
item['매입금액'] = item['장부가'] * item['잔고수량']
|
||||||
|
item['현재가'] = 0
|
||||||
|
item['대비'] = 0
|
||||||
|
item['거래량'] = 0
|
||||||
|
|
||||||
|
# 잔고 추가
|
||||||
|
# key = (code, item['현금신용'],item['대출일'] )
|
||||||
|
key = code
|
||||||
|
jangoDic[key] = item
|
||||||
|
|
||||||
|
if len(jangoDic) >= 3: # 최대 3 종목만,
|
||||||
|
break
|
||||||
|
|
||||||
|
if len(jangoDic) >= 3:
|
||||||
|
break
|
||||||
|
|
||||||
|
if (objRq.Continue == False):
|
||||||
|
break
|
||||||
|
|
||||||
|
check = False
|
||||||
|
for item in jangoDic:
|
||||||
|
if item:
|
||||||
|
check = True
|
||||||
|
break
|
||||||
|
if not check:
|
||||||
|
return None
|
||||||
|
return jangoDic
|
||||||
|
|
||||||
|
# 예약 주문 내역 조회 및 미체결 리스트 구하기
|
||||||
|
def requestOrderList(self):
|
||||||
|
# type = 2: buy, type=1: sell
|
||||||
|
orderList = []
|
||||||
|
# 주문 초기화
|
||||||
|
objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil")
|
||||||
|
initCheck = objTrade.TradeInit(0)
|
||||||
|
if (initCheck != 0):
|
||||||
|
print("주문 초기화 실패")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
# 주식 매수 주문
|
||||||
|
acc = objTrade.AccountNumber[0] # 계좌번호
|
||||||
|
accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분
|
||||||
|
|
||||||
|
objResult = win32com.client.Dispatch("CpTrade.CpTd5339")
|
||||||
|
objResult.SetInputValue(0, acc) # 계좌번호
|
||||||
|
objResult.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째
|
||||||
|
objResult.SetInputValue(4, "0") # 전체
|
||||||
|
objResult.SetInputValue(5, "1") # 정렬 기준 - 역순
|
||||||
|
objResult.SetInputValue(6, "0") # 전체
|
||||||
|
objResult.SetInputValue(7, 20) # 요청개수 - 최대 20개
|
||||||
|
|
||||||
|
while True:
|
||||||
|
ret = objResult.BlockRequest()
|
||||||
|
if objResult.GetDibStatus() != 0:
|
||||||
|
print("통신상태", objResult.GetDibStatus(), objResult.GetDibMsg1())
|
||||||
|
return False
|
||||||
|
|
||||||
|
if (ret == 2 or ret == 3):
|
||||||
|
print("통신 오류", ret)
|
||||||
|
return False;
|
||||||
|
|
||||||
|
# 통신 초과 요청 방지에 의한 요류 인 경우
|
||||||
|
while (ret == 4): # 연속 주문 오류 임. 이 경우는 남은 시간동안 반드시 대기해야 함.
|
||||||
|
time.sleep(1)
|
||||||
|
ret = objResult.BlockRequest()
|
||||||
|
|
||||||
|
# 수신 개수
|
||||||
|
cnt = objResult.GetHeaderValue(5)
|
||||||
|
print("[Cp5339] 수신 개수 ", cnt)
|
||||||
|
if cnt == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
for i in range(cnt):
|
||||||
|
item = OrderItem()
|
||||||
|
item.orderNum = objResult.GetDataValue(1, i)
|
||||||
|
item.orderPrev = objResult.GetDataValue(2, i)
|
||||||
|
item.code = objResult.GetDataValue(3, i) # 종목코드
|
||||||
|
item.name = objResult.GetDataValue(4, i) # 종목명
|
||||||
|
item.orderDesc = objResult.GetDataValue(5, i) # 주문구분내용
|
||||||
|
item.amount = objResult.GetDataValue(6, i) # 주문수량
|
||||||
|
item.price = objResult.GetDataValue(7, i) # 주문단가
|
||||||
|
item.ContAmount = objResult.GetDataValue(8, i) # 체결수량
|
||||||
|
item.credit = objResult.GetDataValue(9, i) # 신용구분
|
||||||
|
item.modAvali = objResult.GetDataValue(11, i) # 정정취소 가능수량
|
||||||
|
item.buysell = objResult.GetDataValue(13, i) # 매매구분코드
|
||||||
|
item.creditdate = objResult.GetDataValue(17, i) # 대출일
|
||||||
|
item.orderFlagDesc = objResult.GetDataValue(19, i) # 주문호가구분코드내용
|
||||||
|
item.orderFlag = objResult.GetDataValue(21, i) # 주문호가구분코드
|
||||||
|
|
||||||
|
orderList.append(item)
|
||||||
|
|
||||||
|
# 연속 처리 체크 - 다음 데이터가 없으면 중지
|
||||||
|
if objResult.Continue == False:
|
||||||
|
print("[Cp5339] 연속 조회 여부: 다음 데이터가 없음")
|
||||||
|
break
|
||||||
|
|
||||||
|
return orderList
|
||||||
|
|
||||||
|
# 미체결 취소하기
|
||||||
|
def cancelOrderList(self, orderList):
|
||||||
|
|
||||||
|
if len(orderList) < 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil")
|
||||||
|
initCheck = objTrade.TradeInit(0)
|
||||||
|
if (initCheck != 0):
|
||||||
|
print("주문 초기화 실패")
|
||||||
|
exit()
|
||||||
|
acc = objTrade.AccountNumber[0] # 계좌번호
|
||||||
|
accFlag = objTrade.GoodsList(acc, 1) # 주식상품 구분
|
||||||
|
|
||||||
|
objCancelOrder = win32com.client.Dispatch("CpTrade.CpTd0314") # 취소
|
||||||
|
|
||||||
|
onums = []
|
||||||
|
codes = []
|
||||||
|
amounts = []
|
||||||
|
for item in orderList:
|
||||||
|
onums.append(item.orderNum)
|
||||||
|
codes.append(item.code)
|
||||||
|
amounts.append(item.amount)
|
||||||
|
|
||||||
|
for i in range(len(onums)):
|
||||||
|
ordernum = onums[i]
|
||||||
|
code = codes[i]
|
||||||
|
amount = amounts[i]
|
||||||
|
objCancelOrder.SetInputValue(1, ordernum) # 원주문 번호 - 정정을 하려는 주문 번호
|
||||||
|
objCancelOrder.SetInputValue(2, acc) # 상품구분 - 주식 상품 중 첫번째
|
||||||
|
objCancelOrder.SetInputValue(3, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째
|
||||||
|
objCancelOrder.SetInputValue(4, code) # 종목코드
|
||||||
|
objCancelOrder.SetInputValue(5, amount) # 정정 수량, 0 이면 잔량 취소임
|
||||||
|
|
||||||
|
# 취소주문 요청
|
||||||
|
ret = objCancelOrder.BlockRequest()
|
||||||
|
print("[CpRPOrder/BlockRequestCancel] 주문결과", objCancelOrder.GetDibStatus(), objCancelOrder.GetDibMsg1())
|
||||||
|
if objCancelOrder.GetDibStatus() != 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
# 주식 현재가 조회
|
||||||
|
def writeStockData(self, stock_codes, given_day):
|
||||||
|
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
|
||||||
|
bConnect = objCpCybos.IsConnect
|
||||||
|
if (bConnect == 0):
|
||||||
|
print("PLUS가 정상적으로 연결되지 않음. ")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
# 차트 객체 구하기
|
||||||
|
objStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
|
||||||
|
|
||||||
|
for stock_code in stock_codes:
|
||||||
|
outfp = open("./data/"+stock_code+"_"+given_day+".csv", mode="w", encoding="utf-8")
|
||||||
|
objStockChart.SetInputValue(0, 'A' + stock_code) # 종목 코드
|
||||||
|
objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회
|
||||||
|
objStockChart.SetInputValue(2, given_day) # 기간 조회 시, 시작일
|
||||||
|
objStockChart.SetInputValue(3, given_day) # 기간 조회 시, 종료일
|
||||||
|
objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수
|
||||||
|
objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량
|
||||||
|
objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청
|
||||||
|
objStockChart.SetInputValue(7, 1)
|
||||||
|
objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용
|
||||||
|
objStockChart.BlockRequest()
|
||||||
|
|
||||||
|
size = objStockChart.GetHeaderValue(3)
|
||||||
|
|
||||||
|
outfp.write("%s,%s,%s,%s,%s,%s,%s\n" % ("날짜", "시간", "시가", "고가", "저가", "종가", "거래량"))
|
||||||
|
for i in range(size - 1, -1, -1):
|
||||||
|
day = objStockChart.GetDataValue(0, i)
|
||||||
|
time = objStockChart.GetDataValue(1, i)
|
||||||
|
start = objStockChart.GetDataValue(2, i)
|
||||||
|
high = objStockChart.GetDataValue(3, i)
|
||||||
|
low = objStockChart.GetDataValue(4, i)
|
||||||
|
close = objStockChart.GetDataValue(5, i)
|
||||||
|
vol = objStockChart.GetDataValue(6, i)
|
||||||
|
outfp.write("%d,%s,%d,%d,%d,%d,%d\n" % (day, str(time).zfill(4), start, high, low, close, vol))
|
||||||
|
outfp.close()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def write(self, day, result):
|
||||||
|
#날짜,시간,시가,고가,저가,종가,거래량
|
||||||
|
#20210909,900,2070,2070,2070,2070,0
|
||||||
|
|
||||||
|
outFp = open(day+".csv", mode="w", encoding="UTF-8")
|
||||||
|
outFp.write("날짜,시간,시가,고가,저가,종가,거래량\n")
|
||||||
|
for i in range(len(result["time"])):
|
||||||
|
outFp.write("%s,%s,%s,%s,%s,%s,%s\n"%(
|
||||||
|
result["time"][i].strftime('%Y%m%d'),
|
||||||
|
result["time"][i].strftime('%H%M'),
|
||||||
|
result["open"][i],
|
||||||
|
result["high"][i],
|
||||||
|
result["low"][i],
|
||||||
|
result["close"][i],
|
||||||
|
result["vol"][i]))
|
||||||
|
outFp.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
# 주식 현재가 조회
|
||||||
|
def getRealTime(self, stock_code, given_day, result):
|
||||||
|
int_given_day = int(given_day)
|
||||||
|
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
|
||||||
|
bConnect = objCpCybos.IsConnect
|
||||||
|
if (bConnect == 0):
|
||||||
|
print("PLUS가 정상적으로 연결되지 않음. ")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
# 차트 객체 구하기
|
||||||
|
objStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
|
||||||
|
|
||||||
|
objStockChart.SetInputValue(0, 'A'+stock_code) # 종목 코드
|
||||||
|
objStockChart.SetInputValue(1, ord('1')) # 1: 기간으로 조회, 2: 개수로 조회
|
||||||
|
objStockChart.SetInputValue(2, given_day) # 기간 조회 시, 시작일
|
||||||
|
objStockChart.SetInputValue(3, given_day) # 기간 조회 시, 종료일
|
||||||
|
objStockChart.SetInputValue(4, 400) # 조회 시 가져오는 Line 개수
|
||||||
|
objStockChart.SetInputValue(5, [0, 1, 2, 3, 4, 5, 8]) # 날짜,시간,시가,고가,저가,종가,거래량
|
||||||
|
objStockChart.SetInputValue(6, ord('m')) # '차트 주가 - 월(M), 주(W), 일(D), 시(H), 분(m), 초(S) 차트 요청
|
||||||
|
objStockChart.SetInputValue(7, 1)
|
||||||
|
objStockChart.SetInputValue(9, ord('1')) # 수정주가 사용
|
||||||
|
objStockChart.BlockRequest()
|
||||||
|
|
||||||
|
size = objStockChart.GetHeaderValue(3)
|
||||||
|
|
||||||
|
#print("날짜", "시간", "시가", "고가", "저가", "종가", "거래량")
|
||||||
|
start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S')
|
||||||
|
for i in range(size-1, -1, -1):
|
||||||
|
int_day = objStockChart.GetDataValue(0, i)
|
||||||
|
int_time = objStockChart.GetDataValue(1, i)
|
||||||
|
|
||||||
|
if int_day < int_given_day:
|
||||||
|
continue
|
||||||
|
time = datetime.strptime(str(int_day)+" "+str(int_time).zfill(4)+"00", '%Y%m%d %H%M%S')
|
||||||
|
if time < start_time:
|
||||||
|
continue
|
||||||
|
|
||||||
|
open = objStockChart.GetDataValue(2, i)
|
||||||
|
close = objStockChart.GetDataValue(5, i)
|
||||||
|
high = objStockChart.GetDataValue(3, i)
|
||||||
|
low = objStockChart.GetDataValue(4, i)
|
||||||
|
vol = objStockChart.GetDataValue(6, i)
|
||||||
|
|
||||||
|
if len(result["check"]) == 0:
|
||||||
|
result["check"].add(start_time)
|
||||||
|
result["time"].append(start_time)
|
||||||
|
result["open"].append(open)
|
||||||
|
result["close"].append(open)
|
||||||
|
result["high"].append(open)
|
||||||
|
result["low"].append(open)
|
||||||
|
result["vol"].append(0)
|
||||||
|
|
||||||
|
if time not in result["check"]:
|
||||||
|
result["check"].add(time)
|
||||||
|
result["time"].append(time)
|
||||||
|
|
||||||
|
result["open"].append(open)
|
||||||
|
result["close"].append(close)
|
||||||
|
result["high"].append(high)
|
||||||
|
result["low"].append(low)
|
||||||
|
result["vol"].append(vol)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def 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)]
|
||||||
|
|
||||||
|
i = size - 1
|
||||||
|
if i < 5:
|
||||||
|
return -1, -1, -1
|
||||||
|
|
||||||
|
buy, weight, sell = self.buySellChecker.getPriceAndWeight1(data, i)
|
||||||
|
return buy, weight, sell
|
||||||
|
|
||||||
|
def getSellingPrice(self, final_price):
|
||||||
|
# 만약 잔고가 있으면 장부가보다 5원 높게 매도한다.
|
||||||
|
jangoDic = self.requstJango()
|
||||||
|
if jangoDic and len(jangoDic.keys()) > 0:
|
||||||
|
for code in jangoDic:
|
||||||
|
if jangoDic[code]['매도가능'] > 0:
|
||||||
|
if final_price >= jangoDic[code]['장부가'] + 5:
|
||||||
|
return jangoDic[code]['매도가능'], final_price
|
||||||
|
else:
|
||||||
|
# 장부가 가격의 마지막 자리를 0으로 만든다. (2090 -> 2090, 2092 -> 2090, 2098 -> 2090)
|
||||||
|
sell_price = int(jangoDic[code]['장부가'] / 10) * 10
|
||||||
|
# 장부가의 마지막 자리수를 가져온다.
|
||||||
|
last_number = int(jangoDic[code]['장부가']) % 10
|
||||||
|
if last_number in [0, 1, 2, 3]:
|
||||||
|
# 장부가의 마지막 자리수가 0,1,2,3 이라면 (2090, 2091, 2092 -> 2095 에 매도)
|
||||||
|
return jangoDic[code]['매도가능'], sell_price + 5
|
||||||
|
elif last_number in [4, 5, 6, 7]:
|
||||||
|
# 장부가의 마지막 자리수가 4,5,6,7 이라면 (2093, 2094, 2095, 2096 -> 2100 에 매도)
|
||||||
|
return jangoDic[code]['매도가능'], sell_price + 10
|
||||||
|
else:
|
||||||
|
# 장부가의 마지막 자리수가 8,9 라면 (2098, 2099 -> 2105 에 매도)
|
||||||
|
return jangoDic[code]['매도가능'], sell_price + 15
|
||||||
|
|
||||||
|
return 0, 0
|
||||||
|
|
||||||
|
def buyRealTime(self, stock_code, GIVEN_DAY):
|
||||||
|
orderChecker = OrderChecker(stock_code)
|
||||||
|
BASE_COUNT = 100
|
||||||
|
|
||||||
|
timecheckList = pd.read_csv("timecheck.csv").values.tolist()
|
||||||
|
timecheck = {GIVEN_DAY + " " + str(second).zfill(6):False for second, check in timecheckList}
|
||||||
|
|
||||||
|
result = {"check": set(),
|
||||||
|
"time": [],
|
||||||
|
"open": [],
|
||||||
|
"close": [],
|
||||||
|
"high": [],
|
||||||
|
"low": [],
|
||||||
|
"vol": []}
|
||||||
|
|
||||||
|
final_price = 0
|
||||||
|
print ("START...")
|
||||||
|
THIS_TIME = datetime.now()
|
||||||
|
while datetime.strptime(GIVEN_DAY + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 15200", '%Y%m%d %H%M%S'):
|
||||||
|
|
||||||
|
if datetime.strptime(GIVEN_DAY + " 090100", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(GIVEN_DAY + " 151500", '%Y%m%d %H%M%S'):
|
||||||
|
if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]:
|
||||||
|
|
||||||
|
# 데이터를 가지고 온다.
|
||||||
|
self.getRealTime(stock_code, GIVEN_DAY, 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:
|
||||||
|
# 기본 100 주에 가중치를 추가해서 매수한다.
|
||||||
|
BUY_COUNT = int(BASE_COUNT * bs_weight)
|
||||||
|
|
||||||
|
# 매수를 주문한다.
|
||||||
|
orderNum = self.requestOrder(OrderType.buy, stock_code, BUY_COUNT , bs_buy_price)
|
||||||
|
|
||||||
|
# 미체결 기록을 가져온다.
|
||||||
|
ORDER_LIST = self.requestOrderList()
|
||||||
|
# 매수 주문을 기록한다.
|
||||||
|
orderListToCancel = orderChecker.add(stock_code, OrderType.buy, orderNum, BUY_COUNT, bs_buy_price, ORDER_LIST)
|
||||||
|
# 두 시간 이전 미체결을 모두 취소한다.
|
||||||
|
self.cancelOrderList(orderListToCancel)
|
||||||
|
# 로그 출력
|
||||||
|
print("BUY", THIS_TIME, BUY_COUNT, bs_buy_price)
|
||||||
|
|
||||||
|
if bs_sell_price > 0:
|
||||||
|
# 미체결 기록을 가져온다.
|
||||||
|
ORDER_LIST = self.requestOrderList()
|
||||||
|
# 매도 주문을 기록을 가져온다.
|
||||||
|
orderListToCancel = orderChecker.remove(stock_code, OrderType.sell, ORDER_LIST)
|
||||||
|
# 매도 미체결을 모두 취소한다.
|
||||||
|
self.cancelOrderList(orderListToCancel)
|
||||||
|
|
||||||
|
# 매도 가격을 가져온다.
|
||||||
|
selling_count, selling_price = self.getSellingPrice(final_price)
|
||||||
|
# 분석되 가격으로 매도 요청한다.
|
||||||
|
if selling_count != 0 and selling_price != 0:
|
||||||
|
# 매도를 요청한다.
|
||||||
|
orderNum = self.requestOrder(OrderType.sell, stock_code, selling_count, selling_price)
|
||||||
|
|
||||||
|
# 로그 출력
|
||||||
|
print("SELL", THIS_TIME, selling_count, selling_price)
|
||||||
|
|
||||||
|
# 로그 출력
|
||||||
|
print("TIMECHECK", THIS_TIME, final_price, data["Low"][data_size-1], data["slow_k"][data_size-1], data["slow_d"][data_size-1])
|
||||||
|
timecheck[THIS_TIME] = True
|
||||||
|
|
||||||
|
if datetime.strptime(GIVEN_DAY + " 151500", '%Y%m%d %H%M%S') < THIS_TIME:
|
||||||
|
# 주문 리스트를 가져온다.
|
||||||
|
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:
|
||||||
|
orderNum = self.requestOrder(OrderType.sell, stock_code, selling_count, selling_price)
|
||||||
|
# 로그 출력
|
||||||
|
print("SELL", THIS_TIME, selling_count, selling_price)
|
||||||
|
|
||||||
|
break
|
||||||
|
time.sleep(0.9)
|
||||||
|
THIS_TIME = datetime.now()
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
# KODEX 인버스 * 2
|
||||||
|
hts = HTS_252670()
|
||||||
|
stock_codes = ["252670"]
|
||||||
|
given_day = datetime.today().strftime('%Y%m%d')
|
||||||
|
|
||||||
|
#hts.writeStockData(stock_codes, "20211015")
|
||||||
|
hts.buyRealTime(stock_codes[0], given_day)
|
||||||
|
|
||||||
|
print ("done...")
|
||||||
@@ -6,59 +6,81 @@ from OrderType import OrderType
|
|||||||
|
|
||||||
class OrderChecker:
|
class OrderChecker:
|
||||||
|
|
||||||
order_df = None # 매수/매도구분, orderNum, 금액, 시각
|
|
||||||
saveFileName = None
|
saveFileName = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, stock_code):
|
||||||
self.saveFileName = "./order/"+datetime.today().strftime("%Y%m%d")+".csv"
|
self.saveFileName = "./order/"+stock_code+"_"+datetime.today().strftime("%Y%m%d")+".csv"
|
||||||
self.read(self.saveFileName)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def read(self, fileName):
|
def read(self):
|
||||||
if os.path.isfile(fileName):
|
if os.path.isfile(self.saveFileName):
|
||||||
self.order_df = pd.read_csv(fileName)
|
order_df = pd.read_csv(self.saveFileName)
|
||||||
else:
|
else:
|
||||||
self.order_df = pd.DataFrame(columns=["type", "orderNum", "count", "price", "datetime"])
|
order_df = pd.DataFrame(columns=["stock_code", "type", "orderNum", "count", "price", "datetime"])
|
||||||
|
|
||||||
self.order_df = self.order_df.astype({"type": str, "orderNum": int, "count": int, "price": int})
|
order_df = order_df.astype({"stock_code": str, "type": str, "orderNum": int, "count": int, "price": int})
|
||||||
self.order_df['datetime'] = pd.to_datetime(self.order_df['datetime'])
|
order_df['datetime'] = pd.to_datetime(order_df['datetime'])
|
||||||
return
|
return order_df
|
||||||
|
|
||||||
def add(self, type, orderNum, count, price, orderList):
|
def add(self, stock_code, type, orderNum, count, price, orderList):
|
||||||
orderListToCancel = []
|
orderListToCancel = []
|
||||||
|
# 매수 요청인 경우만 두 시간 전 주문을 찾아서 제외한다.
|
||||||
|
if type == OrderType.buy:
|
||||||
|
return orderListToCancel
|
||||||
|
|
||||||
# 두 시간 전
|
order_df = self.read()
|
||||||
before_two_hour = datetime.now() - timedelta(hours=2)
|
|
||||||
|
|
||||||
# 두 시간 전 주문을 찾는다.
|
# 두 시간 전 주문을 찾는다.
|
||||||
if orderList is not None and len(orderList) > 0:
|
if orderList is not None and len(orderList) > 0:
|
||||||
# 만약 두시간 전 주문을 찾는다.
|
# 1) 종목 코드를 찾는다.
|
||||||
orderNum_df = self.order_df.loc[self.order_df["datetime"] <= before_two_hour]
|
stock_df = order_df.loc[order_df["stock_code"] == stock_code]
|
||||||
orderNum_df = orderNum_df.loc[orderNum_df["type"] == OrderType.buy.value]
|
|
||||||
|
# 2) 2 시간 전 계산
|
||||||
|
before_two_hour = datetime.now() - timedelta(hours=2)
|
||||||
|
|
||||||
|
# 3) 만약 2 시간 전 주문을 찾는다.
|
||||||
|
stock_twohour_df = stock_df.loc[stock_df["datetime"] <= before_two_hour]
|
||||||
|
|
||||||
|
# 4) 2 시간 전 주문 중에서 매수 데이터만 찾는다.
|
||||||
|
orderNum_df = stock_twohour_df.loc[stock_twohour_df["type"] == OrderType.buy.value]
|
||||||
|
|
||||||
|
# 5) 2시간 전 매수 항목을 별도로 추출한다.
|
||||||
orderNumSet = set(list(orderNum_df["orderNum"]))
|
orderNumSet = set(list(orderNum_df["orderNum"]))
|
||||||
for item in orderList:
|
for item in orderList:
|
||||||
if item.orderNum in orderNumSet:
|
if item.orderNum in orderNumSet:
|
||||||
orderListToCancel.append(item)
|
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.value, "orderNum": orderNum, "count": count, "price": price, "datetime": datetime.now()}, ignore_index=True)
|
# 6) 추출된 항목을 제외시킨다.
|
||||||
self.order_df.to_csv(self.saveFileName)
|
order_df = order_df.loc[order_df["orderNum"] != item.orderNum]
|
||||||
|
|
||||||
|
# 7) 새로운 주문을 추가한다.
|
||||||
|
order_df = order_df.append({"stock_code": stock_code, "type": type.value, "orderNum": orderNum, "count": count, "price": price, "datetime": datetime.now()}, ignore_index=True)
|
||||||
|
|
||||||
|
# 8) 파일로 기록한다.
|
||||||
|
order_df.to_csv(self.saveFileName)
|
||||||
|
|
||||||
return orderListToCancel
|
return orderListToCancel
|
||||||
|
|
||||||
def remove(self, type, orderList):
|
def remove(self, stock_code, type, orderList):
|
||||||
|
order_df = self.read()
|
||||||
orderListToCancel = []
|
orderListToCancel = []
|
||||||
|
|
||||||
if orderList is not None and len(orderList) > 0:
|
if orderList is not None and len(orderList) > 0:
|
||||||
orderNum_df = self.order_df.loc[self.order_df["type"] == type.value]
|
# 1) 종목 코드를 찾는다.
|
||||||
|
stock_df = order_df.loc[order_df["stock_code"] == stock_code]
|
||||||
|
|
||||||
|
# 2) 매도 주문을 찾는다.
|
||||||
|
orderNum_df = stock_df.loc[stock_df["type"] == type.value]
|
||||||
|
|
||||||
|
# 3) 매도 주문 중에서 항목을 별도로 추출한다.
|
||||||
orderNumSet = set(list(orderNum_df["orderNum"]))
|
orderNumSet = set(list(orderNum_df["orderNum"]))
|
||||||
for item in orderList:
|
for item in orderList:
|
||||||
if item.orderNum in orderNumSet:
|
if item.orderNum in orderNumSet:
|
||||||
orderListToCancel.append(item)
|
orderListToCancel.append(item)
|
||||||
# 해당 orderNum 제외하기
|
|
||||||
self.order_df = self.order_df.loc[self.order_df["orderNum"] != item.orderNum]
|
# 4) 해당 orderNum 제외하기
|
||||||
self.order_df.to_csv(self.saveFileName)
|
order_df = order_df.loc[order_df["orderNum"] != item.orderNum]
|
||||||
|
order_df.to_csv(self.saveFileName)
|
||||||
|
|
||||||
return orderListToCancel
|
return orderListToCancel
|
||||||
|
|
||||||
|
|||||||
@@ -133,19 +133,6 @@ class Simulation:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def getAverageVolume(self, stock_code):
|
|
||||||
index = 0
|
|
||||||
while index < 10:
|
|
||||||
this_day = datetime.today() - timedelta(days=index+1)
|
|
||||||
fileName = "./data/"+stock_code+"_"+this_day.strftime("%Y%m%d")+".csv"
|
|
||||||
#fileName = "./data/" + stock_code + "_20211013.csv"
|
|
||||||
if os.path.isfile(fileName):
|
|
||||||
data = pd.read_csv(fileName)
|
|
||||||
return data
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
return 2000000
|
|
||||||
|
|
||||||
def simulate(self, stock_code, GIVEN_DAY):
|
def simulate(self, stock_code, GIVEN_DAY):
|
||||||
result = {"check": set(),
|
result = {"check": set(),
|
||||||
"time": [],
|
"time": [],
|
||||||
@@ -155,8 +142,6 @@ class Simulation:
|
|||||||
"low": [],
|
"low": [],
|
||||||
"vol": []}
|
"vol": []}
|
||||||
|
|
||||||
averageVolume = self.getAverageVolume(stock_code)
|
|
||||||
|
|
||||||
# 데이터를 가지고 온다.
|
# 데이터를 가지고 온다.
|
||||||
self.getCSV("./data/"+stock_code+"_"+GIVEN_DAY+".csv", GIVEN_DAY, result)
|
self.getCSV("./data/"+stock_code+"_"+GIVEN_DAY+".csv", GIVEN_DAY, result)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user