import numpy as np from math import nan import pandas as pd import plotly.graph_objects as go from plotly import subplots import math import os import json from datetime import datetime, timedelta from Upbit import Upbit from hts.BuySell_Minutely import BuySell_Minutely from JSDPattern_minutely import JSDPattern_minutely class Simulation_minutely: test = None upbit = None buySell_Minutely = None def __init__(self, RESOURCE_PATH): self.test = [] self.upbit = Upbit(RESOURCE_PATH) self.buySell_Minutely = BuySell_Minutely(RESOURCE_PATH) self.jSDPattern = JSDPattern_minutely(RESOURCE_PATH) return def clear_BSLINE(self, BUY_LIST, sell_type=None): if sell_type is None or sell_type == '': BUY_LIST['avg_buy_price'] = 0 BUY_LIST['buy_count'] = 0 BUY_LIST["buy_amount"] = 0 BUY_LIST['buy_list'].clear() else: BUY_LIST['avg_buy_price'] = 0 BUY_LIST['buy_count'] = 0 BUY_LIST["buy_amount"] = 0 tmp_sell_type = sell_type.split(',') for i, buy_list in reversed(list(enumerate(BUY_LIST['buy_list']))): for t_sell_type in tmp_sell_type: if buy_list['buy_type'].strip() == t_sell_type.strip(): del BUY_LIST['buy_list'][i] break return def draw(self, ticker, data, data_scaled, bsLine=None, show=False, info=None): stock_code = ticker['ticker_code'] # 어제 데이터는 지운다. #data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])] buy_price_line, buy_count_line, buy_type, buy_count_line, sell_price_line, sell_count_line, sell_type = [], [], [], [], [], [], [] buy_sell_size, buy_colors, sell_colors, buy_colors = [], [], [], [] if bsLine is not None: buy_price_line = bsLine['buy_price'] buy_count_line = bsLine['buy_count'] sell_price_line = bsLine['sell_price'] sell_count_line = bsLine['sell_count'] buy_type = bsLine['buy_type'] sell_type = bsLine['sell_type'] for i in range(len(data)): if buy_price_line[i] < 1: buy_colors.append("#ffffff") buy_price_line[i] = nan buy_sell_size.append(0) else: buy_colors.append("#0C752E") buy_sell_size.append(14) for i in range(len(data)): if sell_price_line[i] < 1: sell_colors.append("#ffffff") sell_price_line[i] = nan else: sell_colors.append("#00ced1") volume_colors = [] for i in range(len(data)): if data['open'].iloc[i] > data['close'].iloc[i]: volume_colors.append("#FF0000") elif data['open'].iloc[i] < data['close'].iloc[i]: volume_colors.append("#FF0000") else: volume_colors.append("#000000") # 그래프를 설정한다. buy_check, sell_check = None, None if bsLine is not None: buy_text_list, sell_text_list = [], [] for i in range(len(data)): buy_text_list.append( "[{}] {:,}
" "{}, {:,} ({:,.2f})

" "[BASIC]
" " support: {:.2f}, resistance: {:.2f}
" " poly_5: {:.5f}, poly_10: {:.5f}, poly_20: {:.5f}, 6: {:.5f}, poly_120: {:.5f}, poly_240: {:.5f}, poly_480: {:.5f}, poly_720: {:.5f}, poly_1440: {:.5f}
" "[INFO]
" " new_high_7: {:,.2f}, new_high_9: {:,.2f}, new_high_26: {:,.2f}, new_low_7: {:,.2f}, new_low_9: {:,.2f}, new_low_26: {:,.2f}
" .format(data['ymd'].iloc[i].strftime('%Y-%m-%d %H:%M'), data["close"].iloc[i], buy_type[i], buy_price_line[i], buy_price_line[i]*buy_count_line[i], data['support'].iloc[i], data['resistance'].iloc[i], data_scaled['poly_5'].iloc[i], data_scaled['poly_10'].iloc[i], data_scaled['poly_20'].iloc[i], data_scaled['poly_60'].iloc[i], data_scaled['poly_120'].iloc[i], data_scaled['poly_240'].iloc[i], data_scaled['poly_480'].iloc[i], data_scaled['poly_720'].iloc[i], data_scaled['poly_1440'].iloc[i], data['new_high_7'].iloc[i], data['new_high_9'].iloc[i], data['new_high_26'].iloc[i], data['new_low_7'].iloc[i], data['new_low_9'].iloc[i], data['new_low_26'].iloc[i], )) sell_text_list.append( "[{}] {:,}
" "{}, {:,} ({:,.2f})

