import sys, time, random, os import json # load strategy # from strategies.indicator import StrategyIndicator from backtesting import Backtest # short-tp error import tracemalloc # load functions # from indicator_util import get_indicators_values from signal_helper import * # load db from db import DB from itertools import combinations from datetime import datetime from dateutil.relativedelta import relativedelta # from trade.candle import CandlePatterns import warnings from time import sleep from strategy import StrategyCandlePattern from multiprocessing import Process, freeze_support from cProfile import Profile from pstats import Stats import gc warnings.filterwarnings(action='ignore') _db = DB() # set config start_time = time.time() top_cash = 0 top_profit = 20 top_win_rate = 60 # best_pattern_arr = [] # [0, 0.23, 0.38, 0.5, 0.61, 0.78, 0.88, 1] # pivonachi profit_arr = [0] + pivo(60) loss_arr = [0] + pivo(60) # 시그널 보조 지표 base_indicators = [ {'HEI': None}, {'RSI_DIV': 14}, {'MFI_DIV': 14}, {'CCI_DIV': 20}, {'WILLR_DIV': 28}, {'RSI': 14}, {'BBANDS': [20, 2]}, {'BBANDS': [34, 2]}, {'CCI': 14}, {'AROON': 14}, {'SAR': [0.00252, 0.22]}, {'AROONOSC': 14}, {'BOP': 14}, {'CCI': 20}, {'MFI': 14}, {'MOM': 10}, {'MOM': 14}, {'ROC': 9}, {'ROC': 14}, {'WILLR': 14}, ] # 시그널 주도 지표(필터링될 지표) signal_indicators = [ {'STOCH_DIV': [14, 1, 1]}, {'STOCH_DIV': [14, 3, 3]}, # {'STOCH_DIV': [20, 12, 12]}, {'STOCHRSI_DIV': [14, 14, 3]}, {'CMO_DIV': 14}, {'CCI_DIV': 14}, {'ADX_DIV': 14}, {'BOP_DIV': 0}, {'OBV_DIV': 0}, {'MOM_DIV': 10}, {'ROC_DIV': 14}, {'ROC_DIV': 9}, {'STOCH_DIV': [14, 3, 14]}, {'STOCH_DIV': [14, 3, 5]}, {'ADOSC_DIV': [3, 10]}, {'ULTOSC_DIV': [7, 14, 28]}, {'TRIX': [14, 9]}, {'STOCH': [20, 12, 12]}, {'STOCH': [14, 3, 14]}, {'STOCH': [14, 3, 5]}, {'DMI': 14}, {'DI': 21}, {'APO': [10, 20]}, {'MACD': [12, 26, 9]}, {'MACDFIX': 26}, {'MACDFIX': 9}, {'MACDFIX': 14}, {'MACDFIX': 31}, {'PPO': [12, 26, 9]}, {'STOCHF': [14, 3]}, {'STOCHRSI': [14, 14, 3]}, {'ULTOSC': [7, 14, 28]}, {'EMA': 30}, {'EMA': 55}, {'DEMA': 55}, {'DEMA': 100}, {'DEMA': 200}, {'MA': 21}, {'MA': 55}, {'MA': 100}, {'MAMA': [0.5, 0.05]}, {'T3': [100, 10]}, {'TRIMA': 30}, {'TRIMA': 50}, {'WMA': 30}, {'WMA': 20}, ] # multi Treading - fackage def simulrating_by_item_fackage(item, data, t_time): global start_time global base_indicators global signal_indicators # global _db _db = DB() cash = 1000 commission = .005 top_info = _db.select_top_date(item['job']) min_profit = 7 if str(item['trade_type']) == 'double': min_profit = 14 if top_info['profit_rate'] is None: global top_profit global top_win_rate else: top_profit = float(top_info['profit_rate']) top_win_rate = float(top_info['win_rate']) filtered_signal_indicators = [] for indicator in signal_indicators: for profit in profit_arr: for loss in loss_arr: # if str(item['trade_type']) == 'double' and loss > 0 and profit == 0: # 숏 포지션 목표가만 있을 시 에러 # continue # if str(item['trade_type']) == 'double' and (loss != 0 or profit != 0): # continue # for test # StrategyCandlePattern.use_indicators = [{"WMA": 30}, {"EMA": 30}, {"STOCHF": [14, 3]}] StrategyCandlePattern.use_indicators = [indicator] StrategyCandlePattern.up_target = float(profit) StrategyCandlePattern.down_target = float(loss) StrategyCandlePattern.trade_type = str(item['trade_type']) bt = Backtest(data, StrategyCandlePattern, cash=cash, commission=commission) bt.run() # 수익 및 거래 수 제한 if float(bt._results['Return [%]']) > min_profit and float(bt._results['# Trades']) >= 5: if indicator not in filtered_signal_indicators: filtered_signal_indicators.append(indicator) # if float(bt._results['Return [%]']) > top_profit or float(bt._results['Win Rate [%]']) >= 60: # filename = 'chart/' + str(item['job']).replace('/', '_') + '_' + str(t_time) + '_' + str( # time.time()) # 단일 지표 미사용 # _db.insert_simul_result( # { # 'item': str(item['job']).replace('/', '_'), # 'time_type': t_time, # 'results': bt._results, # 'stop_profit': profit, # 'stop_loss': loss, # 'use_patterns': json.dumps(StrategyCandlePattern.use_indicators), # 'use_pattern_cnt': len(StrategyCandlePattern.use_indicators), # 'filename': filename, # 'period_cycle': item['period_cycle'], # 'trade_type': item['trade_type'], # }) # if bt._results['Return [%]'] > top_profit: # top_profit = bt._results['Return [%]'] # if bt._results['Win Rate [%]'] > top_win_rate: # top_win_rate = bt._results['Win Rate [%]'] # bt.plot(filename=filename, open_browser=False) # best_pattern_arr.append({ # 't_time': t_time, # 'indicators': [indicator], # 'profit': profit, # 'loss': loss, # 'return': bt._results['Return [%]'], # 'trades': bt._results['# Trades'], # }) bt = None del [[bt]] # 112.3MB gc.collect() e = int(time.time() - start_time) print('시그널 지표 필터링 완료 :', '{:02d}:{:02d}:{:02d}'.format(e // 3600, (e % 3600 // 60), e % 60)) print('지표 총합 :', len(filtered_signal_indicators) + len(base_indicators)) print('필터 지표 리스트', filtered_signal_indicators) if len(filtered_signal_indicators) < 2: print(item, t_time, '- 수익 모델 조건을 만족하는 전략이 없습니다.') return all_indicators = filtered_signal_indicators[::-1] + base_indicators # multi Treading - time def simulrating_by_time(item, t_time): global _db ''' "day": "24H", "hour12": "12H", "hour6": "06H", "hour": "01H", "minute30": "30M", "minute10": "10M", "minute5": "05M", "minute3": "03M", ''' data = _db.get_price_data_from_item_table(item['job'], item['period_cycle']) df = pd.DataFrame(data) # date = df['date'].copy() # 최소 데이터 기준 일자 조건문(2달) std_date = datetime.now() - relativedelta(months=2) if df['date'][0] > std_date: df = None del [df] return df.set_index(df['date'], inplace=True) data_columns_init(df) df.index.name = str(item['job']).replace('/', '_') if t_time != 'hour' and t_time != 'day': time_type = { 'hour': '60min', 'hour2': '120min', 'hour4': '240min', 'hour6': '360min', 'hour12': '720min', # 'week': 'W', # 'month': 'M', } ohlc_dict = { 'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last', 'Volume': 'sum' } # df = df.resample(time_type[t_time], how=ohlc_dict, label='left', base=180) # UTC (트레이딩뷰) df = df.resample(time_type[t_time], how=ohlc_dict, label='left', base=540) # UTC (트레이딩뷰) df = df[:-1] return simulrating_by_item_fackage(item, df, t_time) df = None del [df] def is_bot_by_exchange_name(item): target = item['job'].split('/') return _db.is_bot_by_exchange_name(target[1]) # reboot for windows def reboot(): return 'reboot!' # return os.system("shutdown -t 60 -r -f") def start_backtest(): global _db print('Started Simulating.', datetime.now()) for item in _db.get_cron_list(): # 이미 작동중인 봇이 있을 경우 제외 - 거래소 기준 if is_bot_by_exchange_name(item): continue if item['time_unit'] == 'hour': for t_time in ['hour6', 'hour4']: # 4시간, 6시간봉 시뮬레이팅 return simulrating_by_time(item, t_time) return reboot() simulrating_by_time(item, item['time_unit']) return reboot() return reboot() if __name__ == '__main__': tracemalloc.start() freeze_support() start_backtest() # profiler = Profile() # profiler.runcall(start_backtest) # # stats = Stats(profiler) # stats.strip_dirs() # stats.sort_stats() # stats.print_stats() ''' 메모리 절약해주는 라이브러리 사용하기 from profile import profile from time import sleep from sklearn import datasets # Just an example of 3rd party function call # Method 1 run_profiling = profile(datasets.load_digits) data = run_profiling() # Method 2 @profile def my_function(): # do some stuff a_list = [] for i in range(1,100000): a_list.append(i) return a_list res = my_function() '''