Files
oh_my_bot_simulation/indicator_backtest.py
2025-12-06 22:28:22 +09:00

1576 lines
58 KiB
Python

from backtesting import Backtest, Strategy
# from backtesting.lib import crossover
from backtesting.test import SMA, GOOG
import sys
import talib, numpy, pybithumb, time, random
import pandas as pd
import numpy as np
from itertools import product, combinations
from pprint import pprint
# for divergence
import numpy as np
import pandas as pd
import math
import matplotlib.pyplot as plt
from scipy import stats
from scipy.stats import linregress
import statsmodels
from pandas import Series
import talib
def get_candle_pattern_arr(data = None, use_patterns = talib.get_function_groups()['Pattern Recognition']):
if data is None:
return []
r_data = [None] * len(data.Close)
for p in use_patterns:
f = getattr(talib, p)
res_arr = f(data.Open, data.High, data.Low, data.Close)
# 100 is plus candle / -100 is minus candle
for i in range(0, len(res_arr)):
# print(p, res_arr[i])
if int(res_arr[i]) is not 0:
r_data[i] = {p: int(res_arr[i])}
return r_data
def crossover(p_x_d, x_d, p_y_d, y_d) -> bool:
try:
return p_x_d < p_y_d and x_d > y_d
except IndexError:
return False
def data_columns_init(data):
# data.reset_index(level=0, inplace=True)
t_col = []
for c in data.columns:
t_col.append(c.lower().capitalize())
data.columns = t_col
'''
Long/Short Divergence
params :
i - index
cdl_cnt - candle count
low - low values
high - high values
res_arr - indicator values
'''
def is_divergence(i, cdl_cnt, low, high, res_arr):
# 저가 갱신 / 지표 저점 상승 : 매수
if min(low[i - cdl_cnt:i]) < min(low[i - (cdl_cnt * 2):i - cdl_cnt + 1]) and \
min(res_arr[i - cdl_cnt:i]) > min(res_arr[i - (cdl_cnt * 2):i - cdl_cnt + 1]):
return True
# 고가 갱신 / 지표 고점 하락 : 매도
elif max(high[i - cdl_cnt:i]) > max(high[i - (cdl_cnt * 2):i - cdl_cnt + 1]) and \
max(res_arr[i - cdl_cnt:i]) < max(res_arr[i - (cdl_cnt * 2):i - cdl_cnt + 1]):
return False
class CandlePatterns:
# 매수 패턴
_positive_patterns = [
'CDL3STARSINSOUTH', # Three Stars In The South
'CDL3WHITESOLDIERS', # 적삼병
'CDLCONCEALBABYSWALL',
'CDLDRAGONFLYDOJI',
'CDLLADDERBOTTOM',
'CDLMORNINGDOJISTAR',
'CDLMORNINGSTAR',
'CDLTAKURI',
'CDLHAMMER',
]
# 매도 패턴
_negative_patterns = ['CDLEVENINGDOJISTAR', # 석별형
'CDL2CROWS', # 2봉 까마귀형
'CDL3BLACKCROWS', # 흑삼병
'CDLADVANCEBLOCK', # 블록형 : 매수 탄력 약화, 고점에서 경고 패턴
'CDLDARKCLOUDCOVER',
'CDLEVENINGDOJISTAR',
'CDLEVENINGSTAR',
'CDLGRAVESTONEDOJI',
'CDLHANGINGMAN',
'CDLIDENTICAL3CROWS',
'CDLINNECK',
'CDLHOMINGPIGEON',
'CDLMATCHINGLOW',
'CDLONNECK',
'CDLSHOOTINGSTAR',
'CDLUPSIDEGAP2CROWS',
'CDLINVERTEDHAMMER',
]
# 중립 패턴
_fence_patterns = ['CDL3INSIDE',
'CDL3LINESTRIKE',
'CDL3OUTSIDE',
'CDLABANDONEDBABY',
'CDLBELTHOLD', # 상승/하락 샅바형
'CDLBREAKAWAY',
'CDLCLOSINGMARUBOZU',
'CDLCOUNTERATTACK',
'CDLCONCEALBABYSWALL',
'CDLENGULFING',
'CDLGAPSIDESIDEWHITE',
'CDLHARAMI',
'CDLHARAMICROSS',
# 'CDLHIGHWAVE', # 꼬리나 머리털이 길때
'CDLHIKKAKE',
'CDLHIKKAKEMOD',
'CDLKICKING',
'CDLKICKINGBYLENGTH',
# 'CDLLONGLEGGEDDOJI', # Long Legged Doji
# 'CDLLONGLINE', # Long Line Candle
# 'CDLMARUBOZU', # Marubozu
'CDLMATHOLD',
'CDLPIERCING',
# 'CDLRICKSHAWMAN ', # 그냥 도지임
# 'CDLSHORTLINE', # Short Line Candle 5:5
'CDLRISEFALL3METHODS',
'CDLSEPARATINGLINES',
# 'CDLSPINNINGTOP', # 그냥 도지임
'CDLSTALLEDPATTERN',
'CDLTASUKIGAP',
# 'CDLTHRUSTING', # 지속형
# 'CDLTRISTAR', # 이 패턴은 거의 안나옴 추세 반전 패턴
'CDLUNIQUE3RIVER',
'CDLXSIDEGAP3METHODS',
]
# 역 중립 패턴(음봉때 진입, 양봉때 탈출)
_r_fence_patterns = ['CDLSTICKSANDWICH',
]
def get_fence_patterns(self):
return self._fence_patterns
def get_r_fence_patterns(self):
return self._r_fence_patterns
# 중복 제거
def get_trade_patterns(self):
return self._negative_patterns + self._positive_patterns
def get_long_patterns(self):
return self._positive_patterns
def get_short_patterns(self):
return self._negative_patterns
class StrategyIndicators(Strategy):
use_indicators = None
indicators_data = None
# value = dict()
_sl_percent = 0.03 # 2%
def init(self):
close = self.data.Close
low = self.data.Low
high = self.data.High
open = self.data.Open
volume = self.data.Volume
data = [list()] * len(self.data.Close)
for p in self.use_indicators:
indicator = None
values = None
f = None
indicator, values = list(p.items())[0]
if indicator != 'DI' and hasattr(talib, indicator):
f = getattr(talib, indicator)
if indicator is 'CDLPTN':
for i in range(0, len(close)):
t_d = []
if self.data.Candle_pattern[i] is None:
continue
pattern, value = list(self.data.Candle_pattern[i].items())[0]
if pattern in CandlePatterns._positive_patterns: # 매수 패턴
t_d.append(True)
elif pattern in CandlePatterns._negative_patterns: # 매도 패턴
t_d.append(False)
# elif pattern in CandlePatterns._fence_patterns: # 중립 패턴
# if int(value) > 0:
# t_d.append(True)
# elif int(value) < 0:
# t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'RSI': # 베이스 지표
res_arr = f(close, values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 수치 매매
if res_arr[i] < 25:
t_d.append(True)
elif res_arr[i] > 75:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'STOCH': # 주도 지표
slowk, slowd = f(high, low, close,
fastk_period=values[0],
slowk_period=values[1],
slowd_period=values[2])
start = 1 + numpy.isnan(slowk).sum()
for i in range(start, len(slowk)):
t_d = []
if crossover(slowk[i-1], slowk[i], slowd[i-1], slowd[i]):
t_d.append(False)
elif crossover(slowd[i-1], slowd[i], slowk[i-1], slowk[i]):
t_d.append(True)
data[i] = data[i] + t_d
elif indicator is 'ADX' or indicator is 'ADXR': # 베이스 지표
res_arr = f(high, low, close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if res_arr[i] < 20: # 25초과 - 추세추종 / 20 미만 역추세 매매
t_d.append(True)
else:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'DI': # 주도 지표
res_arr_plus = talib.PLUS_DI(high, low, close, timeperiod=values)
res_arr_minus = talib.MINUS_DI(high, low, close, timeperiod=values)
start = 1 + numpy.isnan(res_arr_plus).sum()
for i in range(start, len(res_arr_plus)):
t_d = []
if res_arr_plus[i] > res_arr_minus[i]:
t_d.append(True)
else:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'APO': # 주도 지표
res_arr = f(close, fastperiod=values[0], slowperiod=values[1], matype=0)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if res_arr[i] > 0:
t_d.append(True)
else:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'AROON': # 주도 지표
aroondown, aroonup = f(high, low, timeperiod=values)
start = 1 + numpy.isnan(aroondown).sum()
for i in range(start, len(aroondown)):
t_d = []
if aroonup[i] > 50 and crossover(aroondown[i-1], aroondown[i], aroonup[i-1], aroonup[i]):
t_d.append(False)
elif aroondown[i] < 50 or crossover(aroonup[i-1], aroonup[i], aroondown[i-1], aroondown[i]):
t_d.append(True)
data[i] = data[i] + t_d
elif indicator is 'AROONOSC': # 베이스 지표
res_arr = f(high, low, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if res_arr[i] > 0:
t_d.append(True)
elif res_arr[i] > 90:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'BOP': # 베이스 지표
res_arr = f(open, high, low, close)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# if res_arr[i] < -0.8: # 과매도 매수
# # t_d.append(True)
# # elif res_arr[i] > 0.7: # 과매수 매도
# # t_d.append(False)
if res_arr[i] > 0 and res_arr[i-1] < 0:
t_d.append(True)
elif res_arr[i] < 0 and res_arr[i-1] > 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'CCI': # 베이스 지표 / 추세
res_arr = f(high, low, close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 120/120
# 시그널
# if res_arr[i] > 0 and res_arr[i-1] < 0:
# t_d.append(True)
# elif res_arr[i] < 0 and res_arr[i-1] > 0:
# t_d.append(False)
# 베이스
if res_arr[i] > 0: # 과매도 -100 / 과매수 +100
t_d.append(True)
elif res_arr[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'CMO': # 베이스 지표 / 추세
res_arr = f(close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 시그널
# if res_arr[i] > -50 and res_arr[i-1] < -50:
# t_d.append(True)
# elif res_arr[i] < 50 and res_arr[i-1] > 50:
# t_d.append(False)
# 베이스
if res_arr[i] > 0:
t_d.append(True)
elif res_arr[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
# elif indicator is 'DX': # 베이스 지표 / 추세
# res_arr = f(high, low, close, timeperiod=values)
# start = 1 + numpy.isnan(res_arr).sum()
#
# for i in range(start, len(res_arr)):
# t_d = []
#
# # 베이스
# if res_arr[i] < 10:
# t_d.append(True)
# elif res_arr[i] > 40:
# t_d.append(False)
#
# data[i] = data[i] + t_d
elif indicator is 'MACD': # 주도 지표
macd, macdsignal, macdhist = f(close,
fastperiod=values[0],
slowperiod=values[1],
signalperiod=values[2])
start = 1 + numpy.isnan(macd).sum()
for i in range(start, len(macd)):
t_d = []
if macd[i] > macdsignal[i] and macd[i-1] < macdsignal[i-1] and macd[i] > 0:
t_d.append(True)
elif macd[i] < macdsignal[i] and macd[i-1] > macdsignal[i-1] or macd[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'MACDFIX': # 주도 지표
macd, macdsignal, macdhist = f(close, signalperiod=values)
start = 1 + numpy.isnan(macd).sum()
for i in range(start, len(macd)):
t_d = []
if macd[i] > macdsignal[i] and macd[i-1] < macdsignal[i-1] and macd[i] > 0:
t_d.append(True)
elif macd[i] < macdsignal[i] and macd[i-1] > macdsignal[i-1] or macd[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'MFI': # 베이스 지표 / 역추세
res_arr = f(high, low, close, volume, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 베이스
if res_arr[i] < 20:
t_d.append(True)
elif res_arr[i] > 80:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'MOM': # 베이스 지표 / 추세
res_arr = f(close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 베이스
if res_arr[i] > 0:
t_d.append(True)
elif res_arr[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'PPO': # 주도 지표
res_arr = f(close, fastperiod=values[0], slowperiod=values[1], matype=0)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 베이스
if res_arr[i] > 0:
t_d.append(True)
elif res_arr[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'ROC': # 베이스 지표 / 추세
res_arr = f(close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 베이스
if res_arr[i] > 0:
t_d.append(True)
elif res_arr[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'ROCP' or indicator is 'ROCR' or indicator is 'ROCR100': # 베이스 지표 / 추세
res_arr = f(close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 베이스
if res_arr[i] > 0:
t_d.append(True)
elif res_arr[i] < 0:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'STOCHF': # 주도 지표
fastk, fastd = f(high, low, close, fastk_period=values[0], fastd_period=values[1], fastd_matype=0)
start = 1 + numpy.isnan(fastk).sum()
for i in range(start, len(fastk)):
t_d = []
if fastd[i] < 20:
t_d.append(True)
elif fastd[i] > 80:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'STOCHRSI': # 주도 지표
fastk, fastd = f(close, timeperiod=values[0], fastk_period=values[1], fastd_period=values[2], fastd_matype=0)
start = 1 + numpy.isnan(fastk).sum()
for i in range(start, len(fastk)):
t_d = []
# print(fastk[i], fastd[i])
if fastd[i] < 20:
t_d.append(True)
elif fastd[i] > 80:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'TRIX': # 베이스 지표 / 역추세 => 매수/매도 시점 괜찮다
trix = f(close, timeperiod=values[0])
t_data = pd.DataFrame(trix)
trix_signal = t_data.rolling(values[1]).mean().values # 이동평균 시그널 생성
del t_data
start = 1 + numpy.isnan(trix_signal).sum()
for i in range(start, len(trix_signal)):
t_d = []
# 14.77%
if trix[i] > trix_signal[i][0]:
t_d.append(True)
elif trix[i] < trix_signal[i][0]:
t_d.append(False)
# base signal
# if trix[i] > 0:
# t_d.append(True)
# elif trix[i] < 0:
# t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'ULTOSC': # 주도 지표
res_arr = f(high, low, close, timeperiod1=values[0], timeperiod2=values[1], timeperiod3=values[2])
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if res_arr[i] < 30:
t_d.append(True)
elif res_arr[i] > 70:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'WILLR': # 베이스 지표 => 강세장에서 효과를 발휘
res_arr = f(high, low, close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# print(res_arr[i])
if res_arr[i] > -50:
t_d.append(True)
elif res_arr[i] < -50:
t_d.append(False)
# 베이스
# if res_arr[i] < -80:
# t_d.append(True)
# elif res_arr[i] > -20:
# t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'BBANDS': # 베이스 지표 / 역추세
upperband, middleband, lowerband = f(close, timeperiod=values[0], nbdevup=values[1], nbdevdn=values[1], matype=0)
start = 1 + numpy.isnan(upperband).sum()
for i in range(start, len(upperband)):
t_d = []
# if close[i] > lowerband[i] and close[i-1] < lowerband[i-1]:
# t_d.append(True)
# elif close[i] < upperband[i] and close[i-1] > upperband[i-1] or high[i-1] > upperband[i-1]:
# t_d.append(False)
# best (7.72%) 캔들이 상/하 밴드에 닿고 밴드 확장, 이평선 => 빈도가 매우 낮음
# if low[i] < lowerband[i] and (upperband[i]-lowerband[i]) > (upperband[i-1]-lowerband[i-1]) and close[i] > middleband[i]:
# t_d.append(True)
# elif high[i] > upperband[i] and (upperband[i]-lowerband[i]) > (upperband[i-1]-lowerband[i-1]) and close[i] < middleband[i]:
# t_d.append(False)
if close[i] < lowerband[i]:
t_d.append(True)
elif close[i] > upperband[i]:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'EMA' or \
indicator is 'DEMA' or \
indicator is 'MA' or \
indicator is 'SMA': # 주도 지표 / 추세
long = f(close, timeperiod=values[0])
short = f(close, timeperiod=values[1])
start = 1 + numpy.isnan(long).sum()
for i in range(start, len(long)):
t_d = []
if long[i] < short[i]:
t_d.append(True)
elif long[i] > short[i]:
t_d.append(False)
data[i] = data[i] + t_d
# elif indicator is 'KAMA': # 주도 지표 / 사용법 모름
# res_arr = f(close, timeperiod=values)
#
# start = 1 + numpy.isnan(res_arr).sum()
# for i in range(start, len(res_arr)):
# t_d = []
#
# if res_arr[i] > res_arr[i-1] and res_arr[i] < res_arr[i-1]:
# t_d.append(True)
# elif res_arr[i] < res_arr[i-1] and res_arr[i] > res_arr[i-1]:
# t_d.append(False)
#
# data[i] = data[i] + t_d
elif indicator is 'MAMA': # 주도 지표 / 추세
# print(values[0]/10, values[1]/100)
mama, fama = f(close, fastlimit=values[0], slowlimit=values[1])
start = 1 + numpy.isnan(mama).sum()
for i in range(start, len(mama)):
t_d = []
if mama[i] > fama[i]:
t_d.append(True)
elif mama[i] < fama[i]:
t_d.append(False)
data[i] = data[i] + t_d
# elif indicator is 'MAVP': # 주도 지표 => 강세장에서 효과를 발휘 => 모르게따 periods?
# res_arr = f(high, low, close, timeperiod=values)
# start = 1 + numpy.isnan(res_arr).sum()
#
# for i in range(start, len(res_arr)):
# t_d = []
#
# print(res_arr[i])
#
# data[i] = data[i] + t_d
elif indicator is 'MIDPOINT': # 주도 지표 => 추세
res_arr = f(close, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if close[i] > res_arr[i]:
t_d.append(True)
elif close[i] < res_arr[i]:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'MIDPRICE': # 주도 지표 => 추세
res_arr = f(high, low, timeperiod=values)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if close[i] > res_arr[i]:
t_d.append(True)
elif close[i] < res_arr[i]:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'SAR': # 주도 지표 => 역추세
res_arr = f(high, low, acceleration=values/100, maximum=values/10)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if close[i] < res_arr[i]:
t_d.append(True)
elif close[i] > res_arr[i]:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'T3' or indicator is 'TEMA' or indicator is 'TRIMA' or indicator is 'WMA': # 주도 지표 => 추세
long = f(close, timeperiod=values[0])
short = f(close, timeperiod=values[1])
start = 1 + numpy.isnan(long).sum()
for i in range(start, len(long)):
t_d = []
if short[i] > long[i]:
t_d.append(True)
elif short[i] < long[i]:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'AD': # 베이스 지표 - 거래량
res_arr = f(high, low, close, volume)
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
# 가격-거래량 반비례 => 추세 반전
if close[i] > close[i-1] and res_arr[i] < res_arr[i-1]:
t_d.append(False)
elif close[i] < close[i-1] and res_arr[i] > res_arr[i-1]:
t_d.append(True)
data[i] = data[i] + t_d
elif indicator is 'ADOSC': # 베이스 지표 - 거래량
res_arr = f(high, low, close, volume, fastperiod=values[0], slowperiod=values[1])
start = 1 + numpy.isnan(res_arr).sum()
for i in range(start, len(res_arr)):
t_d = []
if res_arr[i] < 0:
t_d.append(False)
elif res_arr[i] > 0:
t_d.append(True)
# 가격-거래량 반비례 => 추세 반전
# if close[i] > close[i - 1] and res_arr[i] < res_arr[i - 1]:
# t_d.append(False)
# elif close[i] < close[i - 1] and res_arr[i] > res_arr[i - 1]:
# t_d.append(True)
data[i] = data[i] + t_d
elif indicator is 'DMI': # 주도 지표 - 추세(추매)
adx = talib.ADX(high, low, close, timeperiod=values)
plus_di = talib.PLUS_DI(high, low, close, timeperiod=values)
minus_di = talib.MINUS_DI(high, low, close, timeperiod=values)
start = 1 + numpy.isnan(adx).sum()
for i in range(start, len(adx)):
t_d = []
if adx[i] > adx[i-1]:
if plus_di[i] > minus_di[i] and adx[i] > minus_di[i]:
t_d.append(True)
elif minus_di[i] > minus_di[i-1]:
t_d.append(False)
data[i] = data[i] + t_d
elif indicator is 'OBV': # 베이스 지표 / 역추세
res_arr = f(close, volume)
cdl_cnt = 20
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt:
start = cdl_cnt
for i in range(start, len(res_arr)):
t_d = []
# 고가 갱신 시 매도 / 저가 갱신 시 매수
if res_arr[i] > max(res_arr[i-cdl_cnt:i]):
t_d.append(False)
elif res_arr[i] < min(res_arr[i-cdl_cnt:i]):
t_d.append(True)
data[i] = data[i] + t_d
elif indicator is 'OBV_DIV': # 주도 지표 / 역추세 - 다이버전스
res_arr = f(close, volume)
cdl_cnt = 10
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'RSI_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'RSI')
res_arr = f(close, values)
cdl_cnt = 14
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'ADX_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'ADX')
res_arr = f(high, low, close, timeperiod=values)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'ADXR_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'ADXR')
res_arr = f(high, low, close, timeperiod=values)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'BOP_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'BOP')
res_arr = f(open, high, low, close)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'CCI_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'CCI')
res_arr = f(high, low, close, timeperiod=values)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'CMO_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'CMO')
res_arr = f(close, timeperiod=values)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'MFI_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'MFI')
res_arr = f(high, low, close, volume, timeperiod=values)
cdl_cnt = 20
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'MOM_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'MOM')
res_arr = f(close, timeperiod=values)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'ROC_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'ROC')
res_arr = f(close, timeperiod=values)
cdl_cnt = 10
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'ROCP_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'ROCP')
res_arr = f(close, timeperiod=values)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'ROCR_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'ROCR')
res_arr = f(close, timeperiod=values)
cdl_cnt = 10
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'STOCH_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'STOCH')
slowk, res_arr = f(high, low, close, fastk_period=values[0], slowk_period=values[1], slowd_period=values[2],
slowk_matype=0, slowd_matype=0)
cdl_cnt = 15
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'STOCHF_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'STOCHF')
fastk, res_arr = f(high, low, close, fastk_period=values[0], fastd_period=values[1], fastd_matype=0)
cdl_cnt = 20
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'TRIX_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'TRIX')
res_arr = f(close, timeperiod=values)
cdl_cnt = 20
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
if indicator is 'WILLR_DIV': # 주도 지표 / 역추세 - 다이버전스
f = getattr(talib, 'WILLR')
res_arr = f(high, low, close, timeperiod=values)
cdl_cnt = 10
start = 1 + numpy.isnan(res_arr).sum()
if start < cdl_cnt*2:
start = cdl_cnt*2
for i in range(start, len(res_arr)):
t_d = []
if is_divergence(i, cdl_cnt, low, high, res_arr) is True:
t_d.append(True)
elif is_divergence(i, cdl_cnt, low, high, res_arr) is False:
t_d.append(False)
data[i] = data[i] + t_d
# sys.exit(1)
self.indicators_data = data
def next(self):
idx = (self._broker._i)-1
sl = self.data.Close[-1] - (self.data.Close[-1] * self._sl_percent)
# 배열 동시 시그널 매매
if len(self.indicators_data[idx]) == len(self.use_indicators):
if all(self.indicators_data[idx]):
if not self.orders.is_long:
self.buy(sl=sl)
elif not any(self.indicators_data[idx]):
if self.orders.is_long:
self.position.close()
def get_indicators_args(indicators):
res_data = []
for i in indicators:
if i is 'RSI' or i is 'RSI_DIV': # 베이스 지표
e_range = list(range(9, 31))
# e_range = [14]
for v in e_range:
res_data.append({i:v})
# res_data = list(range(9, 31))
elif i is 'STOCH': # 주도 지표
# res_data.append({i: [5, 3, 3]})
# continue
f_range = list(range(5, 21))
for f_r in f_range:
s_range = list(range(1, f_r+1))
for s_r in s_range:
t_range = list(range(1, s_r+1))
for t_r in t_range:
res_data.append({i : [f_r, s_r, t_r]})
elif i is 'ADX' or i is 'ADXR' or i is 'DMI': # 베이스 지표
e_range = list(range(9, 21))
# e_range = [14]DMI
for v in e_range:
res_data.append({i: v})
elif i is 'DI': # Directional Indicator Plus/Minus # 주도 지표
e_range = list(range(9, 31))
# e_range = [14]
for v in e_range:
res_data.append({i: v})
elif i is 'APO': # 주도 지표
f_range = list(range(17, 31))
for f_r in f_range:
s_range = list(range(10, f_r+1))
for s_r in s_range:
res_data.append({i : [s_r, f_r]})
elif i is 'AROON': # 주도 지표
e_range = list(range(11, 31))
for v in e_range:
res_data.append({i: v})
elif i is 'AROONOSC': # 베이스 지표
e_range = list(range(3, 21))
for v in e_range:
res_data.append({i: v})
elif i is 'BOP': # 베이스
res_data.append({i: None})
elif i is 'CCI': # 베이스
e_range = list(range(11, 31))
for v in e_range:
res_data.append({i: v})
elif i is 'CMO': # 베이스
e_range = list(range(9, 31))
for v in e_range:
res_data.append({i: v})
# elif i is 'DX': # 베이스 / 추세 추종
# e_range = list(range(9, 31))
# for v in e_range:
# res_data.append({i: v})
elif i is 'MACD': # 주도 지표
f_range = list(range(11, 31))
for f_r in f_range:
s_range = list(range(9, f_r+1))
for s_r in s_range:
t_range = list(range(7, s_r+1))
for t_r in t_range:
res_data.append({i : [s_r, f_r, t_r]})
elif i is 'MACDFIX': # 주도 지표
e_range = list(range(5, 21))
for v in e_range:
res_data.append({i: v})
elif i is 'MFI': # 베이스 / 추세
e_range = list(range(9, 31))
for v in e_range:
res_data.append({i: v})
elif i is 'MOM': # 베이스 / 역추세
e_range = list(range(9, 31))
for v in e_range:
res_data.append({i: v})
elif i is 'PPO': # 주도 지표
f_range = list(range(9, 26))
for f_r in f_range:
s_range = list(range(10, f_r+1))
for s_r in s_range:
res_data.append({i : [s_r, f_r]})
elif i is 'ROC' or i is 'ROCP' or i is 'WILLR' or i is 'MIDPOINT' or i is 'MIDPRICE':# 베이스 지표 / 추세
e_range = list(range(9, 31))
for v in e_range:
res_data.append({i: v})
# elif i is 'ROCR':# 베이스 지표 / 추세 => 보류
# e_range = list(range(9, 31))
# for v in e_range:
# res_data.append({i: v}
# elif i is 'ROCR100':# 베이스 지표 / 추세 => 보류
# e_range = list(range(9, 31))
# for v in e_range:
# res_data.append({i: v})
elif i is 'STOCHF': # 주도 지표
f_range = list(range(5, 21))
for f_r in f_range:
s_range = list(range(3, f_r+1))
for s_r in s_range:
res_data.append({i : [f_r, s_r]})
elif i is 'STOCHRSI': # 주도 지표
f_range = list(range(5, 21))
for f_r in f_range:
s_range = list(range(3, f_r+1))
for s_r in s_range:
t_range = list(range(3, s_r+1))
for t_r in t_range:
res_data.append({i : [f_r, s_r, t_r]})
elif i is 'TRIX': # 베이스 지표 / 역추세
f_range = list(range(3, 36))
for f_r in f_range:
s_range = list(range(2, f_r+1))
for s_r in s_range:
res_data.append({i : [f_r, s_r]})
elif i is 'ULTOSC': # 주도 지표
f_range = list(range(7, 31))
for f_r in f_range:
s_range = list(range(5, f_r+1))
for s_r in s_range:
t_range = list(range(5, s_r+1))
for t_r in t_range:
res_data.append({i : [t_r, s_r, f_r]})
elif i is 'BBANDS': # 베이스 지표
f_range = list(range(9, 31))
for f_r in f_range:
s_range = list(range(1, f_r+1))
for s_r in s_range:
res_data.append({i : [f_r, s_r]})
elif i is 'EMA' or i is 'DEMA' or i is 'MA' or i is 'SMA': # 주도 지표
f_range = list(range(9, 36))
for f_r in f_range:
s_range = list(range(5, f_r+1))
for s_r in s_range:
res_data.append({i : [f_r, s_r]})
# elif i is 'KAMA': # 베이스 지표 / 추세 => 사용법 모름
# e_range = list(range(9, 36))
# for v in e_range:
# res_data.append({i: v})
elif i is 'MAMA': # 주도 지표
f_range = list(range(1, 10))
for f_r in f_range:
s_range = list(range(1, 10))
for s_r in s_range:
res_data.append({i : [f_r/10, s_r/100]})
# elif i is 'MAVP': # 주도 지표
# f_range = list(range(9, 36))
# for f_r in f_range:
# s_range = list(range(10, f_r+1))
# for s_r in s_range:
# res_data.append({i : [s_r, f_r]})
elif i is 'SAR': # 베이스 지표 / 역추세 => 거래 빈도만 줄이면 훌륭할 듯
e_range = list(range(1, 5))
for v in e_range:
res_data.append({i: v})
elif i is 'T3': # 주도 지표
f_range = list(range(5, 31))
for f_r in f_range:
s_range = list(range(3, f_r))
for s_r in s_range:
res_data.append({i : [f_r, s_r]})
elif i is 'TEMA' or i is 'TRIMA' or i is 'WMA': # 주도 지표
f_range = list(range(15, 41))
for f_r in f_range:
s_range = list(range(7, f_r))
for s_r in s_range:
res_data.append({i : [f_r, s_r]})
elif i is 'AD': # 베이스 지표 - 거래량
res_data.append({i: None})
elif i is 'ADOSC': # 주도 지표 - 거래량 => 추세
f_range = list(range(7, 31))
for f_r in f_range:
s_range = list(range(3, f_r))
for s_r in s_range:
res_data.append({i : [s_r, f_r]})
elif i is 'OBV' or i is 'BOP_DIV': # 베이스 지표 - 거래량 기반 상승장, 하락장 지표
res_data.append({i: None})
# 다이버전스 주도 지표 / 역추세
elif i is 'ADX_DIV' or i is 'ADXR_DIV' or i is 'AROONOSC_DIV' or i is 'CCI_DIV' or i is 'CMO_DIV' \
or i is 'MFI_DIV' or i is 'MOM_DIV' or i is 'ROC_DIV' or i is 'ROCP_DIV' or i is 'ROCR_DIV' \
or i is 'TRIX_DIV' or i is 'WILLR_DIV':
e_range = list(range(9, 31))
for v in e_range:
res_data.append({i: v})
elif i is 'STOCH_DIV':
f_range = list(range(5, 21))
for f_r in f_range:
s_range = list(range(1, f_r+1))
for s_r in s_range:
t_range = list(range(1, s_r+1))
for t_r in t_range:
res_data.append({i : [f_r, s_r, t_r]})
elif i is 'STOCHF_DIV':
f_range = list(range(7, 31))
for f_r in f_range:
s_range = list(range(3, f_r))
for s_r in s_range:
res_data.append({i : [f_r, s_r]})
return res_data
'''
"day": "24H",
"hour12": "12H",
"hour6": "06H",
"hour": "01H",
"minute30": "30M",
"minute10": "10M",
"minute5": "05M",
"minute3": "03M",
'''
df = pybithumb.get_ohlcv('BTC', 'hour') # params : 종목, 시간
df = df[:-1]
df = df[-1440:] # 최근 두달 데이터
data_columns_init(df)
cash = 1000
commission = .005
top_profit = 0
top_cash = 0
data = df
start_time = time.time()
'''
지표 혼합 방식(모든 지표 동시 시그널 매매 - 현재 방식) or 지표 조합 방식(각 지표별 시그널 매매)
- 추세, 역추세 봇에 따라 지표의 값이 다르고 시그널로 활용할 지 베이스로 활용 할 지도 달라진다.
- 주도 지표는 실질적인 매매 시그널이 있는 지표
- 베이스 지표(추세) => 주도 지표(역추세)로 구분하여 활용
- 베이스 지표는 보조적인 역할을 담당
- DM, DI 지표 사용법을 숙지해서 다시 구현
ADX(Average Directional Movement Index)는 추세를 측정하는 지표로, 다른 지표들과 혼합되어 사용된다.
APO(Absolute Price Oscillator) => 굉장히 매수시점이 좋다. 매도 시점만 받쳐줄 지표와 혼합되면 굉장할 듯.
AROON 지표는 매수 전략만으로 활용 된다.(long 포지션 매매)
BOP(Balance Of Power) : 상승세와 하락세가 서로 경합하면서 주가를 한쪽으로 이동시키려는 강도를 보여준다.
=> 추세 지표
SAR(Parabolic SAR) : 매매 시점이 좋으나, 거래 빈도가 높아 수익률은 낮다. => 조합 사용 시 매우 효과적일듯
OBV(On Balance Volume) : 가격과 다이버전시로 활용 못할 시 무의미한 지표 - 매매 파워 척도 => 상승장/하락장 판단에
매우 유용한 지표
'''
using_indicators = {
'trade_indicators':['STOCH', 'DMI', 'DI', 'APO', 'AROON', 'MACD', 'PPO',
'STOCHF', 'STOCHRSI', 'ULTOSC', 'EMA', 'DEMA', 'MA', 'SMA', 'MAMA', 'MAVP',
'MIDPOINT', 'MIDPRICE', 'SAR', 'T3', '', 'TEMA', 'TRIMA', 'WMA'],
'base_indicators': ['RSI', 'ADX', 'ADXR', 'AROONOSC', 'BOP', 'CCI', 'CMO', 'MFI', 'MOM', 'ROC', 'ROCP',
'ROCR', 'ROCR100', 'TRIX', 'WILLR', 'BBANDS', 'AD', 'ADOSC', 'OBV'],
'div_indicators': ['RSI_DIV', 'OBV_DIV', 'ADXR_DIV', 'ADX_DIV', 'BOP_DIV', 'CCI_DIV', 'CMO_DIV',
'MFI_DIV', 'MOM_DIV', 'ROC_DIV', 'ROCP_DIV', 'ROCR_DIV', 'STOCH_DIV', 'STOCHF_DIV',
'TRIX_DIV', 'WILLR_DIV']
}
# for test
# using_indicators = {
# 'trade_indicators':['SMA'],
# 'base_indicators': ['RSI'],
# 'div_indicators': ['RSI_DIV']
# }
none_stat_filtered = {}
# case 0 : 주도 지표 거래 발생 여부 검증 20분
for type in using_indicators:
temp_array = []
base_values = get_indicators_args(using_indicators[type])
for indicator in base_values:
StrategyIndicators.use_indicators = [indicator]
bt = Backtest(data, StrategyIndicators, cash=cash, commission=commission)
bt.run()
if bt._results['Return [%]'] > top_profit and bt._results['# Trades'] > 0:
top_profit = bt._results['Return [%]']
top_cash = bt._results['Equity Final [$]']
print("최종 금액 : %0.2f" % bt._results['Equity Final [$]'])
print("총 수익률 : %0.2f%%" % bt._results['Return [%]'])
print(StrategyIndicators.use_indicators)
print('-' * 60)
if bt._results['# Trades'] > 0:
temp_array.append(indicator)
none_stat_filtered.update({type: temp_array})
e = int(time.time() - start_time)
print('1차 필터링 종료 :','{:02d}:{:02d}:{:02d}'.format(e // 3600, (e % 3600 // 60), e % 60))
# case 2 : 주도 지표 - 베이스 지표와 검증
main_filterd = []
base_filterd = []
for trade_indicator in none_stat_filtered['trade_indicators'] + none_stat_filtered['div_indicators']:
for base_indicator in none_stat_filtered['base_indicators']:
StrategyIndicators.use_indicators = [trade_indicator, base_indicator]
bt = Backtest(data, StrategyIndicators, cash=cash, commission=commission)
bt.run()
# 수익률, 승률, 승패 등으로 필터링 기준 조정 => 승률이 좋던가, 수익이 좋던가
if bt._results['Return [%]'] > top_profit and bt._results['# Trades'] > 0:
top_profit = bt._results['Return [%]']
top_cash = bt._results['Equity Final [$]']
print("최종 금액 : %0.2f" % bt._results['Equity Final [$]'])
print("총 수익률 : %0.2f%%" % bt._results['Return [%]'])
print(StrategyIndicators.use_indicators)
print('-' * 60)
bt.plot()
if int(bt._results['Return [%]']) > 0:
main_filterd.append(trade_indicator)
base_filterd.append(base_indicator)
e = int(time.time() - start_time)
print('2차 필터링 종료 :','{:02d}:{:02d}:{:02d}'.format(e // 3600, (e % 3600 // 60), e % 60))
# 중복 제거
main_filterd = [dict(t) for t in set([tuple(d.items()) for d in main_filterd])]
base_filterd = [dict(t) for t in set([tuple(d.items()) for d in base_filterd])]
# 랜덤워크로 최대수익 보조지표 조합 도출
while True:
main_indicators = random.choices(main_filterd, k=random.randrange(1, 5))
base_indicators = random.choices(base_filterd, k=random.randrange(0, len(base_filterd)))
StrategyIndicators.use_indicators = main_indicators + base_indicators
bt = Backtest(data, StrategyIndicators, cash=cash, commission=commission)
bt.run()
if bt._results['Return [%]'] > top_profit and bt._results['# Trades'] > 0:
top_profit = bt._results['Return [%]']
top_cash = bt._results['Equity Final [$]']
print("최종 금액 : %0.2f" % bt._results['Equity Final [$]'])
print("총 수익률 : %0.2f%%" % bt._results['Return [%]'])
print(StrategyIndicators.use_indicators)
print('-' * 60)
bt.plot()
pass
# 주도 매매 보조지표 검증
for indicator in res:
StrategyIndicators.use_indicators = [indicator]
bt = Backtest(data, StrategyIndicators, cash=cash, commission=commission)
bt.run()
# print(StrategyIndicators.use_indicators, "수익률 : %0.2f%%" % bt._results['Return [%]'])
# 수익률, 승률, 승패 등으로 필터링 기준 조정 => 승률이 좋던가, 수익이 좋던가
if bt._results['Return [%]'] > top_profit and bt._results['# Trades'] > 0:
top_profit = bt._results['Return [%]']
top_cash = bt._results['Equity Final [$]']
print("최종 금액 : %0.2f" % bt._results['Equity Final [$]'])
print("총 수익률 : %0.2f%%" % bt._results['Return [%]'])
print(StrategyIndicators.use_indicators)
print('-' * 60)
# bt.plot()
if int(bt._results['Return [%]']) > 0 and bt._results['# Trades'] > 0:
indicators.append(indicator)
# print('경우의 수 :', len(indicators))
sys.exit(1)
'''
작업 목록
- OBV 지표 다이버전스 활용 구현
- DI, DX 지표 사용법 숙지 후 구현
- 다이버전스를 활용하는 지표들 다이버전스 활용 구현
- 주도 지표, 베이스 지표 분류
- 캔들 패턴, 주도, 베이스 지표 조합 시뮬레이팅 구현 => 무작위
'''
# 다이버전스가 가능한 지표는 다이버전스 주도 지표로 분류(매매 지표)
# RSI => RSI : 베이스 지표 + RSIDIV : 다이버전스 주도 지표
# 두개 이상의 복합 보조지표 검증
for idx in list(range(2, len(indicators)+1)):
for indic in list(combinations(indicators, idx)):
StrategyIndicators.use_indicators = list(indic)
bt = Backtest(data, StrategyIndicators, cash=cash, commission=commission)
bt.run()
if bt._results['Return [%]'] > top_profit:
top_profit = bt._results['Return [%]']
top_cash = bt._results['Equity Final [$]']
# print(bt._results)
print("최종 금액 : %0.2f" % bt._results['Equity Final [$]'])
print("총 수익률 : %0.2f%%" % bt._results['Return [%]'])
print(StrategyIndicators.use_indicators)
print('-' * 60)
bt.plot()
# init variables
del bt
StrategyIndicators.value = dict()
# 17가지 4시간
e = int(time.time() - start_time)
print('{:02d}:{:02d}:{:02d}'.format(e // 3600, (e % 3600 // 60), e % 60))