" "[BASIC]
" " support: {:.2f}, resistance: {:.2f}
" " poly_5: {:.5f}, poly_10: {:.5f}, poly_20: {:.5f}, 6: {:.5f}, poly_120: {:.5f}, poly_240: {:.5f}, poly_480: {:.5f}, poly_720: {:.5f}, poly_1440: {:.5f}
" "[INFO]
" " new_high_7: {:,.2f}, new_high_9: {:,.2f}, new_high_26: {:,.2f}, new_low_7: {:,.2f}, new_low_9: {:,.2f}, new_low_26: {:,.2f}
" .format( data['ymd'].iloc[i].strftime('%Y-%m-%d %H:%M'), data["close"].iloc[i], sell_type[i], sell_price_line[i], sell_price_line[i]*sell_count_line[i], data['support'].iloc[i], data['resistance'].iloc[i], data_scaled['poly_5'].iloc[i], data_scaled['poly_10'].iloc[i], data_scaled['poly_20'].iloc[i], data_scaled['poly_60'].iloc[i], data_scaled['poly_120'].iloc[i], data_scaled['poly_240'].iloc[i], data_scaled['poly_480'].iloc[i], data_scaled['poly_720'].iloc[i], data_scaled['poly_1440'].iloc[i], data['new_high_7'].iloc[i], data['new_high_9'].iloc[i], data['new_high_26'].iloc[i], data['new_low_7'].iloc[i], data['new_low_9'].iloc[i], data['new_low_26'].iloc[i], )) buy_check = go.Scatter(x=data['ymd'], y=buy_price_line, mode='markers', name="buy_price", marker=dict(size=buy_sell_size, color=buy_colors, line_width=0), text=buy_text_list, hoverinfo="text") sell_check = go.Scatter(x=data['ymd'], y=sell_price_line, mode='markers', name="sell_price", marker=dict(size=14, color=sell_colors, line_width=0), text=sell_text_list, hoverinfo="text") volume_line = go.Bar(x=data['ymd'], y=data["volume"], marker_color=volume_colors, name='volume') avg5 = go.Scatter(x=data['ymd'], y=data["avg5"], name="avg5", line_color='#D27144') avg10 = go.Scatter(x=data['ymd'], y=data["avg10"], name="avg10", line_color='#BBBEC3') avg20 = go.Scatter(x=data['ymd'], y=data["avg20"], name="avg20", line_color='#d755e8') avg60 = go.Scatter(x=data['ymd'], y=data["avg60"], name="avg60", line_color='#099B92') avg120 = go.Scatter(x=data['ymd'], y=data["avg120"], name="avg120", line_color='#640745') avg240 = go.Scatter(x=data['ymd'], y=data["avg240"], name="avg240", line_color='#e68456') avg480 = go.Scatter(x=data['ymd'], y=data["avg480"], name="avg480", line_color='#A18A0D') avg720 = go.Scatter(x=data['ymd'], y=data["avg720"], name="avg720", line_color='#EF3644') avg1440 = go.Scatter(x=data['ymd'], y=data["avg1440"], name="avg1440", line_color='#4479D2') poly_5 = go.Scatter(x=data['ymd'], y=data_scaled["poly_5"], name="poly_5", line_color='#D27144') poly_10 = go.Scatter(x=data['ymd'], y=data_scaled["poly_10"], name="poly_10", line_color='#BBBEC3') poly_20 = go.Scatter(x=data['ymd'], y=data_scaled["poly_20"], name="poly_20", line_color='#d755e8') poly_60 = go.Scatter(x=data['ymd'], y=data_scaled["poly_60"], name="poly_60", line_color='#099B92') poly_120 = go.Scatter(x=data['ymd'], y=data_scaled["poly_120"], name="poly_120", line_color='#e68456') poly_240 = go.Scatter(x=data['ymd'], y=data_scaled["poly_240"], name="poly_240", line_color='#A18A0D') poly_480 = go.Scatter(x=data['ymd'], y=data_scaled["poly_480"], name="poly_480", line_color='#0196ff') poly_720 = go.Scatter(x=data['ymd'], y=data_scaled["poly_720"], name="poly_720", line_color='#EF3644') poly_1440 = go.Scatter(x=data['ymd'], y=data_scaled["poly_1440"], name="poly_1440", line_color='#4479D2') disparity_diff_20_5 = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_20_5"], name="disparity_diff_20_5", line_color='#D27144') disparity_diff_60_20 = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_60_20"], name="disparity_diff_60_20", line_color='#BBBEC3') disparity_diff_120_20 = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_120_20"], name="disparity_diff_120_20", line_color='#d755e8') disparity_diff_240_20 = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_240_20"], name="disparity_diff_240_20", line_color='#099B92') disparity_diff_480_20 = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_480_20"], name="disparity_diff_480_20", line_color='#e68456') disparity_diff_720_20 = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_720_20"], name="disparity_diff_720_20", line_color='#A18A0D') disparity_diff_1440_20 = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_1440_20"], name="disparity_diff_1440_20", line_color='#0196ff') disparity_diff_20_5_rate = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_20_5_rate"], name="disparity_diff_20_5_rate", line_color='#D27144') disparity_diff_60_20_rate = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_60_20_rate"], name="disparity_diff_60_20_rate", line_color='#BBBEC3') disparity_diff_120_20_rate = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_120_20_rate"], name="disparity_diff_120_20_rate", line_color='#d755e8') disparity_diff_240_20_rate = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_240_20_rate"], name="disparity_diff_240_20_rate", line_color='#099B92') disparity_diff_480_20_rate = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_480_20_rate"], name="disparity_diff_480_20_rate", line_color='#e68456') disparity_diff_720_20_rate = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_720_20_rate"], name="disparity_diff_720_20_rate", line_color='#A18A0D') disparity_diff_1440_20_rate = go.Scatter(x=data['ymd'], y=data_scaled["disparity_diff_1440_20_rate"], name="disparity_diff_1440_20_rate", line_color='#0196ff') new_high_7 = go.Scatter(x=data['ymd'], y=data["new_high_7"], name="new_high_7", line_color='#EA62A2') new_high_9 = go.Scatter(x=data['ymd'], y=data["new_high_9"], name="new_high_9", line_color='#0196ff') new_high_26 = go.Scatter(x=data['ymd'], y=data["new_high_26"], name="new_high_26", line_color='#991515') new_low_7 = go.Scatter(x=data['ymd'], y=data["new_low_7"], name="new_low_7", line_color='#EA62A2') new_low_9 = go.Scatter(x=data['ymd'], y=data["new_low_9"], name="new_low_9", line_color='#0196ff') new_low_26 = go.Scatter(x=data['ymd'], y=data["new_low_26"], name="new_low_26", line_color='#991515') info_p_up_limit = [0.8 for i in data['ymd']] info_p_middle_limit = [0.5 for i in data['ymd']] info_p_down_limit = [0.2 for i in data['ymd']] info_n_up_limit = [0.5 for i in data['ymd']] info_n_middle_limit = [0 for i in data['ymd']] info_n_down_limit = [-0.5 for i in data['ymd']] info_p_up_limit = go.Scatter(x=data['ymd'], y=info_p_up_limit, line=dict(color='grey', width=1), name='info_p_up_limit') info_p_middle_limit = go.Scatter(x=data['ymd'], y=info_p_middle_limit, line=dict(color='grey', width=1), name='info_p_middle_limit') info_p_down_limit = go.Scatter(x=data['ymd'], y=info_p_down_limit, line=dict(color='grey', width=1), name='info_p_down_limit') info_n_up_limit = go.Scatter(x=data['ymd'], y=info_n_up_limit, line=dict(color='grey', width=1), name='info_n_up_limit') info_n_middle_limit = go.Scatter(x=data['ymd'], y=info_n_middle_limit, line=dict(color='grey', width=1), name='info_n_middle_limit') info_n_down_limit = go.Scatter(x=data['ymd'], y=info_n_down_limit, line=dict(color='grey', width=1), name='info_n_down_limit') rsi = go.Scatter(x=data['ymd'], y=data_scaled["rsi"], line=dict(color='#239507', width=2), name='rsi') rsi_720 = go.Scatter(x=data['ymd'], y=data_scaled["rsi_720"], line=dict(color='#239507', width=2), name='rsi_720') rsi_1440 = go.Scatter(x=data['ymd'], y=data_scaled["rsi_1440"], line=dict(color='#239507', width=2), name='rsi_1440') macd = go.Scatter(x=data['ymd'], y=data_scaled["macd"], line=dict(color='#079118', width=2), name='macd') macds = go.Scatter(x=data['ymd'], y=data_scaled["macds"], line=dict(dash='dashdot', color='#991515', width=2), name='macds') macdo = go.Bar(x=data['ymd'], y=data_scaled["macdo"], marker_color='#7343e8', name='macdo') macd_720 = go.Scatter(x=data['ymd'], y=data_scaled["macd_720"], line=dict(color='#079118', width=2), name='macd_720') macd_1440 = go.Scatter(x=data['ymd'], y=data_scaled["macd_1440"], line=dict(color='#079118', width=2), name='macd_1440') slowk_up_limit = [80 for i in data['ymd']] slowk_middle_limit = [50 for i in data['ymd']] slowk_down_limit = [20 for i in data['ymd']] slowk_up_limit = go.Scatter(x=data['ymd'], y=slowk_up_limit, line=dict(color='grey', width=1), name='slowk_up_limit') slowk_middle_limit = go.Scatter(x=data['ymd'], y=slowk_middle_limit, line=dict(color='grey', width=1), name='slowk_middle_limit') slowk_down_limit = go.Scatter(x=data['ymd'], y=slowk_down_limit, line=dict(color='grey', width=1), name='slowk_down_limit') slowk_5 = go.Scatter(x=data['ymd'], y=data["slowk_5"], line=dict(color='#D27144', width=2), name='slowk_5') slowd_5 = go.Scatter(x=data['ymd'], y=data["slowd_5"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_5') slowk_10 = go.Scatter(x=data['ymd'], y=data["slowk_10"], line=dict(color='#BBBEC3', width=2), name='slowk_10') slowd_10 = go.Scatter(x=data['ymd'], y=data["slowd_10"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_10') slowk_20 = go.Scatter(x=data['ymd'], y=data["slowk_20"], line=dict(color='#d755e8', width=2), name='slowk_20') slowd_20 = go.Scatter(x=data['ymd'], y=data["slowd_20"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_20') slowk_60 = go.Scatter(x=data['ymd'], y=data["slowk_60"], line=dict(color='#099B92', width=2), name='slowk_60') slowd_60 = go.Scatter(x=data['ymd'], y=data["slowd_60"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_60') slowk_120 = go.Scatter(x=data['ymd'], y=data["slowk_120"], line=dict(color='#640745', width=2), name='slowk_120') slowd_120 = go.Scatter(x=data['ymd'], y=data["slowd_120"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_120') slowk_240 = go.Scatter(x=data['ymd'], y=data["slowk_240"], line=dict(color='#e68456', width=2), name='slowk_240') slowd_240 = go.Scatter(x=data['ymd'], y=data["slowd_240"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_240') slowk_480 = go.Scatter(x=data['ymd'], y=data["slowk_480"], line=dict(color='#A18A0D', width=2), name='slowk_480') slowd_480 = go.Scatter(x=data['ymd'], y=data["slowd_480"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_480') slowk_720 = go.Scatter(x=data['ymd'], y=data["slowk_720"], line=dict(color='#EF3644', width=2), name='slowk_720') slowd_720 = go.Scatter(x=data['ymd'], y=data["slowd_720"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_720') slowk_1440 = go.Scatter(x=data['ymd'], y=data["slowk_1440"], line=dict(color='#4479D2', width=2), name='slowk_1440') slowd_1440 = go.Scatter(x=data['ymd'], y=data["slowd_1440"], line=dict(dash='dashdot', color='grey', width=2), name='slowd_1440') text_list = [] for i in range(len(data)): text_list.append( "[{}] {:,}

" "[BASIC]
" " support: {:.2f}, resistance: {:.2f}
" " poly_5: {:.5f}, poly_10: {:.5f}, poly_20: {:.5f}, 6: {:.5f}, poly_120: {:.5f}, poly_240: {:.5f}, poly_480: {:.5f}, poly_720: {:.5f}, poly_1440: {:.5f}
" "[INFO]
" " new_high_7: {:,.2f}, new_high_9: {:,.2f}, new_high_26: {:,.2f}, new_low_7: {:,.2f}, new_low_9: {:,.2f}, new_low_26: {:,.2f}
" .format( data['ymd'].iloc[i].strftime('%Y-%m-%d %H:%M'), data["close"].iloc[i], data['support'].iloc[i], data['resistance'].iloc[i], data_scaled['poly_5'].iloc[i], data_scaled['poly_10'].iloc[i], data_scaled['poly_20'].iloc[i], data_scaled['poly_60'].iloc[i], data_scaled['poly_120'].iloc[i], data_scaled['poly_240'].iloc[i], data_scaled['poly_480'].iloc[i], data_scaled['poly_720'].iloc[i], data_scaled['poly_1440'].iloc[i], data['new_high_7'].iloc[i], data['new_high_9'].iloc[i], data['new_high_26'].iloc[i], data['new_low_7'].iloc[i], data['new_low_9'].iloc[i], data['new_low_26'].iloc[i], )) support = go.Scatter(x=data['ymd'], y=data["support"], name="support", line_color='#192BB1') resistance = go.Scatter(x=data['ymd'], y=data["resistance"], name="resistance", line_color='#E31313') candle_stick = go.Candlestick(x=data['ymd'], open=data['open'], high=data['high'], low=data['low'], close=data['close'], increasing_line_color='red', decreasing_line_color='blue', name='candle', text=text_list, hoverinfo="text" ) if bsLine is not None: candle_data = [avg5, avg10, avg20, avg60, avg120, avg240, avg480, avg720, avg1440, support, resistance, buy_check, sell_check, candle_stick] else: candle_data = [avg5, avg10, avg20, avg60, avg120, avg240, avg480, avg720, avg1440, support, resistance, candle_stick] volume_data = [volume_line] # 절대정보 indicator1 = [ info_p_up_limit, info_p_middle_limit, info_p_down_limit, info_n_up_limit, info_n_middle_limit, info_n_down_limit, new_high_7, new_high_9, new_high_26, new_low_7, new_low_9, new_low_26, disparity_diff_20_5_rate, disparity_diff_60_20_rate, disparity_diff_120_20_rate, disparity_diff_240_20_rate, disparity_diff_480_20_rate, disparity_diff_720_20_rate, disparity_diff_1440_20_rate, ] # 상대정보 info_data = [ disparity_diff_20_5, disparity_diff_60_20, disparity_diff_120_20, disparity_diff_240_20, disparity_diff_480_20, disparity_diff_720_20, disparity_diff_1440_20, poly_5, poly_10, poly_20, poly_60, poly_120, poly_240, poly_480, poly_720, poly_1440 ] slow_data = [ slowk_up_limit, slowk_middle_limit, slowk_down_limit, slowk_5, slowd_5, slowk_10, slowd_10, slowk_20, slowd_20, slowk_60, slowd_60, slowk_120, slowd_120, slowk_240, slowd_240, slowk_480, slowd_480, slowk_720, slowd_720, slowk_1440, slowd_1440, ] # macd macd_data = [ macd, macds, macdo, macd_720, macd_1440 ] # rsi rsi_data = [ rsi, rsi_720, rsi_1440 ] # 그래프를 그린다. """ fig = go.Figure(data=candle_data) fig.update_layout(title=stock_code) fig.show() """ fig = subplots.make_subplots( rows=7, cols=1, subplot_titles=("기술지표#1", "통계정보", "캔들", "slow", "macd", "rsi", "거래량"), shared_xaxes=True, horizontal_spacing=0.03, vertical_spacing=0.01, row_heights=[200, 200, 800, 200, 200, 200, 200] ) for trace in indicator1: fig.append_trace(trace, 1, 1) for trace in info_data: fig.append_trace(trace, 2, 1) for trace in candle_data: fig.append_trace(trace, 3, 1) for trace in slow_data: fig.append_trace(trace, 4, 1) for trace in macd_data: fig.append_trace(trace, 5, 1) for trace in rsi_data: fig.append_trace(trace, 6, 1) for trace in volume_data: fig.append_trace(trace, 7, 1) #fig.update_xaxes(nticks=5) #fig.update_layout(height=2400, title=stock_code, xaxis_rangeslider_visible=False) df = pd.DataFrame(bsLine) df = df.fillna(-1) if info is not None: buy_count, sell_count = 0, 0 if bsLine is not None: buy_count = len(df.loc[df["buy_price"] > 0]) sell_count = len(df.loc[df["sell_price"] > 0]) fig.update_layout( height=2000, title="{}, buy: {} ({:,.2f}원), sell: {} ({:,.2f}원), profit: {:,.2f}원 ({:.2f}%), holding_amt: {:,.2f}".format(stock_code, buy_count, info['buy_amt'], sell_count, info['sell_amt'], info['profit'], info['rate'], info['holding_amt']), xaxis_rangeslider_visible=False, xaxis1_rangeslider_visible=False, xaxis2_rangeslider_visible = False, xaxis3_rangeslider_visible = False, xaxis4_rangeslider_visible = False ) else: buy_count = 0 if bsLine is not None: buy_count = len(df.loc[df["buy_price"] > 0]) fig.update_layout( height=2700, title="{}, buy: {}번 ".format(stock_code, buy_count), xaxis_rangeslider_visible=False, xaxis1_rangeslider_visible=False, xaxis2_rangeslider_visible=False, xaxis3_rangeslider_visible=False, xaxis4_rangeslider_visible=False ) #fig.update_layout(title=stock_code + "_" + str(buy_count) + "," + str(sell_count)) # 파일로 작성함 ###fileName = os.path.join(self.RESOURCE_PATH, 'analysis', stock_code + '.html') ###po.write_html(fig, file=fileName, auto_open=False) # 화면으로 출력함 if show: fig.show() return def checkTransaction(self, ticker, data, data_scaled, ci): # 어제 오늘 데이터로 분석 bsLine = {} if data is not None and 'close' in data.columns: size = len(data["close"]) bsLine['buy_ymd'] = [None for i in range(size)] bsLine['buy_price'] = [0 for i in range(size)] bsLine['buy_count'] = [0 for i in range(size)] bsLine['buy_type'] = ['' for i in range(size)] bsLine['buy_cut'] = [None for i in range(size)] bsLine['sell_price'] = [0 for i in range(size)] bsLine['sell_count'] = [0 for i in range(size)] bsLine['sell_type'] = ['' for i in range(size)] bsLine['sell_cut'] = [-1 for i in range(size)] size = ci start = 0 for i in range(start, size): bsLine['buy_ymd'][i] = data['ymd'].iloc[i] """ if 0 < len(ticker['BUY_INFO']['buy_list']): count = sum([price['buy_count'] for price in ticker['BUY_INFO']['buy_list']]) prices = [price['buy_price'] for price in ticker['BUY_INFO']['buy_list']] ticker['BUY_INFO']['buy_count'] = count ticker['BUY_INFO']['avg_buy_price'] = (sum(prices) / len(prices)) # loss cut 체크 if 0 < len(ticker['BUY_INFO']['buy_list']): sell_count = 0 for c, buy_list in reversed(list(enumerate(ticker['BUY_INFO']['buy_list']))): # 만약 장기가 아니라면 1일전 가격 아래로 떨어지면 loss cut if buy_list['buy_price'] < np.min(data['close'][i-4320:i]): if data['close'][i] < np.min(data['close'][i-4320:i]): del ticker['BUY_INFO']['buy_list'][c] sell_count += buy_list['buy_count'] if 0 < sell_count: bsLine['sell_price'][i] = data['close'][i] bsLine['sell_count'][i] = sell_count bsLine['sell_type'][i] = 'loss_cut' bsLine['sell_cut'][i] = -1 self.test.append({'type': 'SELL', 'ymd': data['ymd'].iloc[i], 'price': data['close'][i] - ticker['unit'], 'count': count, 'amt': count*(data['close'][i] - ticker['unit'])}) continue """ # 매도 확인 sell_price, sell_count, sell_type = self.buySell_Minutely.getSellPrice(ticker, data, data_scaled, i, bsLine) bsLine['sell_price'][i] = sell_price bsLine['sell_count'][i] = sell_count bsLine['sell_type'][i] = sell_type bsLine['sell_cut'][i] = -1 # buy_cut 체크 check = False if 0 < len(ticker['BUY_INFO']['buy_list']): current_price = data['close'].iloc[i] for c in range(len(ticker['BUY_INFO']['buy_list'])-1, -1, -1): buy_list = ticker['BUY_INFO']['buy_list'][c] buy_cut = ticker['BUY_INFO']['buy_list'][c]['buy_cut'] if buy_cut is not None and 0 < buy_cut and current_price < buy_cut: self.test.append({'type': 'SELL', 'ymd': data['ymd'].iloc[i], 'price': current_price - ticker['unit'], 'count': buy_list['buy_count'], 'amt': buy_list['buy_count']*(current_price - ticker['unit'])}) del ticker['BUY_INFO']['buy_list'][c] bsLine['sell_price'][i] = current_price bsLine['sell_count'][i] = buy_list['buy_count'] bsLine['sell_type'][i] = "buy_cut" bsLine['sell_cut'][i] = c check = True continue if check: continue if 0 < sell_price: self.test.append({'type': 'SELL', 'ymd': data['ymd'].iloc[i], 'price': sell_price-ticker['unit'], 'count': sell_count, 'amt': sell_count*(sell_price - ticker['unit'])}) self.clear_BSLINE(ticker['BUY_INFO'], sell_type) else: # 매도가 아니면 매수 확인 buy_ymd, buy_price, buy_count, buy_type, buy_cut = self.buySell_Minutely.getBuyPrice(ticker, data, data_scaled, i, bsLine) bsLine['buy_price'][i] = buy_price bsLine['buy_count'][i] = buy_count bsLine['buy_type'][i] = buy_type bsLine['buy_cut'][i] = buy_cut if 0 < buy_price: self.test.append({'type': 'BUY', 'ymd': data['ymd'].iloc[i], 'price': buy_price+ticker['unit'], 'count': buy_count, 'amt': buy_count*(buy_price+ticker['unit'])}) ticker['BUY_INFO']['buy_list'].append({'buy_ymd': buy_ymd, 'buy_price': buy_price, 'buy_count': buy_count, 'buy_type': buy_type, 'buy_cut': buy_cut}) ticker['BUY_INFO']["avg_buy_price"] = np.average([buy_list['buy_price'] for buy_list in ticker['BUY_INFO']['buy_list']]) ticker['BUY_INFO']["buy_count"] = np.sum([buy_list['buy_count'] for buy_list in ticker['BUY_INFO']['buy_list']]) ticker['BUY_INFO']["buy_amount"] = ticker['BUY_INFO']["avg_buy_price"] * ticker['BUY_INFO']["buy_count"] return bsLine def simulate(self, ticker, get_days=30, mins=1): total_buy_amount, profit, buy_amt = 0, 0, 0 #data, ci = self.jSDPattern.getData(ticker, mins=1440, ymd=ymd, get_days=1500) data, data_scaled, ci = self.jSDPattern.getData(ticker, mins=mins, ymd=ticker['ymd'], get_days=get_days) if data is None: return with open("config.json", "r", encoding="utf-8") as f: config = json.load(f) BUY_INFO = config['BUY_INFO'] ticker['BUY_INFO'] = BUY_INFO ticker['INIT'] = True ticker['unit'] = self.upbit.checkUnit(data['close'].iloc[-1]) ticker['MAX_BUY'] = self.upbit.getMaxPrice(data['close'].iloc[-1]) bsLine = self.checkTransaction(ticker, data, data_scaled, ci) for item in self.test: if item['type'] == 'BUY': buy_amt += item['amt']*0.9995 else: profit += item['amt'] - buy_amt buy_amt = 0 holding_amt = sum([buy_list['buy_price']*buy_list['buy_count'] for buy_list in ticker['BUY_INFO']['buy_list']]) buy_test = [item['price']*item['count']*0.9995 for item in self.test if item['type'] == 'BUY'] sell_test = [item['price']*item['count']*1.0005 for item in self.test if item['type'] == 'SELL'] if 0 < sum(buy_test): rate = 100 * profit / sum(buy_test) else: rate = 0 print("\n시도 ({}): {}회, 이익: {:,.0f}원 ({:.2f}%)".format(ticker['ticker_code'], len(self.test), profit, rate)) print("\t- 매수: {}회, 금액: {:,.0f}원".format(len(buy_test), sum(buy_test))) print("\t- 매도: {}회, 금액: {:,.0f}원".format(len(sell_test), sum(sell_test))) print("\t- 보유: 금액: {:,.0f}원".format(holding_amt)) total_buy_amount += sum(buy_test) info = {'profit': profit, 'rate': rate, 'buy_count': len(buy_test), 'buy_amt': sum(buy_test), 'sell_count': len(sell_test), 'sell_amt': sum(sell_test), 'holding_amt': holding_amt} self.draw(ticker, data, data_scaled, bsLine, show=True, info=info) return total_buy_amount, profit if __name__ == "__main__": PROJECT_HOME = os.getcwd() RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources") # 1000원 이하: 0.1 # 1000원 이상: 1 # 1만원 이상 10 # 10만원 이상: 50 # 100만원 이상: 1000 day_list = (datetime.now()+timedelta(days=1)).strftime('%Y%m%d') """ tickers = [ {'ticker_code': 'KRW-ADA', 'ticker_name': '에이다', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-AVAX', 'ticker_name': '아발란체', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-BLUR', 'ticker_name': '블러', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-BSV', 'ticker_name': '비트코인에스브이', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-BTC', 'ticker_name': '비트코인', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-BTG', 'ticker_name': '비트코인골드', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-CTC', 'ticker_name': '크레딧코인', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-DOGE', 'ticker_name': '도지코인', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-DOT', 'ticker_name': '폴카닷', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-ETC', 'ticker_name': '이더리움클래식', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-ETH', 'ticker_name': '이더리움', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-FLOW', 'ticker_name': '플로우', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-GAS', 'ticker_name': '가스', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-GLM', 'ticker_name': '골렘', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-HIFI', 'ticker_name': '하이파이', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-IQ', 'ticker_name': '아이큐', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-LINK', 'ticker_name': '체인링크', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-MATIC', 'ticker_name': '폴리곤', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-MINA', 'ticker_name': '미나', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-NEAR', 'ticker_name': '니어프로토콜', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-SAND', 'ticker_name': '샌드박스', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-SC', 'ticker_name': '시아코인', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-SEI', 'ticker_name': '세이', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-SOL', 'ticker_name': '솔라나', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-STORJ', 'ticker_name': '스토리지', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-STRAX', 'ticker_name': '스트라티스', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-STX', 'ticker_name': '스택스', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-SUI', 'ticker_name': '수이', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-THETA', 'ticker_name': '쎄타토큰', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list}, {'ticker_code': 'KRW-XRP', 'ticker_name': '리플', 'BUY_INFO': {}, 'rise_rate': 0.0, 'INIT': True, 'volume_check': False, 'ymd': day_list} ] total_profit, total_buy = 0, 0 for ticker in tickers: simulation = Simulation_minutely(RESOURCE_PATH) total_buy_amount, profit = simulation.simulate(ticker, get_days=14) total_profit += profit total_buy += total_buy_amount print("\nticker: {}개: 총이익: {:,.0f}원 ({:.2f})%".format(len(tickers), total_profit, 100*total_profit/total_buy)) """ simulation = Simulation_minutely(RESOURCE_PATH) ticker = {'ticker_code': 'KRW-ONT', 'ticker_name': '체인링크', 'BUY_INFO': {}, 'ymd': (datetime.now()+timedelta(days=1)).strftime('%Y%m%d')} #ticker = {'ticker_code': 'KRW-BCH', 'ticker_name': '체인링크', 'BUY_INFO': {}, 'ymd': '20240324'} simulation.simulate(ticker, get_days=7) print ("done...")