2015-05-18 2 views
1

У меня есть следующий dataframe:Выберите первую строку, которая соответствует определенному условию

Date   RunningTotal 
01-05-2015 100 
02-05-2015 150 
03_05-2015 140 
04-05-2015 130 
05_05_2015 140 
06-05-2015 170 
07-05-2015 180 

Мне нужно, чтобы определить начало и конец максимального drawdown для нарастающего итога. До сих пор я могу определить позицию стартового индекса для максимальной просадки и индекс позиции максимального сокращения следующим образом:

df.set_index(['RunningTotal'], inplace=True) 
max_drawdown_ix = np.argmax(np.maximum.accumulate(df.index) - df.index)+1 
start_drawdown_ix = np.argmax(df.index[:max_drawdown_ix]) 

То, что я не смог сделать, это определить индекс позиции, когда концы просадки (т. е. когда текущая общая сумма выше, чем была при начале просадки). В приведенном выше примере будет приведен следующий результат:

max_drawdown_ix occurs on 04_05_2015 which is index position 3 
start_drawdown_ix occurs on 02_05_2015 which is index position 1 
end_drawdown_ix occurs on 06_05_2015 which is index position 5 

Любые предложения относительно того, как определить, когда заканчивается наибольшая/максимальная просадка? (т. е. как определить, когда первое происшествие - это то, что выполняемое движение больше, чем start_drawdown_ix, которое происходит после max_drawdown_ix)

+0

Данные могут содержать более одного просадки? Если да, вам нужны все из них самого большого? – matousc

+0

Мне просто нужен самый большой. Код, который я разместил правильно, идентифицирует начало самой большой просадки, а также самую большую позицию просадки. Мне нужно знать, когда заканчивается самая большая просадка. (т. е. когда общее число запусков становится больше, чем было до начала просадки). Спасибо. – darkpool

ответ

2

Сначала давайте рассчитаем вашу просадку.

df['drawdown'] = df.RunningTotal.cummax() - df.RunningTotal 

Далее следует выяснить, где произошло максимальное просадка.

max_dd_idx = df.drawdown.idxmax() 
max_dd_date = df.Date.iat[max_dd_idx] 
>>> max_dd_date 
'04-05-2015' 

Затем мы должны найти первое нулевое значение перед этим местоположением индекса, чтобы найти начало периода просадки.

dd_start_idx = (df.drawdown.loc[:max_dd_idx] 
       [df.drawdown.loc[:max_dd_idx] == 0].index[-1]) 
dd_start_date = df.Date.iat[dd_start_idx] 
>>> dd_start_idx 
'02-05-2015' 

Затем получить местоположение индекса на конец максимальной просадки периода (то есть, где максимальный ДД первый становится равным нулю после Max DD).

dd_end_idx = (df.drawdown.loc[max_dd_idx:] 
       [df.drawdown.loc[max_dd_idx:] == 0].index[0]) 
dd_end_date = df.Date.iat[dd_end_idx] 
>>> dd_end_date 
'06-05-2015' 

Обратите внимание, что вам нужно будет сделать, ограничивающее поверки, чтобы избежать ошибок индекса, если текущий период просадки продолжается.

if len(df.drawdown.loc[max_dd_idx:][df.drawdown.loc[max_dd_idx:] == 0]) == 0: 
    pass # Current drawdown period is ongoing. 
+0

Отлично, спасибо @Alexander – darkpool

+0

Голос был бы также оценен. (-; – Alexander

+0

Извините, я решил выбрать это, поскольку правильный ответ был всем, что требовалось. Нет проблем, ... upvoted :) – darkpool

Смежные вопросы