499 lines
26 KiB
Python
499 lines
26 KiB
Python
import time
|
|
import pandas as pd
|
|
import psutil
|
|
from datetime import datetime
|
|
|
|
from hts.HTS import HTS
|
|
from hts.OrderType import OrderType
|
|
|
|
from hts.OrderChecker import OrderChecker
|
|
from stock.util.TelegramBot import TelegramBot
|
|
from stock.analysis.StockStatus import StockStatus
|
|
|
|
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
|
|
from statsmodels.tsa.seasonal import seasonal_decompose
|
|
|
|
from hts.BuySellChecker import BuySellChecker
|
|
|
|
class HTS_etf(HTS):
|
|
RESOURCE_PATH = None
|
|
SELL_GAP = None
|
|
stock_code = None
|
|
stock_name = None
|
|
buy_count = None
|
|
orderChecker = None
|
|
buySellChecker = None
|
|
bot = None
|
|
stockStatus = None
|
|
|
|
common = None
|
|
stochastic = None
|
|
rsi = None
|
|
macd = None
|
|
ichimokuCloud = None
|
|
|
|
|
|
def __init__(self, RESOURCE_PATH):
|
|
super().__init__(RESOURCE_PATH)
|
|
|
|
self.RESOURCE_PATH = RESOURCE_PATH
|
|
|
|
self.bot = TelegramBot()
|
|
self.stockStatus = StockStatus(RESOURCE_PATH)
|
|
|
|
self.common = Common()
|
|
self.stochastic = Stochastic()
|
|
self.rsi = RSI()
|
|
self.macd = MACD()
|
|
self.ichimokuCloud = IchimokuCloud()
|
|
|
|
self.buySellChecker = BuySellChecker(self.RESOURCE_PATH)
|
|
|
|
return
|
|
|
|
def getBallance(self, stock_code):
|
|
jangoDic = self.requstJango()
|
|
if jangoDic and len(jangoDic.keys()) > 0:
|
|
for code in jangoDic:
|
|
if stock_code is not None:
|
|
if code == "A" + stock_code:
|
|
return jangoDic[code]['장부가'], jangoDic[code]['평가금액'], jangoDic[code]['평가손익']
|
|
return 0, 0, 0
|
|
|
|
def sellStocks(self, stock_code=None, stock_name=None, bs_sell_price=None):
|
|
check = False
|
|
jangoDic = self.requstJango()
|
|
if jangoDic and len(jangoDic.keys()) > 0:
|
|
for code in jangoDic:
|
|
if stock_code is not None:
|
|
if code == "A" + stock_code:
|
|
if bs_sell_price is not None:
|
|
if jangoDic[code]['매도가능'] > 0:
|
|
if jangoDic[code]['평가손익'] < -1.0 or jangoDic[code]['장부가'] + 5 <= jangoDic[code]['현재가']:
|
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], bs_sell_price)
|
|
self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name))
|
|
check = True
|
|
else:
|
|
if jangoDic[code]['매도가능'] > 0:
|
|
if jangoDic[code]['평가손익'] < -1.0 or jangoDic[code]['장부가'] + 5 <= jangoDic[code]['현재가']:
|
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
|
self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name))
|
|
check = True
|
|
else:
|
|
if jangoDic[code]['매도가능'] > 0:
|
|
if jangoDic[code]['평가손익'] < -1.0 or jangoDic[code]['장부가'] + 5 <= jangoDic[code]['현재가']:
|
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
|
self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name))
|
|
check = True
|
|
return check
|
|
|
|
"""
|
|
def sellStocks(self, stock_code=None, stock_name=None, bs_sell_price=None):
|
|
check = False
|
|
jangoDic = self.requstJango()
|
|
if jangoDic and len(jangoDic.keys()) > 0:
|
|
for code in jangoDic:
|
|
if stock_code is not None:
|
|
if code == "A" + stock_code:
|
|
if bs_sell_price is not None:
|
|
if jangoDic[code]['매도가능'] > 0:
|
|
if jangoDic[code]['평가손익'] < -1.0 or 1.5 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], bs_sell_price)
|
|
self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name))
|
|
check = True
|
|
else:
|
|
if jangoDic[code]['매도가능'] > 0:
|
|
if jangoDic[code]['평가손익'] < -1.0 or 1.5 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
|
self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name))
|
|
check = True
|
|
else:
|
|
if jangoDic[code]['매도가능'] > 0:
|
|
if jangoDic[code]['평가손익'] < -1.0 or 1.5 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
|
self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name))
|
|
check = True
|
|
return check
|
|
"""
|
|
|
|
def getSellingPrice(self, log_time, stock_code, final_price, without_loss=False):
|
|
# final_price와 diff를 받으면, 해당 가격으로 그냥 매도한다는 의미
|
|
# final_price와 diff가 None이면 장부가와 final 중 max로 팔겠다는 의미
|
|
# final_price가 0이고 diff가 None이면 장부가로 팔겠다는 의미임
|
|
orderNum = None
|
|
jangoDic = self.requstJango()
|
|
if jangoDic and len(jangoDic.keys()) > 0:
|
|
for code in jangoDic:
|
|
if jangoDic[code]['매도가능'] > 0:
|
|
if without_loss:
|
|
if jangoDic[code]['장부가'] * 0.07 < jangoDic[code]['장부가'] - final_price:
|
|
sell_price = jangoDic[code]['장부가']
|
|
if code == "A" + stock_code:
|
|
orderNum = self.requestOrder(OrderType.sell, stock_code, jangoDic[code]['매도가능'], sell_price)
|
|
return orderNum, log_time.strftime('%Y%m%d %H%M%S'), jangoDic[code]['매도가능'], sell_price
|
|
else:
|
|
max_price = max(jangoDic[code]['장부가'], final_price)
|
|
sell_price = (int(max_price) - int(max_price) % 5) + 5
|
|
if code == "A" + stock_code:
|
|
orderNum = self.requestOrder(OrderType.sell, stock_code, jangoDic[code]['매도가능'], sell_price)
|
|
return orderNum, log_time.strftime('%Y%m%d %H%M%S'), jangoDic[code]['매도가능'], sell_price
|
|
return orderNum, None, None, None
|
|
|
|
def analyze(self, result):
|
|
# 기본 캔들 정보
|
|
open = result["open"]
|
|
close = result["close"]
|
|
high = result["high"]
|
|
low = result["low"]
|
|
volume = result["volume"]
|
|
|
|
if "volume_down" in result:
|
|
volume_down = result["volume_down"]
|
|
if "volume_up" in result:
|
|
volume_up = result["volume_up"]
|
|
if "volume_updown_diff" in result:
|
|
volume_updown_diff = result["volume_updown_diff"]
|
|
|
|
# 이동 평균
|
|
close_df = pd.DataFrame(close)
|
|
avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist()
|
|
avg5 = [item[0] for item in avg5_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]
|
|
avg120_list = close_df.rolling(window=120).mean().fillna(close[0]).values.tolist()
|
|
avg120 = [item[0] for item in avg120_list]
|
|
avg240_list = close_df.rolling(window=240).mean().fillna(close[0]).values.tolist()
|
|
avg240 = [item[0] for item in avg240_list]
|
|
avg480_list = close_df.rolling(window=480).mean().fillna(close[0]).values.tolist()
|
|
avg480 = [item[0] for item in avg480_list]
|
|
avg1500_list = close_df.rolling(window=1500).mean().fillna(close[0]).values.tolist()
|
|
avg1500 = [item[0] for item in avg1500_list]
|
|
|
|
size = int(len(close) / 8)
|
|
pos = round(size / 2)
|
|
close_temp = close + [close[-1]] * pos
|
|
decomposition_results = seasonal_decompose(close_temp, model='multiplicative', period=size)
|
|
trend = decomposition_results.trend[:-pos]
|
|
trend_df = pd.DataFrame(trend).fillna(close[0])
|
|
trend_avg_list = trend_df.rolling(window=20).mean().values.tolist()
|
|
trend_avg = [item[0] for item in trend_avg_list]
|
|
|
|
open_df = pd.DataFrame(close)
|
|
disparity_avg5_list = (open_df / close_df.rolling(window=5).mean()).values.tolist()
|
|
disparity_avg5 = [item[0] for item in disparity_avg5_list]
|
|
disparity_avg20_list = (open_df / close_df.rolling(window=20).mean()).values.tolist()
|
|
disparity_avg20 = [item[0] for item in disparity_avg20_list]
|
|
disparity_avg30_list = (open_df / close_df.rolling(window=30).mean()).values.tolist()
|
|
disparity_avg30 = [item[0] for item in disparity_avg30_list]
|
|
disparity_avg60_list = (open_df / close_df.rolling(window=60).mean()).values.tolist()
|
|
disparity_avg60 = [item[0] for item in disparity_avg60_list]
|
|
disparity_avg120_list = (open_df / close_df.rolling(window=120).mean()).values.tolist()
|
|
disparity_avg120 = [item[0] for item in disparity_avg120_list]
|
|
disparity_avg240_list = (open_df / close_df.rolling(window=240).mean()).values.tolist()
|
|
disparity_avg240 = [item[0] for item in disparity_avg240_list]
|
|
disparity_avg480_list = (open_df / close_df.rolling(window=480).mean()).values.tolist()
|
|
disparity_avg480 = [item[0] for item in disparity_avg480_list]
|
|
disparity_avg1500_list = (open_df / close_df.rolling(window=1500).mean()).values.tolist()
|
|
disparity_avg1500 = [item[0] for item in disparity_avg1500_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) # 하단 볼린저 밴드
|
|
middle_df = (upper_df + lower_df) / 2
|
|
upper_limit_df = upper_df - (upper_df - lower_df) * 0.1
|
|
lower_limit_df = (upper_df - lower_df) * 0.15 + lower_df
|
|
|
|
upper, lower, middle, upper_limit, lower_limit = [], [], [], [], []
|
|
for i in range(len(upper_df)):
|
|
if i < 10:
|
|
upper.append(upper_df.values[0][0])
|
|
lower.append(lower_df.values[0][0])
|
|
middle.append(middle_df.values[0][0])
|
|
upper_limit.append(upper_limit_df.values[0][0])
|
|
lower_limit.append(lower_limit_df.values[0][0])
|
|
else:
|
|
upper.append(upper_df.values[i][0])
|
|
lower.append(lower_df.values[i][0])
|
|
middle.append(middle_df.values[i][0])
|
|
upper_limit.append(upper_limit_df.values[i][0])
|
|
lower_limit.append(lower_limit_df.values[i][0])
|
|
|
|
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["ymd"]
|
|
STOCK = []
|
|
if "volume_up" in result and "volume_updown_diff" in result:
|
|
for i in range(len(open)):
|
|
STOCK.append({'volume': volume[i], 'volume_down': volume_down[i], 'volume_up': volume_up[i], 'volume_updown_diff': volume_updown_diff[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
|
|
'avg5': avg5[i], 'avg20': avg20[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg240': avg240[i], 'avg480': avg480[i], 'avg1500': avg1500[i]})
|
|
else:
|
|
for i in range(len(open)):
|
|
STOCK.append({'volume': volume[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
|
|
'avg5': avg5[i], 'avg20': avg20[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg240': avg240[i], 'avg480': avg480[i], 'avg1500': avg1500[i]})
|
|
|
|
# stochastic
|
|
stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5)
|
|
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 = self.macd.apply(STOCK, short=5, long=20, t=5)
|
|
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 = 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 = ichimokuCloud_df[:len(ichimokuCloud_df) - 51]
|
|
changeLine = ichimokuCloud_df['changeLine'].values.tolist()
|
|
baseLine = ichimokuCloud_df['baseLine'].values.tolist()
|
|
laggingSpan = ichimokuCloud_df['laggingSpan'].values.tolist()
|
|
leadingSpan1 = ichimokuCloud_df['leadingSpan1'].values.tolist()
|
|
leadingSpan2 = ichimokuCloud_df['leadingSpan2'].values.tolist()
|
|
|
|
# 결과
|
|
if "volume_up" in result and "volume_updown_diff" in result:
|
|
temp = {
|
|
"ymd": point_temp,
|
|
"open": open, "high": high, "low": low, "close": close, "volume": volume, "volume_down": volume_down,
|
|
"volume_up": volume_up, "volume_updown_diff": volume_updown_diff,
|
|
"trend": trend, "trend_avg": trend_avg,
|
|
"avg5": avg5, "avg20": avg20, "avg60": avg60, "avg120": avg120, "avg240": avg240, "avg480": avg480,
|
|
"avg1500": avg1500,
|
|
"disparity_avg5": disparity_avg5, "disparity_avg20": disparity_avg20,
|
|
"disparity_avg30": disparity_avg30, "disparity_avg60": disparity_avg60,
|
|
"disparity_avg120": disparity_avg120, "disparity_avg240": disparity_avg240,
|
|
"disparity_avg480": disparity_avg480, "disparity_avg1500": disparity_avg1500,
|
|
"upper": upper, "lower": lower, 'middle': middle, 'upper_limit': upper_limit,
|
|
'lower_limit': lower_limit,
|
|
"macd": macd, "macds": macds, "macdo": macdo,
|
|
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
|
|
"rsi": rsi, "rsis": rsis,
|
|
"changeLine": changeLine, "baseLine": baseLine, "laggingSpan": laggingSpan,
|
|
"leadingSpan1": leadingSpan1, "leadingSpan2": leadingSpan2,
|
|
}
|
|
else:
|
|
temp = {
|
|
"ymd": point_temp,
|
|
"open": open, "high": high, "low": low, "close": close, "volume": volume,
|
|
"trend": trend, "trend_avg": trend_avg,
|
|
"avg5": avg5, "avg20": avg20, "avg60": avg60, "avg120": avg120, "avg240": avg240, "avg480": avg480,
|
|
"avg1500": avg1500,
|
|
"disparity_avg5": disparity_avg5, "disparity_avg20": disparity_avg20,
|
|
"disparity_avg30": disparity_avg30, "disparity_avg60": disparity_avg60,
|
|
"disparity_avg120": disparity_avg120, "disparity_avg240": disparity_avg240,
|
|
"disparity_avg480": disparity_avg480, "disparity_avg1500": disparity_avg1500,
|
|
"upper": upper, "lower": lower, 'middle': middle, 'upper_limit': upper_limit,
|
|
'lower_limit': lower_limit,
|
|
"macd": macd, "macds": macds, "macdo": macdo,
|
|
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
|
|
"rsi": rsi, "rsis": rsis,
|
|
"changeLine": changeLine, "baseLine": baseLine, "laggingSpan": laggingSpan,
|
|
"leadingSpan1": leadingSpan1, "leadingSpan2": leadingSpan2,
|
|
}
|
|
|
|
data = pd.DataFrame(temp)
|
|
df_final_time = pd.DatetimeIndex(point_temp)
|
|
data.index = df_final_time
|
|
|
|
data = data.fillna(-1)
|
|
return data
|
|
|
|
|
|
def makeTickData(self, data, mins=30):
|
|
result = {"check": set(),
|
|
"ymd": [],
|
|
"open": [],
|
|
"close": [],
|
|
"high": [],
|
|
"low": [],
|
|
"volume": [],
|
|
"label": []}
|
|
|
|
for i in range(mins, len(data['ymd']) + 1):
|
|
result["check"].add(data['ymd'][i - 1])
|
|
result["ymd"].append(data['ymd'][i - 1])
|
|
|
|
result["open"].append(data['open'][i - mins])
|
|
result["close"].append(data['close'][i - 1])
|
|
result["high"].append(max(data['high'][i - mins: i]))
|
|
result["low"].append(min(data['low'][i - mins: i]))
|
|
result["volume"].append(sum(data['volume'][i - mins: i]))
|
|
|
|
return result
|
|
|
|
def makeTickData1(self, data, mins=5):
|
|
result = {
|
|
"ymd": [],
|
|
"open": [], "close": [], "high": [], "low": [], "volume": [], "volume_up": [], "volume_down": [], "volume_updown_diff": []
|
|
}
|
|
|
|
for i in range(mins, len(data['ymd'])+1):
|
|
result["ymd"].append(data['ymd'][i-1])
|
|
|
|
result["open"].append(data['open'][i-mins])
|
|
result["close"].append(data['close'][i-1])
|
|
|
|
result["high"].append(max(data['high'][i - mins: i]))
|
|
result["low"].append(min(data['low'][i - mins: i]))
|
|
result["volume"].append(sum(data['volume'][i - mins: i]))
|
|
|
|
up = [data['volume'][i - mins + c] for c in range(len(data['volume'][i - mins: i])) if data['open'][i - mins + c] < data['close'][i - mins + c]]
|
|
down = [data['volume'][i - mins + c] for c in range(len(data['volume'][i - mins: i])) if data['close'][i - mins + c] < data['open'][i - mins + c]]
|
|
result["volume_up"].append(sum(up))
|
|
result["volume_down"].append(sum(down))
|
|
result["volume_updown_diff"].append(sum(up) - sum(down))
|
|
|
|
return result
|
|
|
|
def makeTickData2(self, data, mins=5):
|
|
result = {
|
|
"ymd": [],
|
|
"open": [], "close": [], "high": [], "low": [], "volume": [], "volume_up": [], "volume_down": [], "volume_updown_diff": []
|
|
}
|
|
|
|
for i in range(mins, len(data['ymd'])+1, mins):
|
|
result["ymd"].append(data['ymd'][i-1])
|
|
|
|
result["open"].append(data['open'][i-mins])
|
|
result["close"].append(data['close'][i-1])
|
|
|
|
result["high"].append(max(data['high'][i - mins: i]))
|
|
result["low"].append(min(data['low'][i - mins: i]))
|
|
result["volume"].append(data['volume'][i-1])
|
|
if data['open'][i-1] < data['close'][i-1]:
|
|
result["volume_up"].append(data['volume'][i-1])
|
|
result["volume_down"].append(0)
|
|
elif data['close'][i-1] < data['open'][i-1]:
|
|
result["volume_down"].append(-1*data['volume'][i-1])
|
|
result["volume_up"].append(0)
|
|
else:
|
|
result["volume_up"].append(0)
|
|
result["volume_down"].append(0)
|
|
|
|
up = [data['volume'][i - mins + c] for c in range(len(data['volume'][i - mins: i])) if data['close'][i - mins + c] < data['open'][i - mins + c]]
|
|
down = [data['volume'][i - mins + c] for c in range(len(data['volume'][i - mins: i])) if data['close'][i - mins + c] < data['open'][i - mins + c]]
|
|
result["volume_updown_diff"].append(sum(up) - sum(down))
|
|
|
|
return result
|
|
|
|
def buyRealTime(self, stocks, today, MAX_PRICE=30000):
|
|
#self.orderChecker = OrderChecker(self.RESOURCE_PATH, stock_code)
|
|
|
|
BUY_LIST = {'buy_count': 0, 'buy_avg': 0, 'buy_list': []}
|
|
|
|
print("START...")
|
|
THIS_TIME = datetime.now()
|
|
|
|
#LAST_DATA = self.getLastData(stock_code, today)
|
|
isFirst = 0
|
|
while datetime.strptime(today + " 060000", '%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'):
|
|
|
|
for stock in stocks:
|
|
stock_code = stock['stock_code']
|
|
stock_name = stock['stock_name']
|
|
|
|
if isFirst < 4:
|
|
self.bot.sendMsg("START... {} ({}) MAX_PRICE: {}".format(stock_code, stock_name, MAX_PRICE))
|
|
isFirst += 1
|
|
|
|
# 매도를 체크한다.
|
|
check = self.sellStocks(stock_code, stock_name)
|
|
|
|
# jangoDic[code]['장부가'], jangoDic[code]['평가금액'], jangoDic[code]['평가손익'],
|
|
buy_avg, amount, profit = self.getBallance(stock_code)
|
|
if check or buy_avg == 0:
|
|
BUY_LIST['buy_avg'] = 0
|
|
BUY_LIST['buy_count'] = 0
|
|
BUY_LIST['buy_list'].clear()
|
|
|
|
time.sleep(0.1)
|
|
|
|
#result_m1 = self.getRealTime(stock_code, today, LAST_DATA)
|
|
result_m1 =self.getRealTime(stock_code, today)
|
|
result_tic_m1 = self.makeTickData1(result_m1, mins=1)
|
|
data = self.analyze(result_tic_m1)
|
|
result_tic_m30 = self.makeTickData2(result_tic_m1, mins=30)
|
|
data_signal = self.analyze(result_tic_m30)
|
|
#data.drop(data.index[:len(data) - analyzed_day], inplace=True)
|
|
|
|
# 사야 할 시점과 팔아야 할 시점을 체크한다.
|
|
bsLine1 = self.buySellChecker.checkTransaction1(stock_code, MAX_PRICE, data, data_signal, BUY_LIST, isRealTime=True)
|
|
|
|
if 'sell_price' in bsLine1:
|
|
sell_price = bsLine1['sell_price'][-1]
|
|
if 0 < sell_price:
|
|
profit_rate = 1.002
|
|
if buy_avg * profit_rate < data['close'][-1]:
|
|
check = self.sellStocks(stock_code, sell_price)
|
|
if check:
|
|
#self.orderChecker.sell(datetime.today().strftime('%Y%m%d'), stock_code)
|
|
BUY_LIST['buy_avg'] = 0
|
|
BUY_LIST['buy_count'] = 0
|
|
BUY_LIST['buy_list'].clear()
|
|
self.bot.sendMsg( "Profit {:.2f}, {} ({})".format(profit, stock_code, stock_name))
|
|
|
|
if 'buy_price' in bsLine1:
|
|
buy_price = bsLine1['buy_price'][-1]
|
|
buy_count = int(bsLine1['buy_count'][-1])
|
|
if buy_price > 0:
|
|
# 매수를 요청 한다.
|
|
orderNum = self.requestOrder(OrderType.buy, stock_code, buy_count, buy_price)
|
|
#self.orderChecker.buy(today, "A" + stock_code, buy_count, buy_price, orderNum)
|
|
|
|
#self.orderChecker.buy(datetime.today().strftime('%Y%m%d'), stock_code, buy_count, buy_price)
|
|
self.bot.post(stock_code, stock_name, "[BUY] ", buy_price, buy_count, data['rsi'][-1], -1)
|
|
|
|
|
|
"""
|
|
# 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다.
|
|
ORDER_LIST = self.requestOrderList()
|
|
orderListToCancel = self.orderChecker.cancel(today, "A" + stock_code, ORDER_LIST, mins=3)
|
|
if len(orderListToCancel) > 0:
|
|
self.cancelOrderList(orderListToCancel)
|
|
"""
|
|
if (int(THIS_TIME.strftime("%M")) % 50 == 0 or int(THIS_TIME.strftime("%M")) % 20 == 0):
|
|
#self.bot.alarm_live(stock_code, stock_name)
|
|
vm = psutil.virtual_memory()
|
|
vm_item = dict()
|
|
vm_item['free'] = vm.available // (1024 * 1024)
|
|
vm_item['idle'] = vm.available / vm.total * 100
|
|
self.bot.sendMsg("Alive... {} ({}) avg: {:.2f}, close: {:.2f}, mem: {:.1f}".format(stock_code, stock_name, buy_avg, data['close'][-1], vm_item['idle']))
|
|
|
|
time.sleep(60)
|
|
THIS_TIME = datetime.now()
|
|
|
|
return True |