
В программной торговле часто возникает необходимость рассчитать среднее значение и дисперсию, например, при расчете таких индикаторов, как скользящие средние и волатильность. Когда нам требуются высокочастотные и долгосрочные расчеты, нам необходимо сохранять долгосрочные исторические данные, что не нужно и требует больших затрат времени и ресурсов. В данной статье представлен алгоритм онлайн-обновления для вычисления средневзвешенных значений и дисперсий, что особенно важно для обработки потоков данных в реальном времени и динамической корректировки торговых стратегий, особенно высокочастотных стратегий. В статье также представлена соответствующая реализация кода Python, которая поможет трейдерам быстро развернуть и применить этот алгоритм в реальных транзакциях.
Если мы используем \(\mu_n\) для представления среднего значения \(n\)-й точки данных, предполагая, что мы уже вычислили среднее значение \(\mu_{n-1}\) для \({n-1}\)-й точки данных , теперь мы получили новую точку данных \(x_{n}\). Мы хотим вычислить новое среднее значение \(\mu_{n}\), включающее эту новую точку данных. Ниже приводится подробный вывод.
\(\mu_n = \frac{1}{n} \sum_{i=1}^{n} x_i\) \(\mu_n = \frac{1}{n} \left( x_n + \sum_{i=1}^{n-1} x_i \right)\) \(\mu_{n-1} = \frac{1}{n-1} \sum_{i=1}^{n-1} x_i\) \((n-1)\mu_{n-1} = \sum_{i=1}^{n-1} x_i\) \(\mu_n = \frac{1}{n} \left( x_n + (n-1)\mu_{n-1} \right)\) \(\mu_n = \mu_{n-1} + \frac{1}{n} (x_n - \mu_{n-1})\)
Процесс обновления дисперсии можно разложить на следующие этапы:
\(S_n = \sum_{i=1}^{n} (x_i - \mu_n)^2\) \(S_n = \sum_{i=1}^{n} x_i^2 - n\mu_n^2\) \(S_n - S_{n-1} = x_n^2 - n\mu_n^2 + (n - 1)\mu_{n-1}^2\) \(S_n - S_{n-1} = (x_n - \mu_{n-1})(x_n - \mu_n)\) \(S_n = S_{n-1} + (x_n - \mu_{n-1})(x_n - \mu_n)\) \(\sigma_n^2 = \frac{S_n}{n}\)
Как видно из двух приведенных выше формул, этот процесс позволяет нам обновлять новое среднее значение и дисперсию при получении каждой новой точки данных \(x_n\), сохраняя только среднее значение и дисперсию предыдущих данных, без сохранения исторических данных. , и расчет происходит быстрее. Но проблема в том, что таким образом вычисляются среднее значение и дисперсия всей выборки, в то время как в реальной стратегии нам необходимо рассматривать определенный фиксированный период. Наблюдая за средним обновлением выше, мы можем видеть, что новое среднее обновление представляет собой отклонение новых данных от прошлого среднего, умноженное на отношение. Если это отношение фиксировано, мы получим экспоненциально взвешенное среднее, которое мы обсудим далее.
Экспоненциально взвешенное среднее можно определить с помощью следующего рекурсивного соотношения:
\(\mu_t = \alpha x_t + (1 - \alpha) \mu_{t-1}\)
где \(\mu_t\) — экспоненциально взвешенное среднее значение в момент времени \(t\), \(x_t\) — наблюдаемое значение в момент времени \(t\), \(\alpha\) — весовой коэффициент, а \(\mu_{t-1}\) Это экспоненциально взвешенное среднее значение предыдущего момента времени.
Для дисперсии нам необходимо вычислить экспоненциально взвешенное среднее квадратов отклонений в каждой точке времени. Этого можно добиться с помощью следующего рекуррентного соотношения:
\(S_n = \alpha S_{n-1} + (1 - \alpha)(x_n - \mu_n)(x_n - \mu_{n-1})\)
где \(\sigma_t^2\) — экспоненциально взвешенная дисперсия в момент времени \(t\), а \(\sigma_{t-1}^2\) — экспоненциально взвешенная дисперсия в предыдущий момент времени.
Обратите внимание на экспоненциально взвешенное среднее и дисперсию. Их инкрементальные формы обновления соответствуют интуиции. Они оба сохраняют часть прошлого значения и добавляют новое изменение. Конкретный процесс вывода можно сослаться на эту статью: https://fanf2.user . srcf.net/hermes/doc/antiforgery/stats.pdf
Среднее арифметическое (также известное как среднее арифметическое) и экспоненциально взвешенное среднее — это две распространённые статистические меры, каждая из которых имеет различные характеристики и области применения. Простое среднее значение придает каждому наблюдению одинаковый вес и отражает центральное положение набора данных. Экспоненциально взвешенное среднее значение представляет собой рекурсивный расчет, который придает больший вес более поздним наблюдениям. Вес уменьшается экспоненциально по мере того, как наблюдение удаляется от текущего времени.
Хотя простое среднее и экспоненциально взвешенное среднее концептуально различны, мы можем сделать так, чтобы экспоненциально взвешенное среднее приближенно соответствовало простому среднему для определенного числа наблюдений, выбрав соответствующее значение \(\alpha\). Эту приблизительную взаимосвязь можно описать эффективным размером выборки, который является функцией весового коэффициента \(\alpha\) в экспоненциально взвешенном среднем.
Простая скользящая средняя (SMA) — это среднее арифметическое всех цен в течение заданного временного окна. Для временного окна \(N\) центроид SMA (где находится среднее значение) можно считать следующим:
\(\text{SMA-центроид} = \frac{1 + N}{2}\)
Экспоненциальная скользящая средняя (EMA) — это взвешенное среднее, где более поздние точки данных имеют больший вес. Вес EMA уменьшается экспоненциально с течением времени. Центроид EMA можно получить путем суммирования следующих рядов:
\(\text{EMA-центроид} = \alpha \times \left[1 + 2(1 - \alpha) + 3(1 - \alpha)^2 + \cdots \right] = \frac{1}{\alpha}\)
Если предположить, что SMA и EMA имеют один и тот же центр масс, то получим:
\(\frac{1 + N}{2} = \frac{1}{\alpha}\)
Решая это уравнение, мы можем получить связь между \(\alpha\) и \(N\):
\(\alpha = \frac{2}{N + 1}\)
Это означает, что для заданной \(N\)-дневной SMA соответствующее значение \(\alpha\) можно использовать для расчета «эквивалентной» EMA таким образом, чтобы у них был одинаковый центр масс и результаты были очень похожими.
Предположим, у нас есть EMA, которая обновляется каждую секунду с весовым коэффициентом \(\alpha_1\). Это означает, что каждую секунду к EMA добавляется новая точка данных с весом \(\alpha_1\), в то время как влияние старых точек данных умножается на \(1 - \alpha_1\).
Если мы изменим частоту обновления, скажем, на обновление каждые \(f\) секунд, мы хотим найти новый весовой коэффициент \(\alpha_2\), такой, чтобы общее влияние точки данных в течение \(f\) секунд было таким же, как при обновлении каждую секунду. .
В течение \(f\) секунд, если не будет сделано никаких обновлений, влияние старых точек данных будет непрерывно уменьшаться \(f\) раз, каждый раз умножаясь на \(1 - \alpha_1\). Таким образом, общий коэффициент затухания через \(f\) секунд равен \((1 - \alpha_1)^f\).
Чтобы EMA, обновляемая каждые \(f\) секунд, имела такой же эффект затухания за один цикл обновления, как и EMA, обновляемая один раз в секунду, мы устанавливаем общий коэффициент затухания после \(f\) секунд равным коэффициенту затухания за одно обновление. цикл:
\((1 - \alpha_1)^f = 1 - \alpha_2\)
Решая это уравнение, получаем новый весовой коэффициент \(\alpha_2\):
\(\alpha_2 = 1 - (1 - \alpha_1)^f\)
Эта формула дает приближение для нового весового коэффициента \(\alpha_2\), который сохраняет постоянным эффект сглаживания EMA при изменении частоты обновления. Например, мы вычисляем среднее значение цены \(\alpha_1\) как 0,001 и обновляем последнюю цену каждые 10 секунд. Если мы изменим его на 1 секунду, эквивалент \(\alpha_2\) будет около 0,01
class ExponentialWeightedStats:
def __init__(self, alpha):
self.alpha = alpha
self.mu = 0
self.S = 0
self.initialized = False
def update(self, x):
if not self.initialized:
self.mu = x
self.S = 0
self.initialized = True
else:
temp = x - self.mu
new_mu = self.mu + self.alpha * temp
self.S = self.alpha * self.S + (1 - self.alpha) * temp * (x - self.mu)
self.mu = new_mu
@property
def mean(self):
return self.mu
@property
def variance(self):
return self.S
# 使用示例
alpha = 0.05 # 权重因子
stats = ExponentialWeightedStats(alpha)
data_stream = [] # 数据流
for data_point in data_stream:
stats.update(data_point)
В высокочастотной программной торговле решающее значение имеет быстрая обработка данных в реальном времени. Для повышения эффективности вычислений и снижения потребления ресурсов в данной статье представлен алгоритм онлайн-обновления для непрерывного вычисления взвешенного среднего значения и дисперсии потока данных. Расчет инкрементных обновлений в режиме реального времени также может использоваться для расчета различных статистических данных и показателей, таких как корреляция между ценами двух активов, линейная подгонка и т. д., что имеет большой потенциал. Инкрементные обновления рассматривают данные как систему сигналов, что является эволюцией мышления по сравнению с расчетами с фиксированным периодом. Если в вашей стратегии также есть часть, которая сохраняет расчеты исторических данных, вы можете также модифицировать ее в соответствии с этой идеей, регистрировать только оценку состояния системы, а при поступлении новых данных обновлять состояние системы и т. д.