87 lines
3.0 KiB
Python
87 lines
3.0 KiB
Python
from backtesting import Strategy
|
|
from signal_helper import *
|
|
|
|
|
|
class StrategyIndicator(Strategy):
|
|
use_indicators = None
|
|
indicators_data = None
|
|
cal_data = None
|
|
|
|
# Stop Profit/Loss
|
|
up_target = None
|
|
down_target = None
|
|
|
|
data_len = None
|
|
|
|
def init(self):
|
|
self.data_len = len(self.data.Close)
|
|
self.indicators_data = pd.DataFrame()
|
|
|
|
for p in self.use_indicators:
|
|
indicator, values = list(p.items())[0]
|
|
|
|
if type(values) == int:
|
|
indicator_info = indicator +"_"+ str(values)
|
|
elif type(values) == list:
|
|
indicator_info = indicator+"_"+"_".join(map(str, values))
|
|
|
|
self.indicators_data[indicator_info] = self.cal_data[indicator_info]
|
|
|
|
def next(self):
|
|
idx = (self._broker._i) - 1
|
|
row_data = list(self.indicators_data.iloc[idx])
|
|
prev_row_data = list(self.indicators_data.iloc[idx-1])
|
|
|
|
price = self.data.Close[-1]
|
|
sl = 0
|
|
tp = 0
|
|
|
|
# 배열 동시 시그널 매매
|
|
if len(row_data) == len(self.use_indicators) and prev_row_data:
|
|
if not (None in row_data):
|
|
if all(row_data):
|
|
if self.down_target > 0:
|
|
sl = price - (price * self.down_target)
|
|
if self.up_target > 0:
|
|
tp = price + (price * self.up_target)
|
|
|
|
# only short test
|
|
# if not self.orders.is_short:
|
|
# self.position.close()
|
|
|
|
# Only Long
|
|
if len(self.use_indicators) is 1: # 단일 지표일 경우
|
|
if not self.orders.is_long and not any(prev_row_data):
|
|
if sl != 0 and tp != 0:
|
|
self.buy(sl=sl, tp=tp)
|
|
elif sl != 0:
|
|
self.buy(sl=sl)
|
|
elif tp != 0:
|
|
self.buy(tp=tp)
|
|
else:
|
|
self.buy()
|
|
|
|
elif len(self.use_indicators) > 1: # 여러 지표일 경우
|
|
if not self.orders.is_long:
|
|
if sl != 0 and tp != 0:
|
|
self.buy(sl=sl, tp=tp)
|
|
elif sl != 0:
|
|
self.buy(sl=sl)
|
|
elif tp != 0:
|
|
self.buy(tp=tp)
|
|
else:
|
|
self.buy()
|
|
|
|
elif not any(row_data):
|
|
# short test
|
|
# if self.orders.is_long is None or self.orders.is_short is False:
|
|
# self.sell(sl=r_sl, tp=sl)
|
|
|
|
# only long test
|
|
if self.orders.is_long:
|
|
self.position.close()
|
|
|
|
# 시뮬레이터 종료 시 포지션 종료
|
|
if idx == self.data_len - 2:
|
|
self.position.close()
|