Панды Векторизованные Выгодные Закрыть - PullRequest
0 голосов
/ 12 мая 2019

Я пытаюсь найти быструю реализацию, где я могу определить способ найти точки выхода, если N прибыльных закрытий после исходного триггерного сигнала.

Итак, чтобы четко определить прибыльное закрытие, представьте, что мы получили длинный сигнал, говорящий нам покупать сейчас по цене 100. Стратегия выхода такова, что мы закроем существующую длинную позицию, если будет N = 2 закрытия (не не должно быть последовательным), когда цена больше, чем наша цена входа 100.

signal = pd.DataFrame([0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0], columns=["signal"])
price = pd.DataFrame([100,99,100,99,98,101,99,99,98,90,102,90,103,20,110,120,130], columns=["price"])
data = pd.concat([signal,price],axis=1)

Итак, в приведенном выше примере приведены некоторые данные. Правильный ответ - выход по индексу строки 10.

То, как я (неправильно) делаю это сейчас:

long_short = 1 # 1 equal going only only, -1 is going short
profit_n_exit = 2
sig_diffed = signal .diff().fillna(0.0).replace(-long_short,0)
sig_entry_px = (sig_diffed.replace(0,np.nan) * price ).fillna(method='pad')

# Profitable Closes Given Direction
exit_sig1 = ((np.sign(price  - sig_entry_px).fillna(0) == long_short) * 1)#.replace(0,np.nan)


# Cumulative Count of Profitable Closes
profit_close = (exit_sig1.groupby((exit_sig1 != exit_sig1.shift()).cumsum()).cumcount() + 1) * exit_sig1
profit_close = SignalFill(sig_diffed, sig_diffed.shift(profit_n_exit - 1)).replace(1,np.nan).replace(0,1) * profit_close
profit_close = ((profit_close >= profit_n_exit) * 1)

Моя реализация, похоже, рассчитывает только последовательные прибыльные последовательные закрытия. Мне также нужно найти способ подсчета непоследовательных прибыльных закрытий. есть идеи?

1 Ответ

0 голосов
/ 12 мая 2019

Вот решение, которое дает значения требуемых закрытий и возвращает 0, если для сигнала меньше 2 закрытий:

def get_second(x):
    tmp = x[x.gt(x.iloc[0])]
    return 0 if len(tmp) < 2 else tmp.iloc[1]

data.groupby(data.signal.cumsum()).price.apply(get_second)

Выход:

signal
0      0
1    102
Name: price, dtype: int64

Если нам нужен индекс (номер строки) закрытия:

def get_second_index(x):
    tmp = x[x.gt(x.iloc[0])]
    return -1 if len(tmp) < 2 else tmp.index[1]

(data.groupby(data.signal.cumsum())
     .price.apply(get_second_index))

дает

signal
0    -1
1    10
Name: price, dtype: int64

Еще один контрольный пример:

signal = pd.DataFrame([0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1], columns=["signal"])
price = pd.DataFrame([100,99,100,99,98,101,99,99,98,90,102,90,103,20,110,120,130], columns=["price"])
data = pd.concat([signal,price],axis=1)
data

дает:

signal
0      0
1    102
2    120
3      0
Name: price, dtype: int64

и

signal
0    -1
1    10
2    15
3    -1
Name: price, dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...