init
This commit is contained in:
382
HTS_etf.py
382
HTS_etf.py
@@ -1,6 +1,5 @@
|
|||||||
import time
|
import time
|
||||||
import os
|
import pandas as pd
|
||||||
import sqlite3
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from hts.HTS import HTS
|
from hts.HTS import HTS
|
||||||
@@ -11,11 +10,14 @@ from stock.util.LabelChecker import LabelChecker
|
|||||||
from stock.util.TelegramBot import TelegramBot
|
from stock.util.TelegramBot import TelegramBot
|
||||||
from stock.analysis.StockStatus import StockStatus
|
from stock.analysis.StockStatus import StockStatus
|
||||||
|
|
||||||
from hts.BuySellChecker_122630 import BuySellChecker_122630
|
from stock.analysis.Common import Common
|
||||||
from hts.BuySellChecker_233740 import BuySellChecker_233740
|
from stock.analysis.Stochastic import Stochastic
|
||||||
from hts.BuySellChecker_251340 import BuySellChecker_251340
|
from stock.analysis.RSI import RSI
|
||||||
from hts.BuySellChecker_252670 import BuySellChecker_252670
|
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):
|
class HTS_etf(HTS):
|
||||||
RESOURCE_PATH = None
|
RESOURCE_PATH = None
|
||||||
@@ -25,10 +27,16 @@ class HTS_etf(HTS):
|
|||||||
buy_count = None
|
buy_count = None
|
||||||
orderChecker = None
|
orderChecker = None
|
||||||
buySellChecker = None
|
buySellChecker = None
|
||||||
labelChecker = None
|
|
||||||
bot = None
|
bot = None
|
||||||
stockStatus = None
|
stockStatus = None
|
||||||
|
|
||||||
|
common = None
|
||||||
|
stochastic = None
|
||||||
|
rsi = None
|
||||||
|
macd = None
|
||||||
|
ichimokuCloud = None
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, RESOURCE_PATH, stock_code, stock_name, SELL_GAP):
|
def __init__(self, RESOURCE_PATH, stock_code, stock_name, SELL_GAP):
|
||||||
super().__init__(RESOURCE_PATH)
|
super().__init__(RESOURCE_PATH)
|
||||||
|
|
||||||
@@ -42,19 +50,19 @@ class HTS_etf(HTS):
|
|||||||
self.bot = TelegramBot()
|
self.bot = TelegramBot()
|
||||||
self.stockStatus = StockStatus(RESOURCE_PATH)
|
self.stockStatus = StockStatus(RESOURCE_PATH)
|
||||||
|
|
||||||
self.buySellChecker = None
|
self.common = Common()
|
||||||
if stock_code == '122630':
|
self.stochastic = Stochastic()
|
||||||
self.buySellChecker = BuySellChecker_122630()
|
self.rsi = RSI()
|
||||||
elif stock_code == '233740':
|
self.macd = MACD()
|
||||||
self.buySellChecker = BuySellChecker_233740()
|
self.ichimokuCloud = IchimokuCloud()
|
||||||
elif stock_code == '251340':
|
|
||||||
self.buySellChecker = BuySellChecker_251340()
|
|
||||||
elif stock_code == '252670':
|
|
||||||
self.buySellChecker = BuySellChecker_252670()
|
|
||||||
|
|
||||||
|
self.buySellChecker = BuySellChecker()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def getBallance(self):
|
||||||
|
return
|
||||||
|
|
||||||
def sellStocks(self, stock_code=None, bs_sell_price=None):
|
def sellStocks(self, stock_code=None, bs_sell_price=None):
|
||||||
check = False
|
check = False
|
||||||
jangoDic = self.requstJango()
|
jangoDic = self.requstJango()
|
||||||
@@ -64,19 +72,19 @@ class HTS_etf(HTS):
|
|||||||
if code == "A" + stock_code:
|
if code == "A" + stock_code:
|
||||||
if bs_sell_price is not None:
|
if bs_sell_price is not None:
|
||||||
if jangoDic[code]['매도가능'] > 0:
|
if jangoDic[code]['매도가능'] > 0:
|
||||||
if jangoDic[code]['평가손익'] < -1.5 or 3 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
if jangoDic[code]['평가손익'] < -1.0 or 2 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
||||||
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
||||||
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], bs_sell_price)
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], bs_sell_price)
|
||||||
check = True
|
check = True
|
||||||
else:
|
else:
|
||||||
if jangoDic[code]['매도가능'] > 0:
|
if jangoDic[code]['매도가능'] > 0:
|
||||||
if jangoDic[code]['평가손익'] < -1.5 or 3 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
if jangoDic[code]['평가손익'] < -1.0 or 2 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
||||||
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
||||||
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
||||||
check = True
|
check = True
|
||||||
else:
|
else:
|
||||||
if jangoDic[code]['매도가능'] > 0:
|
if jangoDic[code]['매도가능'] > 0:
|
||||||
if jangoDic[code]['평가손익'] < -1.5 or 3 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
if jangoDic[code]['평가손익'] < -1.0 or 2 < jangoDic[code]['평가손익'] or self.SELL_GAP < jangoDic[code]['평가금액']-jangoDic[code]['매입금액']:
|
||||||
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
# 1.5% 손해 혹은 2% 이상 시 수익 매도
|
||||||
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
|
||||||
check = True
|
check = True
|
||||||
@@ -105,6 +113,188 @@ class HTS_etf(HTS):
|
|||||||
return orderNum, log_time.strftime('%Y%m%d %H%M%S'), jangoDic[code]['매도가능'], sell_price
|
return orderNum, log_time.strftime('%Y%m%d %H%M%S'), jangoDic[code]['매도가능'], sell_price
|
||||||
return orderNum, None, None, None
|
return orderNum, None, None, None
|
||||||
|
|
||||||
|
def analyze(self, result):
|
||||||
|
# 기본 캔들 정보
|
||||||
|
open = result["open"]
|
||||||
|
close = result["close"]
|
||||||
|
high = result["high"]
|
||||||
|
low = result["low"]
|
||||||
|
volume = result["vol"]
|
||||||
|
|
||||||
|
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["time"]
|
||||||
|
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):
|
def makeTickData(self, data, mins=30):
|
||||||
result = {"check": set(),
|
result = {"check": set(),
|
||||||
"time": [],
|
"time": [],
|
||||||
@@ -127,30 +317,63 @@ class HTS_etf(HTS):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def makeTickData1(self, data, mins=5):
|
||||||
|
result = {
|
||||||
|
"ymd": [],
|
||||||
|
"open": [], "close": [], "high": [], "low": [], "volume": [], "volume_up": [], "volume_down": [], "volume_updown_diff": []
|
||||||
|
}
|
||||||
|
|
||||||
def getLIMITInfo(self, stock_code, ymd, dbfile_name="stock.db"):
|
for i in range(mins, len(data['ymd'])+1):
|
||||||
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, dbfile_name))
|
result["ymd"].append(data['ymd'][i-1])
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
cursor.execute('select ymd, open, close, high, low, volume from stock where code=? order by ymd desc limit ?',
|
result["open"].append(data['open'][i-mins])
|
||||||
(stock_code, 100,))
|
result["close"].append(data['close'][i-1])
|
||||||
db_result = cursor.fetchall()
|
|
||||||
cursor.close()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
match = False
|
result["high"].append(max(data['high'][i - mins: i]))
|
||||||
LIMIT_PRICE = []
|
result["low"].append(min(data['low'][i - mins: i]))
|
||||||
for i, rows in enumerate(db_result):
|
result["volume"].append(sum(data['volume'][i - mins: i]))
|
||||||
if rows[0].replace('.', '') == ymd:
|
|
||||||
match = True
|
|
||||||
if match:
|
|
||||||
LIMIT_PRICE.append(rows[2])
|
|
||||||
|
|
||||||
return {'LOW_PRICE': sum(LIMIT_PRICE[:20]) / len(LIMIT_PRICE[:20])}
|
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 buyRealTime(self, today, analyzed_day=1000, logFp=None, MAX_PRICE=30000):
|
def makeTickData2(self, data, mins=5):
|
||||||
INFO = self.getLIMITInfo(self.stock_code, today)
|
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, today, MAX_PRICE=30000):
|
||||||
|
BUY_LIST = {'buy_count': 0, 'buy_avg': 0, 'buy_list': []}
|
||||||
|
|
||||||
print("START...")
|
print("START...")
|
||||||
THIS_TIME = datetime.now()
|
THIS_TIME = datetime.now()
|
||||||
@@ -160,69 +383,72 @@ class HTS_etf(HTS):
|
|||||||
while datetime.strptime(today + " 063000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100",'%Y%m%d %H%M%S'):
|
while datetime.strptime(today + " 063000", '%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 + " 090100", '%Y%m%d %H%M%S'):
|
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 090100", '%Y%m%d %H%M%S'):
|
||||||
self.bot.sendMsg("START... {} ({}) SLOW_K: {}".format(self.stock_code, self.stock_name, MAX_PRICE))
|
self.bot.sendMsg("START... {} ({}) SLOW_K: {}".format(self.stock_code, self.stock_name, MAX_PRICE))
|
||||||
logFp.write("START {} ({}) SLOW_K: {}\n".format(self.stock_code, self.stock_name, MAX_PRICE))
|
|
||||||
|
|
||||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%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'):
|
||||||
|
|
||||||
# 매도를 체크한다.
|
# 매도를 체크한다.
|
||||||
self.sellStocks(self.stock_code)
|
check = self.sellStocks(self.stock_code)
|
||||||
|
|
||||||
|
buy_avg = self.getBallance(self.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)
|
time.sleep(0.1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 데이터를 가지고 온다.
|
# 데이터를 가지고 온다.
|
||||||
result = self.getRealTime(self.stock_code, today, LAST_DATA)
|
result_m1 = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||||
except:
|
except:
|
||||||
print("#ERROR:", self.stock_code)
|
print("#ERROR:", self.stock_code)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
data = self.buySellChecker.analyze(result)
|
result_tic_m1 = self.makeTickData1(result_m1, mins=1)
|
||||||
data.drop(data.index[:len(data) - analyzed_day], inplace=True)
|
data = self.buySellChecker.analyze(result_tic_m1)
|
||||||
|
result_tic_m30 = self.makeTickData2(result_tic_m1, mins=30)
|
||||||
|
data_signal = self.buySellChecker.analyze(result_tic_m30)
|
||||||
|
|
||||||
|
#data.drop(data.index[:len(data) - analyzed_day], inplace=True)
|
||||||
|
|
||||||
# 사야 할 시점과 팔아야 할 시점을 체크한다.
|
# 사야 할 시점과 팔아야 할 시점을 체크한다.
|
||||||
bsLine = self.buySellChecker.checkTransaction(self.stock_code, data, INFO, isRealTime=True)
|
bsLine1 = self.buySellChecker.checkTransaction1(self.stock_code, MAX_PRICE, data, data_signal, BUY_LIST, isRealTime=True)
|
||||||
bs_buy_price = bsLine['buy'][0]
|
|
||||||
bs_buy_weight = bsLine['buy_weight'][0]
|
if 'sell_price' in bsLine1:
|
||||||
bs_sell_price = bsLine['sell'][0]
|
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(self.stock_code, sell_price)
|
||||||
|
if check:
|
||||||
|
self.orderChecker.sell(datetime.today().strftime('%Y%m%d'), self.stock_code)
|
||||||
|
BUY_LIST['buy_avg'] = 0
|
||||||
|
BUY_LIST['buy_count'] = 0
|
||||||
|
BUY_LIST['buy_list'].clear()
|
||||||
|
self.bot.sendMsg( "Profit {:.2f}, {} ({})".format(amount * (profit_rate - 1), self.stock_code, self.stock_name))
|
||||||
|
|
||||||
|
if 'buy_price' in bsLine1:
|
||||||
|
buy_price = bsLine1['buy_price'][-1]
|
||||||
|
buy_count = bsLine1['buy_count'][-1]
|
||||||
|
if buy_price > 0:
|
||||||
|
# 매수를 요청 한다.
|
||||||
|
amount = buy_price * buy_count
|
||||||
|
orderNum = self.requestOrder(OrderType.buy, self.stock_code, buy_count, buy_price)
|
||||||
|
self.orderChecker.buy(today, "A" + self.stock_code, buy_count, buy_price, orderNum)
|
||||||
|
|
||||||
|
self.orderChecker.buy(datetime.today().strftime('%Y%m%d'), self.stock_code, buy_count, buy_price)
|
||||||
|
self.bot.post(self.stock_code, self.stock_name, "[BUY] ", buy_price, buy_count, data['rsi'][-1], -1)
|
||||||
|
|
||||||
# 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다.
|
# 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다.
|
||||||
ORDER_LIST = self.requestOrderList()
|
#ORDER_LIST = self.requestOrderList()
|
||||||
orderListToCancel = self.orderChecker.cancel(today, "A" + self.stock_code, ORDER_LIST, mins=10)
|
#orderListToCancel = self.orderChecker.cancel(today, "A" + self.stock_code, ORDER_LIST, mins=10)
|
||||||
if len(orderListToCancel) > 0:
|
#if len(orderListToCancel) > 0:
|
||||||
self.cancelOrderList(orderListToCancel)
|
# self.cancelOrderList(orderListToCancel)
|
||||||
|
|
||||||
if bs_buy_price > 1000:
|
|
||||||
|
|
||||||
#if not self.orderChecker.exist(today, "A" + self.stock_code, hours=9):
|
|
||||||
buy_count = int(MAX_PRICE / bs_buy_price)
|
|
||||||
|
|
||||||
if buy_count > 0:
|
|
||||||
# 매수를 주문한다.
|
|
||||||
orderNum = self.requestOrder(OrderType.buy, self.stock_code, buy_count, bs_buy_price)
|
|
||||||
self.orderChecker.buy(today, "A" + self.stock_code, buy_count, bs_buy_price, orderNum)
|
|
||||||
|
|
||||||
# 로그 출력
|
|
||||||
print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, self.stock_code, bs_buy_price, buy_count)
|
|
||||||
logFp.write("{} BUY {} {} {}\n".format(THIS_TIME.strftime('%Y%m%d %H%M%S'), self.stock_code, bs_buy_price, buy_count))
|
|
||||||
|
|
||||||
if bs_sell_price > 1000:
|
|
||||||
check = self.sellStocks(self.stock_code, bs_sell_price)
|
|
||||||
|
|
||||||
if check:
|
|
||||||
# 로그 출력
|
|
||||||
print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), self.stock_code, self.stock_name, bs_sell_price)
|
|
||||||
logFp.write("{} SELL {} {} {}\n".format(THIS_TIME.strftime('%Y%m%d %H%M%S'), self.stock_code, bs_buy_price, bs_sell_price))
|
|
||||||
|
|
||||||
# 로그 출력
|
|
||||||
print("TIMECHECK: %s, code: %s, buy: %d, sell: %d, open: %d, close: %d, high: %d, low: %d, macd: %.2f" %
|
|
||||||
(str(THIS_TIME), self.stock_code, bs_buy_price, bs_sell_price, data["open"][len(data["open"])-1], data["close"][len(data["close"])-1], data["high"][len(data["high"])-1], data["low"][len(data["low"])-1], data["macd"][len(data["macd"])-1]))
|
|
||||||
logFp.write("TIMECHECK: %s, code: %s, buy: %d, sell: %d, open: %d, close: %d, high: %d, low: %d, macd: %.2f\n" %
|
|
||||||
(str(THIS_TIME), self.stock_code, bs_buy_price, bs_sell_price, data["open"][len(data["open"])-1], data["close"][len(data["close"])-1], data["high"][len(data["high"])-1], data["low"][len(data["low"])-1], data["macd"][len(data["macd"])-1]))
|
|
||||||
|
|
||||||
if (int(THIS_TIME.strftime("%M")) % 50 == 0 or int(THIS_TIME.strftime("%M")) % 20 == 0):
|
if (int(THIS_TIME.strftime("%M")) % 50 == 0 or int(THIS_TIME.strftime("%M")) % 20 == 0):
|
||||||
self.bot.alarm_live(self.stock_code, self.stock_name, data["close"][len(data["close"])-1], data["macd"][len(data["macd"])-1])
|
self.bot.alarm_live(self.stock_code, self.stock_name, data["close"][len(data["close"])-1], data["macd"][len(data["macd"])-1])
|
||||||
|
|
||||||
logFp.flush()
|
|
||||||
time.sleep(60)
|
time.sleep(60)
|
||||||
THIS_TIME = datetime.now()
|
THIS_TIME = datetime.now()
|
||||||
|
|
||||||
|
|||||||
@@ -19,11 +19,9 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
||||||
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
||||||
logFp = open(os.path.join(RESOURCE_PATH, "log", today_str + "_" + stock_code + ".log"), "w", encoding='utf-8')
|
|
||||||
|
|
||||||
MAX_PRICE = 30000
|
MAX_PRICE = 300000
|
||||||
hts.buyRealTime(today_str, analyzed_day=1000, logFp=logFp, MAX_PRICE=MAX_PRICE)
|
hts.buyRealTime(today_str, MAX_PRICE=MAX_PRICE)
|
||||||
logFp.close()
|
|
||||||
|
|
||||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||||
hts.insertStockData(today, stock_code, stock_name)
|
hts.insertStockData(today, stock_code, stock_name)
|
||||||
|
|||||||
@@ -19,11 +19,9 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
||||||
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
||||||
logFp = open(os.path.join(RESOURCE_PATH, "log", today_str + "_" + stock_code + ".log"), "w", encoding='utf-8')
|
|
||||||
|
|
||||||
MAX_PRICE = 30000
|
MAX_PRICE = 300000
|
||||||
hts.buyRealTime(today_str, analyzed_day=1000, logFp=logFp, MAX_PRICE=MAX_PRICE)
|
hts.buyRealTime(today_str, MAX_PRICE=MAX_PRICE)
|
||||||
logFp.close()
|
|
||||||
|
|
||||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||||
hts.insertStockData(today, stock_code, stock_name)
|
hts.insertStockData(today, stock_code, stock_name)
|
||||||
|
|||||||
@@ -19,11 +19,9 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
||||||
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
||||||
logFp = open(os.path.join(RESOURCE_PATH, "log", today_str + "_" + stock_code + ".log"), "w", encoding='utf-8')
|
|
||||||
|
|
||||||
MAX_PRICE = 30000
|
MAX_PRICE = 300000
|
||||||
hts.buyRealTime(today_str, analyzed_day=1000, logFp=logFp, MAX_PRICE=MAX_PRICE)
|
hts.buyRealTime(today_str, MAX_PRICE=MAX_PRICE)
|
||||||
logFp.close()
|
|
||||||
|
|
||||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||||
hts.insertStockData(today, stock_code, stock_name)
|
hts.insertStockData(today, stock_code, stock_name)
|
||||||
|
|||||||
@@ -19,11 +19,9 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
||||||
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
||||||
logFp = open(os.path.join(RESOURCE_PATH, "log", today_str + "_" + stock_code + ".log"), "w", encoding='utf-8')
|
|
||||||
|
|
||||||
MAX_PRICE = 30000
|
MAX_PRICE = 300000
|
||||||
hts.buyRealTime(today_str, analyzed_day=1000, logFp=logFp, MAX_PRICE=MAX_PRICE)
|
hts.buyRealTime(today_str, MAX_PRICE=MAX_PRICE)
|
||||||
logFp.close()
|
|
||||||
|
|
||||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||||
hts.insertStockData(today, stock_code, stock_name)
|
hts.insertStockData(today, stock_code, stock_name)
|
||||||
|
|||||||
@@ -1,144 +1,211 @@
|
|||||||
import pandas as pd
|
import os
|
||||||
|
from dtw import dtw
|
||||||
|
import json
|
||||||
|
import sqlite3
|
||||||
|
import numpy as np
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from stock.analysis.Common import Common
|
class BuySellChecker():
|
||||||
from stock.analysis.Stochastic import Stochastic
|
|
||||||
from stock.analysis.RSI import RSI
|
|
||||||
from stock.analysis.MACD import MACD
|
|
||||||
from stock.analysis.IchimokuCloud import IchimokuCloud
|
|
||||||
|
|
||||||
|
PATTERNS = None
|
||||||
|
RESOURCE_PATH = None
|
||||||
|
|
||||||
class BuySellChecker:
|
def __init__(self, RESOURCE_PATH, ticker):
|
||||||
common = None
|
self.RESOURCE_PATH = RESOURCE_PATH
|
||||||
stochastic = None
|
self.readBuyPattern(RESOURCE_PATH, ticker)
|
||||||
rsi = None
|
|
||||||
macd = None
|
|
||||||
ichimokuCloud = None
|
|
||||||
|
|
||||||
BUY_COUNT = None
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.common = Common()
|
|
||||||
self.stochastic = Stochastic()
|
|
||||||
self.rsi = RSI()
|
|
||||||
self.macd = MACD()
|
|
||||||
self.ichimokuCloud = IchimokuCloud()
|
|
||||||
|
|
||||||
self.BUY_COUNT = 0
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def getBuyPriceAndWeight(self, i, data):
|
def readBuyPattern(self, RESOURCE_PATH, ticker):
|
||||||
buy, weight, type = -1, -1, ""
|
with open(os.path.join(RESOURCE_PATH, "buy_pattern_data.json"), 'r') as f:
|
||||||
|
PATTERNS = json.load(f)
|
||||||
|
|
||||||
|
self.PATTERNS = {'min_max': [], 'stndardization': []}
|
||||||
|
for key in PATTERNS:
|
||||||
|
for min_max in PATTERNS[key]['min_max']:
|
||||||
|
self.PATTERNS['min_max'].append(min_max)
|
||||||
|
for stndardization in PATTERNS[key]['stndardization']:
|
||||||
|
self.PATTERNS['stndardization'].append(stndardization)
|
||||||
|
return
|
||||||
|
|
||||||
|
def nearDisparity(self, data, i):
|
||||||
|
if (0.998 < data['disparity_avg5'][i] < 1.002 and
|
||||||
|
0.998 < data['disparity_avg5'][i] < 1.002 and
|
||||||
|
0.998 < data['disparity_avg5'][i] < 1.002 and
|
||||||
|
0.998 < data['disparity_avg5'][i] < 1.002 and
|
||||||
|
0.998 < data['disparity_avg5'][i] < 1.002):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def cosine_similarity(self, x, y):
|
||||||
|
return np.dot(x, y) / (np.sqrt(np.dot(x, x)) * np.sqrt(np.dot(y, y)))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# 매수전략 #1: 다이버전스
|
def findBuyPoint(self, data, data_signal, i):
|
||||||
if data['macd'][i] < 0 and data['open'][i] < data['close'][i]:
|
# 코사인 유사도(cosine similarity)로 과거 주가의 유사 패턴을 찾아 미래 예측하기
|
||||||
if 0 < len(data['rsi'].tolist()[i - 10:i - 5]):
|
# https://teddylee777.github.io/pandas/cos-sim-stock/
|
||||||
if min(data['rsi'].tolist()[i - 10:i - 5]) < data['rsi'][i - 1]:
|
|
||||||
if data['low'][i - 1] < min(data['low'].tolist()[i - 10:i - 5]):
|
buy_target = data['close'].iloc[i-179:i+1]
|
||||||
weight = 1
|
window_size = len(buy_target)
|
||||||
buy = data['close'][i]
|
if window_size == 180:
|
||||||
type = 'Divergence'
|
buy_target = (buy_target - buy_target.min()) / (buy_target.max() - buy_target.min())
|
||||||
|
for pattern in self.PATTERNS:
|
||||||
|
cos_similarity = self.cosine_similarity(pattern, buy_target)
|
||||||
|
if 0.995 < cos_similarity:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
high_barrier = 70
|
def findBuyPoint(self, data, i):
|
||||||
low_barrier = 30
|
# DTW (Dynamic Time Warping)
|
||||||
Buy_Price=[]
|
# 시계열 유사도: https://m.blog.naver.com/happyrachy/221693939341
|
||||||
Sell_Price=[]
|
if i < 24:
|
||||||
number=[]
|
return False
|
||||||
temp01 = []
|
|
||||||
temp01_id = []
|
|
||||||
temp02 = []
|
|
||||||
temp01_id = []
|
|
||||||
temp01_min_price = []
|
|
||||||
temp02_min_price = []
|
|
||||||
temp01_min_rsi = []
|
|
||||||
temp02_min_rsi = []
|
|
||||||
n_id=[]
|
|
||||||
i_id=[]
|
|
||||||
flag=1
|
|
||||||
n = 0
|
|
||||||
|
|
||||||
# https://superhky.tistory.com/441
|
for p in range(len(self.PATTERNS['min_max'])):
|
||||||
find = False
|
size = len(self.PATTERNS['stndardization'][p])
|
||||||
for c in range(i-40, i-1):
|
if i - size + 1 < 0:
|
||||||
if data['rsi'][i-1] > low_barrier and data['rsi'][i] < low_barrier:
|
continue
|
||||||
for k in range(c, i):
|
|
||||||
if data['rsi'][k-1] < low_barrier and data['rsi'][k] > low_barrier:
|
|
||||||
temp01 = data['rsi'].iloc[c:k]
|
|
||||||
temp01_id = temp01.argmin() + c
|
|
||||||
temp01_min_rsi = data['rsi'][temp01_id]
|
|
||||||
temp01_min_price = data['close'][temp01_id]
|
|
||||||
|
|
||||||
for m in range(k, i):
|
close = data['close'].iloc[i-size+1:i+1]
|
||||||
if data['rsi'][m-1] < low_barrier and data['rsi'][m] < low_barrier:
|
|
||||||
for n in range(m, i):
|
|
||||||
if data['rsi]'][n-1] < low_barrier and data['rsi'][n] < low_barrier:
|
|
||||||
temp02 = data['rsi'].iloc[m:n]
|
|
||||||
temp02_id = temp02.argmin() + m
|
|
||||||
temp02_min_rsi = data['rsi'][temp02_id]
|
|
||||||
temp02_min_price = data['close'][temp02_id]
|
|
||||||
|
|
||||||
if temp01_min_rsi < temp02_min_rsi and temp01_min_price > temp02_min_price and flag == 1:
|
#min_max = np.array(self.PATTERNS['min_max'][p]).reshape(-1, 1)
|
||||||
if c == i-1:
|
stndardization = np.array(self.PATTERNS['stndardization'][p]).reshape(-1, 1)
|
||||||
weight = 1
|
|
||||||
buy = data['close'][i]
|
|
||||||
type = 'Divergence'
|
|
||||||
find = True
|
|
||||||
break
|
|
||||||
if find: break
|
|
||||||
if find: break
|
|
||||||
if find: break
|
|
||||||
"""
|
|
||||||
# 매수전략 #3: stochastic + rsi + macd
|
|
||||||
check = False
|
|
||||||
if data['slow_k'][i - 1] < data['slow_k'][i] and data['slow_d'][i] < data['slow_k'][i]:
|
|
||||||
|
|
||||||
# 과매도 체크
|
#min_max_y = np.array((close - close.min()) / (close.max() - close.min())).reshape(-1, 1)
|
||||||
index = -1
|
stndardization_y = np.array((close - close.mean()) / close.std()).reshape(-1, 1)
|
||||||
for c in range(i - 40, i):
|
|
||||||
if data['slow_k'][i] < 20:
|
#manhattan_distance = lambda min_max, min_max_y: np.abs(min_max - min_max_y)
|
||||||
index = c
|
#min_max_d, cost_matrix, acc_cost_matrix, path = dtw(min_max, min_max_y, dist=manhattan_distance)
|
||||||
check = True
|
|
||||||
if check:
|
manhattan_distance = lambda stndardization, stndardization_y: np.abs(stndardization - stndardization_y)
|
||||||
# 과매도 후 과매수 였는지 체크
|
stndardization_d, cost_matrix, acc_cost_matrix, path = dtw(stndardization, stndardization_y, dist=manhattan_distance)
|
||||||
check = False
|
|
||||||
for d in range(index, i):
|
if stndardization_d < 2:
|
||||||
if 80 < data['slow_k'][d]:
|
#print(i, data['ymd'].iloc[i], stndardization_d)
|
||||||
check = True
|
return True
|
||||||
break
|
return False
|
||||||
if not check:
|
|
||||||
# 과매도 후 과매수가 아니라면
|
def getMacd(self, ticker_code, day, mins=1):
|
||||||
if data['rsi'][i - 1] < 50 and 50 < data['rsi'][i]:
|
|
||||||
if data['macds'][i] < data['macd'][i] < 0:
|
table = 'minutely_max_macd_' + str(mins)
|
||||||
weight = 1
|
|
||||||
buy = data['close'][i]
|
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, 'coins.db'))
|
||||||
type = 'S+R+M'
|
cursor = conn.cursor()
|
||||||
"""
|
|
||||||
return buy, weight, type
|
day1 = (datetime.strptime(day, '%Y%m%d') - timedelta(1)).strftime('%Y%m%d')
|
||||||
|
cursor.execute('SELECT ymd, hms, macd, close FROM '+table+' WHERE (CODE=? or CODE=?) and (ymd=? or ymd=?) order by macd desc', (ticker_code, ticker_code.replace('KRW-', ''), day, day1, ))
|
||||||
|
db_result1 = cursor.fetchall()
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
macd_limit = [(datetime.strptime(rows[0]+" "+rows[1], '%Y%m%d %H%M%S'), rows[2], rows[3]) for rows in db_result1]
|
||||||
|
macd_dup = list(set(macd_limit))
|
||||||
|
return macd_dup
|
||||||
|
|
||||||
|
def getBuyPriceAndWeight1(self, ticker, MAX_BUY_PRICE, i, data, data_signal, BUY_LIST, isRealTime=True):
|
||||||
|
buy_ymd, buy_price, buy_count, buy_cut, buy_type = None, -1, -1, -1, ''
|
||||||
|
|
||||||
|
df_tmp = data_signal['ymd'] <= data['ymd'][i]
|
||||||
|
df_signal = data_signal.loc[df_tmp]
|
||||||
|
si = len(df_signal) - 1
|
||||||
|
|
||||||
|
if isRealTime:
|
||||||
|
macds = data['macd'][i-300:i].to_list()
|
||||||
|
if 0 < len(macds):
|
||||||
|
macds_max = max(macds)
|
||||||
|
mi = i-300 + macds.index(macds_max)
|
||||||
|
|
||||||
|
if data['macd'][i] < macds_max and data['close'][mi] < data['close'][i]:
|
||||||
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
|
else:
|
||||||
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
|
else:
|
||||||
|
macds = self.getMacd(ticker['ticker_code'], data['ymd'][i].strftime('%Y%m%d'), mins=1)
|
||||||
|
if len(macds) == 0:
|
||||||
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
|
|
||||||
|
macds_sort = sorted(macds, key=lambda x:x[0], reverse=True)
|
||||||
|
if data['macd'][i] < macds_sort[0][1] and macds_sort[0][2] < data['close'][i]:
|
||||||
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
|
|
||||||
|
duration = 3
|
||||||
|
if sum(data['trend_avg'][i - duration:i]) / duration < data['trend_avg'][i]:
|
||||||
|
# 상승 트렌드
|
||||||
|
if data_signal['avg20'][si] < data_signal['avg5'][si]:
|
||||||
|
# 방법 1:
|
||||||
|
if max(data['volume_up'][i-180:i]) < data['volume_up'][i]:
|
||||||
|
if data_signal['slow_k'][si] < 70:
|
||||||
|
if BUY_LIST is not None and 0 < len(BUY_LIST['buy_list']) and BUY_LIST['buy_list'][-1]['buy_price'] < data['close'][i]:
|
||||||
|
buy_price = data['close'][i]
|
||||||
|
buy_type = 'volume_up'
|
||||||
|
buy_ymd = data['ymd'][i]
|
||||||
|
if data['slow_k'][si] < 30:
|
||||||
|
buy_count = MAX_BUY_PRICE / (1 * data['close'][i])
|
||||||
|
elif data['slow_k'][si] < 50:
|
||||||
|
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||||
|
else:
|
||||||
|
buy_count = MAX_BUY_PRICE / (3 * data['close'][i])
|
||||||
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
|
else:
|
||||||
|
buy_price = data['close'][i]
|
||||||
|
buy_type = 'volume_up'
|
||||||
|
buy_ymd = data['ymd'][i]
|
||||||
|
if data['slow_k'][si] < 30:
|
||||||
|
buy_count = MAX_BUY_PRICE / (1 * data['close'][i])
|
||||||
|
elif data['slow_k'][si] < 50:
|
||||||
|
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||||
|
else:
|
||||||
|
buy_count = MAX_BUY_PRICE / (3 * data['close'][i])
|
||||||
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
|
|
||||||
|
# 방법 2:
|
||||||
|
if data['avg480'][i] < data['avg120'][i] < data['avg60'][i] < data['avg20'][i] < data['avg5'][i] < data['close'][i]:
|
||||||
|
if data['avg240'][i] < min(data['avg5'][i], data['avg20'][i], data['avg60'][i], data['avg120'][i]):
|
||||||
|
if BUY_LIST is not None and 0 < len(BUY_LIST['buy_list']) and data['ymd'][i] < BUY_LIST['buy_list'][-1]['buy_ymd'] + timedelta(minutes=10):
|
||||||
|
if BUY_LIST['buy_list'][-1]['buy_price'] < data['close'][i]:
|
||||||
|
buy_price = data['close'][i]
|
||||||
|
buy_type = 'golden'
|
||||||
|
buy_ymd = data['ymd'][i]
|
||||||
|
if data['slow_k'][si] < 30:
|
||||||
|
buy_count = MAX_BUY_PRICE / (1 * data['close'][i])
|
||||||
|
elif data['slow_k'][si] < 50:
|
||||||
|
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||||
|
else:
|
||||||
|
buy_count = MAX_BUY_PRICE / (3 * data['close'][i])
|
||||||
|
else:
|
||||||
|
buy_price = data['close'][i]
|
||||||
|
buy_type = 'golden'
|
||||||
|
buy_ymd = data['ymd'][i]
|
||||||
|
if data['slow_k'][si] < 30:
|
||||||
|
buy_count = MAX_BUY_PRICE / (1 * data['close'][i])
|
||||||
|
elif data['slow_k'][si] < 50:
|
||||||
|
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||||
|
else:
|
||||||
|
buy_count = MAX_BUY_PRICE / (3 * data['close'][i])
|
||||||
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
|
|
||||||
|
|
||||||
def getSellPriceAndWeight(self, i, data):
|
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||||
sell, weight, type = -1, -1, ""
|
|
||||||
|
|
||||||
max_value = max(data['macd'].tolist()) * 0.8
|
def getSellPriceAndWeight1(self, ticker, i, data, data_signal, BUY_LIST=None):
|
||||||
if (max_value < data['macd'][i] or 1.9 < data['macds'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0):
|
sell_price, sell_count = -1, -1
|
||||||
#if data['macds'][i-1] < data['macd'][i-1] and data['macd'][i] < data['macds'][i]:
|
|
||||||
weight = 1
|
|
||||||
sell = data['close'][i]
|
|
||||||
type = 'method1'
|
|
||||||
|
|
||||||
# 매수전략 #2: RSI 과매수에서 데드크로스
|
if BUY_LIST is not None and 0 < len(BUY_LIST['buy_list']):
|
||||||
if (data['macds'][i - 1] < data['macd'][i - 1] and data['macd'][i] < data['macds'][i]):
|
# 방법1에 대해서는 1% 이익시 매도 한다. (Upbit.py 파일에서)
|
||||||
if 70 < data['rsi'][i]:
|
|
||||||
weight = 1
|
|
||||||
sell = data['close'][i]
|
|
||||||
type = 'method2'
|
|
||||||
|
|
||||||
|
# 방법2에 대한 매도
|
||||||
|
if data['close'][i-1] < data['open'][i-1] and data['close'][i] < data['open'][i]:
|
||||||
|
count = sum([price['buy_count'] for price in BUY_LIST['buy_list'] if price['buy_type'] == 'golden'])
|
||||||
|
if 0 < count:
|
||||||
|
sell_price = data['close'][i]
|
||||||
|
sell_count = sum([price['buy_count'] for price in BUY_LIST['buy_list']])
|
||||||
|
|
||||||
return sell, weight, type
|
return sell_price, sell_count
|
||||||
|
|
||||||
|
def checkTransaction1(self, ticker, MAX_BUY_PRICE, data, data_signal, BUY_LIST=None, isRealTime=True):
|
||||||
|
|
||||||
def checkTransaction(self, data, isRealTime=True):
|
|
||||||
# 어제 오늘 데이터로 분석
|
# 어제 오늘 데이터로 분석
|
||||||
bsLine = {}
|
bsLine = {}
|
||||||
|
|
||||||
@@ -149,150 +216,52 @@ class BuySellChecker:
|
|||||||
# isRealTime=True, 실시간 적용
|
# isRealTime=True, 실시간 적용
|
||||||
last_index = size - 1
|
last_index = size - 1
|
||||||
|
|
||||||
buy, buy_weight, buy_type = self.getBuyPriceAndWeight(last_index, data)
|
sell_price, sell_weight = self.getSellPriceAndWeight1(ticker, last_index, data, data_signal, BUY_LIST)
|
||||||
sell, sell_weight, sell_type = self.getSellPriceAndWeight(last_index, data)
|
bsLine['sell_price'] = [sell_price]
|
||||||
|
|
||||||
bsLine['buy'] = [buy]
|
|
||||||
bsLine['buy_weight'] = [buy_weight]
|
|
||||||
bsLine['buy_type'] = [buy_type]
|
|
||||||
bsLine['sell'] = [sell]
|
|
||||||
bsLine['sell_weight'] = [sell_weight]
|
bsLine['sell_weight'] = [sell_weight]
|
||||||
bsLine['sell_type'] = [sell_type]
|
|
||||||
|
|
||||||
|
buy_ymd, buy_price, buy_count, buy_cut, buy_type = self.getBuyPriceAndWeight1(ticker, MAX_BUY_PRICE, last_index, data, data_signal, BUY_LIST, isRealTime)
|
||||||
|
bsLine['buy_ymd'] = [buy_ymd]
|
||||||
|
bsLine['buy_price'] = [buy_price]
|
||||||
|
bsLine['buy_count'] = [buy_count]
|
||||||
|
bsLine['buy_cut'] = [buy_cut]
|
||||||
|
bsLine['buy_type'] = [buy_type]
|
||||||
|
|
||||||
|
if BUY_LIST is not None and 0 < buy_price:
|
||||||
|
BUY_LIST['buy_list'].append({'buy_ymd': buy_ymd, 'buy_price': buy_price, 'buy_count': buy_count, 'buy_cut': buy_cut, 'buy_type': buy_type})
|
||||||
else:
|
else:
|
||||||
# Type=False, 시뮬레이션 적용
|
# Type=False, 시뮬레이션 적용
|
||||||
bsLine['buy'] = [-1 for i in range(size)]
|
bsLine['buy_ymd'] = [-1 for i in range(size)]
|
||||||
bsLine['buy_weight'] = [-1 for i in range(size)]
|
bsLine['buy_price'] = [-1 for i in range(size)]
|
||||||
|
bsLine['buy_count'] = [-1 for i in range(size)]
|
||||||
|
bsLine['buy_cut'] = [-1 for i in range(size)]
|
||||||
bsLine['buy_type'] = ['' for i in range(size)]
|
bsLine['buy_type'] = ['' for i in range(size)]
|
||||||
bsLine['sell'] = [-1 for i in range(size)]
|
bsLine['sell_price'] = [-1 for i in range(size)]
|
||||||
bsLine['sell_weight'] = [-1 for i in range(size)]
|
bsLine['sell_weight'] = [-1 for i in range(size)]
|
||||||
bsLine['sell_type'] = ['' for i in range(size)]
|
|
||||||
|
|
||||||
for last_index in range(size):
|
for last_index in range(size):
|
||||||
buy, buy_weight, buy_type = self.getBuyPriceAndWeight(last_index, data)
|
|
||||||
sell, sell_weight, sell_type = self.getSellPriceAndWeight(last_index, data)
|
sell_price, sell_weight = self.getSellPriceAndWeight1(ticker, last_index, data, data_signal, BUY_LIST)
|
||||||
bsLine['buy'][last_index] = buy
|
bsLine['sell_price'][last_index] = sell_price
|
||||||
bsLine['buy_weight'][last_index] = buy_weight
|
bsLine['sell_weight'][last_index] = sell_weight
|
||||||
|
|
||||||
|
if sell_price < 0:
|
||||||
|
buy_ymd, buy_price, buy_count, buy_cut, buy_type = self.getBuyPriceAndWeight1(ticker, MAX_BUY_PRICE, last_index, data, data_signal, BUY_LIST, isRealTime)
|
||||||
|
bsLine['buy_price'][last_index] = buy_price
|
||||||
|
bsLine['buy_count'][last_index] = buy_count
|
||||||
|
bsLine['buy_cut'][last_index] = buy_cut
|
||||||
bsLine['buy_type'][last_index] = buy_type
|
bsLine['buy_type'][last_index] = buy_type
|
||||||
|
|
||||||
bsLine['sell'][last_index] = sell
|
if BUY_LIST is not None and 0 < buy_price:
|
||||||
bsLine['sell_weight'][last_index] = sell_weight
|
BUY_LIST['buy_list'].append({'buy_ymd': buy_ymd, 'buy_price': buy_price, 'buy_count': buy_count, 'buy_cut': buy_cut, 'buy_type': buy_type})
|
||||||
bsLine['sell_type'][last_index] = sell_type
|
|
||||||
else:
|
else:
|
||||||
bsLine['buy'] = [-1]
|
bsLine['buy_price'] = [-1]
|
||||||
bsLine['buy_weight'] = [-1]
|
bsLine['buy_count'] = [-1]
|
||||||
|
bsLine['buy_cut'] = [-1]
|
||||||
bsLine['buy_type'] = ['']
|
bsLine['buy_type'] = ['']
|
||||||
bsLine['sell'] = [-1]
|
bsLine['sell_price'] = [-1]
|
||||||
bsLine['sell_weight'] = [-1]
|
bsLine['sell_weight'] = [-1]
|
||||||
bsLine['sell_type'] = ['']
|
|
||||||
|
|
||||||
return bsLine
|
return bsLine
|
||||||
|
|
||||||
|
|
||||||
def analyze(self, result):
|
|
||||||
# 기본 캔들 정보
|
|
||||||
open = result["open"]
|
|
||||||
close = result["close"]
|
|
||||||
high = result["high"]
|
|
||||||
low = result["low"]
|
|
||||||
vol = result["vol"]
|
|
||||||
|
|
||||||
# 이동 평균
|
|
||||||
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]
|
|
||||||
avg200_list = close_df.rolling(window=200).mean().fillna(close[0]).values.tolist()
|
|
||||||
avg200 = [item[0] for item in avg200_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_avg200_list = (open_df / close_df.rolling(window=200).mean()).values.tolist()
|
|
||||||
disparity_avg200 = [item[0] for item in disparity_avg200_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],
|
|
||||||
'avg5': avg5[i], 'avg20': avg20[i], 'avg30': avg30[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg200': avg200[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()
|
|
||||||
|
|
||||||
# 결과
|
|
||||||
temp = {
|
|
||||||
"date": point_temp,
|
|
||||||
"open": open, "high": high, "low": low, "close": close, "volume": vol,
|
|
||||||
"avg5": avg5, "avg20": avg20, "avg30": avg30, "avg60": avg60, "avg120": avg120, "avg200": avg200,
|
|
||||||
"disparity_avg5": disparity_avg5, "disparity_avg20": disparity_avg20, "disparity_avg30": disparity_avg30,
|
|
||||||
"disparity_avg60": disparity_avg60, "disparity_avg120": disparity_avg120, "disparity_avg200": disparity_avg200,
|
|
||||||
"upper": upper, "lower": lower,
|
|
||||||
"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
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import telegram
|
import telegram
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import platform
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
|
|
||||||
class TelegramBot:
|
class TelegramBot:
|
||||||
@@ -23,9 +24,9 @@ class TelegramBot:
|
|||||||
username for the bot: ncue_stock_bot
|
username for the bot: ncue_stock_bot
|
||||||
token to access the HTTP API: 6874078562:AAEHxGDavfc0ssAXPQIaW8JGYmTR7LNUJOw
|
token to access the HTTP API: 6874078562:AAEHxGDavfc0ssAXPQIaW8JGYmTR7LNUJOw
|
||||||
"""
|
"""
|
||||||
self.botname = "stockbot"
|
self.botname = "coinbot"
|
||||||
self.username = "ncue_stock_bot"
|
self.username = "ncue_coin_bot"
|
||||||
self.token = "6874078562:AAEHxGDavfc0ssAXPQIaW8JGYmTR7LNUJOw"
|
self.token = "6435061393:AAHOh9wB5yGNGUdb3SfCYJrrWTBe7wgConM"
|
||||||
self.chat_id = '574661323'
|
self.chat_id = '574661323'
|
||||||
self.client = telegram.Bot(token=self.token)
|
self.client = telegram.Bot(token=self.token)
|
||||||
|
|
||||||
@@ -36,25 +37,29 @@ class TelegramBot:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def send(text):
|
def send(text):
|
||||||
client = telegram.Bot(token="6874078562:AAEHxGDavfc0ssAXPQIaW8JGYmTR7LNUJOw")
|
client = telegram.Bot(token="6435061393:AAHOh9wB5yGNGUdb3SfCYJrrWTBe7wgConM")
|
||||||
#client.sendMessage(chat_id='574661323', text=text)
|
if platform.system().lower() == 'windows':
|
||||||
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||||
asyncio.run(client.send_message(chat_id='574661323', text=text))
|
asyncio.run(client.send_message(chat_id='574661323', text=text))
|
||||||
return
|
return
|
||||||
|
|
||||||
def alarm_live(self, stock_code, stock_name):
|
def alarm_live(self, stock_code, stock_name):
|
||||||
if self.enable:
|
if self.enable:
|
||||||
this_time = datetime.now()
|
this_time = datetime.now()
|
||||||
text = "ALIVE (" + this_time.strftime('%Y-%m-%d %H:%M:%S') + ") " + stock_code + "(" + stock_name +")"
|
text = "[ALIVE] {} {} ({})".format(this_time.strftime('%H:%M'), stock_code, stock_name)
|
||||||
pool = Pool(12)
|
pool = Pool(12)
|
||||||
pool.map(self.send, [text])
|
pool.map(self.send, [text])
|
||||||
print(text)
|
print(text)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def post(self, stock_code, stock_name, type, price, count):
|
def post(self, stock_code, stock_name, type, price, amount, rsi, balance=0):
|
||||||
if self.enable:
|
if self.enable:
|
||||||
this_time = datetime.now()
|
this_time = datetime.now()
|
||||||
text = "DATE TIME:" + this_time.strftime('%Y-%m-%d %H:%M:%S') + ", " + "stock_code:" + stock_code + ", " + "stock_name:" + stock_name + ", " + "type:" + type + ", " + "price:" + str(price) + ", " + "count:" + str(count)
|
if 0 < balance:
|
||||||
|
text = "{}, {}, code: {}, name: {}, price: {}, amount: {}, (balance: {:2f}), (rsi: {:2f})".format(type, this_time.strftime('%H:%M'), stock_code, stock_name, price, amount, balance, rsi)
|
||||||
|
else:
|
||||||
|
text = "{}, {}, code: {}, name: {}, price: {}, amount: {}, (rsi: {:2f})".format(type, this_time.strftime('%H:%M'), stock_code, stock_name, price, amount, rsi)
|
||||||
pool = Pool(12)
|
pool = Pool(12)
|
||||||
pool.map(self.send, [text])
|
pool.map(self.send, [text])
|
||||||
print(text)
|
print(text)
|
||||||
@@ -63,7 +68,7 @@ class TelegramBot:
|
|||||||
def sendMsg(self, msg):
|
def sendMsg(self, msg):
|
||||||
if self.enable:
|
if self.enable:
|
||||||
this_time = datetime.now()
|
this_time = datetime.now()
|
||||||
text = "DATE TIME:" + this_time.strftime('%Y-%m-%d %H:%M:%S') + ", " + "msg:" + msg
|
text = "{}: {}".format(this_time.strftime('%H:%M'), msg)
|
||||||
pool = Pool(12)
|
pool = Pool(12)
|
||||||
pool.map(self.send, [text])
|
pool.map(self.send, [text])
|
||||||
print(text)
|
print(text)
|
||||||
@@ -76,10 +81,9 @@ if __name__ == "__main__":
|
|||||||
stock_name = "x2"
|
stock_name = "x2"
|
||||||
type = "BUY"
|
type = "BUY"
|
||||||
price = 2000
|
price = 2000
|
||||||
count = 2
|
|
||||||
|
|
||||||
telegramBot = TelegramBot()
|
telegramBot = TelegramBot()
|
||||||
telegramBot.alarm_live(stock_code, stock_name)
|
telegramBot.alarm_live(stock_code, stock_name)
|
||||||
telegramBot.post(stock_code, stock_name, type, price, count)
|
telegramBot.post(stock_code, stock_name, type, price)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user