|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
from .trade import Trade
|
|
|
|
|
|
|
|
|
|
class Executor(object):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, series, max_hold_bars):
|
|
|
|
|
'''
|
|
|
|
|
Constructor
|
|
|
|
|
'''
|
|
|
|
|
self.series = series
|
|
|
|
|
self.max_hold_bars = max_hold_bars
|
|
|
|
|
|
|
|
|
|
def execute(self, signals, long=True):
|
|
|
|
|
self.trades = []
|
|
|
|
|
sig_vectors = []
|
|
|
|
|
vec_length = 0
|
|
|
|
|
for signal in signals:
|
|
|
|
|
vec = signal.calculate(self.series)
|
|
|
|
|
sig_vectors.append(vec)
|
|
|
|
|
if vec_length == 0:
|
|
|
|
|
vec_length = len(vec)
|
|
|
|
|
else:
|
|
|
|
|
assert(vec_length == len(vec))
|
|
|
|
|
|
|
|
|
|
in_trade = False
|
|
|
|
|
current_entry_price = None
|
|
|
|
|
bar_counter = 0
|
|
|
|
|
entry_bar = 0
|
|
|
|
|
|
|
|
|
|
for i in range(0, vec_length):
|
|
|
|
|
if not in_trade:
|
|
|
|
|
has_signal = True
|
|
|
|
|
for vec in sig_vectors:
|
|
|
|
|
if vec[i] is None or vec[i] == False:
|
|
|
|
|
has_signal = False
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
if has_signal and i + 1 < vec_length:
|
|
|
|
|
in_trade = True
|
|
|
|
|
current_entry_price = self.series.get_open(i + 1)
|
|
|
|
|
entry_bar = i + 1
|
|
|
|
|
bar_counter = 0
|
|
|
|
|
else:
|
|
|
|
|
bar_counter += 1
|
|
|
|
|
if bar_counter >= self.max_hold_bars:
|
|
|
|
|
in_trade = False
|
|
|
|
|
if long:
|
|
|
|
|
trade_dir = Trade.LONG
|
|
|
|
|
else:
|
|
|
|
|
trade_dir = Trade.SHORT
|
|
|
|
|
self.trades.append(Trade(current_entry_price, self.series.get_close(i), entry_bar, i, trade_dir))
|
|
|
|
|
|
|
|
|
|
return self.trades
|