프로그래밍 거래에서 평균값과 미화값을 계산하는 것이 종종 필요합니다. 예를 들어 평균값과 변동률을 계산하는 경우와 같이. 높은 주파수와 긴 주기 계산을 필요로 할 때 오랜 시간 동안의 역사적 데이터를 보존해야하는 것은 불필요하고 자원이 많이 든다. 이 문서에서는 가중 평균값과 미화값을 계산하는 온라인 업데이트 알고리즘을 소개합니다. 이는 실시간 데이터 스트림과 동적 조정 거래 전략을 처리하는 데 특히 중요합니다. 특히 높은 주파수 전략을 다루고 있습니다. 이 문서에서는 거래자가 실제 거래에 신속하게 배포하고 응용하는 데 도움이되는 적절한 파이썬 코드 구현을 제공합니다.
만약 우리가 $\mu_n$로 n$ 데이터 포인트의 평균을 나타낸다면, 우리는 $\mu_{n-1}$ 데이터 포인트의 평균을 계산했다고 가정합니다. 이제 우리는 새로운 데이터 포인트 $x_{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}) $S_n = S_{n-1} + (x_n - \mu_{n-1}) $\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$의 함수인 효과적 샘플 크기 (effective sample size) 로 설명될 수 있다.
단순한 이동 평균 (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를 가지고 있고, 그 가중 인수는 $\alpha_1$이다. 이것은 매초에 새로운 데이터 포인트가 $\alpha_1$의 가중으로 EMA에 추가되고, 오래된 데이터 포인트의 영향은 $1 - \alpha_1$로 곱된다는 것을 의미합니다.
만약 우리가 업데이트의 빈도를 바꾸면, 예를 들어, $f$초에 한 번씩 업데이트하면, 우리는 새로운 중력 인수 $\alpha_2$를 찾고 싶어서, $f$초의 데이터 포인트의 전체 영향은 매초에 업데이트되는 것과 같을 것이다.
$f$초 동안, 업데이트가 이루어지지 않으면, 오래된 데이터 포인트의 영향은 $f$번으로 연속적으로 감소합니다. 각각의 경우 $1 - \alpha_1$로 곱합니다. 따라서, $f$초 후의 총 감소 요인은 $(1 - \alpha_1) ^ f$입니다.
$f$초에 한 번 갱신된 EMA가 갱신 주기에 한 번 갱신된 EMA와 같은 저하 효과를 가지도록 하기 위해, $f$초에 한 번 갱신된 EMA와 같은 총 저하 인수를 갱신 주기에 한 번 갱신된 EMA와 같도록 설정합니다:
$(1 - \alpha_1) ^ f = 1 - \alpha_2$
이 방정식을 풀면, 우리는 새로운 중력 인수를 얻습니다 $\alpha_2$:
$\alpha_2 = 1 - (1 - \alpha_1) ^f$
이 공식은 갱신 주파수의 변화로 EMA를 평행하게 유지하는 새로운 중량 요인 $\alpha_2$의 근사값을 준다. 예를 들어, 우리는 평균값 $\alpha_1$를 0.001로 계산하고, 10s마다 최신값을 업데이트하고, 1s로 변경하면 0.01에 해당하는 $\alpha_2$를 계산한다.
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)
고속 프로그래밍 거래에서 실시간 데이터의 신속한 처리가 중요합니다. 계산 효율성을 높이고 자원의 소모를 줄이기 위해, 이 문서에서는 데이터 스트림을 연속적으로 계산하는 중량화 평균과 분수를 계산하는 온라인 업데이트 알고리즘을 소개합니다. 실시간 인크리멘트 업데이트 계산은 또한 두 가지 자산 가격 관련성, 선형적 적합성 등과 같은 다양한 통계 데이터와 지표 계산에 사용될 수 있으며 잠재력이 크습니다. 인크리멘트 업데이트는 데이터를 신호 시스템으로 보는 것과 비교하여 고정 주기 계산에 대한 생각의 진화입니다.