def vectorized(initial_cash, cashes):
balances = np.concatenate([[initial_cash], cashes])
cumulative_max = np.maximum.accumulate(balances)
drawdowns = (cumulative_max — balances) / cumulative_max
return np.max(drawdowns)

Работает в 7 медленнее. Оно и логично. Версия на numba — однопроходная, без выделений памяти на массивы, а это максимально эффективное использование L1 кэша. Векторизованнная версия имеет 4 векторных операции и 4 вспомогательных массива, под которые выделяется память. Даже если некоторые из 4 векторных операций используют simd, то использование лишних массивов и несколько проходов убивают производительность. Ну и сильно сомневаюсь, что функция np.maximum.accumulate имеет simd реализацию, т.к. по своей природе алгоритм последовательный. Сорри за занудство:)

