Учитывая временные ряды возвратов, нам нужно оценить совокупный доход для каждой комбинации начальной точки до конечной точки.
Первый трюк состоит в том, чтобы преобразовать временные ряды возвратов в ряд возвратов индексы. Учитывая ряд возвратных индексов, я могу рассчитать возврат по любому подпериоду с индексом возврата в начале ri_0 и в конце ri_1. Вычисление: ri_1 / ri_0 - 1.
Второй трюк состоит в том, чтобы создать вторую серию обратных индексов возврата. Если r - моя серия возвратных индексов, то 1 / r - моя серия инверсий.
Третий прием заключается в том, чтобы взять матричное произведение r * (1 / r). Представьте.
r является матрицей nx 1. (1 / r). Перемещение представляет собой 1 x n -матрицу. Получаемый продукт содержит каждую комбинацию ri_j / ri_k. Просто вычтите 1, и я действительно получил доход.
Четвертый трюк заключается в том, чтобы я ограничил свой знаменатель представлением периодов до тех, которые представлены числителем.
Ниже представлена моя векторизованная функция.
import numpy as np
import pandas as pd
def max_dd(returns):
# make into a DataFrame so that it is a 2-dimensional
# matrix such that I can perform an nx1 by 1xn matrix
# multiplication and end up with an nxn matrix
r = pd.DataFrame(returns).add(1).cumprod()
# I copy r.T to ensure r's index is not the same
# object as 1 / r.T's columns object
x = r.dot(1 / r.T.copy()) - 1
x.columns.name, x.index.name = 'start', 'end'
# let's make sure we only calculate a return when start
# is less than end.
y = x.stack().reset_index()
y = y[y.start < y.end]
# my choice is to return the periods and the actual max
# draw down
z = y.set_index(['start', 'end']).iloc[:, 0]
return z.min(), z.argmin()[0], z.argmin()[1]
Как это выполняется?
для векторизованного решения Я выполнил 10 итераций по временным рядам длин [10, 50, 100, 150 , 200]. Время, затраченное на это:
10: 0.032 seconds
50: 0.044 seconds
100: 0.055 seconds
150: 0.082 seconds
200: 0.047 seconds
Тот же тест для петлевого решения ниже:
10: 0.153 seconds
50: 3.169 seconds
100: 12.355 seconds
150: 27.756 seconds
200: 49.726 seconds
Ответ Александра обеспечивает превосходные результаты. Тот же тест с использованием модифицированного кода
10: 0.000 seconds
50: 0.000 seconds
100: 0.004 seconds
150: 0.007 seconds
200: 0.008 seconds
Я изменил его код на следующую функцию:
def max_dd(returns):
r = returns.add(1).cumprod()
dd = r.div(r.cummax()).sub(1)
mdd = drawdown.min()
end = drawdown.argmin()
start = r.loc[:end].argmax()
return mdd, start, end
Можно использовать дурак для отправки электронного письма с вложением
mutt -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt
В зависимости от Вашей версии Linux это можно назвать почтой. Заключить @David в кавычки выше:
mail -s "Backup" -a mysqldbbackup.sql backup@email.com < message.txt
или также:
cat message.txt | mail -s "Backup" -a mysqldbbackup.sql backup@email.com
От рассмотрения man mailx
, mailx программа не имеет опции для присоединения файла. Вы могли использовать другую программу, такую как дурак.
echo "This is the message body" | mutt -a file.to.attach -s "subject of message" recipient@domain.com
Параметры командной строки для дурака можно показать с mutt -h
.
Или, провальный дурак:
gzip -c mysqldbbackup.sql | uuencode mysqldbbackup.sql.gz | mail -s "MySQL DB" backup@email.com
метапочта имеет инструмент, метаотправляют
metasend -f mysqlbackup.sql.gz -t backup@email.com -s Backup -m application/x-gzip -b
Я использую mpack.
mpack -s subject file user@example.com
К сожалению, mpack не распознает '-' как псевдоним для stdin. Но следующая работа, которую можно легко обернуть в псевдоним (оболочки) или сценарий:
mpack -s subject /dev/stdin loser@example.com < file